/**
 * requestCredentials — a {@link CredentialProvider} fed from the INCOMING
 * REQUEST: the credential a tool uses is the one this run's caller sent.
 *
 * ```ts
 * import { requestCredentials, requestContext, decodedWith } from 'agentfootprint/security';
 *
 * // Once, at boot — no secret in here:
 * const credentials = requestCredentials({
 *   services: {
 *     crm: 'crmToken',                                         // bearer, as sent
 *     billing: { secret: 'billingKey', as: asApiKey('x-api-key') },
 *     mcp: { secret: 'mcpToken', as: decodedWith((raw) => decrypt(raw)) },
 *   },
 * });
 * const agent = Agent.create({ provider, credentials }).tool(crmTool).build();
 *
 * // Per request:
 * await agent.run({ message }, { request: requestContext({ secrets: { crmToken, mcpToken } }) });
 * ```
 *
 * A tool declares `needs: { credential: 'crm' }` and reads `ctx.credential`,
 * exactly as with any other provider. Nothing about the tool changes.
 *
 * ── Interface → adapter → strategies ────────────────────────────────────────
 * The interface is the `CredentialProvider` port. This adapter reads the
 * secret named for the service from the request the call belongs to
 * (`CredentialRequest.request`, filled by the framework). A strategy turns the
 * raw value into a `Credential`: {@link asBearer} (the default),
 * {@link asApiKey}, or {@link decodedWith} for a value that must be decrypted
 * or exchanged first.
 *
 * ── Fails closed, by name ───────────────────────────────────────────────────
 * Every refusal is a {@link RequestCredentialError} naming the SERVICE and the
 * secret's NAME — never a value, and never a strategy's own error text (a
 * decrypt library may quote its input). A thrown message reaches the model as
 * the tool result and rides `agentfootprint.credential.failed`.
 *   - no request on the call (a run started without one, a mount no run
 *     reaches, a connection-level caller) → `'no-request'`;
 *   - the request does not carry the secret → `'missing'`;
 *   - a service this provider was not told about → `'unknown-service'`;
 *   - the strategy threw or returned no credential → `'undecodable'`.
 * There is no fallback: a missing per-request credential is never served from
 * another request, a default, or the process.
 *
 * Pattern: Adapter (port) + Strategy (raw value → Credential).
 */
import type { Credential, CredentialProvider } from './types.js';
/** Raw request value → the credential a tool applies. May be async (decrypt, exchange). */
export type RequestCredentialStrategy = (raw: string) => Credential | Promise<Credential>;
/** Where a service's credential comes from in the request, and how it is read. */
export interface RequestCredentialSource {
    /** The secret's name in `requestContext({ secrets })`. */
    readonly secret: string;
    /** How the raw value becomes a credential. Default {@link asBearer}. */
    readonly as?: RequestCredentialStrategy;
}
/** What {@link requestCredentials} takes. */
export interface RequestCredentialsOptions {
    /** Optional id (defaults to `'request-credentials'`). */
    readonly id?: string;
    /**
     * Service id (what a tool's `needs.credential` names) → its source. A string
     * is the secret's name, read as a bearer token.
     */
    readonly services: Readonly<Record<string, string | RequestCredentialSource>>;
}
/** Why a request credential was refused. */
export type RequestCredentialRefusal = 'no-request' | 'missing' | 'unknown-service' | 'undecodable';
/**
 * A request credential that could not be served. Its message names the
 * service and the secret's name; it never carries a value or a strategy's
 * own error.
 */
export declare class RequestCredentialError extends Error {
    readonly reason: RequestCredentialRefusal;
    readonly service: string;
    readonly code: "ERR_REQUEST_CREDENTIAL";
    constructor(reason: RequestCredentialRefusal, service: string, message: string);
}
/** The raw value, as a bearer token (`Authorization: Bearer …`). The default. */
export declare function asBearer(): RequestCredentialStrategy;
/** The raw value, as an API key in one header (default `x-api-key`). */
export declare function asApiKey(headerName?: string): RequestCredentialStrategy;
/**
 * Decode the raw value first — decrypt an encrypted per-request token,
 * exchange it — then read the result with `then` (default {@link asBearer}).
 * `decode` may return the plain value or a finished `Credential`. Whatever it
 * throws is replaced by an `'undecodable'` refusal that quotes nothing.
 */
export declare function decodedWith(decode: (raw: string) => string | Credential | Promise<string | Credential>, then?: RequestCredentialStrategy): RequestCredentialStrategy;
/**
 * Build the provider. Configuration is checked here, at boot: an empty
 * service map, an empty secret name or a strategy that is not a function is
 * refused by name.
 *
 * @throws TypeError on a malformed `services` map.
 */
export declare function requestCredentials(options: RequestCredentialsOptions): CredentialProvider;
