first commit
This commit is contained in:
125
docs/api-stack/api/api-auth-static-principal/README.md
Normal file
125
docs/api-stack/api/api-auth-static-principal/README.md
Normal file
@@ -0,0 +1,125 @@
|
||||
# @suaveplan/api-auth-static-principal — fixed-principal session resolver for @suaveplan/api: returns a configured Principal verbatim on every request. Used in plugin integration tests and the api-plugin-example fixture.
|
||||
|
||||
Fixed-`Principal` session resolver for the `@suaveplan/api` plugin
|
||||
system. Returns the configured `Principal` verbatim on every request —
|
||||
no token decoding, no network I/O, no internal state. Used in plugin
|
||||
integration tests and the `api-plugin-example` fixture, where the goal is to
|
||||
exercise the entire downstream pipeline (RBAC gate, tenant resolver chain
|
||||
reading `principal.tenantId`, tenant-scoped DB) with a deterministic
|
||||
identity carried in config.
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
## Documentation tree
|
||||
|
||||
- [adapter](./src/adapter/adapter.md) — Bundles the static-principal resolver, the (absent) security-scheme contribution, and a pinned `csrf: false` into a sin…
|
||||
- [adapter](./src/adapter/adapter.md) — Bundles the static-principal resolver, the (absent) security-scheme contribution, and a pinned `csrf: false` into a sin…
|
||||
- [error-codes](./src/error-codes/error-codes.md) — Defines the `AUTH_STATIC_PRINCIPAL.*` error-code namespace and the `AuthStaticPrincipalError` concrete subclass of `@su…
|
||||
- [error-codes](./src/error-codes/error-codes.md) — Defines the `AUTH_STATIC_PRINCIPAL.*` error-code namespace and the `AuthStaticPrincipalError` concrete subclass of `@su…
|
||||
- [factory](./src/factory/create-static-principal-resolver.md) — Constructs a `SessionResolver` from `@suaveplan/api-auth` that returns the configured `Principal` verbatim on every req…
|
||||
- [create-static-principal-resolver](./src/factory/create-static-principal-resolver.md) — Constructs a `SessionResolver` from `@suaveplan/api-auth` that returns the configured `Principal` verbatim on every req…
|
||||
- [options](./src/options/options.md) — Owns the runtime contract between the test harness call site and the resolver factory. The schema validates both the ou…
|
||||
- [options](./src/options/options.md) — Owns the runtime contract between the test harness call site and the resolver factory. The schema validates both the ou…
|
||||
- [security-scheme](./src/security-scheme/security-scheme.md) — Provides the per-adapter `SecuritySchemeContribution` slot of `AuthAdapter`. The static-principal adapter is a test-onl…
|
||||
- [security-scheme](./src/security-scheme/security-scheme.md) — Provides the per-adapter `SecuritySchemeContribution` slot of `AuthAdapter`. The static-principal adapter is a test-onl…
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Why does this exist?
|
||||
|
||||
Per the API foundation 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, tenant resolution, tenant-scoped
|
||||
DB — with a deterministic principal in config. No mocks, no JWKS setup, no
|
||||
token signing.
|
||||
|
||||
## Surface
|
||||
|
||||
| Subpath | Export |
|
||||
| -------------- | --------------------------------------------------------------------------------------- |
|
||||
| `./resolver` | `createStaticPrincipalResolver(opts): SessionResolver` |
|
||||
| `./adapter` | `createStaticPrincipalAdapter(opts): AuthAdapter` |
|
||||
| `./error-codes`| `AUTH_STATIC_PRINCIPAL_CODES`, `AuthStaticPrincipalError`, `AuthStaticPrincipalErrorCode` |
|
||||
|
||||
The root barrel re-exports the resolver, adapter, error codes, options
|
||||
schema (`StaticPrincipalResolverOptionsSchema` /
|
||||
`parseStaticPrincipalResolverOptions`), and the empty
|
||||
`staticPrincipalSecurityScheme()` contribution.
|
||||
|
||||
## Usage
|
||||
|
||||
```ts
|
||||
import { createStaticPrincipalAdapter } from "@suaveplan/api-auth-static-principal/adapter";
|
||||
|
||||
const adapter = createStaticPrincipalAdapter({
|
||||
principal: {
|
||||
id: "u1",
|
||||
scopes: ["billing:write"],
|
||||
tenantId: "acme",
|
||||
claims: { sub: "u1" },
|
||||
},
|
||||
});
|
||||
|
||||
host.registerAuth(adapter);
|
||||
// every request now produces `principal === { id: "u1", ... }`.
|
||||
```
|
||||
|
||||
Skip auth on selected paths to test `publicRoutes` behaviour without
|
||||
rewiring the adapter chain:
|
||||
|
||||
```ts
|
||||
const adapter = createStaticPrincipalAdapter({
|
||||
principal: { id: "u1", scopes: [], claims: {} },
|
||||
nullForPaths: ["/healthz", "/webhooks/*"],
|
||||
applyTo: (req) => !req.headers.has("x-skip-auth"),
|
||||
});
|
||||
```
|
||||
|
||||
## Conformance
|
||||
|
||||
The resolver passes `runAuthSessionConformance` from
|
||||
`@suaveplan/api-auth/testing` in seeded-principal mode. See
|
||||
`src/factory/create-static-principal-resolver.spec-conformance.test.ts` and
|
||||
`tests/conformance/api-auth.test.ts`.
|
||||
|
||||
## Errors
|
||||
|
||||
`AUTH_STATIC_PRINCIPAL.INVALID_OPTIONS` — outer options bag failed Zod
|
||||
validation (wrong shape, missing required fields, unknown top-level keys).
|
||||
|
||||
`AUTH_STATIC_PRINCIPAL.INVALID_PRINCIPAL` — the supplied `principal` field
|
||||
is malformed (missing `id`, non-string `id`, non-array `scopes`, unknown
|
||||
keys inside `principal`, …).
|
||||
|
||||
Both fire synchronously at construction time. The resolver itself never
|
||||
throws at request time.
|
||||
|
||||
## Stage-5 wiring (forward-looking)
|
||||
|
||||
When `api-host/testing` ships its Stage-5 `createTestHost` surface, this
|
||||
adapter is registered in the adapter table under
|
||||
`kind: "static-principal"`, so tests will declare it inline:
|
||||
|
||||
```ts
|
||||
const host = createTestHost({
|
||||
adapters: {
|
||||
"auth.session": {
|
||||
kind: "static-principal",
|
||||
principal: { id: "u1", scopes: ["billing:write"], tenantId: "acme" },
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Until then, callers wire the adapter directly via
|
||||
`createStaticPrincipalAdapter()` as shown above.
|
||||
|
||||
Reference in New Issue
Block a user