feat(security): ADR-0056 D1 (canonical OWD vocab) + D2 (anonymous deny posture)#2065
Merged
Conversation
…sharingModel Add the canonical OWD names (public_read / public_read_write) to the object.sharingModel enum alongside the legacy read/read_write/full aliases (non-breaking), and map them in the sharing runtime onto the three enforced behaviours. Unknown values stay enum-rejected (authoring-time fail-closed). Showcase announcement switched to canonical `public_read`, proven end-to-end. sharing-service 32 tests (+4 D1); OWD dogfood proofs 8/8; liveness green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XVdnfUAx85amkerym26vdx
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckNo hand-written docs reference the 0 changed package(s). ✅ |
…nforce) The data API's deny capability already exists (requireAuth=true → 401 for anonymous; share-link / guest_portal / control-plane exempt) but the DEFAULT is fail-open. Add a boot WARN when requireAuth is off so the insecure posture is explicit, WITHOUT flipping the global default (release-gated; flipping would break anonymous-dependent deployments). Proven by showcase-anonymous-deny (4/4): anonymous read+write 401, authenticated 200, control-plane open. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XVdnfUAx85amkerym26vdx
os-zhuang
marked this pull request as ready for review
June 20, 2026 08:31
This was referenced Jun 20, 2026
Merged
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.
Two ADR-0056 decisions, both verified, both non-breaking.
D1 — canonical OWD vocabulary on
object.sharingModelReconciles the three-way naming mismatch to one vocabulary:
private | public_read | public_read_write | controlled_by_parent(canonical) plus legacyread / read_write / fullaliases (kept, non-breaking). The sharing runtime maps them onto the three enforced behaviours; unknown values stay enum-rejected (authoring-time fail-closed). The showcaseannouncementnow declares the canonicalpublic_read, exercised end-to-end.plugin-sharing32 unit tests (+4 D1); OWD dogfood 8/8 with the canonical name; liveness green.D2 — secure-by-default anonymous posture (warn → enforce)
The deny capability already exists:
api.requireAuth=truerejects anonymous viaenforceAuth, and share-link /guest_portal/ control-plane routes are exempt (so public functionality survives). But the default is fail-open (requireAuth=false) — an object with no OWD/RLS is world-readable with no signal.Expert judgment (long-term): the right move is not to flip the global default in a code merge — that would 401 every deployment relying on anonymous reads, and public access already has dedicated declared channels (share-links /
publicSharing). Instead this lands the warn of warn→enforce: a boot-time WARN when running fail-open, making the posture explicit (consistent with D4/D8 honesty). The actual default flip stays a release-gated, announced decision.showcase-anonymous-deny(4/4): anonymous read+write → 401, authenticated → 200, control-plane (/auth) open.ADR-0056 status after this
Done + merged/merging: OWD scenarios (#2062), D4+D8 (#2064), D1+D2 (this). Remaining: D7 default Profile (additive; turnkey already met by member_default), D6 role hierarchy (P4), D10 conformance matrix (CI artifact), and the eventual release-gated
requireAuthdefault flip.🤖 Generated with Claude Code