/** CI/OIDC federation namespace and canonical delegation helpers. */
import type { Client } from "../kernel.js";
import { Unauthorized } from "../errors.js";
import type { PlanRequest, ReleaseSpec } from "./deploy.types.js";
import type { CiBindingRow, CiCreateBindingInput, CiDelegationValues, CiListBindingsInput, CiListBindingsResult, CiTokenExchangeInput, CiTokenExchangeResponse, NormalizedCiDelegationValues } from "./ci.types.js";
export { CI_AUDIENCE, CI_BINDING_REVOKED_ERROR, CI_GITHUB_ACTIONS_ISSUER, CI_GITHUB_ACTIONS_PROVIDER, DEFAULT_CI_DELEGATION_CHAIN_ID, V1_CI_ALLOWED_ACTIONS, V1_CI_ALLOWED_EVENTS_DEFAULT, } from "./ci.types.js";
export declare class Ci {
    private readonly client;
    constructor(client: Client);
    createBinding(input: CiCreateBindingInput): Promise<CiBindingRow>;
    listBindings(input: CiListBindingsInput): Promise<CiListBindingsResult>;
    getBinding(bindingId: string): Promise<CiBindingRow>;
    revokeBinding(bindingId: string): Promise<CiBindingRow>;
    /**
     * Replace the asset_key_scopes on an existing CI binding.
     *
     * The gateway gates `spec.assets` (in plan / commit / direct uploads
     * routed through CI sessions) by per-binding scopes (closed-by-default).
     * Existing bindings created before v1.48 — and every binding created
     * via `createBinding()`, which doesn't yet accept the parameter —
     * default to no scopes, blocking `client.assets.put` under CI auth.
     * This method grants scopes after the fact.
     *
     * Scope strings:
     *   - `"astro/*"` — wildcard prefix; matches every key under `astro/`.
     *     Use this when the consumer uploads under a known prefix
     *     (the @run402/astro integration uses `astro/` by default).
     *   - `"astro/hero.jpg"` — exact key match. Most callers want the
     *     wildcard form.
     *
     * Authorization: same as revokeBinding — the caller's SIWE wallet
     * must match the binding's project owner. Idempotent: passing the
     * same scope list twice is a no-op (returns the same row).
     */
    setAssetKeyScopes(bindingId: string, assetKeyScopes: readonly string[]): Promise<CiBindingRow>;
    exchangeToken(input: CiTokenExchangeInput): Promise<CiTokenExchangeResponse>;
}
/**
 * True when `err` is the CI token-exchange `binding_revoked` denial: a
 * subject-matching binding existed but was revoked — typically because the
 * project was transferred / handed off, which suspends the prior org's CI
 * bindings. The actionable fix is to re-create the binding with
 * `run402 ci link github`, NOT to widen asset scopes (`run402 ci
 * set-asset-scopes` 409s on a revoked binding).
 *
 * Discriminates against `access_denied` (no binding ever matched). The gateway
 * gives both the generic canonical `code: "FORBIDDEN"`, so the only signal is
 * the OAuth-style `error` field on the 403 response body — this guard reads it
 * for you. The thrown error stays an {@link Unauthorized} (`isUnauthorized`
 * remains true), so existing generic-403 handling is unaffected. Structural
 * (brand + body) so it survives duplicate SDK copies and realm boundaries.
 */
export declare function isCiBindingRevoked(err: unknown): err is Unauthorized;
export declare function normalizeCiDelegationValues(values: CiDelegationValues): NormalizedCiDelegationValues;
export declare function buildCiDelegationStatement(values: CiDelegationValues): string;
export declare function buildCiDelegationResourceUri(values: CiDelegationValues): string;
export declare function validateCiSubjectMatch(subject: string): string;
export declare function validateCiNonce(nonce: string): string;
export declare function normalizeCiRouteScopes(values: readonly string[] | undefined | null): string[];
export declare function validateCiRouteScope(value: string, resource?: string): string;
export declare function assertCiDeployableSpec(specOrPlanBody: ReleaseSpec | PlanRequest | unknown): void;
//# sourceMappingURL=ci.d.ts.map