/**
 * OAuth state signer
 *
 * Signs the `state` parameter on outbound OAuth flows so the server can prove,
 * on callback/claim, that the userId + connector + origin it sees were minted
 * by this instance — not forged by an attacker controlling a callback URL.
 *
 * Without integrity protection on `state`, an attacker who controls a
 * `/api/oauth/callback/:name` or `/api/oauth/claim/:connector` URL can
 * forge `{c, u, o}` to bind their own OAuth tokens against a victim's
 * userId. This module closes that gap.
 *
 * Signing key is derived from the workspace master key via HKDF
 * (info="studiograph-oauth-state-v1") so it's distinct from the AEAD key
 * used for at-rest encryption — a leak of one doesn't compromise the other.
 *
 * The serialized state is a base64url-encoded JSON object:
 *   { c, u, o, t, s }
 * where `s` is the base64url HMAC-SHA256 over the canonical message
 * (a JSON array of [c, u, o, t]). The OAuth broker continues to decode
 * `c`, `u`, `o` from this JSON unchanged — adding `t` and `s` is forward-
 * compatible.
 */
export interface OAuthStateClaims {
    connectorName: string;
    userId: number;
    origin: string;
}
export interface OAuthStateSigner {
    sign(claims: OAuthStateClaims): string;
    verify(state: string, opts?: {
        maxAgeMs?: number;
    }): OAuthStateClaims | null;
}
/**
 * Derive a 32-byte signing key from the workspace master key. The `info`
 * binding ensures this key is domain-separated from the AEAD key used to
 * encrypt secrets at rest.
 */
export declare function deriveStateSigningKey(masterKey: Uint8Array): Uint8Array;
export declare function createOAuthStateSigner(key: Uint8Array): OAuthStateSigner;
export interface PayloadSigner {
    sign(payload: Record<string, unknown>): string;
    verify(token: string, opts?: {
        maxAgeMs?: number;
    }): Record<string, unknown> | null;
}
/**
 * Derive the consent signing key from the JWT secret via HKDF. Domain-separated
 * from session JWTs (different mechanism entirely) and from the outbound state
 * signer (different `info`). Keying off the JWT secret — rather than the master
 * key — means the authorization server works on every boot, including
 * non-encrypted/test boots where no master key is wired.
 */
export declare function deriveConsentSigningKey(jwtSecret: string): Uint8Array;
/**
 * Generic HMAC payload signer: serializes `{ p: <payload>, t: <ts> }`, signs
 * the canonical JSON with HMAC-SHA256, and base64url-encodes the blob. `verify`
 * recomputes the HMAC with `timingSafeEqual`, enforces a max age, and rejects
 * future-dated tokens. Returns the payload object on success, null otherwise.
 */
export declare function createConsentSigner(key: Uint8Array): PayloadSigner;
