auth.provider API
    Preparing search index...

    Interface GrantDependencies

    interface GrantDependencies {
        config: {
            http: {
                port: number;
                readinessTimeoutMs: number;
                trustProxy: number | boolean | string[];
            };
            logging: {
                level: | "trace"
                | "debug"
                | "info"
                | "warn"
                | "error"
                | "fatal"
                | "silent";
            };
            oauth: {
                accessToken: { expiresIn: number };
                authorize?: Record<string, never>;
                code?: { adapter?: "memory" | "redis" };
                grants: { [key: string]: unknown };
                jwt: {
                    issuer: string;
                    jwksCacheMaxAge?: number;
                    jwksPath?: 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";
                };
                requireEmailVerified?: boolean;
                resourceIndicator?: { enabled: boolean };
                revocation?: { accessToken: "denylist" | "unsupported" };
                tokenBinding?: {
                    "dispatch-policy": "intent-explicit" | "strict-mutual-exclusion";
                };
                tokenExchange?: { maxActorChainDepth: number };
            };
        } & Record<string, unknown>;
        grantPolicy?: GrantPolicyHook;
        keyStore: KeyStore;
        logger?: Logger;
        pathResolver?: PathResolver;
        refreshTokenFamilyRevocation?: RefreshTokenFamilyRevocation;
        refreshTokenFamilyRotation?: RefreshTokenFamilyRotation;
        sessionFamilyIndex?: SessionFamilyIndex;
        sessionFederationIndex?: SessionFederationIndex;
        sessionRPRegistry?: SessionRPRegistry;
        subjectRevocation?: SubjectRevocation;
        userSessionStore?: UserSessionStore;
    }
    Index
    config: {
        http: {
            port: number;
            readinessTimeoutMs: number;
            trustProxy: number | boolean | string[];
        };
        logging: {
            level: | "trace"
            | "debug"
            | "info"
            | "warn"
            | "error"
            | "fatal"
            | "silent";
        };
        oauth: {
            accessToken: { expiresIn: number };
            authorize?: Record<string, never>;
            code?: { adapter?: "memory" | "redis" };
            grants: { [key: string]: unknown };
            jwt: {
                issuer: string;
                jwksCacheMaxAge?: number;
                jwksPath?: 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";
            };
            requireEmailVerified?: boolean;
            resourceIndicator?: { enabled: boolean };
            revocation?: { accessToken: "denylist" | "unsupported" };
            tokenBinding?: {
                "dispatch-policy": "intent-explicit" | "strict-mutual-exclusion";
            };
            tokenExchange?: { maxActorChainDepth: number };
        };
    } & Record<string, unknown>
    grantPolicy?: GrantPolicyHook
    keyStore: KeyStore
    logger?: Logger

    Optional structured logger for security-relevant grant audit events (RT replay detection, unknown-family policy decisions, legacy-token acceptance). Falls back silently when absent so the grant factory remains usable from minimal test harnesses; production wires the logger slot per ComponentMap.logger declaration merge.

    pathResolver?: PathResolver
    refreshTokenFamilyRevocation?: RefreshTokenFamilyRevocation
    refreshTokenFamilyRotation?: RefreshTokenFamilyRotation
    sessionFamilyIndex?: SessionFamilyIndex
    sessionFederationIndex?: SessionFederationIndex
    sessionRPRegistry?: SessionRPRegistry
    subjectRevocation?: SubjectRevocation

    #376: the #296 subject-revocation watermark, consulted by the refresh grant at RT redemption as the backstop for a partial #322 cascade failure — an RT family the cascade could not revoke must not keep minting fresh access tokens for a subject whose credential changed. A rotated RT carries a fresh iat, so the check only bites RTs minted before the credential change: exactly the intended set.

    userSessionStore?: UserSessionStore