Optional ReadonlyaccessOptional ReadonlyauditOptional ReadonlychallengeOptional ReadonlychallengeReadonlyclientReadonlycodeReadonlyconfigOptionalaccessTokenDenylist?: { adapter?: "memory" | "redis" }Optionalaudit?: { sink: { type: string; [key: string]: unknown } }Optionaldeployment?: { mode?: "single" | "multi" }OptionalmemoryRateLimiter?: {Rate-limit config for SESSION routes (e.g. /session/login bruteforce
protection). Uses windowMs (milliseconds) for historical reasons —
the section was shaped by express-rate-limit, which
packages/session/src/routes/Session.mts consumed until #270.
Since #270 /session/login runs on the shared rateLimiter component
instead, keyed login:ip:<ip>, so the guard is one bucket set across
replicas rather than one per process. These values stay the single
source of truth: both bundled limiter adapters seed their own
limits.login from them (resolveLoginLimitSpec), converting to the
whole seconds a RateLimitSpec takes.
IH-18 — config split:
This section ONLY governs session-route rate limiting. OAuth endpoint
rate limiting (/token, /authorize) is provided via the optional
rateLimiter component slot; the built-in module config lives under
memoryRateLimiter.* / redisRateLimiter.* and uses windowSeconds
(seconds) per RateLimitSpec in packages/core/src/ratelimit/types.mts.
Two independent systems, different keys, different units.
OptionalrateLimiter?: { adapter?: "memory" | "redis" }OptionalredisAccessTokenDenylist?: { keyPrefix?: string }OptionalredisCodeRepository?: { defaultExpiresIn?: number; keyPrefix?: string }OptionalredisRefreshTokenFamilyStore?: { casRetryLimit?: number; keyPrefix?: string }OptionalredisSessionStores?: { keyPrefix?: string }OptionalrefreshTokenFamilyStore?: { redis?: { password?: string; url: string } }Optionalcsrf?: { trustedOrigins: string[]; ttlSeconds: number }#272 — CSRF policy for the state-changing session routes.
.optional() on purpose: a deployment inheriting reference.conf
always has it, and every value has a code-side default, so a
hand-built config (tests, embedders composing their own object) is
not forced to restate a section it has no opinion about.
trustedOrigins is NOT cors.allowedOrigins. "May this origin read
my responses" and "may this origin make me change state" are two
questions, and #272 was filed because one list was answering both.
Deployments whose login UI is served from a different origin than
the provider list those origins here — explicitly.
OptionaluserSessionStores?: { adapter?: "memory" | "redis" }Optional ReadonlyfederationOptional ReadonlyfederationOptional ReadonlygrantOptional ReadonlygrantReadonlykeyReadonlylifecycleBoot-planner-owned lifecycle registrar (D-5). Pre-seeded as a bootstrap
component before any module factory runs. Modules that create disposable
sub-resources (Redis clients, interval timers) declare
optional: ["lifecycleRegistrar"] and forward the value into
createAdapterFactory(kind, { lifecycle: deps.lifecycleRegistrar })
so each builder receives the registrar via BuilderContext.lifecycle.
This slot is NOT consumer-overridable — bootstrap-component-collision
fires if a consumer passes it via bootstrapComponents /
overrideComponents.
Optional ReadonlyloggerReadonlypathOptional ReadonlyrateReadonlyreadinessBoot-planner-owned readiness registrar. Pre-seeded alongside
lifecycleRegistrar and subject to the same rules: modules that open a
connection declare optional: ["readinessRegistrar"] and forward the
value into createAdapterFactory(kind, { readiness: deps.readinessRegistrar })
so builders can register a probe for the resource they hold.
Also NOT consumer-overridable — a second registrar would collect probes
the planner never reads, and /readyz would report ready while the
dependency it was meant to watch is down.
Optional ReadonlyrefreshOptional ReadonlyrefreshOptional ReadonlyrefreshOptional ReadonlyreplayOptional ReadonlysessionOptional ReadonlysessionOptional ReadonlysessionOptional ReadonlysubjectOptional ReadonlysubjectOptional ReadonlytokenReadonlyuserOptional ReadonlyuserOptional ReadonlywebauthnOptional WebAuthn credential store. Present when the webauthn package is wired.
ComponentMap — the typed DI graph for v0.5.0 manifest authoring.
The base interface is intentionally empty. Slot declarations are added by other files in @o3co/auth-provider-core (and by downstream packages such as @o3co/auth-provider-redis) via TypeScript declaration merging:
Per A2-α §6.1 the v0.5.0 baseline slot set is added incrementally during Phases 3–8 of the v0.5.0 redesign. This empty base is the foundation.
Per the cross-spec X1 amendment (documented in v0.5.0 redesign specs A3 §5.5 line 391 and A4 §5.6 of this repository's design history): the v0.5.0 ComponentMap does NOT contain the legacy
userSessionStore: UserSessionStoreBasenorrefreshTokenStore: RefreshTokenStoreBaseslots. Phase 5 (A1) and later phases declaration-merge their replacement slots without those legacy names appearing.Consumer-side augmentation MUST namespace consumer-specific keys (e.g.
acme.cacheClient) to avoid colliding with o3co-claimed slot names.v0.5.0 in-tree slot inventory (declaration-merged into this interface from elsewhere in the package; grep
declare module "@o3co/auth-provider-core"for the authoritative list):config: AppConfig— declared inboot/types.mtsper A2-β §6.2pathResolver: PathResolver— declared inboot/types.mtsper A2-β §6.2