Skip to content

fix: provisioner + signer repro-blockers for local bring-up - #58

Open
rickstaa wants to merge 4 commits into
feat/session-exchange-openmeter-provisioningfrom
rs/pr57-provision-signer-fixes
Open

fix: provisioner + signer repro-blockers for local bring-up#58
rickstaa wants to merge 4 commits into
feat/session-exchange-openmeter-provisioningfrom
rs/pr57-provision-signer-fixes

Conversation

@rickstaa

@rickstaa rickstaa commented Jul 3, 2026

Copy link
Copy Markdown
Member

Three small fixes hit while bringing up this PR's stack (auth0-provisioner + remote-signer) locally. Each is an independent repro-blocker; no functional change to the exchange/provisioning flow.

Fixes

  • remote-signer/entrypoint.sh — source the keystore password from SIGNER_ETH_PASSWORD when set. Previously the password was only read from /data/.eth-password, so a password supplied via .env never reached the file and the signer could not unlock its keystore.
  • auth0-provisioner/provision/bootstrap.sh — look up the client-grant by client_id only and select the matching audience in jq. The prior raw audience query param went out unencoded and returned a mismatched grant, causing a 409 client_grant_conflict on re-run.
  • auth0-provisioner/provision/bootstrap-credentials-exchange-action.sh — accept the auth0 CLI when resolved from PATH (command -v), not just as a local executable ([ -x ]).

Notes

@rickstaa
rickstaa requested a review from eliteprox July 3, 2026 19:56
@rickstaa
rickstaa force-pushed the rs/pr57-provision-signer-fixes branch from 8c49a5c to 342466d Compare July 3, 2026 20:00
rickstaa and others added 3 commits July 3, 2026 22:00
… env

The entrypoint only read the password from /data/.eth-password, so a
password supplied via .env (SIGNER_ETH_PASSWORD) never reached the file
and the signer could not unlock its keystore. Write the env value to the
password file when set, falling back to the existing file otherwise.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Querying client-grants with a raw audience query param left the URL
unencoded and returned a mismatched grant, causing a 409
client_grant_conflict on re-run. Query by client_id only and select the
matching audience in jq instead.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The action bootstrap only accepted the CLI via [ -x "$AUTH0_BIN" ],
which fails when auth0 is resolved from PATH rather than a local file.
Accept either form.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@rickstaa
rickstaa force-pushed the rs/pr57-provision-signer-fixes branch from 342466d to 131a5b7 Compare July 3, 2026 20:00

@eliteprox eliteprox left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Approved with small nites

local client_id="$1" audience="$2" scopes_json="$3" gid body resp
ENSURED_GRANT_CREATED=0
gid="$(aapi_get "client-grants?client_id=${client_id}&audience=${audience}" | jq -r '.[0].id // empty')"
gid="$(aapi_get "client-grants?client_id=${client_id}" | jq -r --arg a "$audience" '[.[] | select(.audience==$a) | .id] | first // empty')"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[.[] | select(.audience==$a) | .id] | first // empty picks an arbitrary match if multiple client-grants exist for the same (client_id, audience) pair, without detecting or reporting the duplication. Failure scenario: since the old unencoded-query bug likely caused previous runs to create duplicate grants instead of finding the existing one (plausibly the actual root cause of the 409 this PR fixes), a tenant carrying that leftover state could now have the script non-deterministically PATCH a different grant on each rerun rather than surfacing the conflict. Worth a guard that errors (or warns) if more than one grant matches.


if [ ! -f /data/.eth-password ]; then
if [ -n "${SIGNER_ETH_PASSWORD:-}" ]; then
printf '%s' "$SIGNER_ETH_PASSWORD" >/data/.eth-password

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small nit, you could optionally log what is happening here (without logging any secrets of course).

…n fallbacks

- bootstrap.sh: percent-encode client_id + audience (RFC 3986) and keep the
  Management API filter instead of client-side jq matching; die when more than
  one grant matches a (client_id, audience) pair rather than PATCHing an
  arbitrary one.
- bootstrap-credentials-exchange-action.sh: resolve the auth0 CLI via a single
  path (PATH, else local copy) instead of a dual command -v / -x chain.
- entrypoint.sh: require an explicit keystore password (SIGNER_ETH_PASSWORD or
  a mounted /data/.eth-password) and fail loudly instead of silently writing an
  empty password file; log the non-secret source.
@eliteprox eliteprox linked an issue Jul 17, 2026 that may be closed by this pull request
eliteprox added a commit that referenced this pull request Aug 12, 2026
Cherry-picks the two auth0-provisioner fixes from #58 (rickstaa). Both are
repro-blockers for the one-command bootstrap this PR adds, and the second one
undermines the idempotency claim that is the main argument for keeping this
provisioner over the Go CLI in #33.

- bootstrap-credentials-exchange-action.sh: when the auth0 CLI is on PATH,
  command -v succeeds and AUTH0_BIN stays "auth0", after which [ -x "auth0" ]
  tests a relative path in the working directory and fails. The script died
  precisely when the CLI was available.

- bootstrap.sh: the client-grants filter sent the audience unencoded. An
  audience is a URI, so ":" and "/" broke the query and the Management API
  returned a mismatched grant, producing 409 client_grant_conflict on re-run.
  Both filters are now percent-encoded, and more than one matching grant is a
  hard stop rather than a silent .[0] pick.

#58's third fix (remote-signer/entrypoint.sh reading SIGNER_ETH_PASSWORD) is
not included: that bug is on main, no PR in this stack touches remote-signer,
and it should land independently rather than ride along here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
eliteprox added a commit that referenced this pull request Aug 13, 2026
Cherry-picks the two auth0-provisioner fixes from #58 (rickstaa). Both are
repro-blockers for the one-command bootstrap this PR adds, and the second one
undermines the idempotency claim that is the main argument for keeping this
provisioner over the Go CLI in #33.

- bootstrap-credentials-exchange-action.sh: when the auth0 CLI is on PATH,
  command -v succeeds and AUTH0_BIN stays "auth0", after which [ -x "auth0" ]
  tests a relative path in the working directory and fails. The script died
  precisely when the CLI was available.

- bootstrap.sh: the client-grants filter sent the audience unencoded. An
  audience is a URI, so ":" and "/" broke the query and the Management API
  returned a mismatched grant, producing 409 client_grant_conflict on re-run.
  Both filters are now percent-encoded, and more than one matching grant is a
  hard stop rather than a silent .[0] pick.

#58's third fix (remote-signer/entrypoint.sh reading SIGNER_ETH_PASSWORD) is
not included: that bug is on main, no PR in this stack touches remote-signer,
and it should land independently rather than ride along here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@eliteprox

Copy link
Copy Markdown
Collaborator

Adopted two of these three into #82, which carries auth0-provisioner/ now that #57 has been split into a reviewable stack (#78#79#80#81#82). Attribution kept in the commit message.

Taken:

  • bootstrap.sh client-grant encoding. This one matters more than its size suggests. Idempotency is the main argument for keeping this shell provisioner over the Go CLI in feat: Go bootstrap CLI for Auth0 + OpenMeter/Konnect #33, and feat(bootstrap): one-command provisioning + sdk-config emitter #82's own README and script header claim re-running is safe — a claim that was false while the audience went out unencoded and re-runs 409'd. The duplicate-grant hard stop came along with it.
  • bootstrap-credentials-exchange-action.sh CLI resolution. Worth spelling out how bad this was: when auth0 is on PATH, command -v succeeds so AUTH0_BIN stays "auth0", and then [ -x "auth0" ] tests a relative path in the working directory and fails. The script died precisely when the CLI was available.

Not taken:

  • remote-signer/entrypoint.sh SIGNER_ETH_PASSWORD. Deliberately left here. That bug is on main and no PR in the stack touches remote-signer, so folding it in would have meant this PR getting absorbed and a real fix quietly vanishing with it. It should land on its own — happy to open a small PR for just that if you'd rather not carry this one.

One thing worth a conscious nod when the grant fix is reviewed: ensure_client_grant now calls die internally on duplicate grants, but callers invoke it as ensure_client_grant … || { rollback_app; die … }. Since die exits from within, rollback_app never runs on that path. It reads deliberate to me — a duplicate-grant state wants a human, and rolling back could delete real Auth0 objects — but it is a behaviour change rather than a pure bug fix.

eliteprox added a commit that referenced this pull request Aug 13, 2026
Cherry-picks the two auth0-provisioner fixes from #58 (rickstaa). Both are
repro-blockers for the one-command bootstrap this PR adds, and the second one
undermines the idempotency claim that is the main argument for keeping this
provisioner over the Go CLI in #33.

- bootstrap-credentials-exchange-action.sh: when the auth0 CLI is on PATH,
  command -v succeeds and AUTH0_BIN stays "auth0", after which [ -x "auth0" ]
  tests a relative path in the working directory and fails. The script died
  precisely when the CLI was available.

- bootstrap.sh: the client-grants filter sent the audience unencoded. An
  audience is a URI, so ":" and "/" broke the query and the Management API
  returned a mismatched grant, producing 409 client_grant_conflict on re-run.
  Both filters are now percent-encoded, and more than one matching grant is a
  hard stop rather than a silent .[0] pick.

#58's third fix (remote-signer/entrypoint.sh reading SIGNER_ETH_PASSWORD) is
not included: that bug is on main, no PR in this stack touches remote-signer,
and it should land independently rather than ride along here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
eliteprox added a commit that referenced this pull request Aug 13, 2026
Cherry-picks the two auth0-provisioner fixes from #58 (rickstaa). Both are
repro-blockers for the one-command bootstrap this PR adds, and the second one
undermines the idempotency claim that is the main argument for keeping this
provisioner over the Go CLI in #33.

- bootstrap-credentials-exchange-action.sh: when the auth0 CLI is on PATH,
  command -v succeeds and AUTH0_BIN stays "auth0", after which [ -x "auth0" ]
  tests a relative path in the working directory and fails. The script died
  precisely when the CLI was available.

- bootstrap.sh: the client-grants filter sent the audience unencoded. An
  audience is a URI, so ":" and "/" broke the query and the Management API
  returned a mismatched grant, producing 409 client_grant_conflict on re-run.
  Both filters are now percent-encoded, and more than one matching grant is a
  hard stop rather than a silent .[0] pick.

#58's third fix (remote-signer/entrypoint.sh reading SIGNER_ETH_PASSWORD) is
not included: that bug is on main, no PR in this stack touches remote-signer,
and it should land independently rather than ride along here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
eliteprox added a commit that referenced this pull request Aug 17, 2026
Cherry-picks the two auth0-provisioner fixes from #58 (rickstaa). Both are
repro-blockers for the one-command bootstrap this PR adds, and the second one
undermines the idempotency claim that is the main argument for keeping this
provisioner over the Go CLI in #33.

- bootstrap-credentials-exchange-action.sh: when the auth0 CLI is on PATH,
  command -v succeeds and AUTH0_BIN stays "auth0", after which [ -x "auth0" ]
  tests a relative path in the working directory and fails. The script died
  precisely when the CLI was available.

- bootstrap.sh: the client-grants filter sent the audience unencoded. An
  audience is a URI, so ":" and "/" broke the query and the Management API
  returned a mismatched grant, producing 409 client_grant_conflict on re-run.
  Both filters are now percent-encoded, and more than one matching grant is a
  hard stop rather than a silent .[0] pick.

#58's third fix (remote-signer/entrypoint.sh reading SIGNER_ETH_PASSWORD) is
not included: that bug is on main, no PR in this stack touches remote-signer,
and it should land independently rather than ride along here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
eliteprox added a commit that referenced this pull request Aug 17, 2026
Cherry-picks the two auth0-provisioner fixes from #58 (rickstaa). Both are
repro-blockers for the one-command bootstrap this PR adds, and the second one
undermines the idempotency claim that is the main argument for keeping this
provisioner over the Go CLI in #33.

- bootstrap-credentials-exchange-action.sh: when the auth0 CLI is on PATH,
  command -v succeeds and AUTH0_BIN stays "auth0", after which [ -x "auth0" ]
  tests a relative path in the working directory and fails. The script died
  precisely when the CLI was available.

- bootstrap.sh: the client-grants filter sent the audience unencoded. An
  audience is a URI, so ":" and "/" broke the query and the Management API
  returned a mismatched grant, producing 409 client_grant_conflict on re-run.
  Both filters are now percent-encoded, and more than one matching grant is a
  hard stop rather than a silent .[0] pick.

#58's third fix (remote-signer/entrypoint.sh reading SIGNER_ETH_PASSWORD) is
not included: that bug is on main, no PR in this stack touches remote-signer,
and it should land independently rather than ride along here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
eliteprox added a commit that referenced this pull request Aug 17, 2026
Cherry-picks the two auth0-provisioner fixes from #58 (rickstaa). Both are
repro-blockers for the one-command bootstrap this PR adds, and the second one
undermines the idempotency claim that is the main argument for keeping this
provisioner over the Go CLI in #33.

- bootstrap-credentials-exchange-action.sh: when the auth0 CLI is on PATH,
  command -v succeeds and AUTH0_BIN stays "auth0", after which [ -x "auth0" ]
  tests a relative path in the working directory and fails. The script died
  precisely when the CLI was available.

- bootstrap.sh: the client-grants filter sent the audience unencoded. An
  audience is a URI, so ":" and "/" broke the query and the Management API
  returned a mismatched grant, producing 409 client_grant_conflict on re-run.
  Both filters are now percent-encoded, and more than one matching grant is a
  hard stop rather than a silent .[0] pick.

#58's third fix (remote-signer/entrypoint.sh reading SIGNER_ETH_PASSWORD) is
not included: that bug is on main, no PR in this stack touches remote-signer,
and it should land independently rather than ride along here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Administrative API wrapper over KongHQ metering & billing

2 participants