/**
 * WS5.2 Account Follow-Me — the `account-credential-share` mesh verb (Mechanism A).
 *
 * STRUCTURALLY SEPARATE from `secret-share` (SecretSync.ts) by design — spec R3a / §6.5.
 * The legacy `secret-share` verb/`SecretShareHandler`/`decryptFromSync` path is PERMISSIVE
 * (any registered peer; no AAD; no mandate). A credential MUST NOT ride it. This file is the
 * distinct, operator-mandate-gated path:
 *
 *   - the credential is sealed with the AAD-bound `encryptAccountCredential` (NOT
 *     `encryptForSync`), so the recipient/account/mandate/grant/epoch are cryptographically
 *     bound (SecretStore.ts);
 *   - the receiver runs an RBAC gate BEFORE decrypt — verify the authorizing mandate, match
 *     the addressed recipient, and CONSUME a single-use grant — and only then attempts the
 *     fail-closed decrypt against THIS machine's live fingerprint + key-rotation epoch.
 *
 * PR1 SCOPE (no live credential): the verb, the builder, and the RBAC-gated handler ship as
 * primitives with injected seams (mandate verifier, grant consumer, credential writer). The
 * real config-home credential write is a LATER PR — here `storeCredential` is optional and,
 * when absent, the handler authenticates+decrypts but reports the write as unwired rather than
 * touching any live credential store. Everything stays dark behind `multiMachine.accountFollowMe`.
 */
import crypto from 'node:crypto';
import { type Secrets } from './SecretStore.js';
/** The DISTINCT credential-share mesh command (never `secret-share`). */
export interface AccountCredentialShareCommand {
    type: 'account-credential-share';
    /** JSON-serialized EncryptedAccountCredentialPayload (AAD-bound, sealed to the recipient). */
    encrypted: string;
    /** Authorizing coordination-mandate id (also bound in the AAD). */
    mandateId: string;
    /** Single-use grant id consumed at the gate (also bound in the AAD). */
    grantId: string;
    /** Routing fingerprint of the addressed recipient machine (also bound in the AAD). */
    targetFingerprint: string;
    /** SubscriptionAccount.id (also bound in the AAD). */
    accountId: string;
    /** Recipient key-rotation generation the seal targeted (also bound in the AAD). */
    pairingEpoch: number;
    /** Absolute expiry (ms since epoch) — rejected after this even before decrypt. */
    expiresAt: number;
}
export interface AccountCredentialSharePeer {
    machineId: string;
    /** Recipient's routing fingerprint (the AAD recipient binding). */
    fingerprint: string;
    /** Recipient's long-term X25519 public key (base64), from its MachineIdentity. */
    encryptionPublicKey: string;
}
export interface BuildCredentialShareArgs {
    secrets: Secrets;
    recipient: AccountCredentialSharePeer;
    accountId: string;
    mandateId: string;
    grantId: string;
    /** Recipient's CURRENT key-rotation epoch (R4b) — sealing to a stale epoch will fail at decrypt. */
    pairingEpoch: number;
    /** Absolute expiry (ms since epoch). */
    expiresAt: number;
}
/** Build an `account-credential-share` command sealed + AAD-bound to one recipient. */
export declare function buildAccountCredentialShareCommand(args: BuildCredentialShareArgs): AccountCredentialShareCommand;
/** Result of the receive-side RBAC + decrypt pipeline. Never throws on a denied command. */
export type CredentialShareResult = {
    accepted: true;
    stored: boolean;
    storeReason?: string;
    accountId: string;
} | {
    accepted: false;
    reason: string;
};
export interface AccountCredentialShareHandlerDeps {
    /** This machine's X25519 private key (KeyObject) for the fail-closed decrypt. */
    ownEncryptionPrivateKey: () => crypto.KeyObject;
    /** This machine's routing fingerprint — the AAD recipient binding is checked against it. */
    currentRecipientFingerprint: () => string;
    /** This machine's CURRENT X25519 key-rotation generation (R4b) — a stale-epoch seal fails. */
    currentPairingEpoch: () => number;
    /**
     * Verify the authorizing mandate authorizes (sender, account, target) — R1/R4a. This is the
     * operator-mandate gate; it returns `{ ok:false, reason }` for deny-by-default / expired /
     * revoked / wrong-bounds / unverified-issuer-signature. Wired to the real cross-machine
     * verifier (primitive #3) at integration; unit-tested with a real test double.
     */
    verifyMandate: (args: {
        mandateId: string;
        sender: string;
        accountId: string;
        targetFingerprint: string;
    }) => {
        ok: boolean;
        reason?: string;
    };
    /** Consume a single-use grant; `{ ok:false }` if unknown / already-consumed / expired (R3). */
    consumeGrant: (grantId: string, mandateId: string) => {
        ok: boolean;
        reason?: string;
    };
    /** Persist the decrypted credential (LATER PR wires the real config-home write). */
    storeCredential?: (accountId: string, secrets: Secrets) => void;
    now?: () => number;
    log?: (msg: string) => void;
}
/**
 * Receive-side handler. Runs the RBAC gate BEFORE decrypt (spec §5.4: "verifies ... AT THE
 * GATE (before decrypt)"), then a fail-closed AAD-bound decrypt against THIS machine's live
 * fingerprint + epoch. Order is load-bearing: a bad sender/recipient/grant is rejected without
 * ever doing the cryptographic work, and a stale/forged seal cannot decrypt regardless.
 */
export declare class AccountCredentialShareHandler {
    private readonly deps;
    constructor(deps: AccountCredentialShareHandlerDeps);
    handle(command: AccountCredentialShareCommand, sender: string): CredentialShareResult;
}
//# sourceMappingURL=AccountCredentialShare.d.ts.map