first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,79 @@
# mTLS gate — `@suaveplan/api-auth-bearer-static`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
The mTLS gate enforces an optional second factor on individual token table
entries. When operators mark an entry with `mtlsRequired: true`, the
resolver MUST refuse to surface the entry's Principal unless the host
listener attached a verified peer certificate to the inbound request via
`request.tls.peerCertificate`. This guards the highest-privilege service
tokens (e.g. internal admin API) against credential leakage — the bearer
token alone is necessary but no longer sufficient.
The adapter does NOT establish TLS itself. The host listener (Bun's
TLS-enabled server, Node's `https`, a Cloudflare-Worker TLS terminator
ahead of the worker, etc.) is responsible for completing the TLS handshake
and surfacing the verified subject as `request.tls.peerCertificate`. This
module just inspects what was attached.
## Features
- Pure function — no I/O, no state.
- Defensive — accepts any `Request`-shaped input even when the `tls` field
was not attached (returns `undefined`).
- Treats `peerCertificate: null` identically to absent.
- `mtlsRequired === false` short-circuits without inspecting the request.
## Usage: Basic
```ts
import { checkMtlsGate } from "@suaveplan/api-auth-bearer-static/mtls";
const request = new Request("https://example/test");
const allowed = checkMtlsGate(request, true);
// allowed === false — no peerCertificate attached
```
## Usage: Advanced
```ts
import {
checkMtlsGate,
extractPeerCertificate,
} from "@suaveplan/api-auth-bearer-static/mtls";
// Host listener pattern — wrap the inbound request before handing off to
// the auth chain.
const withTls = Object.assign(request, {
tls: { peerCertificate: parsedX509Subject },
});
const cert = extractPeerCertificate(withTls);
// cert === parsedX509Subject
const allowed = checkMtlsGate(withTls, true);
// allowed === true
```
## API Reference
- `interface RequestTlsInfo { peerCertificate?: unknown }`
- `extractPeerCertificate(request: Request): unknown | undefined`
- `checkMtlsGate(request: Request, mtlsRequired: boolean): boolean`
## Implementation Notes
The `Request` Web type has no standardised `tls` field. Both Node's
undici-based `Request` and Bun's polyfill ignore unknown properties on
construction, so the host pattern is to attach `tls` as a plain property
after the Request is built (or to wrap it in a Proxy / subclass). The
extractor reads through that property with a single defensive type cast
and returns `undefined` for any shape that does not satisfy the
`{ peerCertificate: <truthy> }` invariant. The opaque certificate itself
is not parsed here — that is the host's job, and a future
`api-auth-mtls` adapter (out of scope for Stage 4) will own subject
extraction.