Files
suaveplan/packages/api-stack/api/api-auth/README.md
2026-05-27 23:29:53 +01:00

110 lines
7.5 KiB
Markdown

# @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.
<!-- begin:auto-docs -->
## 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…
<!-- end:auto-docs -->
## 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. |