design(adr): ADR-0029 — per-repo membership boundary for OCI registry (cloister-7c0a0b)#88
Closed
jamestexas wants to merge 1 commit into
Closed
design(adr): ADR-0029 — per-repo membership boundary for OCI registry (cloister-7c0a0b)#88jamestexas wants to merge 1 commit into
jamestexas wants to merge 1 commit into
Conversation
…y for OCI registry surface (cloister-7c0a0b) Drafts the architectural fix for the P0 finding from cloister-667ea6 adversarial review: the OCI pull surface has no per-repo membership boundary, so an unauthenticated caller can probe HEAD/GET against any digest and learn whether *any* tenant pushed it (then pull the bytes). Architectural constraint that shapes the design: per src/blob-store.ts docstring (lines 14-20), the singleton BlobStore is LOAD-BEARING for ADR-0003 — partitioning storage per-repo would break the content- addressed monoid axiom that the cross-DO orchestrator (BlobStore.put → BeadStore.bead_create → TrustStore.applyAttestation) depends on. The proposal therefore lifts the boundary ORTHOGONAL to storage: a `(repo, blob_digest)` membership index on TrustStore, consulted by the OCI pull surface before BlobStore.get. Pulls without membership return constant-shape 404 (matches the §9.4 "exists but not yours" precedent from threat-model.md / ADR-0024). Pushes write membership as a side effect under the ADR-0012 cross-DO handoff discipline. The ADR also enumerates the four follow-up beads (lazy backfill, manifest-walk grant, peerFp propagation, catalog auth-gate) that together close the cluster of related findings. Status: Proposed. No code changes — this PR is the design pass that PR #87 recommended. Implementation lands as separate beads once the ADR is reviewed. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This was referenced May 24, 2026
Closed
Contributor
Author
|
Superseded by #91 (consolidated ADR-0029 + membership substrate). Closing to reduce review load. |
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.
Independent of the implementation stack (#83 → #87) — pure docs, mergeable on its own.
Closes the design half of cloister-7c0a0b — the P0 architectural finding from cloister-667ea6 adversarial review.
Why this is a separate PR
The implementation stack (#83-#87) closed 4 of 5 cloister-667ea6 findings via code. The 5th — cross-tenant blob/manifest disclosure — needs a design decision before code can land, because of an architectural constraint:
So the fix can't partition storage. The ADR proposes lifting the boundary orthogonal to storage: a
(repo, blob_digest)membership index on TrustStore, consulted by the OCI pull surface beforeBlobStore.get. Constant-shape 404 (matching the §9.4 "exists but not yours" precedent already established by ADR-0024) for misses.What this PR contains
docs/adr/0029-oci-per-repo-membership-boundary.md— 115 lines.What it enables (separate beads / PRs)
registry_tagsinferencepeerFppropagation throughUploadSession(closes a related cloister-667ea6 finding)/v2/_catalog+/v2/<name>/tags/listEach is independently shippable once this design is reviewed.
🤖 Generated with Claude Code