FEDERATION_RESOURCE_VALUES closed allowlist of federation resources (extends in M3+)
Sensitive-resource warning for credentials / api_keys via console.warn (full gating in M2-06)
18 unit tests covering valid/invalid scopes, defaults, intersection guards, range bounds, sentinel warning
Decisions to confirm before M2-06 wires this up
Zod v4 .issues API: Gateway uses Zod ^4.3.6. In Zod v4, the error issues array is accessed via error.issues (not error.errors as in v3). The parser uses this correctly.
filters key type: filters is typed as Record<string, ResourceFilterSchema> (not Record<FederationResource, ...>) to avoid TS strictness issues with optional record keys. The superRefine cross-check enforces filter keys must be in resources at runtime.
include_teams not UUID-validated: Per PRD §8.3, team IDs are arbitrary BetterAuth strings (not UUIDs). The schema accepts string[].
No DTO file created: This is a pure validator/schema module, not a module boundary. DTOs will be added in M2-06 when the NestJS controller is wired.
## Summary
Pure validator for federation grant scope objects per PRD §8.1. Independent of CA / DB / NestJS wiring — those land in M2-06.
## What's in this PR
- `apps/gateway/src/federation/scope-schema.ts` — Zod schema, `parseFederationScope`, `FederationScope` type, `FederationScopeError`
- `FEDERATION_RESOURCE_VALUES` closed allowlist of federation resources (extends in M3+)
- Sensitive-resource warning for `credentials` / `api_keys` via `console.warn` (full gating in M2-06)
- 18 unit tests covering valid/invalid scopes, defaults, intersection guards, range bounds, sentinel warning
## Decisions to confirm before M2-06 wires this up
1. **Zod v4 `.issues` API**: Gateway uses Zod ^4.3.6. In Zod v4, the error issues array is accessed via `error.issues` (not `error.errors` as in v3). The parser uses this correctly.
2. **`filters` key type**: `filters` is typed as `Record<string, ResourceFilterSchema>` (not `Record<FederationResource, ...>`) to avoid TS strictness issues with optional record keys. The `superRefine` cross-check enforces filter keys must be in `resources` at runtime.
3. **`include_teams` not UUID-validated**: Per PRD §8.3, team IDs are arbitrary BetterAuth strings (not UUIDs). The schema accepts `string[]`.
4. **No DTO file created**: This is a pure validator/schema module, not a module boundary. DTOs will be added in M2-06 when the NestJS controller is wired.
## Test plan
- [x] Vitest 18/18 green
- [x] typecheck green
- [x] lint green
- [x] format:check green
- [ ] CI green
Refs #461
Pure Zod-based validator for federation grant scope objects per PRD §8.1.
Independent of CA, DB, and NestJS wiring — those land in M2-06.
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Pure validator for federation grant scope objects per PRD §8.1. Independent of CA / DB / NestJS wiring — those land in M2-06.
What's in this PR
apps/gateway/src/federation/scope-schema.ts— Zod schema,parseFederationScope,FederationScopetype,FederationScopeErrorFEDERATION_RESOURCE_VALUESclosed allowlist of federation resources (extends in M3+)credentials/api_keysviaconsole.warn(full gating in M2-06)Decisions to confirm before M2-06 wires this up
.issuesAPI: Gateway uses Zod ^4.3.6. In Zod v4, the error issues array is accessed viaerror.issues(noterror.errorsas in v3). The parser uses this correctly.filterskey type:filtersis typed asRecord<string, ResourceFilterSchema>(notRecord<FederationResource, ...>) to avoid TS strictness issues with optional record keys. ThesuperRefinecross-check enforces filter keys must be inresourcesat runtime.include_teamsnot UUID-validated: Per PRD §8.3, team IDs are arbitrary BetterAuth strings (not UUIDs). The schema acceptsstring[].Test plan
Refs #461