Repository navigation
R2 mint custody cells granted by iam-converge (grant sets); bootstrap creates bare custody containers (B') - #13298
Merged
Merged
Conversation
…en secrets Run 37211074479 (r2_workspace_object_read_mint) refused at the precondition GET: the fleet convergence identity held no secretmanager.secrets.get on cloudflare-r2-workspace-read-token. Adds viewer / versionAdder / accessor cells for cloudflare-r2-workspace-read-token and -write-token, mirroring the bucket-admin cells, with operator converge entries. Witness 6/6. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…are requires Network like main's Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…custody-iam-reach
…ant set; bootstrap creates bare custody containers
…fold-residue gate refused 16 wildcard sites) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… approval_run_identity)
… gunbc.auth.approval_run_identity's; same fix quick-moth-82 verified 24/24) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
added 3 commits
October 4, 2026 16:59
…absent, never retried), grant member is the convergence principal, census realizes R2 cells federated
…automatic create until observed present or operator-disposed (reuses #13291's election journal)
… the listing only discovers candidate operations
added 4 commits
October 4, 2026 22:15
…emoved it; this branch never changed it
…75902): gcp_iam_converge grant_set_payload_permissions, read by the readback, the bootstrap probe and the witness
This was referenced Oct 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Order: #13291, then this PR. Stacked on #13291 (
gcp-iam-bootstrap-land). #13286 is closed as superseded: its commit is merged in here, so this PR carries the six workspace cells, and the diff stands on #13291 alone. Retarget to main once #13291 lands.Operator decision B' (2026-10-04, relayed by warm-badger-442 and still-dove-673): the R2 mint custody cells move from an operator gcloud session (
GcloudPrintToken) to iam-converge, under the existinggcp-iam-convergeapproval mode. The bootstrap creates the custody containers bare, so no recurring identity holdssecretmanager.secrets.create.What changes
gunbc.auth.gcp_iam_converge: grant sets.GrantSet/gcp_iam_converge_grant_setsadd a second estate population beside the federation targets. A grant set is secret cells for an existing member, with no federation of its own.gcp_secret_access grant_member_resolution, the same fleet-cloud-convergence principal the gcloud ensure granted. So only who grants changes, never who holds.plan_grant_setis pure. It plans per secret, because one secret carries viewer, versionAdder and accessor, and it emits one policy add per secret. It refuses on an absent secret, a partial reading set, or an unresolved member.observe_and_plan_estateplans targets plus grant sets under one approval. It refuses when a label is shared between a target and a grant set, because diffs execute by label.execute_grant_set_diffapplies policy adds only, and refuses any create.grant_set_bindingsgives iam-converge'sgunbcIamConvergeSecretPolicyon each grant-set secret, resource-local.iam_converge_bootstrap_readbackaddsversions.accessandversions.addas ExpectDenied on each grant-set secret.gunbc.cloudflare.r2_mint_secret_access.r2_*_access_convergeentries (GcloudPrintToken) are deleted: a replacement migration that cuts over at the root. They had no other consumers.r2_mint_custody_grantsis the one roster. The custody secret population is derived from it, never listed twice.gunbc.auth.gcp_iam_bootstrap{,_model}(Bootstrap the approval-gated GCP IAM workflow (supersedes #12565) #13291's files; I told snappy-wolf-887 beforehand).iam_authority_record,iam_authority_pin, andWriteCreateNewundertarget/. Per secret and per operation (the bootstrap receipt), an election is written beforeCreateSecret.refused, and a new operation may elect again.iam_bootstrap_custody_create_dispose(an explicit operator disposition) retires it.target/listing only discovers candidate operations (custody_candidate_operations). Every election and terminal mark is read throughiam_authority_record, and must carry exactlycustody_journal_wire(secret, operation)(iam_authority_record_matches). Any of the following makes the journal unreadable, so the step refuses:WriteCreateNew, a corrupt marker, or one restored from elsewhere);Only a valid terminal record resolves an election.
CustodyOperationRecords, as Bootstrap the approval-gated GCP IAM workflow (supersedes #12565) #13291's authority journal takes them), thencustody_container_stepandcustody_after_create, which the effectful step consumes.versions.accessandversions.addexpected not-held on each custody secret. The deny policy is unchanged.gunbc.cloudflare.r2_token_mint_run. The container-create refusal now points to the bootstrap and a grant-set row, instead of an operator-identity run.gunbc.auth.privileged_effect_census.r2_mint_bootstrap_read_access_convergerow (GcloudInteractive) is removed, because its site is deleted.gcp_iam_converge_apply_wetrow (RealizedFederatedGrant), whose subject now names the grant sets.gcp-iam-convergerequest and apply modes already plan and apply, so aworkflow_dispatchplus the recorded approval is the route.Operator: one run, after #13291 lands
iam_bootstrap_apply(gunbc.auth.gcp_iam_bootstrap) is run as documented indocs/plans/gcp-iam-bootstrap.md, with a freshGUNBC_IAM_BOOTSTRAP_RECEIPT. It is idempotent: existing cells read back, and drift refuses adoption. It createscloudflare-r2-workspace-{read,write}-tokenbare and adds the per-secret bindings. After that, agcp-iam-convergedispatch and one tap grant all 13 cells.Witnesses (claim_batch on BuildBuddy, full rosters, head c3967a8)
test.claim.gcp_iam_converge_witness_testtest.claim.auth.gcp_iam_bootstrap_witness_testtest.claim.r2_mint_secret_access_witness_testtest.claim.authorization_pattern_selection_witness_test(the census executes and agrees)Memory, pre-existing:
gcp_iam_converge_witness_testis OOM-killed (rc=137) at a 16 GiB bind on #13291's own base as well (0/21 there), so this does not come from this PR. Its verdict needsCTRL_BUILD_RUNNER_EXEC_PROPERTIES=EstimatedMemory=60GBwithGUNBC_BIND_MEMORY_CGROUP_BYTES=51539607552(48 GiB), where it passes 25/25.Discriminating REDs (§4b rung honesty)
Each wall was removed alone, on top of c3967a8: copy
dag/, apply the single removal, run only the named claim, then restoredag/from the copy. All 11 REDs failed at this head. At d601416 the earlier ten also failed in two identical passes, after BuildBuddy retried the dispatch. Restored PASS is the full-roster run above at the same head.custodydropped fromiam_bootstrap_capability_bindingsgrant_set_secrets_are_bound_per_secret_never_on_the_projectrc=1 FAILgrant_set_bindings()replaced by[]custody_secrets_are_bound_per_secret_and_their_payload_stays_deniedrc=1 FAILversions.access/versions.addExpectDeniedcustody_secrets_are_bound_per_secret_and_their_payload_stays_deniedrc=1 FAILan_ambiguous_create_blocks_every_later_automatic_create(run 1: absent, unknown create; run 2: absent plus run 1's election, so it must refuse and never reach the create)rc=1 FAILCustodyCreateOutcomeUnknownmapped toCustodyCreateRefusedDefinitely, which would release run 2an_ambiguous_create_blocks_every_later_automatic_createrc=1 FAILan_unresolved_create_is_settled_by_observing_the_containerrc=1 FAILrefusedmark is not honoredresolved_journals_admit_a_new_create_and_unreadable_ones_refuserc=1 FAILcustody_record_validanswers true without comparing bytesa_terminal_mark_settles_only_with_its_exact_wire: a valid election, a disposed marker that is empty, carries another operation's wire, or is unreadable, and an absent container, must refuse and never create; a terminal mark with no election refuses. Positive control: the exact wire lets a new operation createrc=1 FAIL.weakened to-(candidate discovery)resolved_journals_admit_a_new_create_and_unreadable_ones_refuserc=1 FAILplan_grant_setgrants to iam-converge's membercustody_cells_name_the_resolved_convergence_principal_never_iam_converge(planned through the realgrant_member_resolution)rc=1 FAILr2_mint_secret_accessGcloudInteractive row restoredthe_r2_custody_cells_are_realized_by_the_federated_iam_routerc=1 FAILThe journal and container decisions are pure folds over closed carriers and the
target/listing, so their claims are driven by supplied observations and journal names built by the same naming functions the effect writes. The real GetSecret, CreateSecret and journal files are exercised by the operator'siam_bootstrap_applyrun.🤖 Generated with Claude Code