import type { ExternalIdentityReference } from "./external-identity-reference.js";
/** Fields signed by the org. Excludes signatures themselves. */
export interface PassportClaims {
    passport_id: string;
    agent_id: string;
    issuing_org_id: string;
    model_lineage_hash: string;
    governance_policy_version: string;
    authorized_scope: {
        read_data: boolean;
        write_data: boolean;
        trigger_workflows: boolean;
        call_external_apis: boolean;
        max_concurrent_actions: number;
        allowed_domains: readonly string[];
    };
    issued_at: string;
    expires_at: string;
    pack_binding: readonly string[];
    /**
     * Per-agent Ed25519 public key as base64url unpadded (43 chars). Embedded
     * directly in the signed payload so relying parties can verify with ONLY
     * the passport + the platform CA public key (true Locked Invariant 4
     * offline verification — no platform contact required at verify time).
     * Substituting a different key would invalidate the signature since the
     * key is part of the signed bytes.
     */
    public_key_b64: string;
    /** SHA-256 hex of the public key. Convenience field for indexing. */
    public_key_fingerprint: string;
    /**
     * Bound external identities (Locked Architectural Invariant 9). Optional;
     * empty array for greenfield agents. Each entry cross-references the agent
     * to an existing IdP identity (Okta, SailPoint, AWS IAM, Azure AD, etc.).
     * Part of the signed payload — tampering invalidates the signature.
     */
    external_identity_references: readonly ExternalIdentityReference[];
    /**
     * Renewal generation. 0 = original issuance; increments on each renewal.
     * agent_id stays stable across renewals (reputation portability); each
     * renewal gets a new passport_id + new public_key_b64 + new signature but
     * the same agent_id. Behavioral history accrues against agent_id.
     */
    renewal_generation: number;
    /** Optional: passport_id of the predecessor (set for renewal_generation > 0). */
    predecessor_passport_id?: string;
    /**
     * A-1: scope discriminant for Journey B (IDE governance on a developer
     * laptop) vs Journey A/network (enterprise fleet). When 'personal', the
     * passport is bound to a single end-user (see user_id below) and is
     * invisible to other users within the same org. When 'team' (default),
     * the passport is visible org-wide per the standard RLS policy.
     *
     * Optional in the type for backward compatibility with pre-A-1 passports
     * already in the wild; the database column defaults to 'team'.
     */
    passport_scope?: "personal" | "team";
    /**
     * A-1: end-user subject (JWT `sub` at issuance) for personal-scope
     * passports. REQUIRED when passport_scope='personal'; ignored otherwise.
     * The DB CHECK constraint enforces this binding at the storage layer.
     *
     * Per Journey B design: a personal-scope passport is a developer's IDE
     * governance state. Listing personal-scope passports across users within
     * the same org would leak each developer's interactive history; the RLS
     * policy filters on (org_id, user_id) for personal-scope rows.
     */
    user_id?: string;
}
export interface SignedPassport extends PassportClaims {
    /** Base64url Ed25519 signature by the org. 86 chars. */
    signature: string;
    /**
     * Base64url Ed25519 signature by the platform CA. 86 chars when present.
     * NULL on provisional passports (per S0-D §2.3.1 — Shield-R2 #9 enforcement).
     */
    platform_countersignature: string | null;
    /** True if `platform_countersignature` is null AND verifier should respect provisional semantics. */
    provisional: boolean;
}
/**
 * Sign a passport. The org's private key signs the canonical payload; the
 * platform CA private key countersigns. If `platformPrivateKey` is omitted,
 * the result is a provisional passport (no countersignature).
 */
export declare function signPassport(args: {
    claims: PassportClaims;
    orgPrivateKey: Uint8Array;
    platformPrivateKey?: Uint8Array;
}): SignedPassport;
export type VerificationResult = {
    valid: true;
    passport: SignedPassport;
} | {
    valid: false;
    reason: VerificationFailureReason;
};
export type VerificationFailureReason = "expired" | "signature_mismatch" | "platform_countersignature_mismatch" | "missing_platform_countersignature" | "malformed" | "revoked";
/**
 * A single entry in the signed revocation list (A-5).
 * Relying parties receive this from GET /v1/revocation-list (unauthenticated).
 */
export interface RevocationListEntry {
    passport_id: string;
    revoked_at: string;
    reason: string;
}
export interface VerifyOptions {
    /** Org public key (32 bytes). */
    orgPublicKey: Uint8Array;
    /** Platform CA public key (32 bytes). */
    platformPublicKey: Uint8Array;
    /**
     * If true, reject any passport without `platform_countersignature` even if
     * the org signature is valid. Default true (a relying org should require
     * countersignature unless it has explicit policy to accept provisional).
     */
    requireCountersignature?: boolean;
    /** Override "now" for deterministic tests. */
    now?: Date;
}
/**
 * Verify a passport. Returns a discriminated union — NEVER throws on bad input
 * (per Locked Invariant 5). The provisional case is reachable only when
 * `requireCountersignature: false` is opted into by the verifying org.
 */
export declare function verifyPassport(passport: unknown, opts: VerifyOptions): VerificationResult;
/**
 * True offline verification per Locked Invariant 4: extract the per-agent
 * public key directly from the passport (it's embedded + signed). Verifier
 * needs ONLY the passport + the platform CA public key — no platform contact,
 * no out-of-band key channel.
 *
 * Substituting a different key into the passport would invalidate the
 * signature since the key bytes are part of the signed payload.
 *
 * A-5: optional `revocationList` — when provided, the passport_id is checked
 * against the list. If found, returns `{ valid: false, reason: 'revoked' }`.
 * When absent, falls back to current behavior (Invariant 3 graceful
 * degradation — never throws on missing list).
 */
export declare function verifyPassportOffline(passport: unknown, platformPublicKey: Uint8Array, options?: {
    requireCountersignature?: boolean;
    now?: Date;
    /** A-5: optional signed revocation list. passport_id found in list → revoked. */
    revocationList?: RevocationListEntry[];
}): VerificationResult;
//# sourceMappingURL=passport-signer.d.ts.map