@apifuse/provider-sdk 2.2.0-beta.59 → 2.2.0-beta.60

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.
Files changed (72) hide show
  1. package/AUTHORING.md +16 -0
  2. package/CHANGELOG.md +4 -0
  3. package/bin/apifuse-dev.ts +2 -1
  4. package/bin/apifuse-perf.ts +41 -4
  5. package/bin/apifuse-record.ts +3 -2
  6. package/dist/config/loader.js +13 -12
  7. package/dist/engine.js +3 -2
  8. package/dist/index.d.ts +2 -1
  9. package/dist/index.js +1 -1
  10. package/dist/lint.js +36 -15
  11. package/dist/provider.d.ts +1 -1
  12. package/dist/provider.js +1 -1
  13. package/dist/runtime/browser.js +2 -1
  14. package/dist/runtime/cache.js +3 -2
  15. package/dist/runtime/diagnostic-env-values.d.ts +5 -0
  16. package/dist/runtime/diagnostic-env-values.js +57 -0
  17. package/dist/runtime/diagnostic-env.d.ts +11 -0
  18. package/dist/runtime/diagnostic-env.js +35 -0
  19. package/dist/runtime/diagnostic-redactor.d.ts +49 -0
  20. package/dist/runtime/diagnostic-redactor.js +569 -0
  21. package/dist/runtime/egress-lease.d.ts +2 -0
  22. package/dist/runtime/egress-lease.js +4 -1
  23. package/dist/runtime/env.js +2 -1
  24. package/dist/runtime/instrumentation.js +3 -0
  25. package/dist/runtime/ocr.js +2 -1
  26. package/dist/runtime/otlp.js +5 -4
  27. package/dist/runtime/proxy-nodemaven.js +3 -2
  28. package/dist/runtime/request-options.d.ts +7 -0
  29. package/dist/runtime/request-options.js +62 -22
  30. package/dist/runtime/resolver-vendors/browser.js +0 -1
  31. package/dist/runtime/resolver.js +3 -2
  32. package/dist/runtime/stt.js +3 -2
  33. package/dist/runtime/trace.d.ts +5 -0
  34. package/dist/runtime/trace.js +115 -20
  35. package/dist/schema.d.ts +11 -0
  36. package/dist/schema.js +56 -2
  37. package/dist/server/self-test-redaction.js +8 -33
  38. package/dist/server/sensitive-values.d.ts +26 -0
  39. package/dist/server/sensitive-values.js +131 -0
  40. package/dist/server/serve-implementation.js +219 -78
  41. package/dist/server/trace-output.d.ts +2 -1
  42. package/dist/server/trace-output.js +46 -14
  43. package/dist/trace-sanitization.d.ts +4 -3
  44. package/dist/trace-sanitization.js +45 -22
  45. package/package.json +2 -1
  46. package/src/config/loader.ts +13 -12
  47. package/src/engine.ts +3 -2
  48. package/src/index.ts +2 -0
  49. package/src/lint.ts +42 -16
  50. package/src/provider.ts +1 -0
  51. package/src/runtime/browser.ts +2 -1
  52. package/src/runtime/cache.ts +3 -2
  53. package/src/runtime/diagnostic-env-values.ts +56 -0
  54. package/src/runtime/diagnostic-env.ts +55 -0
  55. package/src/runtime/diagnostic-redactor.ts +662 -0
  56. package/src/runtime/egress-lease.ts +6 -1
  57. package/src/runtime/env.ts +2 -1
  58. package/src/runtime/instrumentation.ts +3 -0
  59. package/src/runtime/ocr.ts +2 -1
  60. package/src/runtime/otlp.ts +5 -4
  61. package/src/runtime/proxy-nodemaven.ts +3 -2
  62. package/src/runtime/request-options.ts +76 -28
  63. package/src/runtime/resolver-vendors/browser.ts +0 -1
  64. package/src/runtime/resolver.ts +3 -2
  65. package/src/runtime/stt.ts +3 -2
  66. package/src/runtime/trace.ts +168 -26
  67. package/src/schema.ts +63 -2
  68. package/src/server/self-test-redaction.ts +10 -40
  69. package/src/server/sensitive-values.ts +200 -0
  70. package/src/server/serve-implementation.ts +301 -96
  71. package/src/server/trace-output.ts +77 -17
  72. package/src/trace-sanitization.ts +70 -23
@@ -1,5 +1,7 @@
1
- import { createHash } from "node:crypto";
1
+ import { STATUS_CODES } from "node:http";
2
+ import { readDiagnosticEnv, withDiagnosticEnv } from "../runtime/diagnostic-env.js";
2
3
  import { AsyncLocalStorage } from "node:async_hooks";
4
+ import { createHash } from "node:crypto";
3
5
  import { existsSync } from "node:fs";
4
6
  import { createRequire } from "node:module";
5
7
  import { join } from "node:path";
@@ -8,15 +10,15 @@ import { Hono } from "hono";
8
10
  import { z } from "zod";
9
11
  import { AuthAbortError, createAuthFlowHelpers } from "../auth.js";
10
12
  import { validateFailClosedDeclaration } from "../declaration-validation.js";
11
- import { safeProviderErrorObservability } from "../error-observability.js";
12
13
  import {
13
14
  createInProcessProviderEngine,
14
15
  ENGINE_OWNED_PROXY_CREDENTIAL_ENV_NAMES,
15
16
  isEngineOwnedEnvName,
16
- readEngineProxyCredentials,
17
17
  type ProviderEngine,
18
18
  type ProviderEngineBindingCandidates,
19
+ readEngineProxyCredentials,
19
20
  } from "../engine.js";
21
+ import { safeProviderErrorObservability } from "../error-observability.js";
20
22
  import {
21
23
  SDK_OWNED_PROVIDER_ERROR_CODES,
22
24
  SDK_RUNTIME_OWNED_ERROR_CODES,
@@ -42,11 +44,11 @@ import {
42
44
  import type { ProviderLocale } from "../i18n/keys.js";
43
45
  import {
44
46
  categoryForStatus,
45
- type ProviderErrorSource,
46
- sourceForCategory,
47
47
  isRetryableCategory,
48
48
  PROVIDER_OBSERVABILITY_TAXONOMY_VERSION,
49
49
  type ProviderErrorCategory,
50
+ type ProviderErrorSource,
51
+ sourceForCategory,
50
52
  } from "../observability.js";
51
53
  import { createScratchpad } from "../runtime/auth-flow.js";
52
54
  import type * as BrowserRuntimeModule from "../runtime/browser.js";
@@ -56,6 +58,19 @@ import {
56
58
  PROVIDER_RUNTIME_CHOICE_TOKEN_MASTER_SECRET_ENV,
57
59
  } from "../runtime/choice.js";
58
60
  import { createCredentialContext } from "../runtime/credential.js";
61
+ import {
62
+ bindDiagnosticSensitiveRegistry,
63
+ type CompiledDiagnosticSensitiveValues,
64
+ compileProcessDiagnosticSensitiveValues,
65
+ createDiagnosticRedactor,
66
+ type DiagnosticRedactor,
67
+ REDACTION_FAILED,
68
+ isDiagnosticRedactionSuppressed,
69
+ bindCriticalDiagnosticRedactor,
70
+ redactCriticalDiagnosticText,
71
+ redactDiagnosticText,
72
+ registerDiagnosticSensitiveValues,
73
+ } from "../runtime/diagnostic-redactor.js";
59
74
  import {
60
75
  createCeremonyEgressLeaseRuntime,
61
76
  ENGINE_CEREMONY_EGRESS_LEASE,
@@ -65,8 +80,8 @@ import { executeOperation } from "../runtime/executor.js";
65
80
  import { createHttpClient } from "../runtime/http.js";
66
81
  import { wrapWithInstrumentation } from "../runtime/instrumentation.js";
67
82
  import type * as NativeNetworkRuntimeModule from "../runtime/native-network.js";
68
- import { getProviderBaseUrl } from "../runtime/provider.js";
69
83
  import { createOcrClientFromEnv } from "../runtime/ocr.js";
84
+ import { getProviderBaseUrl } from "../runtime/provider.js";
70
85
  import {
71
86
  PROXY_AUTH_IP_DENIED_CODE,
72
87
  PROXY_EDGE_AUTH_REJECTED_CODE,
@@ -78,24 +93,24 @@ import {
78
93
  type ProxyTelemetryLogPayload,
79
94
  } from "../runtime/proxy-telemetry.js";
80
95
  import {
96
+ type ClosedEnum,
81
97
  closedEnum,
82
98
  RequestTelemetry,
83
- tenantOpaqueKeys,
84
- type ClosedEnum,
85
99
  type TenantNeutral,
86
100
  type TenantOpaqueKeys,
101
+ tenantOpaqueKeys,
87
102
  } from "../runtime/request-telemetry.js";
88
- import {
89
- ResolverTelemetryCollector,
90
- type ResolverTelemetryLogPayload,
91
- } from "../runtime/resolver-telemetry.js";
92
103
  import type * as ResolverRuntimeModule from "../runtime/resolver.js";
93
104
  import {
94
- createUnsupportedResolverClient,
95
105
  bindResolverTelemetry,
106
+ createUnsupportedResolverClient,
96
107
  inheritResolverTelemetryBinding,
97
108
  type ResolverSolveWithRecorder,
98
109
  } from "../runtime/resolver-shared.js";
110
+ import {
111
+ ResolverTelemetryCollector,
112
+ type ResolverTelemetryLogPayload,
113
+ } from "../runtime/resolver-telemetry.js";
99
114
  import {
100
115
  assertRequiredSecretsPresent,
101
116
  listMissingRequiredSecrets,
@@ -105,9 +120,9 @@ import {
105
120
  createProviderRuntimeStateFromEnv,
106
121
  createUnsupportedProviderRuntimeState,
107
122
  } from "../runtime/state.js";
108
- import { StealthCookieJar } from "../runtime/stealth-cookies.js";
109
123
  import type * as StealthRuntimeModule from "../runtime/stealth.js";
110
124
  import type { StealthChallengeRuntime } from "../runtime/stealth-akamai-sbsd.js";
125
+ import { StealthCookieJar } from "../runtime/stealth-cookies.js";
111
126
  import { createSttClientFromEnv } from "../runtime/stt.js";
112
127
  import {
113
128
  createTraceContext,
@@ -118,21 +133,21 @@ import {
118
133
  } from "../runtime/trace.js";
119
134
  import { resolveTraceConfigFromEnv } from "../runtime/trace-config.js";
120
135
  import { parseSchema } from "../schema.js";
136
+ import { StatefulRoutingDeadlineError } from "../stateful/errors.js";
121
137
  import {
122
138
  STATEFUL_NONCE_HEADER as STATEFUL_FORWARDING_NONCE_HEADER,
123
139
  STATEFUL_SIGNATURE_HEADER as STATEFUL_FORWARDING_SIGNATURE_HEADER,
124
140
  STATEFUL_TIMESTAMP_HEADER as STATEFUL_FORWARDING_TIMESTAMP_HEADER,
125
141
  verifyStatefulRequestSignature,
126
142
  } from "../stateful-signing.js";
127
- import { StatefulRoutingDeadlineError } from "../stateful/errors.js";
128
143
  import { getStealthProfile } from "../stealth/profiles.js";
129
- import { sanitizeTraceAttributes } from "../trace-sanitization.js";
130
144
  import {
131
145
  APIFUSE_STREAM_DONE_EVENT,
132
146
  APIFUSE_STREAM_ERROR_EVENT,
133
147
  encodeSseEvent,
134
148
  error as streamError,
135
149
  } from "../stream.js";
150
+ import { sanitizeSpanNameForOutput, sanitizeTraceAttributes } from "../trace-sanitization.js";
136
151
  import type {
137
152
  AuthContext,
138
153
  AuthTurn,
@@ -140,15 +155,15 @@ import type {
140
155
  FlowContext,
141
156
  FlowContextStore,
142
157
  HttpRetrySummary,
158
+ OcrContext,
143
159
  OperationDefinition,
144
160
  OperationErrorCode,
145
161
  OperationHttpStreamTransport,
146
162
  OperationSseTransport,
147
- OcrContext,
148
- ProviderErrorStatus,
149
- ProviderContext,
150
163
  ProviderCacheResponseMeta,
164
+ ProviderContext,
151
165
  ProviderDefinition,
166
+ ProviderErrorStatus,
152
167
  ProviderFilesContext,
153
168
  ProviderProxyPolicy,
154
169
  ProviderRuntimeState,
@@ -162,6 +177,10 @@ import type {
162
177
  import { VALID_OPERATION_ERROR_STATUSES } from "../types.js";
163
178
  import type { SelfTestCancellationLogEvent } from "./self-test.js";
164
179
  import { resolveSelfTestMasterSecrets } from "./self-test-token.js";
180
+ import {
181
+ collectStaticDiagnosticSensitiveValues,
182
+ createDiagnosticEnvObserver,
183
+ } from "./sensitive-values.js";
165
184
  import { resolveServerTraceContextOptions } from "./trace-output.js";
166
185
  import {
167
186
  type AuthFlowRequest,
@@ -307,9 +326,7 @@ export type ProviderServerOperationExecutorInput<
307
326
 
308
327
  export type ProviderServerOperationExecutor<
309
328
  TContext extends Partial<ProviderContext> = ProviderContext,
310
- > = (
311
- input: ProviderServerOperationExecutorInput<TContext>,
312
- ) => Promise<unknown>;
329
+ > = (input: ProviderServerOperationExecutorInput<TContext>) => Promise<unknown>;
313
330
 
314
331
  type RequestTerminalOutcome =
315
332
  | { kind: "completed"; status: number }
@@ -317,6 +334,7 @@ type RequestTerminalOutcome =
317
334
  | { kind: "cancelled"; status?: number };
318
335
 
319
336
  type RequestStreamLifecycle = {
337
+ redact: DiagnosticRedactor;
320
338
  runStep<T>(fn: () => Promise<T>): Promise<T>;
321
339
  registerCleanup(cleanup: () => void | Promise<void>): void;
322
340
  terminalize(outcome: RequestTerminalOutcome): void;
@@ -823,6 +841,7 @@ function providerSecretNames(provider: ProviderDefinition): string[] {
823
841
  }
824
842
 
825
843
  type RequestScopeContext = {
844
+ redact: DiagnosticRedactor;
826
845
  trace: RuntimeTraceContext;
827
846
  telemetry: RequestTelemetry;
828
847
  resolverTelemetry: ResolverTelemetryCollector;
@@ -899,6 +918,7 @@ function createProviderContext(
899
918
  request.requestId,
900
919
  "stealth",
901
920
  error,
921
+ scope.redact,
902
922
  );
903
923
 
904
924
  const env = createEnvContext([
@@ -940,7 +960,7 @@ function createProviderContext(
940
960
  provider.runtime === "browser"
941
961
  ? capabilityModules.browser!.createBrowserClient({
942
962
  allowedHosts: provider.allowedHosts,
943
- cdpUrl: process.env.APIFUSE__CDP_POOL__URL,
963
+ cdpUrl: readDiagnosticEnv("APIFUSE__CDP_POOL__URL"),
944
964
  headless: true,
945
965
  requireCdpPool: isProductionProviderBrowserMode(provider),
946
966
  stealth: true,
@@ -1101,6 +1121,7 @@ function createAuthFlowContext(
1101
1121
  providerId: provider.id,
1102
1122
  flowId: request.flowId,
1103
1123
  affinityKey: proxyClientOptions.affinityKey,
1124
+ onHandle: (handle) => registerDiagnosticSensitiveValues(scope.trace, [handle]),
1104
1125
  ...(request.engine?.egressLease ? { handle: request.engine.egressLease } : {}),
1105
1126
  })
1106
1127
  : undefined;
@@ -1161,6 +1182,7 @@ function createAuthFlowContext(
1161
1182
  request.requestId,
1162
1183
  "stealth",
1163
1184
  error,
1185
+ scope.redact,
1164
1186
  );
1165
1187
  const credential = request.connection
1166
1188
  ? createCredentialContext({
@@ -1418,15 +1440,18 @@ function finishRequestCost(input: {
1418
1440
  };
1419
1441
  }
1420
1442
 
1421
- function zodDetails(error: z.ZodError): Array<{
1443
+ function zodDetails(
1444
+ error: z.ZodError,
1445
+ redact?: DiagnosticRedactor,
1446
+ ): Array<{
1422
1447
  path: string;
1423
1448
  code: string;
1424
1449
  message: string;
1425
1450
  }> {
1426
1451
  return error.issues.map((issue) => ({
1427
- path: issue.path.join("."),
1428
- code: issue.code,
1429
- message: issue.message,
1452
+ path: sanitizeSpanNameForOutput(issue.path.join("."), redact),
1453
+ code: sanitizeSpanNameForOutput(issue.code, redact),
1454
+ message: sanitizeSpanNameForOutput(issue.message, redact),
1430
1455
  }));
1431
1456
  }
1432
1457
 
@@ -1453,6 +1478,7 @@ function toErrorResponse(
1453
1478
  error: unknown,
1454
1479
  requestId: string | undefined,
1455
1480
  observabilityDetails: ErrorObservabilityDetails,
1481
+ redact?: DiagnosticRedactor,
1456
1482
  ): OperationErrorResponse {
1457
1483
  const observability = observabilityDetails;
1458
1484
  const source = publicErrorSource(error, observability.category);
@@ -1491,7 +1517,7 @@ function toErrorResponse(
1491
1517
  ...(requestId ? { requestId } : {}),
1492
1518
  retryable: observability.retryable,
1493
1519
  source,
1494
- details: zodDetails(error),
1520
+ details: zodDetails(error, redact),
1495
1521
  },
1496
1522
  };
1497
1523
  }
@@ -1787,14 +1813,17 @@ export type ProviderErrorCauseFrame = {
1787
1813
  const MAX_PROVIDER_ERROR_CAUSE_FRAMES = 5;
1788
1814
  const MAX_PROVIDER_ERROR_CAUSE_MESSAGE_LENGTH = 300;
1789
1815
 
1790
- function providerErrorCauseMessage(message: string): string {
1791
- const sanitized = sanitizeDiagnosticText(message);
1816
+ function providerErrorCauseMessage(message: string, redact?: DiagnosticRedactor): string {
1817
+ const sanitized = sanitizeDiagnosticText(redactDiagnosticText(message, redact));
1792
1818
  return sanitized.length > MAX_PROVIDER_ERROR_CAUSE_MESSAGE_LENGTH
1793
1819
  ? `${sanitized.slice(0, MAX_PROVIDER_ERROR_CAUSE_MESSAGE_LENGTH)}… [truncated]`
1794
1820
  : sanitized;
1795
1821
  }
1796
1822
 
1797
- function providerErrorCauseChain(error: unknown): ProviderErrorCauseFrame[] | undefined {
1823
+ function providerErrorCauseChain(
1824
+ error: unknown,
1825
+ redact?: DiagnosticRedactor,
1826
+ ): ProviderErrorCauseFrame[] | undefined {
1798
1827
  if (!(error instanceof Error) && !isProviderError(error)) return undefined;
1799
1828
 
1800
1829
  const seen = new Set<object>([error]);
@@ -1811,9 +1840,9 @@ function providerErrorCauseChain(error: unknown): ProviderErrorCauseFrame[] | un
1811
1840
  const providerObservability = safeProviderErrorObservability(cause);
1812
1841
  const causeCode = providerErrorCode(cause);
1813
1842
  frames.push({
1814
- errorClass: cause.name,
1815
- ...(causeCode !== undefined ? { code: causeCode } : {}),
1816
- message: providerErrorCauseMessage(message),
1843
+ errorClass: redactDiagnosticText(cause.name, redact),
1844
+ ...(causeCode !== undefined ? { code: redactDiagnosticText(causeCode, redact) } : {}),
1845
+ message: providerErrorCauseMessage(message, redact),
1817
1846
  messageLength: message.length,
1818
1847
  messageFingerprint: createHash("sha256").update(message).digest("hex").slice(0, 12),
1819
1848
  ...(providerObservability ? { providerObservability } : {}),
@@ -1837,6 +1866,7 @@ function logProviderError(
1837
1866
  telemetry: RequestTelemetry | undefined,
1838
1867
  observabilityDetails: ErrorObservabilityDetails,
1839
1868
  correlation: RequestCorrelationIds = {},
1869
+ redact?: DiagnosticRedactor,
1840
1870
  ): void {
1841
1871
  const providerCode = isProviderError(error) ? providerErrorCode(error) : undefined;
1842
1872
  const code = isProviderError(error)
@@ -1848,7 +1878,7 @@ function logProviderError(
1848
1878
  : "internal_error";
1849
1879
  const errorClass = error instanceof Error ? error.name : typeof error;
1850
1880
  const message = error instanceof Error ? error.message : String(error);
1851
- const causeChain = providerErrorCauseChain(error);
1881
+ const causeChain = providerErrorCauseChain(error, redact);
1852
1882
  const details = observabilityDetails;
1853
1883
  const isUnregisteredProviderErrorCode =
1854
1884
  status === 500 &&
@@ -1868,24 +1898,28 @@ function logProviderError(
1868
1898
  emit({
1869
1899
  level: status >= 500 ? "error" : "warn",
1870
1900
  event: "provider_request_failed",
1871
- providerId: provider.id,
1901
+ providerId: redactDiagnosticText(provider.id, redact),
1872
1902
  kind,
1873
- route,
1874
- ...(requestId ? { requestId } : {}),
1903
+ route: redactCriticalDiagnosticText(route, redact),
1904
+ ...(requestId ? { requestId: redactCriticalDiagnosticText(requestId, redact) } : {}),
1875
1905
  ...(correlation.connectionId !== undefined
1876
- ? { connectionId: correlation.connectionId }
1906
+ ? { connectionId: redactDiagnosticText(correlation.connectionId, redact) }
1907
+ : {}),
1908
+ ...(correlation.flowId !== undefined
1909
+ ? { flowId: redactDiagnosticText(correlation.flowId, redact) }
1910
+ : {}),
1911
+ ...(correlation.tenantId !== undefined
1912
+ ? { tenantId: redactDiagnosticText(correlation.tenantId, redact) }
1877
1913
  : {}),
1878
- ...(correlation.flowId !== undefined ? { flowId: correlation.flowId } : {}),
1879
- ...(correlation.tenantId !== undefined ? { tenantId: correlation.tenantId } : {}),
1880
1914
  ...(correlation.requestedProviderId !== undefined
1881
- ? { requestedProviderId: correlation.requestedProviderId }
1915
+ ? { requestedProviderId: redactDiagnosticText(correlation.requestedProviderId, redact) }
1882
1916
  : {}),
1883
1917
  status,
1884
1918
  ...cost,
1885
1919
  ...(telemetryPayload ?? {}),
1886
- code,
1887
- errorClass,
1888
- message,
1920
+ code: sanitizeSpanNameForOutput(redactCriticalDiagnosticText(code, redact)),
1921
+ errorClass: redactDiagnosticText(errorClass, redact),
1922
+ message: sanitizeDiagnosticText(redactDiagnosticText(message, redact)),
1889
1923
  ...(causeChain ? { causeChain } : {}),
1890
1924
  ...(providerObservability ? { providerObservability } : {}),
1891
1925
  ...(details.upstreamStatus ? { upstreamStatus: details.upstreamStatus } : {}),
@@ -1899,7 +1933,7 @@ function logProviderError(
1899
1933
  "Declare this code (with status and retryable) in the operation's errorCodes so it serves its intended status instead of 500.",
1900
1934
  }
1901
1935
  : {}),
1902
- ...(error instanceof z.ZodError ? { issues: zodDetails(error) } : {}),
1936
+ ...(error instanceof z.ZodError ? { issues: zodDetails(error, redact) } : {}),
1903
1937
  });
1904
1938
  }
1905
1939
 
@@ -1911,6 +1945,7 @@ function logProviderCleanupError(
1911
1945
  requestId: string | undefined,
1912
1946
  resource: "browser" | "stealth",
1913
1947
  error: unknown,
1948
+ redact?: DiagnosticRedactor,
1914
1949
  ): void {
1915
1950
  const emit = typeof logger === "function" ? logger : defaultProviderServerLogger;
1916
1951
  const errorClass = error instanceof Error ? error.name : typeof error;
@@ -1918,13 +1953,13 @@ function logProviderCleanupError(
1918
1953
  emit({
1919
1954
  level: "warn",
1920
1955
  event: "provider_cleanup_failed",
1921
- providerId: provider.id,
1956
+ providerId: redactDiagnosticText(provider.id, redact),
1922
1957
  kind,
1923
- route: operationId,
1924
- ...(requestId ? { requestId } : {}),
1958
+ route: redactCriticalDiagnosticText(operationId, redact),
1959
+ ...(requestId ? { requestId: redactCriticalDiagnosticText(requestId, redact) } : {}),
1925
1960
  resource,
1926
- errorClass,
1927
- message,
1961
+ errorClass: redactDiagnosticText(errorClass, redact),
1962
+ message: sanitizeDiagnosticText(redactDiagnosticText(message, redact)),
1928
1963
  });
1929
1964
  }
1930
1965
 
@@ -1938,23 +1973,28 @@ function logProviderSuccess(
1938
1973
  cost: ProviderRequestCost,
1939
1974
  telemetry?: RequestTelemetry,
1940
1975
  correlation: RequestCorrelationIds = {},
1976
+ redact?: DiagnosticRedactor,
1941
1977
  ): void {
1942
1978
  const telemetryPayload = telemetry?.toLogPayload();
1943
1979
  const emit = typeof logger === "function" ? logger : defaultProviderServerLogger;
1944
1980
  emit({
1945
1981
  level: "info",
1946
1982
  event: "provider_request_completed",
1947
- providerId: provider.id,
1983
+ providerId: redactDiagnosticText(provider.id, redact),
1948
1984
  kind,
1949
- route,
1950
- ...(requestId ? { requestId } : {}),
1985
+ route: redactCriticalDiagnosticText(route, redact),
1986
+ ...(requestId ? { requestId: redactCriticalDiagnosticText(requestId, redact) } : {}),
1951
1987
  ...(correlation.connectionId !== undefined
1952
- ? { connectionId: correlation.connectionId }
1988
+ ? { connectionId: redactDiagnosticText(correlation.connectionId, redact) }
1989
+ : {}),
1990
+ ...(correlation.flowId !== undefined
1991
+ ? { flowId: redactDiagnosticText(correlation.flowId, redact) }
1992
+ : {}),
1993
+ ...(correlation.tenantId !== undefined
1994
+ ? { tenantId: redactDiagnosticText(correlation.tenantId, redact) }
1953
1995
  : {}),
1954
- ...(correlation.flowId !== undefined ? { flowId: correlation.flowId } : {}),
1955
- ...(correlation.tenantId !== undefined ? { tenantId: correlation.tenantId } : {}),
1956
1996
  ...(correlation.requestedProviderId !== undefined
1957
- ? { requestedProviderId: correlation.requestedProviderId }
1997
+ ? { requestedProviderId: redactDiagnosticText(correlation.requestedProviderId, redact) }
1958
1998
  : {}),
1959
1999
  status,
1960
2000
  ...cost,
@@ -1968,6 +2008,7 @@ type RequestScopeFinishResult = {
1968
2008
  };
1969
2009
 
1970
2010
  type RequestScope = RequestScopeContext & {
2011
+ seedCredentials(rawBody: unknown, kind: "operation" | "auth" | "stateful"): void;
1971
2012
  enrich(input: {
1972
2013
  route?: string;
1973
2014
  requestId?: string;
@@ -2039,8 +2080,91 @@ function requestTraceId(
2039
2080
  );
2040
2081
  }
2041
2082
 
2083
+ /** Harvest only credential subtrees, iteratively and before schema diagnostics. */
2084
+ function rawRequestCredentials(
2085
+ rawBody: unknown,
2086
+ kind: "operation" | "auth" | "stateful",
2087
+ ): { values: string[]; exhausted: boolean } {
2088
+ const record = (value: unknown): Record<string, unknown> | undefined =>
2089
+ value !== null && typeof value === "object" ? (value as Record<string, unknown>) : undefined;
2090
+ const own = (value: unknown, key: string): unknown => {
2091
+ const object = record(value);
2092
+ return object && Object.hasOwn(object, key) ? object[key] : undefined;
2093
+ };
2094
+ const body = kind === "stateful" ? own(rawBody, "operationRequest") : rawBody;
2095
+ const values: string[] = [];
2096
+ let remainingBytes = 64 * 1024;
2097
+ let exhausted = false;
2098
+ const add = (value: unknown): void => {
2099
+ if (typeof value !== "string") return;
2100
+ const bytes = Buffer.byteLength(value, "utf8");
2101
+ if (bytes > remainingBytes) {
2102
+ exhausted = true;
2103
+ return;
2104
+ }
2105
+ remainingBytes -= bytes;
2106
+ if (value) values.push(value);
2107
+ const trimmed = value.trim();
2108
+ if (trimmed && trimmed !== value) values.push(trimmed);
2109
+ };
2110
+ function* entries(object: Record<string, unknown>) {
2111
+ for (const key in object) {
2112
+ if (Object.hasOwn(object, key)) yield [key, object[key]] as const;
2113
+ }
2114
+ }
2115
+ const visit = (root: unknown): void => {
2116
+ const object = record(root);
2117
+ if (!object) {
2118
+ add(root);
2119
+ return;
2120
+ }
2121
+ // Connection inventories are usually flat. Walk the root directly and only
2122
+ // allocate iterator frames when a nested credential container is encountered.
2123
+ for (const key in object) {
2124
+ if (!Object.hasOwn(object, key)) continue;
2125
+ const value = object[key];
2126
+ add(key);
2127
+ if (exhausted) break;
2128
+ const child = record(value);
2129
+ if (!child) {
2130
+ add(value);
2131
+ if (exhausted) break;
2132
+ continue;
2133
+ }
2134
+ const stack = [{ iterator: entries(child), depth: 1 }];
2135
+ while (stack.length && !exhausted) {
2136
+ const frame = stack[stack.length - 1];
2137
+ const entry = frame.iterator.next();
2138
+ if (entry.done) {
2139
+ stack.pop();
2140
+ continue;
2141
+ }
2142
+ const [key, value] = entry.value;
2143
+ add(key);
2144
+ if (exhausted) break;
2145
+ const child = record(value);
2146
+ if (child) {
2147
+ if (frame.depth >= 8) {
2148
+ exhausted = true;
2149
+ break;
2150
+ }
2151
+ stack.push({ iterator: entries(child), depth: frame.depth + 1 });
2152
+ } else add(value);
2153
+ }
2154
+ if (exhausted) break;
2155
+ }
2156
+ };
2157
+ visit(own(own(body, "connection"), "secrets"));
2158
+ if (kind === "auth" && !exhausted) {
2159
+ add(own(own(body, "engine"), "egressLease"));
2160
+ if (!exhausted) visit(own(body, "input"));
2161
+ }
2162
+ return { values, exhausted };
2163
+ }
2164
+
2042
2165
  function createRequestScope(input: {
2043
2166
  provider: ProviderDefinition;
2167
+ staticSensitiveValues: CompiledDiagnosticSensitiveValues;
2044
2168
  kind: "operation" | "auth";
2045
2169
  route: string;
2046
2170
  requestId?: string;
@@ -2052,8 +2176,25 @@ function createRequestScope(input: {
2052
2176
  setHeader?: (name: string, value: string) => void;
2053
2177
  declaredErrorCode?: (error: unknown) => OperationErrorCode | undefined;
2054
2178
  }): RequestScope {
2179
+ const sensitiveRegistry = createDiagnosticRedactor([], input.staticSensitiveValues);
2180
+ const redact = (text: string) => redactDiagnosticText(text, sensitiveRegistry.redact);
2181
+ bindCriticalDiagnosticRedactor(
2182
+ redact,
2183
+ sensitiveRegistry.redactCritical,
2184
+ sensitiveRegistry.redactStructured,
2185
+ () => sensitiveRegistry.suppressed,
2186
+ );
2055
2187
  const requestCost = startRequestCost();
2056
- const traceConfig = resolveTraceConfigFromEnv();
2188
+ const observeEnv = {
2189
+ observe: createDiagnosticEnvObserver(
2190
+ input.provider,
2191
+ sensitiveRegistry.add,
2192
+ sensitiveRegistry.has,
2193
+ ),
2194
+ finished: false,
2195
+ staticValues: input.staticSensitiveValues,
2196
+ };
2197
+ const traceConfig = withDiagnosticEnv(observeEnv, () => resolveTraceConfigFromEnv());
2057
2198
  const details = {
2058
2199
  route: input.route,
2059
2200
  requestId: input.requestId,
@@ -2072,12 +2213,16 @@ function createRequestScope(input: {
2072
2213
  const initialTraceId = requestTraceId(input.headers, input.requestId);
2073
2214
  const trace: RuntimeTraceContext = traceConfig
2074
2215
  ? createTraceContext({
2075
- ...resolveServerTraceContextOptions(traceConfig, traceAttributes),
2216
+ ...withDiagnosticEnv(observeEnv, () =>
2217
+ resolveServerTraceContextOptions(traceConfig, traceAttributes, undefined, redact),
2218
+ ),
2219
+ redact,
2076
2220
  ...(initialTraceId ? { traceId: initialTraceId } : {}),
2077
2221
  })
2078
- : createTraceContext();
2222
+ : createTraceContext({ redact });
2223
+ bindDiagnosticSensitiveRegistry(trace, sensitiveRegistry);
2079
2224
  const proxyCollector = new ProxyTelemetryCollector();
2080
- const resolverCollector = new ResolverTelemetryCollector();
2225
+ const resolverCollector = new ResolverTelemetryCollector({ redact });
2081
2226
  const telemetry = new RequestTelemetry(trace);
2082
2227
  telemetry.register(proxyCollector);
2083
2228
  telemetry.register(resolverCollector);
@@ -2104,12 +2249,14 @@ function createRequestScope(input: {
2104
2249
  if (outcome.kind === "cancelled") return clientCancelledError();
2105
2250
  return undefined;
2106
2251
  };
2107
- const root = trace.span(`request:${input.kind}:${input.route}`, async () => {
2108
- rootRunner = AsyncLocalStorage.snapshot();
2109
- const outcome = await rootTerminal;
2110
- const error = terminalError(outcome);
2111
- if (error !== undefined) throw error;
2112
- });
2252
+ const root = withDiagnosticEnv(observeEnv, () =>
2253
+ trace.span(`request:${input.kind}:${input.route}`, async () => {
2254
+ rootRunner = AsyncLocalStorage.snapshot();
2255
+ const outcome = await rootTerminal;
2256
+ const error = terminalError(outcome);
2257
+ if (error !== undefined) throw error;
2258
+ }),
2259
+ );
2113
2260
  void root.catch(() => undefined);
2114
2261
 
2115
2262
  const settleRoot = (): void => {
@@ -2144,7 +2291,7 @@ function createRequestScope(input: {
2144
2291
  traceAttributes.route = details.route;
2145
2292
  const traceId = requestTraceId(details.headers, details.requestId);
2146
2293
  const sanitizedAttributes = Object.fromEntries(
2147
- Object.entries(sanitizeTraceAttributes(traceAttributes)).map(([key, value]) => [
2294
+ Object.entries(sanitizeTraceAttributes(traceAttributes, redact)).map(([key, value]) => [
2148
2295
  key,
2149
2296
  String(value),
2150
2297
  ]),
@@ -2156,9 +2303,16 @@ function createRequestScope(input: {
2156
2303
  };
2157
2304
 
2158
2305
  const scope: RequestScope = {
2306
+ redact,
2159
2307
  trace,
2160
2308
  telemetry,
2161
2309
  resolverTelemetry: resolverCollector,
2310
+ seedCredentials(rawBody, kind): void {
2311
+ const harvested = rawRequestCredentials(rawBody, kind);
2312
+ sensitiveRegistry.add(harvested.values);
2313
+ // An incomplete inventory cannot certify free text: emit less.
2314
+ if (harvested.exhausted) sensitiveRegistry.suppress();
2315
+ },
2162
2316
  enrich(enrichment): void {
2163
2317
  if (terminalOutcome) return;
2164
2318
  if (enrichment.route !== undefined) details.route = enrichment.route;
@@ -2208,6 +2362,7 @@ function createRequestScope(input: {
2208
2362
  },
2209
2363
  terminalize(outcome): RequestScopeFinishResult {
2210
2364
  if (finishedResult) return finishedResult;
2365
+ observeEnv.finished = true;
2211
2366
  terminalOutcome = outcome;
2212
2367
  const error = terminalError(outcome);
2213
2368
  finishedResult = {};
@@ -2215,8 +2370,7 @@ function createRequestScope(input: {
2215
2370
  const declaredErrorCode =
2216
2371
  error === undefined ? undefined : input.declaredErrorCode?.(error);
2217
2372
  const status =
2218
- outcome.status ??
2219
- (error === undefined ? 200 : toStatusCode(error, declaredErrorCode));
2373
+ outcome.status ?? (error === undefined ? 200 : toStatusCode(error, declaredErrorCode));
2220
2374
  finishedResult = headerSnapshot(error);
2221
2375
  const cost = finishRequestCost(requestCost);
2222
2376
  try {
@@ -2231,6 +2385,7 @@ function createRequestScope(input: {
2231
2385
  cost,
2232
2386
  telemetry,
2233
2387
  details.correlation,
2388
+ redact,
2234
2389
  );
2235
2390
  } else {
2236
2391
  logProviderError(
@@ -2246,6 +2401,7 @@ function createRequestScope(input: {
2246
2401
  telemetry,
2247
2402
  finishedResult.errorObservability as ErrorObservabilityDetails,
2248
2403
  details.correlation,
2404
+ redact,
2249
2405
  );
2250
2406
  }
2251
2407
  } catch {
@@ -2281,8 +2437,9 @@ function createRequestScope(input: {
2281
2437
  return scope;
2282
2438
  }
2283
2439
 
2284
- // A raw `Response` result skips `toErrorResponse`, so its body stays
2285
- // provider-owned, but the observability header is still SDK-owned: derive it
2440
+ // A raw `Response` result skips `toErrorResponse`. Its payload shape stays
2441
+ // provider-owned; known credentials in error payloads still need redaction.
2442
+ // The observability header is SDK-owned: derive it
2286
2443
  // from the status. Only timeouts, rate limits, and 5xx are retryable;
2287
2444
  // `isRetryableCategory` would otherwise mark every other 4xx (`upstream_http`)
2288
2445
  // as retryable.
@@ -2297,11 +2454,12 @@ function rawResponseErrorObservability(status: number): ErrorObservabilityDetail
2297
2454
  // `rawStatusFallback` is decided by the caller from the outcome, not from a
2298
2455
  // missing snapshot: a failed outcome whose thrown value is `undefined` also has
2299
2456
  // no `errorObservability`, and its 500 carries the SDK envelope, not a raw body.
2300
- function responseWithRequestScopeHeaders(
2457
+ async function responseWithRequestScopeHeaders(
2301
2458
  response: Response,
2302
2459
  finished: RequestScopeFinishResult,
2303
2460
  rawStatusFallback: boolean,
2304
- ): Response {
2461
+ redact: DiagnosticRedactor,
2462
+ ): Promise<Response> {
2305
2463
  const headers = new Headers(response.headers);
2306
2464
  headers.delete(PROVIDER_TELEMETRY_HEADER);
2307
2465
  if (finished.providerTelemetryHeader) {
@@ -2316,24 +2474,36 @@ function responseWithRequestScopeHeaders(
2316
2474
  if (errorObservability) {
2317
2475
  headers.set(ERROR_OBSERVABILITY_HEADER, JSON.stringify(errorObservability));
2318
2476
  }
2319
- return new Response(response.body, {
2477
+ // Raw Response bodies are provider-owned. Preserve their stream and representation.
2478
+ const body = response.body;
2479
+ const statusText =
2480
+ rawStatusFallback && response.status >= 400
2481
+ ? redactDiagnosticText(response.statusText, redact)
2482
+ : response.statusText;
2483
+ return new Response(body, {
2320
2484
  headers,
2321
2485
  status: response.status,
2322
- statusText: response.statusText,
2486
+ // When free text cannot be certified, use the SDK's standard HTTP reason
2487
+ // phrase. It preserves the status contract without trusting provider text.
2488
+ statusText:
2489
+ statusText === REDACTION_FAILED && isDiagnosticRedactionSuppressed(redact)
2490
+ ? (STATUS_CODES[response.status] ?? "")
2491
+ : statusText,
2323
2492
  });
2324
2493
  }
2325
2494
 
2326
- function finalizeRequestResponse(
2495
+ async function finalizeRequestResponse(
2327
2496
  scope: RequestScope,
2328
2497
  response: Response,
2329
2498
  outcome: RequestTerminalOutcome,
2330
- ): Response {
2499
+ ): Promise<Response> {
2331
2500
  try {
2332
2501
  const error = outcome.kind === "failed" ? outcome.error : undefined;
2333
- const finalResponse = responseWithRequestScopeHeaders(
2502
+ const finalResponse = await responseWithRequestScopeHeaders(
2334
2503
  response,
2335
2504
  scope.snapshotHeaders(error),
2336
2505
  outcome.kind === "completed",
2506
+ scope.redact,
2337
2507
  );
2338
2508
  scope.terminalize(outcome);
2339
2509
  return finalResponse;
@@ -2552,11 +2722,7 @@ function toSseResponse(
2552
2722
  const validated = await validateSseEvent(operation, next.value);
2553
2723
  const encodedEvent = encodeSseEvent(validated);
2554
2724
  const bytes = encoder.encode(encodedEvent);
2555
- assertStreamPayloadWithinLimit(
2556
- bytes.byteLength,
2557
- transport?.maxEventBytes,
2558
- "event",
2559
- );
2725
+ assertStreamPayloadWithinLimit(bytes.byteLength, transport?.maxEventBytes, "event");
2560
2726
  return bytes;
2561
2727
  });
2562
2728
  controller.enqueue(encodedBytes);
@@ -2565,9 +2731,13 @@ function toSseResponse(
2565
2731
  controller.enqueue(
2566
2732
  encoder.encode(
2567
2733
  encodeSseEvent(
2568
- streamError("stream_error", message, {
2569
- ...(requestId ? { requestId } : {}),
2570
- }),
2734
+ streamError(
2735
+ "stream_error",
2736
+ sanitizeDiagnosticText(redactDiagnosticText(message, lifecycle.redact)),
2737
+ {
2738
+ ...(requestId ? { requestId } : {}),
2739
+ },
2740
+ ),
2571
2741
  ),
2572
2742
  ),
2573
2743
  );
@@ -2810,6 +2980,7 @@ async function handleOperation(
2810
2980
  request.requestId,
2811
2981
  "stealth",
2812
2982
  error,
2983
+ scope.redact,
2813
2984
  );
2814
2985
  }
2815
2986
  }
@@ -2825,11 +2996,13 @@ async function handleOperation(
2825
2996
  request.requestId,
2826
2997
  "browser",
2827
2998
  error,
2999
+ scope.redact,
2828
3000
  );
2829
3001
  }
2830
3002
  }
2831
3003
  };
2832
3004
  const streamLifecycle: RequestStreamLifecycle = {
3005
+ redact: scope.redact,
2833
3006
  runStep<T>(fn: () => Promise<T>): Promise<T> {
2834
3007
  return scope.runStreamStep(fn);
2835
3008
  },
@@ -2953,6 +3126,7 @@ async function handleAuthFlow(
2953
3126
  request.requestId,
2954
3127
  "stealth",
2955
3128
  error,
3129
+ scope.redact,
2956
3130
  );
2957
3131
  }
2958
3132
  }
@@ -3074,12 +3248,15 @@ function operationRequestFromForwardingEnvelope(
3074
3248
  };
3075
3249
  }
3076
3250
 
3077
- function parseStatefulForwardingEnvelope(rawBody: unknown): ProviderServerStatefulForwardEnvelope {
3251
+ function parseStatefulForwardingEnvelope(
3252
+ rawBody: unknown,
3253
+ redact: DiagnosticRedactor,
3254
+ ): ProviderServerStatefulForwardEnvelope {
3078
3255
  const parsed = ProviderServerStatefulForwardEnvelopeSchema.safeParse(rawBody);
3079
3256
  if (parsed.success) return parsed.data;
3080
3257
  throw new ProviderError("Stateful forwarding envelope is invalid.", {
3081
3258
  code: "STATEFUL_FORWARDING_ENVELOPE_INVALID",
3082
- details: zodDetails(parsed.error),
3259
+ details: zodDetails(parsed.error, redact),
3083
3260
  });
3084
3261
  }
3085
3262
 
@@ -3087,7 +3264,9 @@ function parseStatefulForwardingEnvelope(rawBody: unknown): ProviderServerStatef
3087
3264
  * Primary, cross-runtime app factory. Declared capability ESM is preloaded
3088
3265
  * asynchronously, so this path works on Bun and every supported Node release.
3089
3266
  */
3090
- export async function createServerAppAsync<TContext extends Partial<ProviderContext> = ProviderContext>(
3267
+ export async function createServerAppAsync<
3268
+ TContext extends Partial<ProviderContext> = ProviderContext,
3269
+ >(
3091
3270
  provider: ProviderDefinition<TContext>,
3092
3271
  options: ProviderServerOptions<TContext> = {},
3093
3272
  ): Promise<Hono> {
@@ -3134,6 +3313,12 @@ function createServerAppWithCapabilityModules(
3134
3313
  engine: serverOptions.engine ?? createInProcessProviderEngine(),
3135
3314
  };
3136
3315
  const app = new Hono();
3316
+ // Compile the startup inventory once, composed with the shared outside-context fallback.
3317
+ const staticSensitiveValues = compileProcessDiagnosticSensitiveValues(
3318
+ collectStaticDiagnosticSensitiveValues(provider, {
3319
+ statefulForwardingSecret: options.statefulForwarding?.secret,
3320
+ }),
3321
+ );
3137
3322
  const logger = options.logger ?? defaultProviderServerLogger;
3138
3323
  const operationErrorCodes = buildOperationErrorCodeLookup(provider);
3139
3324
  const statefulForwardingReplayCache = new StatefulForwardingReplayCache(
@@ -3189,6 +3374,7 @@ function createServerAppWithCapabilityModules(
3189
3374
  const operation = "stateful-internal";
3190
3375
  const requestScope = createRequestScope({
3191
3376
  provider,
3377
+ staticSensitiveValues,
3192
3378
  kind: "operation",
3193
3379
  route: operation,
3194
3380
  headers: Object.fromEntries(c.req.raw.headers.entries()),
@@ -3218,7 +3404,8 @@ function createServerAppWithCapabilityModules(
3218
3404
  code: "STATEFUL_FORWARDING_ENVELOPE_INVALID",
3219
3405
  });
3220
3406
  }
3221
- const envelope = parseStatefulForwardingEnvelope(rawBody);
3407
+ requestScope.seedCredentials(rawBody, "stateful");
3408
+ const envelope = parseStatefulForwardingEnvelope(rawBody, requestScope.redact);
3222
3409
  if (envelope.providerId !== provider.id) {
3223
3410
  throw new ProviderError(
3224
3411
  "Stateful forwarding envelope providerId does not match the served provider.",
@@ -3354,7 +3541,10 @@ function createServerAppWithCapabilityModules(
3354
3541
  ...(requestId ? { requestId } : {}),
3355
3542
  });
3356
3543
  const observabilityDetails = errorObservabilityDetails(error, declaredErrorCode);
3357
- const response = c.json(toErrorResponse(error, requestId, observabilityDetails), status);
3544
+ const response = c.json(
3545
+ toErrorResponse(error, requestId, observabilityDetails, requestScope.redact),
3546
+ status,
3547
+ );
3358
3548
  return finalizeRequestResponse(requestScope, response, {
3359
3549
  kind: "failed",
3360
3550
  status,
@@ -3368,6 +3558,7 @@ function createServerAppWithCapabilityModules(
3368
3558
  const operation = c.req.param("operation");
3369
3559
  const requestScope = createRequestScope({
3370
3560
  provider,
3561
+ staticSensitiveValues,
3371
3562
  kind: "operation",
3372
3563
  route: operation,
3373
3564
  operationId: operation,
@@ -3381,6 +3572,7 @@ function createServerAppWithCapabilityModules(
3381
3572
  .clone()
3382
3573
  .json()
3383
3574
  .catch(() => undefined);
3575
+ requestScope.seedCredentials(rawBody, "operation");
3384
3576
  const body = OperationRequestSchema.parse(rawBody);
3385
3577
  const requestHeaders = Object.fromEntries(c.req.raw.headers.entries());
3386
3578
  body.headers = { ...requestHeaders, ...body.headers };
@@ -3405,7 +3597,12 @@ function createServerAppWithCapabilityModules(
3405
3597
  );
3406
3598
  const response = handled instanceof Response ? handled : c.json(handled);
3407
3599
  return streaming
3408
- ? responseWithRequestScopeHeaders(response, requestScope.snapshotHeaders(), true)
3600
+ ? responseWithRequestScopeHeaders(
3601
+ response,
3602
+ requestScope.snapshotHeaders(),
3603
+ true,
3604
+ requestScope.redact,
3605
+ )
3409
3606
  : response;
3410
3607
  };
3411
3608
  const response = streaming
@@ -3422,7 +3619,10 @@ function createServerAppWithCapabilityModules(
3422
3619
  const requestId = extractRequestId(rawBody);
3423
3620
  requestScope.enrich({ ...(requestId ? { requestId } : {}) });
3424
3621
  const observabilityDetails = errorObservabilityDetails(error, declaredErrorCode);
3425
- const response = c.json(toErrorResponse(error, requestId, observabilityDetails), status);
3622
+ const response = c.json(
3623
+ toErrorResponse(error, requestId, observabilityDetails, requestScope.redact),
3624
+ status,
3625
+ );
3426
3626
  return finalizeRequestResponse(requestScope, response, {
3427
3627
  kind: "failed",
3428
3628
  status,
@@ -3448,6 +3648,7 @@ function createServerAppWithCapabilityModules(
3448
3648
  let rawBody: unknown;
3449
3649
  const requestScope = createRequestScope({
3450
3650
  provider,
3651
+ staticSensitiveValues,
3451
3652
  kind: "auth",
3452
3653
  route: logRoute,
3453
3654
  headers: Object.fromEntries(c.req.raw.headers.entries()),
@@ -3459,6 +3660,7 @@ function createServerAppWithCapabilityModules(
3459
3660
  .clone()
3460
3661
  .json()
3461
3662
  .catch(() => undefined);
3663
+ requestScope.seedCredentials(rawBody, "auth");
3462
3664
  const body = withAuthRequestHeaders(
3463
3665
  AuthFlowRequestSchema.parse(rawBody),
3464
3666
  c.req.raw.headers,
@@ -3498,7 +3700,10 @@ function createServerAppWithCapabilityModules(
3498
3700
  const requestId = extractRequestId(rawBody);
3499
3701
  requestScope.enrich({ ...(requestId ? { requestId } : {}) });
3500
3702
  const observabilityDetails = errorObservabilityDetails(error);
3501
- const response = c.json(toErrorResponse(error, requestId, observabilityDetails), status);
3703
+ const response = c.json(
3704
+ toErrorResponse(error, requestId, observabilityDetails, requestScope.redact),
3705
+ status,
3706
+ );
3502
3707
  return finalizeRequestResponse(requestScope, response, {
3503
3708
  kind: "failed",
3504
3709
  status,