@ory/argus 0.8.0 → 0.8.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.
package/dist/client.js CHANGED
@@ -658,10 +658,8 @@ function attachOtlpExporterFromEnv(client, harness) {
658
658
  return;
659
659
  client.tracer.setExporter(exporter);
660
660
  client.logger.info("otel.export.enabled", {
661
- endpoint: process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ??
662
- process.env.OTEL_EXPORTER_OTLP_ENDPOINT ??
663
- process.env.ORY_OTLP_ENDPOINT,
664
- serviceName: process.env.OTEL_SERVICE_NAME ?? `ory-agent-plugin-${harness}`,
661
+ endpoint: exporter.endpoint,
662
+ serviceName: exporter.resource.attributes["service.name"],
665
663
  });
666
664
  }
667
665
  /**
package/dist/dev.js CHANGED
@@ -322,16 +322,7 @@ async function runDevLauncher(config) {
322
322
  ? buildLocalOryEnv(localOry.gatewayUrl, localOry.seed)
323
323
  : { ORY_AGENT_SUBJECT_ID: sessionName }),
324
324
  ...(otelEndpoint
325
- ? {
326
- OTEL_EXPORTER_OTLP_ENDPOINT: otelEndpoint,
327
- // ORY-prefixed alias for harnesses (e.g. Claude Code) that
328
- // filter the env passed to hook subprocesses and drop
329
- // OTEL_*-prefixed vars. The OTLP exporter reads this as a
330
- // fallback so traces still reach Jaeger when OTEL_* is stripped.
331
- ORY_OTLP_ENDPOINT: otelEndpoint,
332
- OTEL_SERVICE_NAME: process.env.OTEL_SERVICE_NAME ??
333
- `ory-agent-plugin-${config.harnessName}`,
334
- }
325
+ ? buildOtelEnv(otelEndpoint, config.harnessName)
335
326
  : {}),
336
327
  };
337
328
  const result = (0, node_child_process_1.spawnSync)(config.command, forwardedArgs, {
@@ -488,10 +479,53 @@ async function bootstrapLocalOry(localDir) {
488
479
  `${seed.permissions.tuples} permissions in '${namespace}' for ${seed.permissions.subject}.`);
489
480
  return { active: true, gatewayUrl, seed };
490
481
  }
482
+ /**
483
+ * OTel env vars the dev launcher propagates into the harness child. Each
484
+ * entry pairs the standard `OTEL_*` name with its `ORY_OTLP_*` alias; the
485
+ * alias is set in lockstep so harnesses (notably Claude Code) that sanitize
486
+ * `OTEL_*` out of the hook-subprocess env still receive the configuration.
487
+ *
488
+ * Keep this list in sync with `ORY_ENV_ALIAS` in
489
+ * `packages/core/src/otel/otlp.ts` — the exporter consults the same aliases
490
+ * on the read side.
491
+ */
492
+ const OTEL_FORWARDED_VARS = [
493
+ ["OTEL_EXPORTER_OTLP_ENDPOINT", "ORY_OTLP_ENDPOINT"],
494
+ ["OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", "ORY_OTLP_TRACES_ENDPOINT"],
495
+ ["OTEL_EXPORTER_OTLP_HEADERS", "ORY_OTLP_HEADERS"],
496
+ ["OTEL_EXPORTER_OTLP_TRACES_HEADERS", "ORY_OTLP_TRACES_HEADERS"],
497
+ ["OTEL_EXPORTER_OTLP_PROTOCOL", "ORY_OTLP_PROTOCOL"],
498
+ ["OTEL_EXPORTER_OTLP_TRACES_PROTOCOL", "ORY_OTLP_TRACES_PROTOCOL"],
499
+ ["OTEL_SERVICE_NAME", "ORY_OTLP_SERVICE_NAME"],
500
+ ["OTEL_RESOURCE_ATTRIBUTES", "ORY_OTLP_RESOURCE_ATTRIBUTES"],
501
+ ];
502
+ /**
503
+ * Compose the OTLP env block for the harness child process. The resolved
504
+ * endpoint is always written under both `OTEL_EXPORTER_OTLP_ENDPOINT` and
505
+ * `ORY_OTLP_ENDPOINT`; every other OTel knob inherited from the parent
506
+ * shell (and `OTEL_SERVICE_NAME`, which we default when unset) is mirrored
507
+ * to its `ORY_OTLP_*` alias on the way through.
508
+ */
509
+ function buildOtelEnv(endpoint, harnessName) {
510
+ const out = {};
511
+ const defaults = {
512
+ OTEL_EXPORTER_OTLP_ENDPOINT: endpoint,
513
+ OTEL_SERVICE_NAME: process.env.OTEL_SERVICE_NAME ?? `ory-agent-plugin-${harnessName}`,
514
+ };
515
+ for (const [standardName, aliasName] of OTEL_FORWARDED_VARS) {
516
+ const value = defaults[standardName] ?? process.env[standardName];
517
+ if (!value)
518
+ continue;
519
+ out[standardName] = value;
520
+ out[aliasName] = value;
521
+ }
522
+ return out;
523
+ }
491
524
  /**
492
525
  * Determine the OTLP endpoint for the dev launch:
493
526
  * 1. Honor OTEL_EXPORTER_OTLP_ENDPOINT / OTEL_EXPORTER_OTLP_TRACES_ENDPOINT
494
- * from the parent shell (Honeycomb, custom collector, etc.).
527
+ * (or their ORY_OTLP_* aliases) from the parent shell (Honeycomb,
528
+ * custom collector, etc.).
495
529
  * 2. Otherwise auto-launch a local Jaeger container and use it. If Jaeger
496
530
  * is already reachable (from `local up` or a prior dev launch), reuse
497
531
  * it without spawning another container.
@@ -500,7 +534,9 @@ async function bootstrapLocalOry(localDir) {
500
534
  */
501
535
  async function resolveOtelEndpoint() {
502
536
  const fromEnv = process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ??
503
- process.env.OTEL_EXPORTER_OTLP_ENDPOINT;
537
+ process.env.OTEL_EXPORTER_OTLP_ENDPOINT ??
538
+ process.env.ORY_OTLP_TRACES_ENDPOINT ??
539
+ process.env.ORY_OTLP_ENDPOINT;
504
540
  if (fromEnv)
505
541
  return fromEnv;
506
542
  console.log("[ory-dev] Ensuring Jaeger is running for trace viewing...");
@@ -7,16 +7,22 @@
7
7
  * is converted to a `ReadableSpan` shape and handed to the SDK exporter,
8
8
  * which serializes (JSON or protobuf) and POSTs to an OTLP HTTP endpoint.
9
9
  *
10
- * Standard OTel env vars consumed by `otlpExporterFromEnv()`:
11
- * - OTEL_EXPORTER_OTLP_ENDPOINT base URL (we append /v1/traces)
12
- * - OTEL_EXPORTER_OTLP_TRACES_ENDPOINT full traces URL (overrides base)
13
- * - OTEL_EXPORTER_OTLP_HEADERS `k=v,k=v` pairs
14
- * - OTEL_EXPORTER_OTLP_TRACES_HEADERS traces-specific headers
15
- * - OTEL_EXPORTER_OTLP_PROTOCOL `http/protobuf` (default) or `http/json`
16
- * - OTEL_EXPORTER_OTLP_TRACES_PROTOCOL traces-specific protocol
17
- * - OTEL_SERVICE_NAME service.name resource attribute
18
- * - OTEL_RESOURCE_ATTRIBUTES additional resource attributes
19
- * - ORY_OTLP_ENDPOINT Ory-prefixed alias for the dev launcher
10
+ * Standard OTel env vars consumed by `otlpExporterFromEnv()`. Each one has
11
+ * an `ORY_OTLP_*`-prefixed alias that is consulted as a fallback when the
12
+ * standard name is unset. Some harnesses (notably Claude Code) sanitize the
13
+ * env passed to hook subprocesses and drop every `OTEL_*` var, so the dev
14
+ * launcher mirrors each setting under the Ory prefix to survive the strip.
15
+ *
16
+ * Standard name Ory-prefixed fallback
17
+ * ───────────────────────────────────── ─────────────────────────────────
18
+ * OTEL_EXPORTER_OTLP_ENDPOINT ORY_OTLP_ENDPOINT
19
+ * OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ORY_OTLP_TRACES_ENDPOINT
20
+ * OTEL_EXPORTER_OTLP_HEADERS ORY_OTLP_HEADERS
21
+ * OTEL_EXPORTER_OTLP_TRACES_HEADERS ORY_OTLP_TRACES_HEADERS
22
+ * OTEL_EXPORTER_OTLP_PROTOCOL ORY_OTLP_PROTOCOL
23
+ * OTEL_EXPORTER_OTLP_TRACES_PROTOCOL ORY_OTLP_TRACES_PROTOCOL
24
+ * OTEL_SERVICE_NAME ORY_OTLP_SERVICE_NAME
25
+ * OTEL_RESOURCE_ATTRIBUTES ORY_OTLP_RESOURCE_ATTRIBUTES
20
26
  *
21
27
  * Failures are swallowed (callers receive a resolved Promise) so trace
22
28
  * export can never break the agent session. Transport errors surface
@@ -80,6 +86,12 @@ export declare function otlpExporterFromEnv(opts: {
80
86
  onError?: (err: unknown) => void;
81
87
  env?: NodeJS.ProcessEnv;
82
88
  }): OtlpExporter | undefined;
89
+ /**
90
+ * Read an OTel env var, falling back to its `ORY_OTLP_*`-prefixed alias when
91
+ * the standard name is unset. Trims whitespace and treats empty strings as
92
+ * absent so a propagated-but-blank var doesn't shadow the alias.
93
+ */
94
+ export declare function readEnvWithAlias(env: NodeJS.ProcessEnv, standardName: string): string | undefined;
83
95
  /**
84
96
  * Parse the OTel `k=v,k2=v2` env-var format. Values may be URL-encoded.
85
97
  */
package/dist/otel/otlp.js CHANGED
@@ -8,16 +8,22 @@
8
8
  * is converted to a `ReadableSpan` shape and handed to the SDK exporter,
9
9
  * which serializes (JSON or protobuf) and POSTs to an OTLP HTTP endpoint.
10
10
  *
11
- * Standard OTel env vars consumed by `otlpExporterFromEnv()`:
12
- * - OTEL_EXPORTER_OTLP_ENDPOINT base URL (we append /v1/traces)
13
- * - OTEL_EXPORTER_OTLP_TRACES_ENDPOINT full traces URL (overrides base)
14
- * - OTEL_EXPORTER_OTLP_HEADERS `k=v,k=v` pairs
15
- * - OTEL_EXPORTER_OTLP_TRACES_HEADERS traces-specific headers
16
- * - OTEL_EXPORTER_OTLP_PROTOCOL `http/protobuf` (default) or `http/json`
17
- * - OTEL_EXPORTER_OTLP_TRACES_PROTOCOL traces-specific protocol
18
- * - OTEL_SERVICE_NAME service.name resource attribute
19
- * - OTEL_RESOURCE_ATTRIBUTES additional resource attributes
20
- * - ORY_OTLP_ENDPOINT Ory-prefixed alias for the dev launcher
11
+ * Standard OTel env vars consumed by `otlpExporterFromEnv()`. Each one has
12
+ * an `ORY_OTLP_*`-prefixed alias that is consulted as a fallback when the
13
+ * standard name is unset. Some harnesses (notably Claude Code) sanitize the
14
+ * env passed to hook subprocesses and drop every `OTEL_*` var, so the dev
15
+ * launcher mirrors each setting under the Ory prefix to survive the strip.
16
+ *
17
+ * Standard name Ory-prefixed fallback
18
+ * ───────────────────────────────────── ─────────────────────────────────
19
+ * OTEL_EXPORTER_OTLP_ENDPOINT ORY_OTLP_ENDPOINT
20
+ * OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ORY_OTLP_TRACES_ENDPOINT
21
+ * OTEL_EXPORTER_OTLP_HEADERS ORY_OTLP_HEADERS
22
+ * OTEL_EXPORTER_OTLP_TRACES_HEADERS ORY_OTLP_TRACES_HEADERS
23
+ * OTEL_EXPORTER_OTLP_PROTOCOL ORY_OTLP_PROTOCOL
24
+ * OTEL_EXPORTER_OTLP_TRACES_PROTOCOL ORY_OTLP_TRACES_PROTOCOL
25
+ * OTEL_SERVICE_NAME ORY_OTLP_SERVICE_NAME
26
+ * OTEL_RESOURCE_ATTRIBUTES ORY_OTLP_RESOURCE_ATTRIBUTES
21
27
  *
22
28
  * Failures are swallowed (callers receive a resolved Promise) so trace
23
29
  * export can never break the agent session. Transport errors surface
@@ -26,6 +32,7 @@
26
32
  Object.defineProperty(exports, "__esModule", { value: true });
27
33
  exports.OtlpExporter = void 0;
28
34
  exports.otlpExporterFromEnv = otlpExporterFromEnv;
35
+ exports.readEnvWithAlias = readEnvWithAlias;
29
36
  exports.parseKeyValueList = parseKeyValueList;
30
37
  exports.toReadableSpan = toReadableSpan;
31
38
  const api_1 = require("@opentelemetry/api");
@@ -124,9 +131,10 @@ function otlpExporterFromEnv(opts) {
124
131
  const protocol = resolveProtocol(env, opts.onError);
125
132
  if (!protocol)
126
133
  return undefined;
127
- const headers = mergeHeaders(parseKeyValueList(env.OTEL_EXPORTER_OTLP_HEADERS), parseKeyValueList(env.OTEL_EXPORTER_OTLP_TRACES_HEADERS));
134
+ const headers = mergeHeaders(parseKeyValueList(readEnvWithAlias(env, "OTEL_EXPORTER_OTLP_HEADERS")), parseKeyValueList(readEnvWithAlias(env, "OTEL_EXPORTER_OTLP_TRACES_HEADERS")));
128
135
  const resource = {
129
- "service.name": env.OTEL_SERVICE_NAME ?? `ory-agent-plugin-${opts.harness}`,
136
+ "service.name": readEnvWithAlias(env, "OTEL_SERVICE_NAME") ??
137
+ `ory-agent-plugin-${opts.harness}`,
130
138
  "service.namespace": "ory.agent_plugins",
131
139
  "ory.harness": opts.harness,
132
140
  "process.pid": process.pid,
@@ -145,7 +153,7 @@ function otlpExporterFromEnv(opts) {
145
153
  resource["ory.git.branch"] = opts.gitBranch;
146
154
  if (opts.gitCommit)
147
155
  resource["ory.git.commit"] = opts.gitCommit;
148
- for (const [k, v] of Object.entries(parseKeyValueList(env.OTEL_RESOURCE_ATTRIBUTES))) {
156
+ for (const [k, v] of Object.entries(parseKeyValueList(readEnvWithAlias(env, "OTEL_RESOURCE_ATTRIBUTES")))) {
149
157
  resource[k] = v;
150
158
  }
151
159
  return new OtlpExporter({
@@ -157,22 +165,20 @@ function otlpExporterFromEnv(opts) {
157
165
  });
158
166
  }
159
167
  function resolveEndpoint(env) {
160
- const tracesUrl = env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT?.trim();
168
+ // ORY_OTLP_*-prefixed aliases survive harnesses (e.g. Claude Code) that
169
+ // sanitize the env passed to hook subprocesses and drop OTEL_*-prefixed
170
+ // vars. The standard OTel name still wins when present.
171
+ const tracesUrl = readEnvWithAlias(env, "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT");
161
172
  if (tracesUrl)
162
173
  return tracesUrl;
163
- // ORY_OTLP_ENDPOINT is an Ory-prefixed alias used by the dev launcher.
164
- // Some harnesses (e.g. Claude Code) filter the env they pass to hook
165
- // subprocesses and drop OTEL_*-prefixed vars, but allow ORY_*-prefixed
166
- // ones through. The alias lets the launcher hand the OTLP endpoint to
167
- // the hook process without depending on OTEL_* propagation.
168
- const base = env.OTEL_EXPORTER_OTLP_ENDPOINT?.trim() || env.ORY_OTLP_ENDPOINT?.trim();
174
+ const base = readEnvWithAlias(env, "OTEL_EXPORTER_OTLP_ENDPOINT");
169
175
  if (!base)
170
176
  return undefined;
171
177
  return base.replace(/\/+$/, "") + TRACES_PATH;
172
178
  }
173
179
  function resolveProtocol(env, onError) {
174
- const raw = (env.OTEL_EXPORTER_OTLP_TRACES_PROTOCOL ??
175
- env.OTEL_EXPORTER_OTLP_PROTOCOL ??
180
+ const raw = (readEnvWithAlias(env, "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL") ??
181
+ readEnvWithAlias(env, "OTEL_EXPORTER_OTLP_PROTOCOL") ??
176
182
  "http/protobuf")
177
183
  .trim()
178
184
  .toLowerCase();
@@ -181,6 +187,37 @@ function resolveProtocol(env, onError) {
181
187
  onError?.(new Error(`OTEL_EXPORTER_OTLP_PROTOCOL=${raw} not supported (only http/protobuf and http/json). Skipping OTel export.`));
182
188
  return undefined;
183
189
  }
190
+ /**
191
+ * Standard OTel env var name → Ory-prefixed fallback. Standard wins when set;
192
+ * the alias is consulted only when the standard name is empty/missing. The
193
+ * historical `ORY_OTLP_ENDPOINT` alias for `OTEL_EXPORTER_OTLP_ENDPOINT` is
194
+ * preserved verbatim for compatibility with existing dev-launcher envs.
195
+ */
196
+ const ORY_ENV_ALIAS = {
197
+ OTEL_EXPORTER_OTLP_ENDPOINT: "ORY_OTLP_ENDPOINT",
198
+ OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: "ORY_OTLP_TRACES_ENDPOINT",
199
+ OTEL_EXPORTER_OTLP_HEADERS: "ORY_OTLP_HEADERS",
200
+ OTEL_EXPORTER_OTLP_TRACES_HEADERS: "ORY_OTLP_TRACES_HEADERS",
201
+ OTEL_EXPORTER_OTLP_PROTOCOL: "ORY_OTLP_PROTOCOL",
202
+ OTEL_EXPORTER_OTLP_TRACES_PROTOCOL: "ORY_OTLP_TRACES_PROTOCOL",
203
+ OTEL_SERVICE_NAME: "ORY_OTLP_SERVICE_NAME",
204
+ OTEL_RESOURCE_ATTRIBUTES: "ORY_OTLP_RESOURCE_ATTRIBUTES",
205
+ };
206
+ /**
207
+ * Read an OTel env var, falling back to its `ORY_OTLP_*`-prefixed alias when
208
+ * the standard name is unset. Trims whitespace and treats empty strings as
209
+ * absent so a propagated-but-blank var doesn't shadow the alias.
210
+ */
211
+ function readEnvWithAlias(env, standardName) {
212
+ const primary = env[standardName]?.trim();
213
+ if (primary)
214
+ return primary;
215
+ const aliasName = ORY_ENV_ALIAS[standardName];
216
+ if (!aliasName)
217
+ return undefined;
218
+ const alias = env[aliasName]?.trim();
219
+ return alias || undefined;
220
+ }
184
221
  // ─── Env parsing helpers ───────────────────────────────────────────
185
222
  /**
186
223
  * Parse the OTel `k=v,k2=v2` env-var format. Values may be URL-encoded.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ory/argus",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
4
4
  "description": "Ory Argus: the core API for building authentication, authorization, and audit into AI agent harness plugins, extensions, and custom integrations",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://ory.com",