/** * Small, runtime-neutral request-signing primitives for app-to-app federation. * * Federation peers authenticate one bounded HTTP request with a shared vault * secret. They never exchange an end-user session or an odla-db application * key. The signature binds the sender, method, path/query, timestamp, nonce, * and exact body bytes. Callers remain responsible for authorizing the named * sender and, for non-idempotent operations, consuming the nonce exactly once. */ /** Header names used by the version-1 federation signature envelope. */ declare const FEDERATION_HEADERS: { readonly version: "x-odla-federation"; readonly sender: "x-odla-federation-sender"; readonly timestamp: "x-odla-federation-timestamp"; readonly nonce: "x-odla-federation-nonce"; readonly signature: "x-odla-federation-signature"; }; /** Current wire version for signed federation requests. */ declare const FEDERATION_VERSION = "1"; /** Input for {@link signFederatedRequest}. */ interface SignFederatedRequestOptions { /** Vaulted edge secret shared only by the two server runtimes. */ secret: string; /** Stable app/site slug asserted by the sender. */ sender: string; method: string; url: string | URL; /** Exact request body text. Omit for a bodyless request. */ body?: string; /** Epoch milliseconds. Defaults to `Date.now()`. */ timestamp?: number; /** Base64url-safe request nonce. Defaults to 128 random bits. */ nonce?: string; } /** Options for {@link verifyFederatedRequest}. */ interface VerifyFederatedRequestOptions { /** Vaulted edge secret expected for this route. */ secret: string; /** Optional sender allowlist. An omitted list accepts any valid sender slug. */ senders?: readonly string[]; /** Epoch-millisecond clock injection. */ now?: () => number; /** Maximum past/future clock skew. Defaults to five minutes. */ maxSkewMs?: number; /** * Optional replay gate. Return true only when this sender+nonce was consumed * for the first time. Idempotent read routes can omit it. */ consumeNonce?: (sender: string, nonce: string, timestamp: number) => boolean | Promise; } /** Successful verification, including the cloned request body. */ interface VerifiedFederatedRequest { ok: true; sender: string; timestamp: number; nonce: string; body: string; } /** Stable failure reasons suitable for a route's audit log. */ type FederationVerificationFailure = "missing_headers" | "unsupported_version" | "invalid_sender" | "sender_not_allowed" | "invalid_timestamp" | "expired" | "invalid_nonce" | "invalid_signature" | "replayed"; /** Failed verification. No secret or submitted signature is reflected. */ interface RejectedFederatedRequest { ok: false; reason: FederationVerificationFailure; } /** Result returned by {@link verifyFederatedRequest}. */ type FederationVerification = VerifiedFederatedRequest | RejectedFederatedRequest; /** * Sign one app-to-app HTTP request. Add the returned headers to the exact * method, URL path/query, and body passed here. */ declare function signFederatedRequest(options: SignFederatedRequestOptions): Promise>; /** * Verify one signed federation request. Verification reads a clone, leaving the * original request body available; the verified clone body is also returned so * route code can parse exactly the bytes covered by the signature. */ declare function verifyFederatedRequest(request: Request, options: VerifyFederatedRequestOptions): Promise; export { FEDERATION_HEADERS, FEDERATION_VERSION, type FederationVerification, type FederationVerificationFailure, type RejectedFederatedRequest, type SignFederatedRequestOptions, type VerifiedFederatedRequest, type VerifyFederatedRequestOptions, signFederatedRequest, verifyFederatedRequest };