Skip to content

Fix double-minted secret at first provision - #7

Merged
solsson merged 2 commits into
mainfrom
fix/first-provisioning-double-mint
Sep 4, 2026
Merged

solsson merged 2 commits into
mainfrom
fix/first-provisioning-double-mint

Conversation

@solsson

@solsson solsson commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

No description provided.

solsson and others added 2 commits September 4, 2026 07:19
First provisioning of a serviceAccount-enabled access minted two
keys about a second apart and revoked the first, stranding any
consumer that had read the Secret in between (11 of 19
provisionings in one project; a gateway pod served a lapsed token
for hours with the access reporting Ready=True).

The reconciler's Secret write and status patch both re-enqueue
the access, so a second reconcile always follows the first mint
within a second. ensureAccessKey then verified the Secret's key
against keys.list, and the listing - eventually consistent - had
not caught up yet. The code read that as "revoked out of band",
minted a replacement, and the reconciler dutifully revoked the
key it had just handed out.

A revoke is irreversible, so it must rest on positive evidence.
The Secret's key is now reused unless it does not parse, names
another identity, or the listing shows it expired. Absence from
the listing no longer triggers anything. The consequence is that
a key deleted server-side is no longer replaced automatically;
the rotation runbook becomes "delete the Secret", which mints a
fresh key and, through the existing replaced-principal path,
revokes the previous one. SPEC, the driver docs and the example
README are updated accordingly.

The fake IAM gains an "unlisted" set so the lifecycle test covers
the lag; it fails on the previous code with the second key
minted.

Release pin bumped.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
When GrantAccess returns a new principal the reconciler revokes
the previous one, which is the right thing for a lost or rotated
Secret - and invisible: the access stays Ready=True, the Secret
holds a valid key, and nothing in the controller log names the
namespace. The stranded gateway pod in
ISSUE_first_provisioning_mints_two_keys_and_revokes_the_one_a_consumer_read.md
was only found through the IAM audit log.

A Normal PrincipalReplaced event now names the revoked and the
current principal and tells the operator to restart consumers
that loaded the Secret once. Steady-state reconciles emit
nothing; the test covers both.

Release pin bumped.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@solsson
solsson merged commit 0b1515a into main Sep 4, 2026
2 checks passed
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.

1 participant