import type { SignedPassport } from '../../types/passport.js'; import type { CoreVerifyClockOptions } from '../../types/policy.js'; /** Why a request was denied at the gate. Closed set, ordered: a missing * passport is reported before signature, signature before scope. */ export type GateDenyReason = 'NO_PASSPORT' | 'PASSPORT_INVALID' | 'MISSING_SCOPE'; export interface GateDecision { /** True iff the request is authorized to proceed to application logic. */ admit: boolean; /** Set iff admit is false. */ reason?: GateDenyReason; /** Suggested HTTP status for the deny response. 401 for credential * problems, 403 for an authenticated agent lacking scope. Undefined on * admit. The adapter is free to override. */ status?: 401 | 403; /** Human-readable detail for logs and the deny body. Never leaks key * material; names the failing check only. */ detail?: string; /** Verifier errors from the passport check, when applicable. Useful for * audit logs; not sent to the caller by default. */ errors?: string[]; } export interface GateOptions { /** Trust anchors. When provided, the passport MUST carry a valid issuer * countersignature from one of these. When omitted, self-signed * passports verify (signature + expiry only) - documented and weaker. */ trustedIssuers?: string[]; /** Uniform clock-skew option, threaded into verifyPassport. Reuses the * one millisecond-based skew option the SDK exposes. */ clock?: CoreVerifyClockOptions; /** Scopes the request requires. ALL listed scopes must be present in the * passport's capabilities[] for admission (logical AND). Empty or * omitted means "any valid passport admits" (authentication only). */ requiredScopes?: string[]; /** When true, a required scope is satisfied if the passport carries ANY * one of requiredScopes (logical OR) instead of all. Default false. */ anyScope?: boolean; } /** * The gate decision. Pure and offline: it runs verifyPassport (signature, * validity window, optional issuer-trust) and then the scope check, in * that order, and returns admit/deny. No network, no mutation, no I/O. * * `presented` is whatever the transport adapter extracted. `undefined` or * a malformed value denies with NO_PASSPORT rather than throwing, so a * missing credential is a clean 401, not a 500. */ export declare function evaluateRequest(presented: SignedPassport | undefined | null, opts?: GateOptions): GateDecision; /** Minimal request surface the gate reads. The adapter supplies a * getPassport that knows where the credential lives on the transport * (a header, the parsed body, a verified session). */ export interface GateRequestLike { getPassport: () => SignedPassport | undefined | null; } /** Minimal response surface the gate writes on deny. */ export interface GateResponseLike { /** Send a deny response with the given status and JSON body, then end. */ deny: (status: number, body: { error: GateDenyReason; detail?: string; }) => void; } /** * Run the gate against a transport-shaped request/response. On admit, * calls `proceed()` (the framework's next()/handler). On deny, writes the * deny response and does NOT call proceed - unauthorized traffic is * dropped before application logic. * * Returns the decision so an adapter or test can assert on it. */ export declare function runGate(req: GateRequestLike, res: GateResponseLike, proceed: () => void, opts?: GateOptions): GateDecision; //# sourceMappingURL=middleware.d.ts.map