@ory/openclaw 0.9.1 → 0.11.0

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/README.md CHANGED
@@ -106,7 +106,7 @@ ory-temporal-up # start a local Temporal dev server (for ory-temporal-worker)
106
106
 
107
107
  Or via the CLI: `npx -y -p @ory/openclaw ory-openclaw local up | down`.
108
108
 
109
- `ory-local-up` runs a complete Ory on your laptop: the Ory APIs (Identities, OAuth2, Permissions) at `http://localhost:4000`, a login UI on `:3000`, and Jaeger (the trace viewer) on `:16686`. A test user identity is seeded and its credentials are printed for you. Use it to:
109
+ `ory-local-up` runs a complete Ory on your laptop: the Ory APIs (Identities, OAuth2, Permissions) at `http://localhost:4000`, a login UI on `:4455` (not :3000, to avoid Next.js port conflicts), and Jaeger (the trace viewer) on `:16686`. A test user identity is seeded and its credentials are printed for you. Use it to:
110
110
 
111
111
  - **Learn Ory hands-on** without signing up for a hosted project.
112
112
  - **Prototype** flows (login, social, MFA, recovery, permissions) against a real Ory backend.
@@ -254,7 +254,7 @@ Highlights:
254
254
 
255
255
  ## Troubleshooting
256
256
 
257
- - **`ory-local-up` fails.** Make sure Docker is running and ports `3000`, `4000`, `4100`, and `16686` are free.
257
+ - **`ory-local-up` fails.** Make sure Docker is running and ports `4455` (login UI), `4000`, `4100`, and `16686` are free.
258
258
  - **PKCE login loops.** Clear persisted state with `npx -y -p @ory/openclaw ory-openclaw agent unregister` and retry.
259
259
  - **`npx` fetches an old version.** Force a fresh fetch: `npx -y -p @ory/openclaw@latest ory-openclaw …`.
260
260
  - **Need more signal.** Set `ORY_AGENT_DEBUG=true` and `ORY_AGENT_LOG_FILE=/tmp/ory.log` to capture structured logs.
package/dist/plugin.js CHANGED
@@ -67,6 +67,12 @@ function createSessionStartHandler(client, deps) {
67
67
  // attaches the agent's bearer token to outgoing Ory API calls.
68
68
  const agentGate = deps.agentGate ?? argus_1.ensureAgentIdentity;
69
69
  await agentGate(client, { projectUrl: (0, argus_1.resolveConfig)().projectUrl, harness: "openclaw" });
70
+ // Record the user→agent delegation so the audit trail captures that
71
+ // this user authorized this agent for this session. Best-effort:
72
+ // requires both principals to be populated, and any failure is logged
73
+ // and swallowed (fail-open — delegation tracking is for audit, not
74
+ // enforcement).
75
+ await recordUserDelegatesAgent(client);
70
76
  if (decision.mode !== "disabled") {
71
77
  return;
72
78
  }
@@ -508,6 +514,40 @@ function createSubagentEndedHandler(client) {
508
514
  function resolveNamespace() {
509
515
  return process.env.ORY_PERMISSION_NAMESPACE ?? "AgentTools";
510
516
  }
517
+ /**
518
+ * Write the user→agent delegation tuple. Idempotent and fail-open:
519
+ * requires both principal subjects to be populated; any error (including
520
+ * an unconfigured projectUrl, which manifests as a network_error) is
521
+ * logged and swallowed. Purely audit-trail data — does not affect
522
+ * enforcement.
523
+ */
524
+ async function recordUserDelegatesAgent(client) {
525
+ const user = client.userPrincipal.subject;
526
+ const agent = client.agentPrincipal.subject;
527
+ if (!user || !agent) {
528
+ client.logger.debug("delegation.skip", {
529
+ reason: "missing principal",
530
+ hasUser: !!user,
531
+ hasAgent: !!agent,
532
+ });
533
+ return;
534
+ }
535
+ try {
536
+ await client.createRelationship({
537
+ namespace: resolveNamespace(),
538
+ object: `agent:${agent}`,
539
+ relation: "delegate",
540
+ subjectId: `user:${user}`,
541
+ }, { spanAttributes: { delegation: "user-to-agent" } });
542
+ }
543
+ catch (err) {
544
+ const oryErr = err;
545
+ client.logger.warn("delegation.user_to_agent.failed", {
546
+ code: oryErr.code,
547
+ message: oryErr.message,
548
+ });
549
+ }
550
+ }
511
551
  function isOryError(err) {
512
552
  return (typeof err === "object" &&
513
553
  err !== null &&
@@ -522,9 +562,6 @@ function handlePermissionError(err, toolId, client) {
522
562
  code: err.code,
523
563
  message: "Failing open",
524
564
  });
525
- client.tracer.record("tool.invoke", "ok", {
526
- attributes: { toolName: toolId, failOpen: true, reason: err.code },
527
- });
528
565
  return;
529
566
  }
530
567
  client.logger.error("permission.check.error", {
@@ -539,8 +576,7 @@ function handlePermissionError(err, toolId, client) {
539
576
  error: err instanceof Error ? err.message : String(err),
540
577
  });
541
578
  }
542
- // Record fail-open trace for unknown errors too
543
- client.tracer.record("tool.invoke", "ok", {
544
- attributes: { toolName: toolId, failOpen: true },
545
- });
579
+ // Fail-open is log-and-allow: no tool.invoke span, matching the core
580
+ // gate() vocabulary. The errored permission.check span carries the audit
581
+ // trail for the failed check itself.
546
582
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ory/openclaw",
3
- "version": "0.9.1",
3
+ "version": "0.11.0",
4
4
  "description": "Ory plugin for OpenClaw: scaffolding skills, a local Ory instance, and authentication, authorization, and audit for every tool call",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://ory.com",
@@ -65,7 +65,7 @@
65
65
  "!dist/**/*.tsbuildinfo"
66
66
  ],
67
67
  "dependencies": {
68
- "@ory/argus": "0.9.1"
68
+ "@ory/argus": "0.11.0"
69
69
  },
70
70
  "engines": {
71
71
  "node": ">=22"