@palbase/backend 39.1.0 → 39.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import '../index-pK2At5Yc.cjs';
2
- export { A as App, g as AuthVerifier, B as BootRefused, h as COMMAND_EXECUTOR_DDL, j as CreateAppOptions, D as DECLARATION_REFUSAL, a as DeclarationRefused, E as EgressPolicy, k as EngineConfig, M as ModuleClients, R as RateLimiter, l as RequestDatabase, m as RouteEntry, n as RuntimeHooks, S as ScrubResult, o as SqlDriver, p as SqlTx, q as buildRouteTable, r as createApp, s as createLazyTransaction, t as createOps, u as createRequestDatabase, v as effectiveAuth, w as hostAllowed, x as installCommandExecutor, y as installEgressFence, i as isDeclarationRefused, z as loadConfig, F as makeMemoryCache, G as matchRoute, H as quoteIdent, I as scrubSecrets, J as setCursorKey, K as withQueryCancellation, L as withTables } from '../index-B0mjUnxy.cjs';
2
+ export { A as App, g as AuthVerifier, B as BootRefused, h as COMMAND_EXECUTOR_DDL, j as CreateAppOptions, D as DECLARATION_REFUSAL, a as DeclarationRefused, E as EgressPolicy, k as EngineConfig, M as ModuleClients, R as RateLimiter, l as RequestDatabase, m as RouteEntry, n as RuntimeHooks, S as ScrubResult, o as SqlDriver, p as SqlTx, q as buildRouteTable, r as createApp, s as createLazyTransaction, t as createOps, u as createRequestDatabase, v as effectiveAuth, w as hostAllowed, x as installCommandExecutor, y as installEgressFence, i as isDeclarationRefused, z as loadConfig, F as makeMemoryCache, G as matchRoute, H as quoteIdent, I as scrubSecrets, J as setCursorKey, K as withQueryCancellation, L as withTables } from '../index-Brhp8cxj.cjs';
3
3
  import 'zod';
4
4
  import '../db/env.cjs';
5
5
  import '../stack.cjs';
@@ -1,5 +1,5 @@
1
1
  import '../index-eN4KzGa5.js';
2
- export { A as App, g as AuthVerifier, B as BootRefused, h as COMMAND_EXECUTOR_DDL, j as CreateAppOptions, D as DECLARATION_REFUSAL, a as DeclarationRefused, E as EgressPolicy, k as EngineConfig, M as ModuleClients, R as RateLimiter, l as RequestDatabase, m as RouteEntry, n as RuntimeHooks, S as ScrubResult, o as SqlDriver, p as SqlTx, q as buildRouteTable, r as createApp, s as createLazyTransaction, t as createOps, u as createRequestDatabase, v as effectiveAuth, w as hostAllowed, x as installCommandExecutor, y as installEgressFence, i as isDeclarationRefused, z as loadConfig, F as makeMemoryCache, G as matchRoute, H as quoteIdent, I as scrubSecrets, J as setCursorKey, K as withQueryCancellation, L as withTables } from '../index-yDno9Ju9.js';
2
+ export { A as App, g as AuthVerifier, B as BootRefused, h as COMMAND_EXECUTOR_DDL, j as CreateAppOptions, D as DECLARATION_REFUSAL, a as DeclarationRefused, E as EgressPolicy, k as EngineConfig, M as ModuleClients, R as RateLimiter, l as RequestDatabase, m as RouteEntry, n as RuntimeHooks, S as ScrubResult, o as SqlDriver, p as SqlTx, q as buildRouteTable, r as createApp, s as createLazyTransaction, t as createOps, u as createRequestDatabase, v as effectiveAuth, w as hostAllowed, x as installCommandExecutor, y as installEgressFence, i as isDeclarationRefused, z as loadConfig, F as makeMemoryCache, G as matchRoute, H as quoteIdent, I as scrubSecrets, J as setCursorKey, K as withQueryCancellation, L as withTables } from '../index-Dlu2b9-f.js';
3
3
  import 'zod';
4
4
  import '../db/env.js';
5
5
  import '../stack.js';
@@ -20,7 +20,7 @@ import {
20
20
  setCursorKey,
21
21
  withQueryCancellation,
22
22
  withTables
23
- } from "../chunk-JJSR4BUX.js";
23
+ } from "../chunk-C525N4OW.js";
24
24
  import {
25
25
  DECLARATION_REFUSAL,
26
26
  DeclarationRefused,
@@ -895,18 +895,6 @@ interface RouteMatch {
895
895
  /** First match wins; the table is small and declaration order is the tiebreak. */
896
896
  declare function matchRoute(table: readonly RouteEntry[], method: string, pathname: string): RouteMatch | null;
897
897
 
898
- /**
899
- * engine/auth.ts — verifying the stack's own access tokens.
900
- *
901
- * The engine does this itself rather than trusting a header stamped upstream.
902
- * In the isolate architecture a gateway verified the token and the runtime read
903
- * the result; a backend that boots on its own has no such upstream, so the
904
- * verification lives here — against the keys the stack publishes.
905
- *
906
- * Deliberately narrow: ES256 over P-256, which is what palauth mints. An
907
- * unrecognised `alg` is refused rather than accommodated, because the classic
908
- * JWT break is a verifier that is helpful about algorithms.
909
- */
910
898
  /** The claims the engine reads. Everything else rides along untyped. */
911
899
  interface VerifiedClaims extends Record<string, unknown> {
912
900
  sub?: string;
@@ -930,20 +918,26 @@ declare class AuthVerifier {
930
918
  private keys;
931
919
  private fetchedAt;
932
920
  private inflight;
921
+ private nextRefreshAt;
922
+ private refreshFailed;
933
923
  private readonly jwksUrl;
934
924
  private readonly issuer?;
935
925
  private readonly fetchImpl;
936
926
  private readonly ttl;
937
927
  constructor(opts: AuthVerifierOptions);
938
- /** Fetch the keyset at most once per TTL, and at most once concurrently. */
928
+ /** Fetch once concurrently. Known keys use their trust TTL; misses and
929
+ * failures share a short cooldown so arbitrary kids cannot force a fetch
930
+ * per request, and recovery does not wait for an entire trust TTL. */
939
931
  private refresh;
932
+ private fetchKeyset;
940
933
  private key;
941
934
  /**
942
935
  * Verify an `Authorization` header value.
943
936
  *
944
937
  * @returns the verified claims, or `null` for absent / malformed / expired /
945
- * wrong-issuer / bad-signature. One `null` for every failure on purpose:
946
- * the caller answers 401 either way, and a detailed reason is an oracle.
938
+ * wrong-issuer / bad-signature. Credential refusals deliberately share one
939
+ * result. An unavailable keyset throws 503 instead: no authentication
940
+ * decision was possible, and the caller's session must not be invalidated.
947
941
  */
948
942
  verify(authorization: string | null | undefined): Promise<VerifiedClaims | null>;
949
943
  }
@@ -895,18 +895,6 @@ interface RouteMatch {
895
895
  /** First match wins; the table is small and declaration order is the tiebreak. */
896
896
  declare function matchRoute(table: readonly RouteEntry[], method: string, pathname: string): RouteMatch | null;
897
897
 
898
- /**
899
- * engine/auth.ts — verifying the stack's own access tokens.
900
- *
901
- * The engine does this itself rather than trusting a header stamped upstream.
902
- * In the isolate architecture a gateway verified the token and the runtime read
903
- * the result; a backend that boots on its own has no such upstream, so the
904
- * verification lives here — against the keys the stack publishes.
905
- *
906
- * Deliberately narrow: ES256 over P-256, which is what palauth mints. An
907
- * unrecognised `alg` is refused rather than accommodated, because the classic
908
- * JWT break is a verifier that is helpful about algorithms.
909
- */
910
898
  /** The claims the engine reads. Everything else rides along untyped. */
911
899
  interface VerifiedClaims extends Record<string, unknown> {
912
900
  sub?: string;
@@ -930,20 +918,26 @@ declare class AuthVerifier {
930
918
  private keys;
931
919
  private fetchedAt;
932
920
  private inflight;
921
+ private nextRefreshAt;
922
+ private refreshFailed;
933
923
  private readonly jwksUrl;
934
924
  private readonly issuer?;
935
925
  private readonly fetchImpl;
936
926
  private readonly ttl;
937
927
  constructor(opts: AuthVerifierOptions);
938
- /** Fetch the keyset at most once per TTL, and at most once concurrently. */
928
+ /** Fetch once concurrently. Known keys use their trust TTL; misses and
929
+ * failures share a short cooldown so arbitrary kids cannot force a fetch
930
+ * per request, and recovery does not wait for an entire trust TTL. */
939
931
  private refresh;
932
+ private fetchKeyset;
940
933
  private key;
941
934
  /**
942
935
  * Verify an `Authorization` header value.
943
936
  *
944
937
  * @returns the verified claims, or `null` for absent / malformed / expired /
945
- * wrong-issuer / bad-signature. One `null` for every failure on purpose:
946
- * the caller answers 401 either way, and a detailed reason is an oracle.
938
+ * wrong-issuer / bad-signature. Credential refusals deliberately share one
939
+ * result. An unavailable keyset throws 503 instead: no authentication
940
+ * decision was possible, and the caller's session must not be invalidated.
947
941
  */
948
942
  verify(authorization: string | null | undefined): Promise<VerifiedClaims | null>;
949
943
  }
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { k as PalbaseResult, l as PolicyExpr, S as SchemaDef, A as AuthSpec, H as HttpError } from './index-pK2At5Yc.cjs';
2
2
  export { m as AggregateInput, n as AggregateResult, o as AnyColumn, p as AtomicDatabase, q as AtomicOptions, r as Auth, s as AuthConfig, B as BackfillDef, t as BadRequest, u as Cache, i as CacheClient, v as CheckDef, w as ClientInfo, x as ColRef, y as ColumnBuilder, z as ColumnDef, F as ColumnMap, G as ColumnType, C as CommandOptions, I as Conflict, a as DBClient, e as DBOps, J as Database, D as DatabaseBudget, d as DatabaseDiagnostics, c as DatabaseDiagnosticsOptions, K as DatabaseQueryEvent, L as DeadlockDetected, M as Documents, N as EXTENSION_DEPENDENCIES, O as EmbeddingModelRef, Q as EnvSchemas, E as EnvServiceDatabase, U as EnvTables, V as EnvTypedDatabase, W as EnvTypedTable, X as ErrorDef, Y as ErrorMap, Z as ErrorThrowers, $ as FileContext, a0 as FindManyOpts, a1 as FkAction, a2 as FkMatch, a3 as Flags, a4 as Forbidden, a5 as ForeignKeyBuilder, a6 as ForeignKeyDef, a7 as FreezeBuilder, a8 as FreezeDef, a9 as GuardBuilder, aa as GuardDef, ab as GuardEvent, ac as HttpMethod, ad as IndexBuilder, ae as IndexDef, af as InsertManyOptions, ag as InsertShape, ah as InsertValues, ai as LifecycleHook, aj as Log, ak as Logger, al as Materialized, am as Middleware, an as MiddlewareContext, ao as MiddlewareHandler, ap as MutateInput, aq as NotFound, ar as Notifications, as as OnDeleteAction, at as OrderBySpec, au as PALBASE_EXTENSIONS, av as PBRequest, P as Page, aw as PageInfo, ax as PageInput, ay as PageNavigation, az as PalError, aA as PalbaseAnalyticsClient, aB as PalbaseAnalyticsManagementNamespace, aC as PalbaseAnalyticsProperties, aD as PalbaseAnalyticsQueryNamespace, aE as PalbaseAttestAndroidParams, aF as PalbaseAttestAndroidResult, aG as PalbaseAttestiOSParams, aH as PalbaseAttestiOSResult, aI as PalbaseAuthAdminClient, aJ as PalbaseAuthClient, aK as PalbaseBatchOverrideOperation, aL as PalbaseBatchSetOverridesResult, aM as PalbaseBindDeviceParams, aN as PalbaseBucketClient, aO as PalbaseClearAllOverridesResult, aP as PalbaseClearOverrideResult, aQ as PalbaseCohortQueryInput, aR as PalbaseCohortResult, aS as PalbaseCollectionRef, aT as PalbaseCountQueryInput, aU as PalbaseCountResult, aV as PalbaseCreateLinkParams, aW as PalbaseDeviceInfo, aX as PalbaseDeviceTokenView, aY as PalbaseDocsClient, aZ as PalbaseDocumentRef, a_ as PalbaseDocumentSnapshot, a$ as PalbaseEmailClient, b0 as PalbaseEmailSendParams, b1 as PalbaseEmailSendResponse, b2 as PalbaseEventNamesResult, b3 as PalbaseEventsQueryInput, b4 as PalbaseEventsResult, b5 as PalbaseExtension, b6 as PalbaseFileObject, b7 as PalbaseFlag, b8 as PalbaseFlagContext, b9 as PalbaseFlagSource, ba as PalbaseFlagValue, bb as PalbaseFlagVariant, bc as PalbaseFlagsClient, bd as PalbaseFlagsServiceClient, be as PalbaseFunctionsClient, bf as PalbaseFunnelQueryInput, bg as PalbaseFunnelResult, bh as PalbaseIdentifyTraits, bi as PalbaseInboxClient, bj as PalbaseInboxListOptions, bk as PalbaseInboxListResult, bl as PalbaseInboxMessage, bm as PalbaseInboxSendParams, bn as PalbaseInboxSendResponse, bo as PalbaseInitialLink, bp as PalbaseInvokeOptions, bq as PalbaseLink, br as PalbaseLinkAnalytics, bs as PalbaseLinkDetails, bt as PalbaseLinksClient, bu as PalbaseListLinksOptions, bv as PalbaseListLinksResult, bw as PalbaseListOptions, bx as PalbaseMatchParams, by as PalbaseMultiChannelResponse, bz as PalbaseNotificationChannel, bA as PalbaseNotificationsClient, bB as PalbaseOverviewResult, bC as PalbasePreferences, bD as PalbasePreferencesClient, bE as PalbasePushClient, bF as PalbasePushSendParams, bG as PalbasePushSendResponse, bH as PalbaseQrCodeOptions, bI as PalbaseQuerySnapshot, bJ as PalbaseRealtimeClient, bK as PalbaseRegisterDeviceParams, bL as PalbaseRetentionQueryInput, bM as PalbaseRetentionResult, bN as PalbaseSession, bO as PalbaseSetOverrideResult, bP as PalbaseSetOverridesResult, bQ as PalbaseSignedUrlResponse, bR as PalbaseSmsClient, bS as PalbaseSmsSendParams, bT as PalbaseSmsSendResponse, bU as PalbaseStorageClient, bV as PalbaseTransformOptions, bW as PalbaseUpdateLinkParams, bX as PalbaseUploadOptions, bY as PalbaseUser, bZ as PalbaseUserDetailResult, b_ as PalbaseUsersQueryInput, b$ as PalbaseUsersResult, c0 as PalbaseVerifyRequestSignatureParams, c1 as PalbaseWhatsAppClient, c2 as PalbaseWhatsAppEvent, c3 as PalbaseWhatsAppSendParams, c4 as PalbaseWhatsAppSendResponse, c5 as PalbaseWhatsAppTemplate, c6 as PalbaseWhereOperator, c7 as PolicyBinOp, c8 as PolicyBuilder, c9 as PolicyCommand, ca as PolicyDef, cb as PolicyExprCtx, cc as PolicyExprRef, cd as PolicyMode, ce as PolicyOperand, cf as QueryInput, R as RateLimitConfig, cg as RawConstraintDef, f as RawPageOptions, ch as Realtime, ci as Ref, cj as RequestStore, ck as RowShape, b as RuntimeServices, cl as Secrets, cm as SecretsService, cn as SerializationFailure, co as SetShape, cp as SetValue, cq as ShutdownRunner, cr as SqlFragment, cs as Storage, ct as TABLE_META, cu as TableDef, cv as TableHandle, cw as TableInput, cx as TableRef, cy as TooManyRequests, T as TransactionIsolation, cz as TxColumnExpr, cA as TxInsertShape, cB as TxInsertValue, cC as TxNow, cD as TxPlan, g as TxPlanBody, cE as TxPlanError, cF as TxPlanHandle, cG as TxPlanOpResult, cH as TxPlanRejection, h as TxPlanResponse, cI as TxRefError, cJ as TxRow, cK as TxRows, cL as TxSelectOptions, cM as TxSetShape, cN as TxSetValue, cO as TxTable, cP as TxTables, cQ as TxWhere, cR as TxWireExpr, cS as TxWireGuard, cT as TxWireOp, cU as TxWireRef, cV as TxWireValue, cW as TypedDB, cX as TypedTable, cY as TypedTx, cZ as Unauthorized, c_ as UniqueViolation, c$ as UniqueWhere, d0 as UserT, d1 as VerifiedDevice, d2 as WhereFilter, d3 as WhereOp, d4 as __getRuntime, j as __requestALS, d5 as __resetLifecycleHooks, d6 as __runStartHooks, _ as __runWithRuntime, d7 as __setRuntime, d8 as backfill, d9 as bigint, da as boolean, db as can, dc as check, dd as col, de as dec, df as decrement, dg as defineMiddleware, dh as defineSchema, di as defineTable, dj as enumType, dk as exprCtx, dl as foreignKey, dm as freeze, dn as guard, dp as inc, dq as increment, dr as index, ds as installationRef, dt as integer, du as isPalbaseExtension, dv as isRetryable, dw as jsonb, dx as makeTypedDB, dy as now, dz as numeric, dA as onShutdown, dB as onStart, dC as openai, dD as ownedByUser, dE as policy, dF as raw, dG as sqlFragment, dH as text, dI as timestamp, dJ as userRef, dK as uuid, dL as vector, dM as withRetry } from './index-pK2At5Yc.cjs';
3
- import { M as ModuleClients, C as Container } from './index-B0mjUnxy.cjs';
4
- export { D as DECLARATION_REFUSAL, a as DeclarationRefused, b as DiError, c as DiKind, d as ModulePressure, e as assertNoOrphanEntryPoints, f as buildContainer, i as isDeclarationRefused } from './index-B0mjUnxy.cjs';
3
+ import { M as ModuleClients, C as Container } from './index-Brhp8cxj.cjs';
4
+ export { D as DECLARATION_REFUSAL, a as DeclarationRefused, b as DiError, c as DiKind, d as ModulePressure, e as assertNoOrphanEntryPoints, f as buildContainer, i as isDeclarationRefused } from './index-Brhp8cxj.cjs';
5
5
  export { TableTypes, Tables } from './db/env.cjs';
6
6
  export { PalbaseBucketName, PalbaseFlagKey, PalbaseSecretName } from './stack.cjs';
7
7
  import { a as RouteOptions } from './registry-9dNeVN5d.cjs';
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { k as PalbaseResult, l as PolicyExpr, S as SchemaDef, A as AuthSpec, H as HttpError } from './index-eN4KzGa5.js';
2
2
  export { m as AggregateInput, n as AggregateResult, o as AnyColumn, p as AtomicDatabase, q as AtomicOptions, r as Auth, s as AuthConfig, B as BackfillDef, t as BadRequest, u as Cache, i as CacheClient, v as CheckDef, w as ClientInfo, x as ColRef, y as ColumnBuilder, z as ColumnDef, F as ColumnMap, G as ColumnType, C as CommandOptions, I as Conflict, a as DBClient, e as DBOps, J as Database, D as DatabaseBudget, d as DatabaseDiagnostics, c as DatabaseDiagnosticsOptions, K as DatabaseQueryEvent, L as DeadlockDetected, M as Documents, N as EXTENSION_DEPENDENCIES, O as EmbeddingModelRef, Q as EnvSchemas, E as EnvServiceDatabase, U as EnvTables, V as EnvTypedDatabase, W as EnvTypedTable, X as ErrorDef, Y as ErrorMap, Z as ErrorThrowers, $ as FileContext, a0 as FindManyOpts, a1 as FkAction, a2 as FkMatch, a3 as Flags, a4 as Forbidden, a5 as ForeignKeyBuilder, a6 as ForeignKeyDef, a7 as FreezeBuilder, a8 as FreezeDef, a9 as GuardBuilder, aa as GuardDef, ab as GuardEvent, ac as HttpMethod, ad as IndexBuilder, ae as IndexDef, af as InsertManyOptions, ag as InsertShape, ah as InsertValues, ai as LifecycleHook, aj as Log, ak as Logger, al as Materialized, am as Middleware, an as MiddlewareContext, ao as MiddlewareHandler, ap as MutateInput, aq as NotFound, ar as Notifications, as as OnDeleteAction, at as OrderBySpec, au as PALBASE_EXTENSIONS, av as PBRequest, P as Page, aw as PageInfo, ax as PageInput, ay as PageNavigation, az as PalError, aA as PalbaseAnalyticsClient, aB as PalbaseAnalyticsManagementNamespace, aC as PalbaseAnalyticsProperties, aD as PalbaseAnalyticsQueryNamespace, aE as PalbaseAttestAndroidParams, aF as PalbaseAttestAndroidResult, aG as PalbaseAttestiOSParams, aH as PalbaseAttestiOSResult, aI as PalbaseAuthAdminClient, aJ as PalbaseAuthClient, aK as PalbaseBatchOverrideOperation, aL as PalbaseBatchSetOverridesResult, aM as PalbaseBindDeviceParams, aN as PalbaseBucketClient, aO as PalbaseClearAllOverridesResult, aP as PalbaseClearOverrideResult, aQ as PalbaseCohortQueryInput, aR as PalbaseCohortResult, aS as PalbaseCollectionRef, aT as PalbaseCountQueryInput, aU as PalbaseCountResult, aV as PalbaseCreateLinkParams, aW as PalbaseDeviceInfo, aX as PalbaseDeviceTokenView, aY as PalbaseDocsClient, aZ as PalbaseDocumentRef, a_ as PalbaseDocumentSnapshot, a$ as PalbaseEmailClient, b0 as PalbaseEmailSendParams, b1 as PalbaseEmailSendResponse, b2 as PalbaseEventNamesResult, b3 as PalbaseEventsQueryInput, b4 as PalbaseEventsResult, b5 as PalbaseExtension, b6 as PalbaseFileObject, b7 as PalbaseFlag, b8 as PalbaseFlagContext, b9 as PalbaseFlagSource, ba as PalbaseFlagValue, bb as PalbaseFlagVariant, bc as PalbaseFlagsClient, bd as PalbaseFlagsServiceClient, be as PalbaseFunctionsClient, bf as PalbaseFunnelQueryInput, bg as PalbaseFunnelResult, bh as PalbaseIdentifyTraits, bi as PalbaseInboxClient, bj as PalbaseInboxListOptions, bk as PalbaseInboxListResult, bl as PalbaseInboxMessage, bm as PalbaseInboxSendParams, bn as PalbaseInboxSendResponse, bo as PalbaseInitialLink, bp as PalbaseInvokeOptions, bq as PalbaseLink, br as PalbaseLinkAnalytics, bs as PalbaseLinkDetails, bt as PalbaseLinksClient, bu as PalbaseListLinksOptions, bv as PalbaseListLinksResult, bw as PalbaseListOptions, bx as PalbaseMatchParams, by as PalbaseMultiChannelResponse, bz as PalbaseNotificationChannel, bA as PalbaseNotificationsClient, bB as PalbaseOverviewResult, bC as PalbasePreferences, bD as PalbasePreferencesClient, bE as PalbasePushClient, bF as PalbasePushSendParams, bG as PalbasePushSendResponse, bH as PalbaseQrCodeOptions, bI as PalbaseQuerySnapshot, bJ as PalbaseRealtimeClient, bK as PalbaseRegisterDeviceParams, bL as PalbaseRetentionQueryInput, bM as PalbaseRetentionResult, bN as PalbaseSession, bO as PalbaseSetOverrideResult, bP as PalbaseSetOverridesResult, bQ as PalbaseSignedUrlResponse, bR as PalbaseSmsClient, bS as PalbaseSmsSendParams, bT as PalbaseSmsSendResponse, bU as PalbaseStorageClient, bV as PalbaseTransformOptions, bW as PalbaseUpdateLinkParams, bX as PalbaseUploadOptions, bY as PalbaseUser, bZ as PalbaseUserDetailResult, b_ as PalbaseUsersQueryInput, b$ as PalbaseUsersResult, c0 as PalbaseVerifyRequestSignatureParams, c1 as PalbaseWhatsAppClient, c2 as PalbaseWhatsAppEvent, c3 as PalbaseWhatsAppSendParams, c4 as PalbaseWhatsAppSendResponse, c5 as PalbaseWhatsAppTemplate, c6 as PalbaseWhereOperator, c7 as PolicyBinOp, c8 as PolicyBuilder, c9 as PolicyCommand, ca as PolicyDef, cb as PolicyExprCtx, cc as PolicyExprRef, cd as PolicyMode, ce as PolicyOperand, cf as QueryInput, R as RateLimitConfig, cg as RawConstraintDef, f as RawPageOptions, ch as Realtime, ci as Ref, cj as RequestStore, ck as RowShape, b as RuntimeServices, cl as Secrets, cm as SecretsService, cn as SerializationFailure, co as SetShape, cp as SetValue, cq as ShutdownRunner, cr as SqlFragment, cs as Storage, ct as TABLE_META, cu as TableDef, cv as TableHandle, cw as TableInput, cx as TableRef, cy as TooManyRequests, T as TransactionIsolation, cz as TxColumnExpr, cA as TxInsertShape, cB as TxInsertValue, cC as TxNow, cD as TxPlan, g as TxPlanBody, cE as TxPlanError, cF as TxPlanHandle, cG as TxPlanOpResult, cH as TxPlanRejection, h as TxPlanResponse, cI as TxRefError, cJ as TxRow, cK as TxRows, cL as TxSelectOptions, cM as TxSetShape, cN as TxSetValue, cO as TxTable, cP as TxTables, cQ as TxWhere, cR as TxWireExpr, cS as TxWireGuard, cT as TxWireOp, cU as TxWireRef, cV as TxWireValue, cW as TypedDB, cX as TypedTable, cY as TypedTx, cZ as Unauthorized, c_ as UniqueViolation, c$ as UniqueWhere, d0 as UserT, d1 as VerifiedDevice, d2 as WhereFilter, d3 as WhereOp, d4 as __getRuntime, j as __requestALS, d5 as __resetLifecycleHooks, d6 as __runStartHooks, _ as __runWithRuntime, d7 as __setRuntime, d8 as backfill, d9 as bigint, da as boolean, db as can, dc as check, dd as col, de as dec, df as decrement, dg as defineMiddleware, dh as defineSchema, di as defineTable, dj as enumType, dk as exprCtx, dl as foreignKey, dm as freeze, dn as guard, dp as inc, dq as increment, dr as index, ds as installationRef, dt as integer, du as isPalbaseExtension, dv as isRetryable, dw as jsonb, dx as makeTypedDB, dy as now, dz as numeric, dA as onShutdown, dB as onStart, dC as openai, dD as ownedByUser, dE as policy, dF as raw, dG as sqlFragment, dH as text, dI as timestamp, dJ as userRef, dK as uuid, dL as vector, dM as withRetry } from './index-eN4KzGa5.js';
3
- import { M as ModuleClients, C as Container } from './index-yDno9Ju9.js';
4
- export { D as DECLARATION_REFUSAL, a as DeclarationRefused, b as DiError, c as DiKind, d as ModulePressure, e as assertNoOrphanEntryPoints, f as buildContainer, i as isDeclarationRefused } from './index-yDno9Ju9.js';
3
+ import { M as ModuleClients, C as Container } from './index-Dlu2b9-f.js';
4
+ export { D as DECLARATION_REFUSAL, a as DeclarationRefused, b as DiError, c as DiKind, d as ModulePressure, e as assertNoOrphanEntryPoints, f as buildContainer, i as isDeclarationRefused } from './index-Dlu2b9-f.js';
5
5
  export { TableTypes, Tables } from './db/env.js';
6
6
  export { PalbaseBucketName, PalbaseFlagKey, PalbaseSecretName } from './stack.js';
7
7
  import { a as RouteOptions } from './registry-B8ddZiMY.js';
package/docs/auth.md CHANGED
@@ -5,6 +5,26 @@ unless it opts out with `auth: false`. Client SDKs attach the user's token
5
5
  automatically, so on the backend you declare what a route needs and inject the
6
6
  user.
7
7
 
8
+ ## Temporary verification failures
9
+
10
+ An absent or invalid access token produces `401 unauthorized` on a protected
11
+ route. If the runtime cannot retrieve a usable signing keyset, it instead
12
+ returns `503 auth_unavailable`. A network failure, an unsuccessful JWKS response,
13
+ or a keyset with no usable signing keys is an availability failure, not evidence
14
+ that the caller's token is invalid. Keep the session and retry after the service
15
+ recovers; signing in again is not required while the token remains valid.
16
+
17
+ The same rule applies to upload authorization. Requests that cannot be verified
18
+ do not reach the handler or the database, and uploads receive no grant. Public
19
+ requests without credentials continue to work.
20
+
21
+ Known signing keys remain usable within their trust TTL (five minutes by
22
+ default). Expired keysets are not trusted during an outage. Concurrent refreshes
23
+ share one request, and failed refreshes and unknown key IDs share a one-second
24
+ retry interval so recovery and key rotation do not wait for the entire TTL.
25
+
26
+ ## Declaring authentication
27
+
8
28
  ```ts
9
29
  import { Controller, Get, Post, Body, User, OptionalUser } from "@palbase/backend";
10
30
  import type { UserT } from "@palbase/backend";
@@ -795,6 +795,26 @@ unless it opts out with `auth: false`. Client SDKs attach the user's token
795
795
  automatically, so on the backend you declare what a route needs and inject the
796
796
  user.
797
797
 
798
+ ## Temporary verification failures
799
+
800
+ An absent or invalid access token produces `401 unauthorized` on a protected
801
+ route. If the runtime cannot retrieve a usable signing keyset, it instead
802
+ returns `503 auth_unavailable`. A network failure, an unsuccessful JWKS response,
803
+ or a keyset with no usable signing keys is an availability failure, not evidence
804
+ that the caller's token is invalid. Keep the session and retry after the service
805
+ recovers; signing in again is not required while the token remains valid.
806
+
807
+ The same rule applies to upload authorization. Requests that cannot be verified
808
+ do not reach the handler or the database, and uploads receive no grant. Public
809
+ requests without credentials continue to work.
810
+
811
+ Known signing keys remain usable within their trust TTL (five minutes by
812
+ default). Expired keysets are not trusted during an outage. Concurrent refreshes
813
+ share one request, and failed refreshes and unknown key IDs share a one-second
814
+ retry interval so recovery and key rotation do not wait for the entire TTL.
815
+
816
+ ## Declaring authentication
817
+
798
818
  ```ts
799
819
  import { Controller, Get, Post, Body, User, OptionalUser } from "@palbase/backend";
800
820
  import type { UserT } from "@palbase/backend";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@palbase/backend",
3
- "version": "39.1.0",
3
+ "version": "39.1.1",
4
4
  "description": "Palbase Backend SDK — class controllers (@Controller/@Get/@Post + @Body/@QueryParams/@Param), error classes, schema DSL",
5
5
  "license": "MIT",
6
6
  "repository": {