# `@suaveplan/api-auth-static-principal` — Fixed-Principal session resolver for tests **Package**: `@suaveplan/api-auth-static-principal` **Status**: PROPOSED **Type**: new-package **Stage**: 5 (Testing kit + conformance suites) — see umbrella `openspec/changes/api-plugin-foundation/` ## Why Per design doc §13.2, the testing kit needs an auth adapter that supplies a fixed `Principal` without any token decoding. The §13.2 example uses it directly: ```ts adapters: { "auth.session": { kind: "static-principal", principal: { id: "u1", scopes: ["billing:write"], tenantId: "acme" } }, } ``` Tests exercise the whole pipeline — RBAC gate, tenant resolver chain reading `principal.tenantId`, tenant-scoped DB — with a deterministic principal carried verbatim in config. No mocks, no token signing, no JWKS setup. ## What changes Net-new package depending on `@suaveplan/api-auth` (contract + `./testing` conformance), `@suaveplan/api-types`, `@suaveplan/error`, `zod`. - ADDED: `createStaticPrincipalResolver(opts)` — factory returning an `AuthAdapter` whose `resolveSession()` always returns `opts.principal` (a single fixed `Principal`). Optional `nullForPaths?: string[]` makes the resolver return `null` for matching request paths (test public-route behaviour without rewiring the whole adapter chain). - ADDED: `StaticPrincipalResolverOptions` — Zod schema validating the `Principal` shape (`id`, `scopes`, `tenantId?`, `claims?`) and the optional `nullForPaths` glob list. - ADDED: `securitySchemeContribution()` — returns an empty `securitySchemes` block (no auth flows to document for test use). - ADDED: `AUTH_STATIC_PRINCIPAL_*` error codes (`AUTH_STATIC_PRINCIPAL_INVALID_OPTIONS`). - ADDED: Registered in `@suaveplan/api-host/testing`'s adapter table as the `{ kind: "static-principal", principal: ... }` shorthand. ## Out of scope - Multiple Principals selected by token / header — for that, write a custom resolver or compose two `static-principal` resolvers behind a chain. - Worker-proxy surface — Stage 5 in-memory adapters are direct-only (cf. `api-router-in-memory`). ## Source mapping Genesis-original. Source of design intent: `docs/superpowers/specs/2026-05-13-api-plugin-foundation-design.md`. | Requirement | Design doc section | |---|---| | Fixed Principal config in test host | §13.2 | | Registered in `api-host/testing` adapter table | §15 Stage 5 | ## Verification approach - `src/factory/create-static-principal-resolver.test.ts` — resolves to the configured Principal; null for matching path patterns; deep equality (not reference equality) on the returned Principal. - `src/factory/create-static-principal-resolver.spec-conformance.test.ts` — `runAuthSessionConformance("static-principal-direct", ...)`. - `tests/integration/integration.test.ts` — booted by `createTestHost`'s default adapter table. ## Migration impact None — additive only.