import type { HandlerContext } from "@aotter/mantle-runtime"; import { type Diagnostic } from "@aotter/mantle-spec"; import { type MantleAuth as Auth } from "@aotter/mantle-auth"; export type ConsumerCredentialResolution = { readonly kind: "not-handled"; } | { readonly kind: "invalid"; } | { readonly kind: "verified"; readonly credential: { readonly credential: "api-key" | "personal-token"; readonly credentialId: string | null; readonly userId: string | null; readonly clientId?: string | null; readonly scopes?: readonly string[]; }; }; /** Adapter-owned extension seam. Consumers recognize and verify their * own credential formats here; Core never stores or issues them. */ export type ConsumerCredentialResolver = (request: Request) => ConsumerCredentialResolution | Promise; export interface ResolveCallerOptions { readonly auth: Auth; readonly credentialResolver?: ConsumerCredentialResolver; /** Enables JWT bearer verification against this Auth issuer/JWKS. */ readonly jwtBearer?: { readonly audience: string; /** Optional server-wide floor. Manifest operation scopes are still * evaluated by the runtime's ctx.auth.scope predicates. */ readonly scopes?: readonly string[]; }; readonly env?: unknown; readonly waitUntil?: (promise: Promise) => void; /** Optional observability wrapper around the two I/O steps: bearer * verification (`oauth`) and the fresh role read (`role`). */ readonly phase?: PhaseHook; } export type PhaseHook = (phase: "oauth" | "role", run: () => Promise) => Promise; export type CallerResolution = { readonly kind: "anonymous" | "authenticated"; readonly context: HandlerContext; } | { readonly kind: "invalid"; readonly status: 401 | 403; readonly diagnostic: Diagnostic; /** Verifier reason (e.g. `invalid-dpop-proof`) for transports that render a challenge. */ readonly reason: string; }; /** Normalize consumer credentials, OAuth bearer, or cookie session in * that precedence order. A presented-but-invalid credential never * falls back to a valid session cookie. */ export declare function resolveCaller(request: Request, options: ResolveCallerOptions): Promise; export declare function contextForVerifiedUser(userId: string | null, authContext: NonNullable, auth: Auth, base: Pick, currentRole?: string | null, phase?: PhaseHook): Promise; /** Which callers a transport surface admits before the target's own `requires` runs. */ export type SurfacePolicy = "public" | "staff"; export type CallerGate = { readonly kind: "allow"; readonly context: HandlerContext; } | { readonly kind: "deny"; readonly status: 401 | 403; readonly diagnostic: Diagnostic; /** `invalid-credential`, `invalid-dpop-proof`, `insufficient-scope`, `cross-origin`, `unauthenticated` or `insufficient-role`. */ readonly reason: string; /** The identity the gate did establish before refusing (role and * origin denials). Absent when the credential itself was invalid. */ readonly context?: HandlerContext; }; /** * The one caller gate every transport shares (#977). It resolves identity * through `resolveCaller`, applies the cross-origin guard only when the * credential is a cookie session, and lets `surface` decide exactly one * thing: whether `ctx.staff` is required. `public` admits anonymous callers; * the target's `requires.auth` and guard still run on every invocation, so * enforcement stays where the manifest declares it rather than at the * transport. Transports differ only in how they render a denial. */ export declare function gateCaller(request: Request, options: ResolveCallerOptions & { readonly surface?: SurfacePolicy; }): Promise; //# sourceMappingURL=resolveCaller.d.ts.map