/**
 * Cache of **write approvals** — the passkey-signed, target-scoped tokens a
 * wallet-less person mints with `run402 approve` to provision, deploy, or write
 * secrets from the command line. Distinct from the sign-in session
 * ({@link ControlPlaneSessionCache}) it pairs with, and never a step-up. The
 * gateway scopes each token to one `(action, target)`, so this is a
 * **multi-entry** cache keyed by `(api_origin, control_plane_session_hash,
 * action, target)`. An `org.project.create` approval for org Y and a
 * `project.deploy` approval for project X coexist.
 *
 * Stored at the BASE config dir (principal-scoped), mode 0600 — as sensitive as
 * the wallet key. The token dies with its sign-in session; the
 * `control_plane_session_hash` binding lets the client drop a stale approval
 * locally rather than replay it into a `WRITE_APPROVAL_BINDING_MISMATCH`.
 */
export interface WriteApproval {
    write_approval_token: string;
    token_type: string;
    header: string;
    /** Gateway capability: `org.project.create` | `project.deploy` | `project.secret.write`. */
    action: string;
    org_id?: string;
    project_id?: string;
    /** Epoch ms when the approval expires (derived from the gateway-returned session). */
    expires_at: number;
    /** Short hash of the control-plane session this approval is bound to. */
    control_plane_session_hash: string;
    control_plane_principal_id: string;
    /** API origin (e.g. `https://api.run402.com`) the token was minted against. */
    api_origin: string;
    amr?: string[];
    minted_at: number;
}
/** The token payload from `POST /agent/v1/control-plane/write-approval/cli/token`. */
export interface WriteApprovalTokenResponse {
    write_approval_token: string;
    token_type?: string;
    header?: string;
    /** The write-approval session; its idle expiry is the token's expiry. */
    session?: {
        idle_expires_at?: string | number;
        expires_at?: string | number;
        absolute_expires_at?: string | number;
        amr?: string[];
        [k: string]: unknown;
    } | null;
    [k: string]: unknown;
}
/** A capability target — exactly one of these is set per approval. */
export interface WriteApprovalTargetKey {
    org_id?: string;
    project_id?: string;
}
/**
 * Path to the approval cache: `{base}/write-approvals.json`.
 * `RUN402_WRITE_APPROVALS_PATH` overrides for testing.
 */
export declare function getWriteApprovalsPath(): string;
/** Stable short hash binding an approval to a control-plane session token. */
export declare function hashControlPlaneSession(token: string): string;
/**
 * Read all cached approvals. Returns `[]` for the "no cache" cases (absent,
 * unreadable, unparseable). Throws when the file parses as JSON but the shape
 * is wrong, so a corrupted cache surfaces a clear fix-it.
 */
export declare function readApprovals(path?: string): WriteApproval[];
/**
 * Persist an approval. Replaces any existing entry with the same
 * `(api_origin, control_plane_session_hash, action, target)` key and leaves
 * every other entry intact (multi-entry, non-thrashing). Atomic, mode 0600.
 */
export declare function saveApproval(approval: WriteApproval, path?: string): void;
/** Delete the whole approval cache — local half of `run402 logout`. Idempotent. */
export declare function clearApprovals(path?: string): void;
/** Whether an approval is past its usable life (with a small skew buffer). */
export declare function isApprovalExpired(approval: WriteApproval, nowMs?: number, skewMs?: number): boolean;
/**
 * Return the cached approval matching ALL of `(apiOrigin, cpSessionHash,
 * capability, target)` and still live, or `null` if none matches or it is
 * expired. This is the exact-match the gateway's target gate requires — a
 * non-match (wrong action/target/origin/session) fails closed.
 */
export declare function loadLiveApproval(q: {
    apiOrigin: string;
    cpSessionHash: string;
    capability: string;
    target: WriteApprovalTargetKey;
}, path?: string, nowMs?: number): WriteApproval | null;
/**
 * Build a cache entry from the gateway token response + the binding context
 * (the cp-session it was minted under, the API origin, and the `(action,
 * target)` it covers). Expiry is taken from the returned `session`.
 */
export declare function approvalFromTokenResponse(resp: WriteApprovalTokenResponse, binding: {
    action: string;
    target: WriteApprovalTargetKey;
    apiOrigin: string;
    controlPlaneSessionHash: string;
    controlPlanePrincipalId: string;
}, nowMs?: number): WriteApproval;
//# sourceMappingURL=write-approvals.d.ts.map