auth.provider API
    Preparing search index...
    • Declarative manifest for the OAuth 2.0 endpoint suite.

      Per A2-γ §3.2.1 + Amendment 1 (§1.1.1 routes-factory shape) + Amendment 3 (§1.1.3 grantHandlerResolver synthetic dep) + Amendment 4 (§1.1.4 four-store session split).

      Caller surface: oauthModule({ clientRepository, codeRepository, express? })oauthModule({ config }). All dependencies now flow through the typed DI graph (requires / optional).

      Route contributions (Amendment 1):

      • "oauth-endpoints" @ /oauth — always contributed.
      • "oidc-discovery" @ /.well-known/openid-configuration — conditional on config.oauth.jwt.issuer being a non-empty string.

      The v0.4.x lazy closure () => context.federationProviders is REMOVED. deps.federationProviders is the typed, stable read at factory invocation time (Theme E structural fix).

      grantPolicy and refreshTokenFamilyRevocation are declared as ComponentMap slots (colocated augmentations in core/src/policy/types.mts and core/src/refresh-token-family/types.mts). Both are consumed by routes.mtsgrantPolicy.evaluate gates /oauth/token, and refreshTokenFamilyRevocation.isFamilyRevoked is read by introspect, userinfo, logout cascade, and federation-token. The legacy RefreshTokenStoreBase slot was removed in issue #101 (A3 §5.3).

      Theme B (one responsibility per module), Theme C (no synthetic-key redeclaration), Theme D (immutability — const defineModule, no ctx mutation), Theme E (structural temporal contracts — stable deps closure replaces lazy getter).

      Parameters

      • params: {
            config: {
                cors: { allowedOrigins: string[] };
                endpoints: { login: { url: string } };
                federations: z.ZodRecord<
                    z.ZodString,
                    z.ZodObject<
                        {
                            enabled: z.ZodPreprocess<z.ZodBoolean>;
                            type: z.ZodOptional<z.ZodString>;
                        },
                        z.core.$loose,
                    >,
                >;
                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?: "redis" | "memory" };
                    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?: (...) | (...);
                                        publicKeyPath?: (...) | (...);
                                    }[];
                                    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?: "redis"
                | "memory" };
                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: "none" | "lax" | "strict";
                    secret: string;
                    secure: boolean;
                    storage: {
                        redis?: { password?: string; url: string };
                        type: string;
                        [key: string]: unknown;
                    };
                };
                userSessionStores?: { adapter?: "redis"
                | "memory" };
            };
        }

      Returns Module