auth.provider API
    Preparing search index...

    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:

    declare module "@o3co/auth-provider-core" {
      interface ComponentMap {
        readonly mySlot: MyType;
      }
    }
    

    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: UserSessionStoreBase nor refreshTokenStore: RefreshTokenStoreBase slots. 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 in boot/types.mts per A2-β §6.2
    • pathResolver: PathResolver — declared in boot/types.mts per A2-β §6.2
    • (Phase 5 onward adds storage / federation / session slots)
    interface ComponentMap {
        accessTokenDenylist?: AccessTokenDenylist;
        auditSink?: AuditSink;
        challengeCeremony?: ChallengeCeremony;
        challengeStore?: ChallengeStore;
        clientRepository: ClientRepository;
        codeRepository: CodeRepository;
        config: {
            cors: { allowedOrigins: string[] };
            endpoints: { login: { url: string } };
            federations: Record<
                string,
                { enabled: boolean; type?: string; [key: string]: unknown },
            >;
            http: { port: number; trustProxy: boolean };
            memoryRateLimiter?: {
                defaultLimit?: { limit: number; windowSeconds: number };
                limits?: Record<string, { limit: number; windowSeconds: number }>;
                maxBuckets?: number;
            };
            oauth: {
                accessToken: { expiresIn: number };
                code?: { adapter?: "memory" | "redis" };
                grants: { [key: string]: unknown };
                jwt: {
                    issuer?: string;
                    legacyTypAccept?: boolean;
                    signingKey: {
                        local?:
                            | {
                                algorithm: "HS256";
                                kid: string;
                                previousSecrets?: { expiresAt: string; kid: string; secret: string }[];
                                secret?: string;
                            }
                            | {
                                algorithm: "RS256"
                                | "ES256"
                                | "EdDSA";
                                kid: string;
                                previousKeys?: {
                                    expiresAt: string;
                                    kid: string;
                                    publicKey?: string;
                                    publicKeyPath?: string;
                                }[];
                                privateKey?: string;
                                privateKeyPath?: string;
                                publicKey?: string;
                                publicKeyPath?: string;
                                [key: string]: unknown;
                            };
                        provider: string;
                        [key: string]: unknown;
                    };
                };
                nonce?: { maxLength: number };
                oidcMode: "oidc-required" | "dual";
                refreshToken: {
                    expiresIn: number;
                    legacyRtPolicy: "reject";
                    unknownFamilyPolicy: "accept" | "reject";
                };
                resourceIndicator?: { enabled: boolean };
                tokenExchange?: { maxActorChainDepth: number };
            };
            rateLimit: {
                failMode: "open"
                | "closed";
                login: { limit: number; windowMs: number };
            };
            rateLimiter?: { adapter?: "memory"
            | "redis" };
            redisCodeRepository?: { defaultExpiresIn?: number; keyPrefix?: string };
            redisRefreshTokenFamilyStore?: {
                casRetryLimit?: number;
                keyPrefix?: string;
            };
            redisSessionStores?: { keyPrefix?: string };
            refreshTokenFamilyStore?: { redis?: { password?: string; url: string } };
            repositories: {
                client: { type: string; [key: string]: unknown };
                code: { type: string; [key: string]: unknown };
                user: { type: string; [key: string]: unknown };
            };
            session: {
                domain: string
                | null;
                maxAge: number;
                name: string;
                sameSite: "lax" | "none" | "strict";
                secret: string;
                secure: boolean;
                storage: {
                    redis?: { password?: string; url: string };
                    type: string;
                    [key: string]: unknown;
                };
            };
            userSessionStores?: { adapter?: "memory"
            | "redis" };
        };
        federationProviders?: ReadonlyMap<string, unknown>;
        federationTokenStore?: FederationTokenStore;
        grantHandlerResolver?: GrantHandlerResolver;
        grantPolicy?: GrantPolicyHook;
        keyStore: KeyStore;
        lifecycleRegistrar: LifecycleRegistrar;
        logger?: Logger;
        pathResolver: PathResolver;
        rateLimiter?: RateLimiter;
        refreshTokenFamilyRevocation?: RefreshTokenFamilyRevocation;
        refreshTokenFamilyRotation?: RefreshTokenFamilyRotation;
        refreshTokenFamilyStore?: RefreshTokenFamilyStore;
        replaySeenSet?: ReplaySeenSet;
        sessionFamilyIndex?: SessionFamilyIndex;
        sessionFederationIndex?: SessionFederationIndex;
        sessionRPRegistry?: SessionRPRegistry;
        tokenExchangeValidatorResolver?: TokenExchangeValidatorResolver;
        userRepository: UserRepository;
        userSessionStore?: UserSessionStore;
        webauthnCredentialStore?: WebAuthnCredentialStore;
    }
    Index

    Properties

    accessTokenDenylist?: AccessTokenDenylist
    auditSink?: AuditSink
    challengeCeremony?: ChallengeCeremony
    challengeStore?: ChallengeStore
    clientRepository: ClientRepository
    codeRepository: CodeRepository
    config: {
        cors: { allowedOrigins: string[] };
        endpoints: { login: { url: string } };
        federations: Record<
            string,
            { enabled: boolean; type?: string; [key: string]: unknown },
        >;
        http: { port: number; trustProxy: boolean };
        memoryRateLimiter?: {
            defaultLimit?: { limit: number; windowSeconds: number };
            limits?: Record<string, { limit: number; windowSeconds: number }>;
            maxBuckets?: number;
        };
        oauth: {
            accessToken: { expiresIn: number };
            code?: { adapter?: "memory" | "redis" };
            grants: { [key: string]: unknown };
            jwt: {
                issuer?: string;
                legacyTypAccept?: boolean;
                signingKey: {
                    local?:
                        | {
                            algorithm: "HS256";
                            kid: string;
                            previousSecrets?: { expiresAt: string; kid: string; secret: string }[];
                            secret?: string;
                        }
                        | {
                            algorithm: "RS256"
                            | "ES256"
                            | "EdDSA";
                            kid: string;
                            previousKeys?: {
                                expiresAt: string;
                                kid: string;
                                publicKey?: string;
                                publicKeyPath?: string;
                            }[];
                            privateKey?: string;
                            privateKeyPath?: string;
                            publicKey?: string;
                            publicKeyPath?: string;
                            [key: string]: unknown;
                        };
                    provider: string;
                    [key: string]: unknown;
                };
            };
            nonce?: { maxLength: number };
            oidcMode: "oidc-required" | "dual";
            refreshToken: {
                expiresIn: number;
                legacyRtPolicy: "reject";
                unknownFamilyPolicy: "accept" | "reject";
            };
            resourceIndicator?: { enabled: boolean };
            tokenExchange?: { maxActorChainDepth: number };
        };
        rateLimit: {
            failMode: "open"
            | "closed";
            login: { limit: number; windowMs: number };
        };
        rateLimiter?: { adapter?: "memory"
        | "redis" };
        redisCodeRepository?: { defaultExpiresIn?: number; keyPrefix?: string };
        redisRefreshTokenFamilyStore?: {
            casRetryLimit?: number;
            keyPrefix?: string;
        };
        redisSessionStores?: { keyPrefix?: string };
        refreshTokenFamilyStore?: { redis?: { password?: string; url: string } };
        repositories: {
            client: { type: string; [key: string]: unknown };
            code: { type: string; [key: string]: unknown };
            user: { type: string; [key: string]: unknown };
        };
        session: {
            domain: string
            | null;
            maxAge: number;
            name: string;
            sameSite: "lax" | "none" | "strict";
            secret: string;
            secure: boolean;
            storage: {
                redis?: { password?: string; url: string };
                type: string;
                [key: string]: unknown;
            };
        };
        userSessionStores?: { adapter?: "memory"
        | "redis" };
    }

    Type Declaration

    • cors: { allowedOrigins: string[] }
    • endpoints: { login: { url: string } }
    • federations: Record<string, { enabled: boolean; type?: string; [key: string]: unknown }>
    • http: { port: number; trustProxy: boolean }
    • OptionalmemoryRateLimiter?: {
          defaultLimit?: { limit: number; windowSeconds: number };
          limits?: Record<string, { limit: number; windowSeconds: number }>;
          maxBuckets?: number;
      }
    • oauth: {
          accessToken: { expiresIn: number };
          code?: { adapter?: "memory" | "redis" };
          grants: { [key: string]: unknown };
          jwt: {
              issuer?: string;
              legacyTypAccept?: boolean;
              signingKey: {
                  local?:
                      | {
                          algorithm: "HS256";
                          kid: string;
                          previousSecrets?: { expiresAt: string; kid: string; secret: string }[];
                          secret?: string;
                      }
                      | {
                          algorithm: "RS256"
                          | "ES256"
                          | "EdDSA";
                          kid: string;
                          previousKeys?: {
                              expiresAt: string;
                              kid: string;
                              publicKey?: string;
                              publicKeyPath?: string;
                          }[];
                          privateKey?: string;
                          privateKeyPath?: string;
                          publicKey?: string;
                          publicKeyPath?: string;
                          [key: string]: unknown;
                      };
                  provider: string;
                  [key: string]: unknown;
              };
          };
          nonce?: { maxLength: number };
          oidcMode: "oidc-required" | "dual";
          refreshToken: {
              expiresIn: number;
              legacyRtPolicy: "reject";
              unknownFamilyPolicy: "accept" | "reject";
          };
          resourceIndicator?: { enabled: boolean };
          tokenExchange?: { maxActorChainDepth: number };
      }
    • rateLimit: { failMode: "open" | "closed"; login: { limit: number; windowMs: number } }

      Rate-limit config for SESSION routes (e.g. /session/login bruteforce protection). Uses windowMs (milliseconds) because this section is consumed by express-rate-limit in packages/session/src/routes/Session.mts.

      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" }
    • OptionalredisCodeRepository?: { defaultExpiresIn?: number; keyPrefix?: string }
    • OptionalredisRefreshTokenFamilyStore?: { casRetryLimit?: number; keyPrefix?: string }
    • OptionalredisSessionStores?: { keyPrefix?: string }
    • OptionalrefreshTokenFamilyStore?: { redis?: { password?: string; url: string } }
    • repositories: {
          client: { type: string; [key: string]: unknown };
          code: { type: string; [key: string]: unknown };
          user: { type: string; [key: string]: unknown };
      }
    • session: {
          domain: string | null;
          maxAge: number;
          name: string;
          sameSite: "lax" | "none" | "strict";
          secret: string;
          secure: boolean;
          storage: {
              redis?: { password?: string; url: string };
              type: string;
              [key: string]: unknown;
          };
      }
    • OptionaluserSessionStores?: { adapter?: "memory" | "redis" }
    federationProviders?: ReadonlyMap<string, unknown>
    federationTokenStore?: FederationTokenStore
    grantHandlerResolver?: GrantHandlerResolver
    grantPolicy?: GrantPolicyHook
    keyStore: KeyStore
    lifecycleRegistrar: LifecycleRegistrar

    Boot-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.

    logger?: Logger
    pathResolver: PathResolver
    rateLimiter?: RateLimiter
    refreshTokenFamilyRevocation?: RefreshTokenFamilyRevocation
    refreshTokenFamilyRotation?: RefreshTokenFamilyRotation
    refreshTokenFamilyStore?: RefreshTokenFamilyStore
    replaySeenSet?: ReplaySeenSet
    sessionFamilyIndex?: SessionFamilyIndex
    sessionFederationIndex?: SessionFederationIndex
    sessionRPRegistry?: SessionRPRegistry
    tokenExchangeValidatorResolver?: TokenExchangeValidatorResolver
    userRepository: UserRepository
    userSessionStore?: UserSessionStore
    webauthnCredentialStore?: WebAuthnCredentialStore

    Optional WebAuthn credential store. Present when the webauthn package is wired.