/**
 * hosting/identityVerification — the door checks the badge, instead of reading
 * the name off it.
 *
 * Until 9.26 the hosting port had exactly one honest sentence about WHO is
 * calling: `HostRequest.userId` is "what the transport said", and how much that
 * is worth is the transport's answer. A managed runtime that authenticates in
 * front of the container can fill it in; a container you expose yourself cannot,
 * because a header there is a string anybody can send. That sentence is still
 * true. This module is the other half of it: a way to make the door itself the
 * thing that knows, so a deployment does not have to choose between "trust a
 * header" and "no identity at all".
 *
 * ── The shape: one strategy, one method ──────────────────────────────────────
 * {@link IdentityVerifier} takes the bearer token off the wire and hands back
 * {@link VerifiedIdentity} — `{ userId, roles?, claims? }` — or throws. It is
 * vendor-neutral by construction: a JWT from any IdP, an opaque token
 * introspected against a server, a mutual-TLS thumbprint an edge proxy already
 * checked. `jwksIdentity({ jwksUrl, issuer, audience })` is the one adapter
 * this release ships, and it covers cloud IdPs and on-prem ones alike because
 * JWKS is the same protocol in both.
 *
 * ── Where it sits, exactly ───────────────────────────────────────────────────
 * BEFORE `identityForRequest` composes the run's scope. That ordering is the
 * whole feature: the composed scope is what memory namespaces on, what
 * artifacts isolate on, and what a credential provider scopes a token vault on.
 * Verifying after any of that would be checking the badge on the way out.
 *
 * ── The refusal law, and why it is not optional ──────────────────────────────
 * With a verifier configured, a request that names a `userId` and cannot prove
 * it is REFUSED — never quietly downgraded to anonymous, and never served under
 * the name it claimed. Both alternatives are the accepted-and-silently-wrong
 * failure wearing different clothes: one produces an audit trail that names the
 * wrong party, the other produces a door that anybody opens by omitting a
 * field.
 *
 * ── Secrets never travel ─────────────────────────────────────────────────────
 * A bearer token is a credential. It never appears in an error message, an
 * event payload, a log line or a reply body — not truncated, not fingerprinted,
 * not "just the first 8 characters". What travels is the CLASS of the failure
 * ({@link IdentityFailureClass}) and nothing else, which is exactly what an
 * operator needs to act (`expired` → the client should refresh;
 * `wrong-audience` → the client is pointed at the wrong API;
 * `keys-unavailable` → your IdP is unreachable and this is not the caller's
 * fault). That is the `sdkFailure` law, applied to the front door.
 */
import type { IdentityFailureClass } from './errors.js';
import type { SignInSource } from './signin/types.js';
/**
 * What a verifier proved. The badge, read after it was checked.
 *
 * Deliberately NOT a `MemoryIdentity`: this is evidence about a PERSON, and the
 * run's identity is a tenant/principal/conversation TUPLE the composer builds
 * from this plus the session. Keeping them separate is what stops a verifier
 * from silently re-namespacing somebody's conversation by returning a field.
 */
export interface VerifiedIdentity {
    /** The end user's id — what becomes {@link HostRequest.userId} and, through
     *  `identityForRequest`, the run's `principal`. Non-empty by contract; a
     *  verifier that cannot name the subject must throw rather than invent one. */
    readonly userId: string;
    /**
     * Roles the token asserted, when it asserted any.
     *
     * These reach the ADMISSION policy (`admission.decide({ identity, … })`) and
     * the session-history ops, and nothing else — they do not enter the run's
     * identity, which stays the three-field tuple every store already scopes on.
     * Stated rather than implied, because "the agent can see my roles" is exactly
     * the kind of belief that gets built on.
     */
    readonly roles?: readonly string[];
    /**
     * The verified claim set, as the verifier read it. Whatever an authorization
     * decision in THIS deployment needs (a tenant claim, a plan, a scope list)
     * and this library has no business interpreting.
     *
     * Never logged and never emitted by the framework — a claim set routinely
     * carries an email, and one echo puts it in every sink.
     */
    readonly claims?: Readonly<Record<string, unknown>>;
}
/**
 * The port — one method, vendor-neutral.
 *
 * `verify` is handed the RAW bearer token exactly as the wire delivered it
 * (without the `Bearer ` prefix) and must either return a
 * {@link VerifiedIdentity} or throw. Throwing an
 * {@link IdentityNotVerifiedError} names the failure class; throwing anything
 * else is treated as `'unverifiable'`, because a verifier that failed in a way
 * it did not describe has not verified anything.
 *
 * Implementations must never put the token into what they throw.
 */
export interface IdentityVerifier {
    verify(token: string): Promise<VerifiedIdentity>;
}
/**
 * How a host door is told to check badges — {@link StandingAgentBaseOptions.identity}.
 *
 * The 9.26 shape, unchanged for its callers (`verify` required), plus two
 * optional additions: `signIn` (a sign-in the server keeps, named by the key
 * the transport passes after stripping the sign-in cookie) and `tokenHeader`.
 * A door that takes sign-ins ONLY is a {@link SignInOnlyIdentity}; every door
 * accepts either, as a {@link DoorIdentity}.
 */
export interface IdentityVerificationOptions {
    /** The strategy. `jwksIdentity({ … })`, `oidcIdentity({ … })`, or any {@link IdentityVerifier}. */
    readonly verify: IdentityVerifier['verify'];
    /**
     * Let a request that presents NO credential through as anonymous.
     * Default **`false`** — configuring a verifier closes the door.
     *
     * The default is the load-bearing half. A door that verifies a token when one
     * is offered and waves the request through when it is not is a door anybody
     * opens by sending less, and every per-user bound built on top of it (spend
     * ceilings, session listing) evaporates for exactly the callers those bounds
     * exist for.
     *
     * Say `true` when a deployment genuinely serves both — a public demo lane and
     * a signed-in lane on one host. An anonymous request can then never carry a
     * `userId`: it is refused rather than served under a name nobody proved.
     */
    readonly allowAnonymous?: boolean;
    /** The sign-ins this door ALSO accepts (`signInSource({ store, idleMinutes })`). */
    readonly signIn?: SignInSource;
    /**
     * Which header carries the token, lower-case. Default `'authorization'`,
     * read as `Bearer <token>`. Any other name is read as the raw token (a
     * leading `Bearer ` is tolerated) — the header an authenticating proxy
     * forwards a signed token in.
     */
    readonly tokenHeader?: string;
}
/**
 * A door that accepts sign-ins only — no bearer tokens. A presented token is
 * `unverifiable` there.
 */
export interface SignInOnlyIdentity {
    readonly verify?: undefined;
    /** The sign-ins this door accepts. */
    readonly signIn: SignInSource;
    /** As {@link IdentityVerificationOptions.allowAnonymous}. */
    readonly allowAnonymous?: boolean;
    /** As {@link IdentityVerificationOptions.tokenHeader}. */
    readonly tokenHeader?: string;
}
/** What every door takes: a verifier (optionally with sign-ins), or sign-ins only. */
export type DoorIdentity = IdentityVerificationOptions | SignInOnlyIdentity;
/**
 * Pull the bearer token out of the delivered transport headers.
 *
 * ONE extraction, so every dialect's tokens are read the same way. The header
 * is `Authorization: Bearer <token>` — the vocabulary every transport this
 * package speaks already normalizes onto:
 *
 *  - `httpHost` (and therefore `nodeHost` / `jsonWire`) hands the handler the
 *    request's lower-cased headers verbatim, so the token is simply there;
 *  - the managed-runtime dialect maps its own bearer SUBPROTOCOL onto
 *    `headers.authorization` before the port ever sees it, which is why that
 *    mapping was written the way it was;
 *  - a custom `HttpWire` that carries the credential somewhere else supplies
 *    the header itself, or wraps its own verifier.
 *
 * The scheme match is case-insensitive (RFC 7235 says it is), and a header with
 * a different scheme returns `undefined` rather than being half-read — handing
 * a Basic credential to a JWT verifier would produce a confusing refusal about
 * the wrong thing.
 */
export declare function bearerToken(headers: Readonly<Record<string, string>> | undefined): string | undefined;
/**
 * The token a request presents under `options.tokenHeader` — `bearerToken` for
 * the default `authorization`, the raw (trimmed) value for any other header.
 */
export declare function presentedToken(headers: Readonly<Record<string, string>> | undefined, tokenHeader: string | undefined): string | undefined;
/**
 * Run one request's verification and hand back the proven identity — or refuse.
 *
 * Shared by every door on the composer (a turn, an artifact redemption, a
 * session-history op) so all three inherit one answer to "who is this", and a
 * later door cannot accidentally be the lenient one.
 *
 * @param options   the configured verifier, or `undefined` — with `undefined`
 *                  this returns `undefined` immediately and NOTHING about the
 *                  request changes (the zero-delta path).
 * @param headers   the delivered transport headers.
 * @param claimedUserId  what the transport put on `HostRequest.userId`.
 * @param signInKey what the transport put on `HostRequest.signInKey` — the
 *                  sign-in cookie's key, the cookie itself already stripped.
 *
 * One credential per request (rule 13): a token AND a sign-in together are
 * refused as `'two-credentials'` — which one to believe is not a question a
 * door should answer. A sign-in that ended, expired or never existed is
 * `'expired'`, one answer for all three. A sign-in store that cannot answer is
 * {@link VerifierUnavailableError} (503), never a signed-out caller.
 */
export declare function verifyRequestIdentity(options: DoorIdentity | undefined, headers: Readonly<Record<string, string>> | undefined, claimedUserId: string | undefined, signInKey?: string): Promise<VerifiedIdentity | undefined>;
/** Re-exported so a consumer typing a verifier reads one vocabulary. */
export type { IdentityFailureClass };
