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