Repository navigation
feat(api): relay and delegate by principal (#377 PR-B 2c) - #601
Conversation
In principal mode a human a surface relays for, or an agent run delegates to, now gets its tenants from the same PrincipalAuthz decision the middleware applies to a direct caller: by principal, never by login, and never platform admin. A subject whose principal or membership cannot be read is refused with 503 instead of being carried with no tenants; for the relay that replaces relaying without a principal id, aligning it with delegation (design.md B5). main.go builds the PrincipalAuthz once and hands it to both the middleware and the handlers, so the two decisions cannot drift. Claude-Session: https://claude.ai/code/session_0151SmHa5Uwfv9sm6G2XwDnE
|
Claude finished @mashkovd's task in 4m 12s —— View job Review complete ✓Todo list
SummaryReviewed
Verdict: Approved — no P1/P2 findings, no P3 nits worth flagging. |
Antigravity (agy) review — informationalModel: gemini-3.8-flash-medium · commit No significant issues found. |
There was a problem hiding this comment.
No P1/P2 findings (0 P3). authorizeSubject is wired in the correct order in both relaySubject and agentPrincipalGate (after AttachPrincipal/grant cross-check, before the subject reaches the handler); PrincipalAuthz.Apply's actingPrincipal guard correctly denies admin to relayed/delegated subjects even when their principal is in ADMIN_PRINCIPALS; the TenantResolver skip in principal mode (!h.principalMode()) is correctly gated so legacy/shadow behavior is unchanged; the dedup of cfg.principalAuthz(gitReader) into one shared instance for the middleware and Options.PrincipalAuthz matches the stated goal of preventing drift. Test coverage (relay_principal_test.go) covers member-by-principal, member-by-login-only, admin-principal-relayed, membership-unreadable, principal-unresolved, and not-configured, matching the 503 fail-closed behavior described in the PR body. Good to merge.
|
Claude finished @mashkovd's task in 2m 32s —— View job Code Review complete ✓Todo list
SummaryReviewed
Verdict: Approved — No P1/P2 findings (0 P3). Good to merge. |
There was a problem hiding this comment.
No P1/P2 findings (0 P3). authorizeSubject (internal/api/tenant_authz_principal.go) is wired in the correct order in both relaySubject and agentPrincipalGate (after AttachPrincipal/grant cross-check, before the subject reaches the handler); PrincipalAuthz.Apply's actingPrincipal guard correctly denies admin to relayed/delegated subjects even when their principal is in ADMIN_PRINCIPALS; the TenantResolver skip (!h.principalMode()) is correctly scoped to leave legacy/shadow behavior unchanged; the dedup of cfg.principalAuthz(gitReader) into one shared instance (cmd/api/main.go) for the middleware and Options.PrincipalAuthz matches the stated goal of preventing drift between a relayed decision and a direct one. Verified NewRelayedUser/NewDelegatedUser set githubLogin with no githubID, so Identity() resolves KindHuman and Apply correctly decides tenants/admin for them. Test coverage (relay_principal_test.go) covers member-by-principal, member-by-login-only, admin-principal-relayed, membership-unreadable, principal-unresolved, and not-configured for the relay, and the delegation analogue, matching the 503 fail-closed behavior described in the PR body. Good to merge.
Antigravity (agy) review — informationalModel: gemini-3.8-flash-medium · commit No significant issues found. |
Refs #377. PR-B slice 2c (task B5). This is stacked on #600 (2b), which is stacked on #598 (2a). Review only the top two commits.
What
In
TENANT_AUTHZ_MODE=principal, both the surface relay (relaySubject) and agent delegation (agentPrincipalGate) now decide the subject's tenants with the sameauth.PrincipalAuthzthe middleware applies to a direct caller:TenantResolveris not consulted.ADMIN_PRINCIPALS. This uses theactingPrincipalguard inApply.PrincipalAuthzis not configured, the request gets 503 (surface_identity_unavailable/delegation_unavailable), never an empty tenant set. For the relay, this replaces "relay without a principal id" in this mode, which matches delegation (it already fails closed).main.gobuilds thePrincipalAuthzonce and passes it to both the middleware andOptions.PrincipalAuthz, so a relayed decision and a direct decision cannot drift.Behaviour outside principal mode does not change, and
ParseTenantAuthzModestill refusesprincipal.Tests
TestSurfaceRelay_PrincipalMode(Postgres, through the router):ADMIN_PRINCIPALSwith no membership → 403TestAgentPrincipalGate_PrincipalMode:authorizeSubjectcall, or the relayed-admin guard inApply, fails these tests.Remaining
principal_idon unlink, then unlockingParseTenantAuthzMode.github:subject. That is follow-up work, not a regression.🤖 Generated with Claude Code
https://claude.ai/code/session_0151SmHa5Uwfv9sm6G2XwDnE