feat(#462): add federation scope enforcement service #672
Reference in New Issue
Block a user
Delete Branch "feat/federation-m3-scope-service"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Implements FED-M3-04: pure server-side federation scope enforcement service.
FederationScopeServicewith structured allow/deny results for M4 audit.parseFederationScopeand enforces:excluded_resourcessubjectUserIdinclude_teams/include_personalintersection without widening RBACmax_rows_per_querycapsVerification
pnpm --filter @mosaicstack/gateway test -- src/federation/server/__tests__/scope.service.spec.ts— pass (10 tests)pnpm build— passpnpm typecheck— passpnpm lint— passpnpm format:check— passpnpm test— pass after localpostgres/valkey+pnpm --filter @mosaicstack/db db:pushfor DB-backed suites~/.config/mosaic/tools/codex/codex-code-review.sh --uncommitted— approve, 0 findings~/.config/mosaic/tools/codex/codex-security-review.sh --uncommitted— risk none, 0 findingsNotes
docs/federation/TASKS.mdis orchestrator-owned, so this PR does not edit it.Refs #462
758d73a6d1toa648c8c64dREVIEW-OF-RECORD — APPROVE ON MERITS (FED-M3-04 scope.service). Re-review after commit
a648c8c6confirms the prior blocker is closed: new test covers native RBAC includePersonal=false winning even when federation scope requests include_personal=true. Scope pipeline remains sound: invalid scope/resource/excluded/not-granted/invalid-limit/native-RBAC deny paths return structured { allowed:false, deny:{ code, stage, statusCode, grantId, peerId, subjectUserId, resource } } with no partial data; RBAC evaluation is as subjectUserId via injected evaluator; include_teams intersection cannot widen native RBAC; row limit is capped by max_rows_per_query. Rebase preserved QuerySourceService + CapabilitiesController + FederationScopeService module registration. Reviewer verification: scope.service.spec 11/11 pass; scope-schema.spec 18/18 pass; gateway typecheck pass; gateway lint pass; prettier check pass.a648c8c64dto8bd288a7dbREVIEW-OF-RECORD — APPROVE — stands on rebased SHA
8bd288a7db. Prior approval id=15903 remains valid; this was a pure rebase onto mainfc2970916fwith no content change to the reviewed scope.service diff.REVIEW-OF-RECORD — APPROVE (#672 FED-M3-04 scope.service) — head
8bd288a7db. Re-read the rebased diff and verified the trust-boundary behavior: parseFederationScope is reused before access evaluation; invalid scope/resource/excluded/not-granted/invalid-limit/native-RBAC deny paths return structured { allowed:false, deny:{ code, stage, statusCode, grantId, peerId, subjectUserId, resource } } with no partial data; native RBAC is evaluated as subjectUserId through the injected evaluator; include_teams and include_personal intersect with native RBAC and do not widen access; max_rows_per_query caps requested limits. The previous include_personal blocker is covered by the native-RBAC-personal-deny test. Reviewer verification on rebased SHA: scope.service.spec 11/11 pass; scope-schema.spec 18/18 pass; gateway typecheck pass; gateway lint pass; prettier check pass. APPROVE.