/**
 * # cli/credentials — the registered-agent credential store (kestrel-markets-0t0).
 *
 * When `kestrel register` self-registers an autonomous agent (PLAT-ADR-0021 tier 1),
 * the durable capability it receives is persisted HERE so subsequent `--api` calls
 * present it as `Authorization: Bearer <capability>` instead of self-minting a fresh
 * anonymous trial each time. This is the CLI's ONLY at-rest secret, so it lives in a
 * single, owner-only file.
 *
 * There is no pre-existing CLI config-dir idiom in this repo (only the lake cache uses
 * `homedir()`), so this establishes one: `~/.kestrel/credentials.json`, created 0700
 * dir / 0600 file — the credential is a bearer token; a world-readable file would leak
 * it. `KESTREL_HOME` overrides the base dir (used by tests to stay hermetic).
 *
 * Dependency-light on purpose (node built-ins only): this module is imported on the
 * light command path (backend selection reads the stored credential), so it must not
 * pull `bun:sqlite` or any heavy runtime.
 */
/** The on-disk credential shape (v1). `capability` is the durable bearer token. */
export interface StoredCredential {
    readonly version: 1;
    /** The API base the credential was minted against — a credential is host-scoped. */
    readonly api: string;
    readonly agent_id: string;
    readonly capability: string;
    readonly token_type: string;
    readonly scopes: readonly string[];
    /** ISO-8601 expiry of the capability. */
    readonly expiry: string;
    /**
     * The capability SUBJECT the durable token binds to (PLAT-ADR-0021). Stored so the
     * keypair-JWT auth path (cli/keypair.ts) can set the JWT `sub` the platform resolves the
     * enrolled key by. Present on credentials minted by a platform that returns `subject`.
     */
    readonly subject?: string;
    /**
     * True once `kestrel register --keypair` enrolled an Ed25519 key for this credential
     * (kestrel-markets-0t0 slice 2). The private key lives in the sibling keyfile
     * ({@link defaultKeypairPath}); when it is present the CLI authenticates by minting
     * short-lived JWTs instead of replaying this durable capability.
     */
    readonly keypair_enrolled?: boolean;
    /**
     * What the CLI DISCLOSED and sent as CLAIMED (unverified) git attribution, kept for
     * transparency (AX doctrine) — this is never trusted as an identity, here or server-side.
     */
    readonly claimed?: {
        readonly name?: string;
        readonly email?: string;
    };
}
/**
 * The on-disk agent-keypair file (v1) — the CLI's SECOND at-rest secret (the enrolled
 * private key), stored 0600 ALONGSIDE credentials.json in `~/.kestrel/`. The private key
 * never leaves the machine; the CLI signs short-lived request JWTs with it. `audience` +
 * `max_ttl_seconds` are captured from the platform's enrollment response so the minted JWT
 * targets exactly the audience the platform verifies against.
 */
export interface StoredKeypair {
    readonly version: 1;
    /** The API base the key was enrolled against — host-scoped, like the credential. */
    readonly api: string;
    /** The agent subject the JWT `sub` must carry (the platform's enrolled-key lookup key). */
    readonly subject: string;
    readonly public_jwk: {
        readonly kty: "OKP";
        readonly crv: "Ed25519";
        readonly x: string;
    };
    /** The PRIVATE JWK — the only truly-secret bytes; the file is 0600 for this reason. */
    readonly private_jwk: {
        readonly kty: "OKP";
        readonly crv: "Ed25519";
        readonly x: string;
        readonly d: string;
    };
    /** The audience the platform expects on a request JWT (from the enrollment response). */
    readonly audience: string;
    /** The max JWT TTL (seconds) the platform accepts (from the enrollment response). */
    readonly max_ttl_seconds: number;
    /** When the key was enrolled (ISO-8601). */
    readonly enrolled_at: string;
}
/** The env this module reads (only `KESTREL_HOME`, for test isolation). */
interface Env {
    readonly [k: string]: string | undefined;
}
/** The default credential path: `$KESTREL_HOME/.kestrel/credentials.json` (else `~`). */
export declare function defaultCredentialsPath(env?: Env): string;
/** The default keyfile path: `$KESTREL_HOME/.kestrel/agent-key.json` (else `~`). */
export declare function defaultKeypairPath(env?: Env): string;
/**
 * Persist a credential, owner-only. Creates `~/.kestrel` 0700 and writes the file 0600,
 * then chmods it explicitly so a pre-existing file with looser perms is tightened too
 * (the create-mode is not applied to an existing file).
 */
export declare function saveCredential(cred: StoredCredential, path?: string): void;
/**
 * Persist the agent keypair file, owner-only (0600) in the same 0700 `~/.kestrel` dir.
 * The private key is a secret at least as sensitive as the bearer capability, so the file
 * gets the identical hardened perms (and an explicit chmod to tighten a pre-existing file).
 */
export declare function saveKeypair(keypair: StoredKeypair, path?: string): void;
/**
 * Load the stored keypair, or `undefined` if absent/unreadable/malformed. Best-effort +
 * fail-quiet: a missing/corrupt keyfile just means "no keypair" (the caller falls back to
 * the durable capability or an anonymous trial), never a crash on the command path.
 */
export declare function loadKeypair(path?: string): StoredKeypair | undefined;
/**
 * Load the stored credential, or `undefined` if absent/unreadable/malformed. Best-effort
 * and fail-quiet: a corrupt or missing file simply means "no stored credential" (the
 * caller falls back to an anonymous trial), never a crash on the command path.
 */
export declare function loadCredential(path?: string): StoredCredential | undefined;
/** The default operator-secrets path: `$KESTREL_HOME/.kestrel/.env` (else `~`). */
export declare function defaultSecretsPath(env?: Env): string;
/** The stable, agent-matchable codes an operator-surface key can be refused with. */
export type SecretKeyViolationCode = "SECRET_LIVE_KEY_REFUSED" | "SECRET_INVALID_KEY_NAME";
/** A refused operator-surface key: a stable `code`, a redacted `message`, and an actionable `hint`. */
export interface SecretKeyViolation {
    readonly code: SecretKeyViolationCode;
    readonly message: string;
    readonly hint: string;
}
/**
 * Decide whether `key` may be MINTED as an operator secret name, applying the two jh9w.5.1 refusals in
 * order: the paper-only live-broker refusal (OSS-ADR-0054 §5), then the canonical-uppercase format check.
 * Returns the FIRST violation, or `undefined` when the key is storable. Never reads a value and never
 * touches disk — a face calls this BEFORE it receives (or writes) any secret value, so a refusal leaks
 * nothing. The regexes match the CLI's historical behavior exactly (case-insensitive, segment-bounded
 * `LIVE`; strict `^[A-Z_][A-Z0-9_]*$`) so this refactor is byte-compatible with the shipped CLI codes.
 */
export declare function checkOperatorSecretKey(key: string): SecretKeyViolation | undefined;
/**
 * Set (or overwrite) one operator secret in `~/.kestrel/.env`, owner-only + atomically.
 * Existing keys are preserved (read-modify-write). Throws on an invalid key BEFORE touching
 * disk (fail closed — nothing is written on rejection).
 */
export declare function saveSecret(key: string, value: string, path?: string): void;
/**
 * Resolve one secret with the loading precedence `process.env` **wins**, the on-disk store
 * is the fallback. Returns `undefined` when absent everywhere — never a silent default.
 */
export declare function loadSecret(key: string, opts?: {
    env?: Env;
    path?: string;
}): string | undefined;
/** Read the ENTIRE on-disk store as a plain object (does not consult `process.env`). */
export declare function loadSecrets(path?: string): Record<string, string>;
/**
 * The NAMES held in the on-disk store, sorted — the values never leave this module on this
 * path. `kestrel secrets list` is built on this rather than {@link loadSecrets} so a listing
 * code path never even HOLDS a value to accidentally render (kestrel-jh9w.2).
 */
export declare function secretNames(path?: string): string[];
/**
 * Remove one secret from the store, atomically. Returns `true` if the key was present (and is
 * now gone), `false` if it was already absent — the caller decides whether an absent key is an
 * error (the CLI reports it as NOT_FOUND rather than a silent success). An invalid key throws
 * BEFORE touching disk, like {@link saveSecret}.
 */
export declare function deleteSecret(key: string, path?: string): boolean;
/** A mutable environment the shim populates — `process.env` by default; injected for tests. */
type MutableEnv = {
    [k: string]: string | undefined;
};
/**
 * Hydrate the process environment from the shared out-of-tree secrets home (OSS-ADR-0054).
 *
 * Reads `~/.kestrel/.env` (or `$KESTREL_HOME/.kestrel/.env`) ONCE and copies each stored key into
 * `env` **only if that key is currently UNSET** — an already-present value always WINS, honoring the
 * store's `process.env`-wins precedence (the same rule {@link loadSecret} enforces per-key, applied
 * in bulk so an entrypoint can hydrate the whole environment before any downstream reader — the IBKR
 * config resolver, a bench pull — consults `process.env`). This is the in-process complement to the
 * `kestrel env -- <cmd>` exec wrapper (kestrel-jh9w.4), which resolves the same store for an external
 * process.
 *
 * FAIL-QUIET and dependency-light (node built-ins only, via {@link readSecretStore}): an absent,
 * unreadable, or malformed store simply hydrates nothing — never a throw on the command path, and
 * NEVER a logged value. Under the hermetic `KESTREL_HOME` tests use (a temp home with no `.env`) it
 * is a no-op, so it cannot perturb determinism or a fixture's environment.
 *
 * Returns the NAMES it populated (values never leave this module), sorted — useful for a one-line
 * diagnostic that says WHICH keys came from the store without disclosing any secret.
 */
export declare function loadEnvFallback(opts?: {
    env?: MutableEnv;
    path?: string;
}): string[];
export {};
//# sourceMappingURL=credentials.d.ts.map