import { BUILDER_CREDENTIAL_KEYS } from "./builder-credential-keys.js"; export { isHostedWorkspaceRuntime, resolveVercelDeploymentProtectionHeaders, } from "./deployment-protection.js"; /** * The `app_secrets` row a Builder key-pair write or delete targets, by the * role table every Builder save path shares (`decideCredentialWriteScope`). * Callers have already authorized the write and checked the personal-key * policy. */ export declare function resolveCredentialWriteScope(email: string, orgId: string | null | undefined, role: string | null | undefined): { scope: "user" | "org"; scopeId: string; }; export declare class FeatureNotConfiguredError extends Error { readonly statusCode = 400; readonly errorCode = "feature_not_configured"; readonly requiredCredential: string; readonly builderConnectUrl?: string; readonly byokDocsUrl?: string; constructor(opts: { requiredCredential: string; message?: string; builderConnectUrl?: string; byokDocsUrl?: string; }); } /** * The credential store could not be read — which is NOT the same as the * credential being absent. Never render this as "not configured": the user has * nothing to configure, they have something to retry. */ export declare class CredentialStoreUnavailableError extends Error { readonly errorCode = "credential_store_unavailable"; readonly retryable = true; constructor(cause?: unknown); } export declare function assertCredentialStoreReadable(result: { lookupFailed: boolean; cause?: unknown; }): void; /** * Read deployment-owned configuration. LLM provider keys have an app-wide * fallback policy; user and workspace credentials must use scoped resolvers. */ export declare function readDeployCredentialEnv(key: string): string | undefined; /** * Legacy deployment-level credential policy for non-provider call sites. * Model-provider env keys use `canUseDeployCredentialFallbackForRequest()` so * self-hosted apps and local PGlite development can share an app-owned * inference key. * * @deprecated Use `canUseDeployCredentialFallbackForRequest()` for generic * provider secrets. This stricter helper remains for legacy call sites with * identity-bearing deploy credentials. */ export declare function isDeployCredentialFallbackAllowed(): boolean; export declare function canUseDeployCredentialFallbackForRequest(key?: string): boolean; export declare const BUILDER_GATEWAY_TOKEN_ENV_VAR = "BUILDER_GATEWAY_TOKEN"; export declare const BUILDER_GATEWAY_SPACE_ID_ENV_VAR = "BUILDER_GATEWAY_SPACE_ID"; export { BUILDER_CREDENTIAL_KEYS }; export declare function hasPlatformRuntimeMarker(): boolean; export declare function isProductionLikeRuntime(): boolean; export declare function isTrustedSelfHostedRuntime(): boolean; export declare function builderCreditsRefusalStatus(chatEligible: boolean): { builderCreditsRefused?: true; }; /** @internal Test isolation for the once-per-process refusal warning. */ export declare function resetBuilderCreditsRefusedWarningForTests(): void; type BuilderCredentialSource = "user" | "org" | "workspace" | "env"; /** * Host hook: an app hosted inside Builder, with Builder as its identity * provider, already holds the caller's own Builder credential. When a * provider answers for the request's user, every Builder-backed feature (the * AI gateway engine, Fusion containers, credits, deploys) uses that * credential instead of a stored per-app Builder connection, so Builder sees * and authorizes the real user in the real space. */ export interface DelegatedBuilderCredentials { /** The user's own bearer (e.g. a Builder Firebase ID token). */ token: string; /** The Builder space the user is acting in. */ spaceId: string; userId?: string; } /** * What a host's provider says about a user: * - credentials: the caller's own Builder credential, used for every Builder * feature; * - `null`: not a host-managed user, so ordinary stored credentials apply; * - `"none"`: a host-managed user with no usable credential right now (it * expired, or was never exchanged). Lookup stops: a shared or stored * credential must never stand in for the user's own, and the host asks them * to sign in again. * A provider that throws is an outage, reported as a failed lookup rather than * as the absence of a credential. * It may answer asynchronously, so a host on serverless can keep the * credential in shared storage rather than per-instance memory. */ export type DelegatedBuilderCredentialsResult = DelegatedBuilderCredentials | null | "none"; type DelegatedBuilderCredentialsProvider = (email: string) => DelegatedBuilderCredentialsResult | Promise; export declare function registerDelegatedBuilderCredentials(provider: DelegatedBuilderCredentialsProvider | null): void; export interface BuilderCredentialLookupIdentity { userEmail?: string | null; orgId?: string | null; } export declare function resolveBuilderCredential(key: string, identity?: BuilderCredentialLookupIdentity): Promise; export declare function isBuilderEnvManaged(): boolean; export declare function resolveBuilderPrivateKey(identity?: BuilderCredentialLookupIdentity): Promise; export declare function resolveBuilderAuthHeader(): Promise; export declare function resolveHasBuilderPrivateKey(): Promise; export declare function resolveHasCompleteBuilderConnection(): Promise; /** * Resolve where the effective Builder assistant connection came from. This * intentionally requires a complete private+public key pair from one scope so * status UIs don't report a mixed user/org credential set as connected. */ export declare function resolveBuilderCredentialSource(): Promise; export interface BuilderCredentialsDetailed { privateKey: string | null; publicKey: string | null; userId: string | null; orgName: string | null; orgKind: string | null; subscription: string | null; subscriptionLevel: string | null; subscriptionName: string | null; isEnterprise: boolean | null; isFreeAccount: boolean | null; source: BuilderCredentialSource | null; /** True when a lookup failed, rather than answering cleanly with "no row". */ lookupFailed: boolean; /** Optional Builder profile metadata failed after the required key pair was read. */ optionalMetadataLookupFailure?: "unreadable" | "unavailable"; cause?: unknown; /** A host-managed user with no credential: no fallback may stand in. */ hostManagedWithoutCredential?: boolean; } export declare function resolveBuilderCredentialsDetailed(identity?: BuilderCredentialLookupIdentity): Promise; export declare function resolveBuilderCredentials(identity?: BuilderCredentialLookupIdentity): Promise<{ privateKey: string | null; publicKey: string | null; userId: string | null; orgName: string | null; orgKind: string | null; subscription: string | null; subscriptionLevel: string | null; subscriptionName: string | null; isEnterprise: boolean | null; isFreeAccount: boolean | null; lookupFailed?: boolean; optionalMetadataLookupFailure?: "unreadable" | "unavailable"; }>; export type BuilderGatewayLane = "identity" | "gateway-deploy"; export interface BuilderGatewayCredentialsDetailed extends BuilderCredentialsDetailed { lane: BuilderGatewayLane | null; } export declare function resolveUsableBuilderGatewayDeployCredentials(): Promise<{ token: string; spaceId: string; } | null>; export declare function isBuilderGatewayDeployConfigured(): boolean; export declare function gatewayLaneUnavailableMessage(ownerFacing: string): string; /** * Gateway-lane credentials. Fall-through: the request's own Builder connection, * then the deployment's credits pair, then the legacy pair. * * Identity-bearing calls (asset upload, design systems, Admin GraphQL, browser * agent) must keep using `resolveBuilderCredentials`: a `['gateway']` token 403s * on all of them. */ export declare function resolveBuilderGatewayCredentialsDetailed(identity?: BuilderCredentialLookupIdentity): Promise; /** * @deprecated Use `resolveBuilderGatewayAuth()` instead — it also checks the * request owner's Builder OAuth grant, which this key-only shape cannot * represent. Kept only so an external caller built against the old export * does not break; no code in this repo calls it anymore. */ export declare function resolveBuilderGatewayCredentials(identity?: BuilderCredentialLookupIdentity): Promise<{ privateKey: string | null; publicKey: string | null; userId: string | null; orgName: string | null; orgKind: string | null; subscription: string | null; subscriptionLevel: string | null; subscriptionName: string | null; isEnterprise: boolean | null; isFreeAccount: boolean | null; }>; export interface BuilderGatewayAuth { authorization: string; /** * Send as `x-builder-api-key`. Null for a legacy single-key deployment, or * for an OAuth access token: the token itself carries the caller's identity, * so the gateway does not require a space id alongside it. */ spaceId: string | null; userId: string | null; } export declare class BuilderCredentialLookupError extends Error { readonly cause: unknown; constructor(cause?: unknown); } export declare function resolveHasBuilderGatewayCredential(): Promise; export declare function resolveBuilderGatewayAuth(identity?: BuilderCredentialLookupIdentity): Promise; export declare const BUILDER_AUTH_FAILURE_TTL_MS: number; export interface BuilderCredentialAuthFailure { fingerprint: string; message: string; status?: number; code?: string; at: number; ownerEmail?: string | null; orgId?: string | null; } export declare function builderCredentialFingerprint(privateKey?: string | null, publicKey?: string | null): string | null; export declare function getBuilderCredentialAuthFailure(creds?: { privateKey?: string | null; publicKey?: string | null; }): Promise; export declare function recordBuilderCredentialAuthFailure(details?: { status?: number; code?: string; message?: string; }): Promise; export declare function clearBuilderCredentialAuthFailure(creds: { privateKey?: string | null; publicKey?: string | null; }): Promise; export declare const PROVIDER_AUTH_FAILURE_TTL_MS: number; export interface ProviderCredentialAuthFailure { fingerprint: string; key: string; message: string; status?: number; code?: string; at: number; ownerEmail?: string | null; orgId?: string | null; } export declare function providerCredentialFingerprint(key?: string | null, value?: string | null): string | null; export declare function getProviderCredentialAuthFailure(opts: { key?: string | null; value?: string | null; throwOnReadError?: boolean; }): Promise; /** The recorded message is the provider's own and can echo the key, so it stays server-side. */ export interface ProviderCredentialRejection { at: number; status?: number; } /** * The last rejection recorded for each exact key/value pair, keyed by `key`, * whether or not its backoff has passed: the engine retries an expired * marker, but only a successful call or a new value clears it, so Settings * shows the key as rejected until then. Throws when the markers can't be read, * unlike `getProviderCredentialAuthFailure`, so an unreadable marker is never * reported as a working key. */ export declare function readProviderCredentialRejections(credentials: ReadonlyArray<{ key: string; value: string; }>): Promise>; export declare function recordProviderCredentialAuthFailure(opts: { key?: string | null; value?: string | null; status?: number; code?: string; message?: string; }): Promise; export declare function clearProviderCredentialAuthFailure(opts: { key?: string | null; value?: string | null; }): Promise; export declare function recordBuilderGatewayAuthFailure(details?: { status?: number; code?: string; message?: string; }): Promise; export declare function clearBuilderGatewayAuthFailure(creds: { privateKey?: string | null; publicKey?: string | null; }): Promise; export declare function writeBuilderCredentials(email: string, creds: { privateKey: string; publicKey: string; userId?: string | null; orgName?: string | null; orgKind?: string | null; subscription?: string | null; subscriptionLevel?: string | null; subscriptionName?: string | null; isEnterprise?: boolean | null; isFreeAccount?: boolean | null; }, options?: { orgId?: string | null; role?: string | null; }): Promise<{ scope: "user" | "org"; scopeId: string; }>; export declare function deleteBuilderCredentials(email: string, options?: { orgId?: string | null; role?: string | null; }): Promise<{ scope: "user" | "org"; scopeId: string; }>; export interface BuilderKeyConnectionSummary { /** When the stored private key was last written; null when unrecorded. */ connectedAt: number | null; /** Stored but unusable: its public key is missing or Builder rejected it. */ needsReconnect: boolean; } export interface BuilderKeyConnections { org?: BuilderKeyConnectionSummary; personal?: BuilderKeyConnectionSummary; } /** * The Builder key pairs stored as the org's shared connection and as this * user's personal one, each read on its own: unlike the resolvers, a personal * pair never hides the org's. These are the rows `deleteBuilderCredentials` * removes at each scope. Throws when the store cannot be read, so "no keys" * and "could not look" stay different answers. */ export declare function getBuilderKeyConnections(email: string, orgId: string | null): Promise; /** * Warm this request's secret memo for many keys with one read per scope. * * `resolveSecret` walks four scopes per key, so a status endpoint asking about * a dozen keys costs ~50 round trips against a remote database. Reading each * scope once for the whole key set collapses that to four, and the subsequent * `resolveSecret` calls answer from the per-request memo — same precedence, * same identity scoping, no new cache to invalidate. * * Best-effort on purpose: `readAppSecrets` only memoizes keys a statement * actually covered, so a failure here leaves each key's own lookup to run and * report the failure. It must never turn an unreadable store into "not set". */ export declare function prefetchSecrets(keys: readonly string[]): Promise; /** * Resolve a request-scoped secret. Reads from `app_secrets` first (current * user override, active org, workspace row for that org, the solo workspace * row, then the explicitly designated workspace vault organization); falls * back to `process.env` only when the deploy fallback policy allows it. * * Resolving several keys in one request? Call `prefetchSecrets` first. */ export declare function resolveSecret(key: string): Promise; type SecretPairKeys = readonly [string, string]; type ResolveSecretPairOptions = { allowUserScope?: boolean; preferWorkspaceScope?: boolean; }; export declare function resolveSecretPairs(keyPairs: ReadonlyArray, options?: ResolveSecretPairOptions): Promise<[string, string] | null>; export declare function resolveSecretPair(keys: SecretPairKeys, options?: ResolveSecretPairOptions): Promise<[string, string] | null>; export type ResolvedSecretSource = "user" | "org" | "workspace" | "env"; export interface ResolvedSecretDetail { value: string | null; lookupFailed: boolean; cause?: unknown; source?: ResolvedSecretSource; scopeId?: string; } export declare function resolveSecretDetailed(key: string, options?: { skipUserScope?: boolean; }): Promise; export declare function hasBuilderPrivateKey(): boolean; export declare function getBuilderProxyOrigin(): string; export declare function getBuilderGatewayBaseUrl(): string; export declare function getBuilderImageGenerationBaseUrl(): string; export declare function getBuilderEmbeddingsBaseUrl(): string; export declare function getBuilderVideoGenerationBaseUrl(): string; export declare function getBuilderWebSearchBaseUrl(): string; export declare function getBuilderAuthHeader(): string | null;