# @suaveplan/api-auth - Abstract session-resolver contract for the Suaveplan API plugin system. Defines the SessionResolver interface (Request → Principal | null), SessionResolverChain (ordered, first-match-wins, fail-closed-on-throw), SecuritySchemeContribution (OpenAPI emission metadata), CsrfPolicy default rules, the composite AuthAdapter, the AUTH_CODES registry, and a runAuthSessionConformance harness reused by every concrete resolver in Stages 4/6/8. **$2** for the Suaveplan API plugin system. Defines the abstract session-resolver shape (`Request → Principal | null`) used by the host on every request, plus the first-match-wins runner, the OpenAPI security-scheme contribution, the default CSRF policy, the composite `AuthAdapter`, and the conformance harness every concrete resolver implementation passes. This package is **session resolution only** — account lifecycle (login, register, oauth callback, password reset) lives in the separate `@suaveplan/api-auth-provider` package per design doc §2.3. ## Documentation tree - [capability-id](./src/capability-id/capability-id.md) — Pins this package's `CapabilityId` contribution as a stand-alone literal type plus runtime constant. The `CapabilityId`… - [capability-id](./src/capability-id/capability-id.md) — Pins this package's `CapabilityId` contribution as a stand-alone literal type plus runtime constant. The `CapabilityId`… - [chain](./src/chain/chain.md) — Ordered, first-match-wins runtime over an array of `SessionResolver`s. The chain is the integration point at design-doc… - [chain](./src/chain/chain.md) — Ordered, first-match-wins runtime over an array of `SessionResolver`s. The chain is the integration point at design-doc… - [csrf-policy](./src/csrf-policy/csrf-policy.md) — Exposes a single pure predicate, `CsrfPolicy.requiresCsrf(scheme)`, that defaults CSRF protection ON for any cookie-bas… - [csrf-policy](./src/csrf-policy/csrf-policy.md) — Exposes a single pure predicate, `CsrfPolicy.requiresCsrf(scheme)`, that defaults CSRF protection ON for any cookie-bas… - [error-codes](./src/error-codes/error-codes.md) — Defines the stable, namespaced error-code registry for the `@suaveplan/api-auth` package and the concrete `AuthError` c… - [error-codes](./src/error-codes/error-codes.md) — Defines the stable, namespaced error-code registry for the `@suaveplan/api-auth` package and the concrete `AuthError` c… - [resolver](./src/resolver/resolver.md) — `SessionResolver` is the abstract per-request session-resolver shape that every concrete adapter in Stages 4/6/8 (`api-… - [resolver](./src/resolver/resolver.md) — `SessionResolver` is the abstract per-request session-resolver shape that every concrete adapter in Stages 4/6/8 (`api-… - [security-scheme](./src/security-scheme/security-scheme.md) — Defines the shape every concrete `SessionResolver` MUST contribute so the `api-openapi` package can emit the right `com… - [security-scheme](./src/security-scheme/security-scheme.md) — Defines the shape every concrete `SessionResolver` MUST contribute so the `api-openapi` package can emit the right `com… - [session-adapter](./src/session-adapter/session-adapter.md) — `AuthAdapter` is the composite shape every concrete session-auth adapter exports — pairing the per-request `SessionReso… - [session-adapter](./src/session-adapter/session-adapter.md) — `AuthAdapter` is the composite shape every concrete session-auth adapter exports — pairing the per-request `SessionReso… - [testing](./src/testing/conformance.md) — A reusable Vitest `describe(...)` block every concrete `SessionResolver` must pass before publishing. The harness cover… - [conformance](./src/testing/conformance.md) — A reusable Vitest `describe(...)` block every concrete `SessionResolver` must pass before publishing. The harness cover… ## What's inside | Module | Subpath | Purpose | |-------------------------------|----------------------------------------|---------------------------------------------------------------| | `SessionResolver` interface | `@suaveplan/api-auth/resolver` | Abstract `resolve(req) → Principal \| null` + `dispose`. | | `SessionResolverChain` runner | `@suaveplan/api-auth/chain` | Ordered first-match-wins; fail-closed-on-throw by default. | | Security-scheme contract | `@suaveplan/api-auth/security-scheme` | Zod-validated OpenAPI security-scheme metadata. | | CSRF policy default | `@suaveplan/api-auth/csrf-policy` | Cookie schemes → ON; bearer / oauth2 / OIDC → OFF. | | Composite `AuthAdapter` | `@suaveplan/api-auth/session-adapter` | `{ resolver, securityScheme, csrf? }` registration shape. | | `auth.session` capability id | `@suaveplan/api-auth/capability-id` | Re-export of `"auth.session"` with type-level assertion. | | `AUTH_CODES` registry | `@suaveplan/api-auth/error-codes` | Frozen `AUTH.*` error-code registry + `AuthError` class. | | Conformance harness | `@suaveplan/api-auth/testing` | `runAuthSessionConformance(spec)` for concrete resolvers. | ## Co-located documentation Each module ships a sibling `.md`: - [`src/resolver/resolver.md`](src/resolver/resolver.md) - [`src/chain/chain.md`](src/chain/chain.md) - [`src/security-scheme/security-scheme.md`](src/security-scheme/security-scheme.md) - [`src/csrf-policy/csrf-policy.md`](src/csrf-policy/csrf-policy.md) - [`src/session-adapter/session-adapter.md`](src/session-adapter/session-adapter.md) - [`src/capability-id/capability-id.md`](src/capability-id/capability-id.md) - [`src/error-codes/error-codes.md`](src/error-codes/error-codes.md) - [`src/testing/conformance.md`](src/testing/conformance.md) ## Quick example ```ts import { SessionResolverChain } from "@suaveplan/api-auth/chain"; import { validateAuthAdapter } from "@suaveplan/api-auth/session-adapter"; import type { SessionResolver } from "@suaveplan/api-auth/resolver"; declare const jwt: SessionResolver; declare const staticBearer: SessionResolver; const jwtAdapter = validateAuthAdapter({ resolver: jwt, securityScheme: { name: "bearerAuth", scheme: { type: "http", scheme: "bearer", bearerFormat: "JWT" }, }, }); const bearerAdapter = validateAuthAdapter({ resolver: staticBearer, securityScheme: { name: "staticBearer", scheme: { type: "http", scheme: "bearer" }, }, }); const chain = new SessionResolverChain([ jwtAdapter.resolver, bearerAdapter.resolver, ]); const principal = await chain.resolve(new Request("https://example.test")); ``` ## Versioning 1.0`. Graduates to `1.0.0` when the Stage 1 contract bundle (`api-types`, `api-auth`, `api-tenant-resolver`, `api-secrets`, `api-db-adapter`) all reach 1.0. ## Dependencies | Dep | Why | |---------------------------|------------------------------------------------------| | `@suaveplan/api-types` | `Principal`, `CapabilityId`. | | `@suaveplan/error` | `SuaveplanError`, `defineCodes`. | | `@suaveplan/types` | Cross-package contracts (logger, clock, etc.). | | `tslib` | TypeScript runtime helpers (catalog). | | `zod` | Boundary validation for security-scheme contributions. |