import { Hono } from 'hono'; import type { Context as hono_Context, MiddlewareHandler } from 'hono'; import type { HonoBase } from 'hono/hono-base'; import type { MergePath, Schema as core_Schema } from 'hono/types'; import { type Method } from 'mppx'; import { Mppx, tempo } from 'mppx/hono'; import type * as App from '../App.js'; import * as ApiKey from '../ApiKey.js'; import * as Db from '../db/Db.js'; import type * as Store from './Store.js'; import * as Memberships from '../db/tables/memberships.js'; import * as Organizations from '../db/tables/organizations.js'; import * as Projects from '../db/tables/projects.js'; import * as RateLimit from './RateLimit.js'; import * as Response from './Response.js'; import * as Scope from '../Scope.js'; import type * as Viem from './Viem.js'; /** Auth context consumed by Tempo API handlers. */ export type Context = { /** API key authentication configuration. */ apiKey?: { /** * API-key quotas keyed by quota scope. The reserved `'*'` entry is the * config default; any other key sets that scope's quota. Mirrors the * per-key {@link ApiKey.ApiKey.rateLimits} shape. */ rateLimits?: Record | undefined; /** Resolves a presented token against the app's KV store on `c`. */ resolve: (c: hono_Context, token: string) => Promise; } | undefined; /** MPP payment configuration. */ mpp?: MppHandler | undefined; /** * Configured default anonymous public quota. Used as the throttle ceiling for * sandbox keys without active billing on routes that expose no public lane * (where the per-route `policy.public` is absent). Omit to fall back to the * framework default. */ publicRateLimit?: RateLimit.Limit | undefined; /** Resolves a trusted client IP for public quota identity. */ publicClientIp?: ((request: Request) => string | undefined) | undefined; /** Rate-limit store used by API handlers. */ rateLimit?: RateLimit.Store | undefined; /** Session lane resolution (the session surface's capability), or undefined when sessions are unmounted. */ session?: Session | undefined; /** Super-admin machine credential (sha256 of the configured secret), or undefined when disabled. */ superAdmin?: { tokenHash: string; } | undefined; }; /** Hono environment variables set by auth middleware. */ export type Environment = { Variables: Variables; }; /** * HTTP endpoint key inferred from a Hono app schema. The schema is matched * against `HonoBase` (which carries it as its 2nd generic) rather than `Hono` * (which re-declares only 3 generics and loses the inferred schema when used * as a value type from `ReturnType`). */ export type Endpoint, mount extends string = '/'> = app extends HonoBase ? endpoint.FromSchema : never; /** Metadata for an accepted payment. */ export type Payment = { /** Verified MPP payer identifier. */ payer?: string | undefined; /** Why payment was required for the request. */ reason: 'api_key_over_quota' | 'public_over_quota'; /** Payment protocol kind. */ type: 'mpp'; }; /** MPP route-policy types. Distinct from the SIWE {@link Session} capability. */ export declare namespace Mpp { /** MPP Session request options used by route access policies. */ type Session = Method.RequestDefaults> & { /** Optional human-readable payment description. */ description?: string | undefined; /** Optional challenge expiration timestamp or date. */ expires?: Date | string | undefined; /** Optional server-defined correlation data. */ meta?: Record | undefined; /** Optional route/resource scope bound to the challenge. */ scope?: string | undefined; }; } /** MPP payment handler consumed by auth policies. */ type MppHandler = { /** Paid-request quota per access principal. */ rateLimit?: RateLimit.Limit | undefined; /** Creates a Hono middleware for a Tempo Session payment. */ session(options: Mpp.Session): MiddlewareHandler; /** Resolves the chain from a challenge issued by this server. */ sessionChainId?: ((c: hono_Context) => number | undefined) | undefined; /** Chains accepted from request-driven Tempo Session payment overrides. */ sessionChainIds?: ReadonlySet | undefined; }; /** * Route-level auth policy override. Each lane is independent: `true` enables it * with the middleware defaults, `false` disables it, an object enables it with * the given overrides, and omitting it inherits the resolved policy. All lanes * are default-closed (see {@link middleware}). * * Routes grant API-key, public, or paid access explicitly via {@link policy}; * otherwise only `super_admin` reaches them. */ export type PolicyOverride = { /** API-key lane: pass quota/scopes overrides, or a boolean to enable/disable. */ apiKey?: { /** API-key quota override for this route (a protective per-route cap). */ rateLimit?: RateLimit.Limit | undefined; /** Required API-key scopes override for this route. */ scopes?: readonly Scope.Id[] | undefined; } | boolean | undefined; /** MPP paid lane: object to override the Session request, or boolean to enable/disable. */ mpp?: { /** Paid-request quota override for this route (a protective per-route cap). */ rateLimit?: RateLimit.Limit | undefined; /** Tempo Session request override for this route. */ session?: Mpp.Session | undefined; } | boolean | undefined; /** Public lane: object to override the quota, or boolean to enable/disable. */ public?: { /** Anonymous public quota override for this route. */ rateLimit?: RateLimit.Limit | undefined; } | boolean | undefined; /** Session lane: `true` allows signed-in wallet sessions, `false` disables. */ session?: boolean | undefined; }; /** Authenticated or anonymous caller. */ export type Principal = { /** Resolved API key. */ apiKey: ApiKey.ApiKey; /** Key environment (`production` accesses any chain; `sandbox` is non-mainnet only). */ environment: ApiKey.ApiKey['environment']; /** Principal id. */ id: string; /** Owning organization id. */ orgId: string; /** Payment metadata for paid overflow requests. */ payment?: Payment | undefined; /** Attributed project id, when present. */ projectId?: string | undefined; /** Principal kind. */ type: 'api_key'; } | { /** Public quota identity. */ id: string; /** Payment metadata for paid overflow requests. */ payment?: Payment | undefined; /** Principal kind. */ type: 'public'; } | { /** Verified email bound to the session, when present. */ email?: string | undefined; /** Principal id: the user id (`usr_…`). */ id: string; /** Identity that established the session, as a provider/subject pair (OIDC `iss`/`sub` semantics). */ identity: { /** Identity provider: `wallet` for SIWE sign-in, an OIDC issuer otherwise. */ provider: string; /** Provider-scoped subject — the wallet address for `wallet`. */ subject: string; }; /** Payment metadata for paid overflow requests. */ payment?: Payment | undefined; /** Principal kind. */ type: 'session'; } | { /** Attributed super admin identity (`'super_admin'` for the configured machine secret). */ actor: string; /** Principal id. */ id: string; /** Payment metadata for paid overflow requests. */ payment?: Payment | undefined; /** Principal kind. */ type: 'super_admin'; }; /** Hono variables set by auth middleware. */ export type Variables = { /** Auth context consumed by protected handlers. */ auth: Context; /** Caller's membership resolved by {@link ensureOrg} or {@link ensureProject}; absent for API keys and `super_admin`. */ membership?: Memberships.Record | undefined; /** Organization resolved by {@link ensureOrg} or {@link ensureProject} for the current request. */ org?: Organizations.Record | undefined; /** Authenticated or anonymous caller. */ principal?: Principal | undefined; /** Project resolved by {@link ensureProject} for the current request. */ project?: Projects.Record | undefined; }; /** Reads the authenticated principal from a Hono context. */ export declare function getPrincipal(c: hono_Context): NonNullable<(import("hono/utils/types").IsAny extends true ? { Variables: import("hono").ContextVariableMap & Record; } : environment)["Variables"]["principal"]> | null; /** * Guards `:orgId` routes and resolves the organization. Sessions require membership, API keys require ownership, and the super admin bypasses ownership. */ export declare function ensureOrg(options?: ensureOrg.Options): MiddlewareHandler; export declare namespace ensureOrg { /** Options for the org guard. */ type Options = { /** Minimum session role; defaults to `member`. */ role?: Memberships.Role | undefined; }; } /** * Resolves `:projectId`, preserving nested organization scope. Sessions require membership; API keys require organization ownership and matching project attribution when present. */ export declare function ensureProject(): MiddlewareHandler; /** * Always false at runtime, but typed as `boolean` so handlers can include a * never-reached scope-error branch in Hono's inferred response union (the * ensure middlewares produce these `404`s before the handler runs). */ export declare const narrowScope: boolean; /** Always false at runtime; lets handlers include organization role errors in inferred response unions. */ export declare const narrowOrgRole: boolean; /** Typed org-scope error response for Hono client inference. Never reached at runtime. */ export declare function ensureOrgError(c: hono_Context): Response & import("hono").TypedResponse<{ error: { code: "organization_not_found"; details?: readonly Response.error.Detail[] | undefined; message: string; }; requestId: string; }, 404, "json">; /** Typed organization-role error response for Hono client inference. Never reached at runtime. */ export declare function ensureOrgRoleError(c: hono_Context): Response & import("hono").TypedResponse<{ error: { code: "forbidden"; details?: readonly Response.error.Detail[] | undefined; message: string; }; requestId: string; }, 403, "json">; /** Typed project-scope error response for Hono client inference. Never reached at runtime. */ export declare function ensureProjectError(c: hono_Context): Response & import("hono").TypedResponse<{ error: { code: "organization_not_found" | "project_not_found"; details?: readonly Response.error.Detail[] | undefined; message: string; }; requestId: string; }, 404, "json">; /** Reads the caller's membership resolved by the organization or project guard; `undefined` for API keys and `super_admin`. */ export declare function membership(c: hono_Context): Memberships.Record | undefined; /** Reads the organization resolved by the organization or project guard; throws when neither middleware ran. */ export declare function org(c: hono_Context): Organizations.Record; /** Reads the project resolved by {@link ensureProject}; throws when the middleware did not run. */ export declare function project(c: hono_Context): Projects.Record; /** * Always false at runtime, but typed as `boolean` so handlers can include a * never-reached access-error branch in Hono's inferred response union. */ export declare const narrowAccess: boolean; /** Typed auth/payment error response for Hono client inference. Never reached at runtime. */ export declare function accessError(c: hono_Context): (Response & import("hono").TypedResponse<{ error: { code: "api_key_malformed"; details?: readonly Response.error.Detail[] | undefined; message: string; }; requestId: string; }, 400, "json">) | (Response & import("hono").TypedResponse<{ error: { code: "api_key_forbidden" | "api_key_ip_forbidden"; details?: readonly Response.error.Detail[] | undefined; message: string; }; requestId: string; }, 403, "json">) | (Response & import("hono").TypedResponse<{ error: { code: "api_key_invalid" | "api_key_missing"; details?: readonly Response.error.Detail[] | undefined; message: string; }; requestId: string; }, 401, "json">) | (Response & import("hono").TypedResponse<{ error: { code: "payment_required" | "rate_limit_exceeded"; details?: readonly Response.error.Detail[] | undefined; message: string; }; requestId: string; }, 429, "json">); /** Typed lane-less policy error response for Hono client inference. Never reached at runtime. */ export declare function superAdminAccessError(c: hono_Context): (Response & import("hono").TypedResponse<{ error: { code: "api_key_malformed"; details?: readonly Response.error.Detail[] | undefined; message: string; }; requestId: string; }, 400, "json">) | (Response & import("hono").TypedResponse<{ error: { code: "forbidden"; details?: readonly Response.error.Detail[] | undefined; message: string; }; requestId: string; }, 403, "json">) | (Response & import("hono").TypedResponse<{ error: { code: "api_key_invalid" | "api_key_missing"; details?: readonly Response.error.Detail[] | undefined; message: string; }; requestId: string; }, 401, "json">); /** Typed auth/payment error response for Hono client inference. Never reached at runtime. */ export declare function paidAccessError(c: hono_Context): (Response & import("hono").TypedResponse<{ error: { code: "api_key_malformed"; details?: readonly Response.error.Detail[] | undefined; message: string; }; requestId: string; }, 400, "json">) | (Response & import("hono").TypedResponse<{ error: { code: "api_key_forbidden" | "api_key_ip_forbidden"; details?: readonly Response.error.Detail[] | undefined; message: string; }; requestId: string; }, 403, "json">) | (Response & import("hono").TypedResponse<{ error: { code: "api_key_invalid" | "api_key_missing"; details?: readonly Response.error.Detail[] | undefined; message: string; }; requestId: string; }, 401, "json">) | (Response & import("hono").TypedResponse<{ error: { code: "payment_required" | "rate_limit_exceeded"; details?: readonly Response.error.Detail[] | undefined; message: string; }; requestId: string; }, 429, "json">) | (Response & import("hono").TypedResponse); /** Creates auth middleware for protected OpenAPI routes. */ export declare function middleware(options: middleware.Options): MiddlewareHandler; export declare namespace middleware { /** Per-route policy overrides keyed by HTTP endpoint. */ type Overrides = Partial, PolicyOverride | false | undefined>>; /** Options for creating auth middleware. */ type Options = { /** Default API-key access policy. Pass false to disable API-key access. */ apiKey?: { /** * Resolve-cache tuning (per-isolate, positive 60s / negative 10s by * default), or `false` to resolve uncached on every request — e.g. * when immediate key updates matter more than the per-request * backend read. */ cache?: Cache | false | undefined; /** API-key quotas keyed by quota scope (reserved `'*'` is the config default). */ rateLimits?: Record | undefined; /** Required API-key scopes. */ scopes?: readonly Scope.Id[] | undefined; } | false | undefined; /** MPP payment options. Pass false to disable paid overflow. */ mpp?: MppOptions | false | undefined; /** Per-route policy overrides keyed by HTTP endpoint, e.g. `GET /tokens/:token`. */ overrides?: Overrides | undefined; /** Default public access policy. Pass false to disable anonymous access. */ public?: { /** Resolves the client IP from trusted runtime or proxy metadata. Required outside Cloudflare for API-key allowlists. */ clientIp?: ((request: Request) => string | undefined) | undefined; /** Anonymous public quota for protected routes. */ rateLimit?: RateLimit.Limit | undefined; } | false | undefined; /** Rate-limit store options. */ rateLimit?: RateLimit.memory.Options | undefined; /** Scope catalog accepted while resolving API-key records. */ scopeCatalog?: Scope.Catalog | undefined; /** Session lane resolution — the session surface's capability; omit to leave the session lane closed. */ session?: Session | undefined; /** * Super-admin machine credential. A presented API-key token matching this * secret resolves to a `super_admin` principal — bypassing scope and quota * checks — before the key lookup runs. Omit to disable the entry entirely. */ superAdmin?: { secret: string; } | undefined; }; /** Resolve-cache tuning for API-key resolution. */ type Cache = { /** Time-to-live for negative (`null`) results in milliseconds. */ negativeTtl?: number | undefined; /** Clock used for expiry. */ now?: (() => number) | undefined; /** Time-to-live for positive results in milliseconds. */ ttl?: number | undefined; }; /** MPP payment options used by auth middleware. */ type MppOptions = Omit]>>[0], 'methods'> & { /** Paid-request quota per access principal. Defaults to 100 per minute. */ rateLimit?: RateLimit.Limit | undefined; /** Global Tempo Session options passed to the MPP method instantiator. */ session?: NonNullable[0]> | undefined; /** Chains accepted from request-driven Tempo Session payment overrides. Omit to preserve the MPP client's chain support. */ sessionChainIds?: readonly number[] | undefined; }; } /** * Builds the built-in auth pieces from `App.create`'s `auth` option: the * session-surface app to mount (when `session` is configured) and the * enforcement middleware, wired with the surface's resolver. `auth: false` * disables both. */ export declare function install(options: install.Options): { app: (HonoBase, "/", string> & { session: Session; }) | undefined; middleware: MiddlewareHandler | undefined; }; export declare namespace install { /** Options for building the built-in auth pieces. */ type Options = { auth: (Omit & { /** Session sign-in surface: mounts `/v1/auth/siwe` (challenge/verify/logout) and enables the session lane. Pass true for defaults or a config object. Requires `kv`. */ session?: Session | undefined; }) | false | undefined; /** Authoritative database holding user rows. */ db: Db.Source; /** Resolves the configured Tempo RPC client used for SIWE signature verification. */ getClient: (chainId: number) => Viem.getClient.ReturnType; /** KV state store, or undefined when key auth is closed. */ kv: { store: Store.State; } | undefined; /** Scope catalog accepted while resolving API-key records. */ scopeCatalog: Scope.Catalog; }; /** Session sign-in surface configuration: `true` for defaults, or a config object. */ type Session = boolean | { /** SIWE wallet sign-in configuration. */ wallet?: Wallet | undefined; }; /** SIWE wallet sign-in configuration. */ type Wallet = { /** Identity (verified email) issuer override; defaults to the Tempo wallet's production OIDC mount. */ issuer?: string | undefined; /** Pinned absolute origin for SIWE domain binding. Required off-Workers; on Workers the edge proxy headers are trusted by default. */ origin?: string | undefined; /** Reject sign-ins that carry no valid identity token, so every session holds a verified email. */ requireEmail?: boolean | undefined; /** Session and challenge TTL overrides, in seconds. */ ttl?: { challenge?: number | undefined; session?: number | undefined; } | undefined; }; } /** Creates route middleware that contributes an auth policy override. */ export declare function policy(options: policy.Options): MiddlewareHandler; export declare namespace policy { /** Route policy plus metadata for compatibility aliases. */ type Options = PolicyOverride & { /** HTTP method whose configured override this route inherits when its own is absent. */ inheritOverridesFrom?: string | undefined; }; } /** Adds management POSTs for OpenAPI-registered MPP GET resources. */ export declare function installMppManagementRoutes(app: Hono, options?: MppManagementOptions): void; export declare namespace endpoint { /** * HTTP endpoint key inferred from a Hono app schema. Distributes over the * schema union so the `BlankSchema | MergeSchemaPath<...>` shape Hono * produces from `.basePath(...).route(...)` chains contributes its typed * routes (a non-distributing mapped type would collapse `BlankSchema` to * `never` and infect the whole union). */ type FromSchema = schema extends infer s ? { [path in keyof s & string]: { [method in keyof s[path] & `$${string}`]: `${Method} ${Path>}`; }[keyof s[path] & `$${string}`]; }[keyof s & string] : never; /** HTTP method string extracted from Hono's schema method key. */ type Method = method extends `$${infer value}` ? Uppercase : never; /** Public endpoint path with Hono route regex constraints removed. */ type Path = path extends `${infer head}/${infer tail}` ? `${Segment}/${Path}` : Segment; /** Public endpoint path segment with any regex constraint removed. */ type Segment = segment extends `:${infer parameter}{${string}` ? `:${parameter}` : segment; } type MppManagementOptions = { basePath?: string | undefined; overrides?: Record | undefined; }; /** Resolved access lanes for one documented operation. */ export type OperationAccess = { /** Whether API-key access is allowed. */ apiKey: boolean; /** Whether MPP payment is accepted (enables the `402` payment-challenge response). */ mpp: boolean; /** Whether anonymous public-quota access is allowed (keeps the anonymous security option). */ public: boolean; /** Required API-key scopes (`[]` accepts any valid key); empty when the API-key lane is disabled. */ scopes: readonly Scope.Id[]; /** Whether signed-in sessions are allowed. */ session: boolean; }; /** * Maps each documented operation id to its resolved access lanes by reading the * `policy` overrides co-located on the app's routes. This is the single source * of truth for per-operation `security` and the `402` response in the generated * OpenAPI document (see `App.create`): all lanes are default-closed, and an * operation surfaces only the lanes its route opts into via {@link policy}. */ export declare function describeAccess(app: Hono): Record; /** Requires route access through API key, public quota, or MPP payment. */ export declare function require(policy: require.Policy): MiddlewareHandler; export declare namespace require { /** Route access policy. */ type Policy = { /** API-key access policy. */ apiKey?: { /** API-key quota override for this route (a protective per-route cap). */ rateLimit?: RateLimit.Limit | undefined; /** * Required API-key scopes. Defaults to `['*']`, so a route that does * not declare scopes requires a full-access key; narrow it by listing * catalog scopes via {@link policy}. */ scopes: readonly (Scope.Id | typeof Scope.wildcard)[]; } | undefined; /** MPP payment access policy. */ mpp?: { /** Paid-request quota override for this route (a protective per-route cap). */ rateLimit?: RateLimit.Limit | undefined; /** Tempo Session request policy. */ session: Mpp.Session; } | undefined; /** Public access policy. */ public?: { /** Anonymous public quota for this route. */ rateLimit: RateLimit.Limit; } | undefined; /** Session access policy: `true` allows signed-in wallet sessions. */ session?: boolean | undefined; }; } /** True when the request carries an `Authorization: Payment` MPP credential. */ export declare function hasPaymentCredential(c: hono_Context): boolean; /** Session principal resolved by the session lane. */ export type SessionPrincipal = Extract; /** * Session resolution capability installed on app context (`session`) by * `App.create` when session auth is configured; `undefined` leaves the session * lane closed. */ export type Session = { /** Resolves the request's session (cookie or bearer token) to a principal. */ resolve: (c: hono_Context) => Promise; }; /** Thrown when a rate-limit consume exceeds {@link rateLimitConsumeTimeout}. */ export declare class RateLimitTimeoutError extends Error { name: string; constructor(ms: number); } export {}; //# sourceMappingURL=Auth.d.ts.map