refactor(security): migrate handleSecurity admin gate to shouldDenyAnonymous (#2567 follow-up)#2997
Merged
Conversation
…onymous (#2567 follow-up) The /security/suggested-bindings admin surface was the last HTTP seam still hand-rolling the anonymous check. It now delegates to the shared shouldDenyAnonymous decision with requireAuth:true hardcoded, preserving its UNCONDITIONAL semantics (an admin surface denies anonymous even on a requireAuth:false deployment — pinned by the existing test that constructs the dispatcher with no options and still expects 401). The 401 body adopts the shared shape (code: 'unauthenticated'), asserted in the test. Deliberately NOT migrated: handleNotification's !userId check — a "needs a user identity" predicate (inbox is keyed by userId; a system context has no inbox), not an anonymous-posture decision. Verified: http-dispatcher + http-dispatcher.requireauth suites 185/185, lint clean, check-single-authz-resolver intact. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ShknNUYoSTspJLBiqorD8V
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 16 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
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.
Final #2567 follow-up (Phases 1/2/docs merged as #2973 / #2987 / #2993). One-seam refactor — no behavior change beyond the 401 body adopting the shared shape.
Change
handleSecurity(/security/suggested-bindings, the ADR-0090 D5/D9 admin surface) was the last HTTP seam still hand-rolling the!userId && !isSystem → 401check. It now delegates to the sharedshouldDenyAnonymousdecision like every other seam.Semantics preserved deliberately: this gate is UNCONDITIONAL —
requireAuth: trueis hardcoded into the call, because an admin surface must deny anonymous callers even on arequireAuth: falsedemo deployment. The existing test pins this (dispatcher constructed with no options, whererequireAuthdefaults false, still expects 401); it now also asserts the shared body'scode: 'unauthenticated'.Triage — deliberately NOT migrated:
handleNotification's!userIdcheck. That is a "needs a user identity" predicate (the inbox is keyed byuserId; a system context has no inbox), not an anonymous-posture decision — migrating it would letisSystempass the gate and then query with an undefineduserId.Realtime "fourth door" investigation (no code — findings recorded here)
Also per the #2567 wrap-up, we audited whether a realtime/WebSocket/SSE surface constitutes an ungated fourth door. Verdict: no such door exists.
service-realtimeis an in-process pub/sub bus only (registerService('realtime')+ thesys_presenceobject; the contract's optionalhandleUpgradeWebSocket hook is unimplemented). It registers zero HTTP routes./realtimebranch and nohandleRealtime; neither the dispatcher-plugin nor the hono plugin mounts any realtime route —/api/v1/realtimefalls through to the semantic 404.handleAIpath.One cosmetic defect found (tracked separately, not in this PR): discovery advertises
realtime: ${prefix}/realtimeeven though the route 404s, andmetadata-protocolreferences a nonexistentplugin-realtimeprovider.Verification
http-dispatcher+http-dispatcher.requireauthsuites: 185/185 (401 case now also asserts the shared body code)check:single-authz-resolverintact; changeset added (@objectstack/runtimepatch)🤖 Generated with Claude Code
https://claude.ai/code/session_01ShknNUYoSTspJLBiqorD8V
Generated by Claude Code