@alfe.ai/openclaw-identity 0.1.26 → 0.1.28

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 ADDED
@@ -0,0 +1,14 @@
1
+ # `@alfe.ai/openclaw-identity`
2
+
3
+ OpenClaw plugin for Alfe identity resolution, self-service verification, and
4
+ role-based `agent:exec` tool gating.
5
+
6
+ The plugin registers identity tools, prepares a short-lived sender context from
7
+ inbound messages, and evaluates tool calls with `@auriclabs/roles`. The
8
+ `OPENCLAW_TOOL_GATING` environment variable accepts `fail-open` or
9
+ `fail-closed`; it intentionally defaults to `fail-open` while the staged
10
+ permission rollout is incomplete.
11
+
12
+ This package is installed by the core Alfe integration. For platform setup and
13
+ documentation, visit [alfe.ai](https://alfe.ai) and
14
+ [docs.alfe.ai](https://docs.alfe.ai).
package/dist/index.cjs CHANGED
@@ -7,7 +7,7 @@ const require_plugin = require("./plugin2.cjs");
7
7
  /**
8
8
  * Build the gate context object used by sift evaluation. This is the
9
9
  * round-6 "strict namespacing" shape — `args` is a top-level field, not
10
- * spread, so an attacker-controlled `tool` field inside `toolArgs` cannot
10
+ * spread, so an attacker-controlled `tool` field inside `params` cannot
11
11
  * override the gate's `tool` value.
12
12
  *
13
13
  * Stage E's gate calls:
@@ -19,7 +19,7 @@ const require_plugin = require("./plugin2.cjs");
19
19
  function buildGateContext(event) {
20
20
  return {
21
21
  tool: event.toolName,
22
- args: event.toolArgs
22
+ args: event.params
23
23
  };
24
24
  }
25
25
  //#endregion
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import plugin from "./plugin.cjs";
1
+ import { t as plugin } from "./plugin.cjs";
2
2
 
3
3
  //#region src/runtime-contract.d.ts
4
4
 
@@ -11,18 +11,19 @@ import plugin from "./plugin.cjs";
11
11
  * permit/deny decision via `@auriclabs/roles`.
12
12
  *
13
13
  * Contract:
14
- * - `ToolCallEvent` describes the tool being called (name + args).
15
- * - `ToolCallContext` describes the calling context (tenant, agent, actor).
14
+ * - `ToolCallEvent` describes the tool being called (name + params).
15
+ * - `ToolCallContext` mirrors the fields OpenClaw actually supplies.
16
16
  *
17
- * The hook receives `(event, ctx)`. Both arguments are required. The daemon
18
- * is responsible for populating every required field; the plugin's gate
19
- * applies the per-agent `IdentityFailureMode` when an optional field is
20
- * absent and a permission decision can't be made cleanly.
17
+ * The hook receives `(event, ctx)`. OpenClaw currently supplies tool identity,
18
+ * run/session identity, and an optional agent id. It does not supply tenant,
19
+ * conversation, actor, auth-method, or token-permission fields. The plugin
20
+ * bridges the active conversation from `message_received` into the run instead
21
+ * of pretending those absent fields are runtime guarantees.
21
22
  *
22
23
  * Round 6 note (gate context shape): the gate context passed to `sift` is
23
- * `{ tool: event.toolName, args: event.toolArgs }` with strict namespacing
24
+ * `{ tool: event.toolName, args: event.params }` with strict namespacing
24
25
  * (no spread). This prevents an attacker-controlled `tool` field inside
25
- * `toolArgs` from overriding the gate's value.
26
+ * `params` from overriding the gate's value.
26
27
  */
27
28
  /**
28
29
  * Per-agent fallback policy when an optional `ctx.actingIdentityId` is
@@ -47,7 +48,11 @@ interface ToolCallEvent {
47
48
  /** Namespaced tool name, e.g. "gmail:send_email". */
48
49
  readonly toolName: string;
49
50
  /** Arbitrary argument bag passed to the tool's `execute` function. */
50
- readonly toolArgs: Record<string, unknown>;
51
+ readonly params: Record<string, unknown>;
52
+ /** Stable run identifier for this invocation, when supplied. */
53
+ readonly runId?: string;
54
+ /** Provider-specific tool-call identifier, when supplied. */
55
+ readonly toolCallId?: string;
51
56
  }
52
57
  /**
53
58
  * What initiated the tool call. Three buckets:
@@ -97,18 +102,24 @@ interface RuntimePermission {
97
102
  readonly type?: "can" | "cannot";
98
103
  }
99
104
  /**
100
- * Calling context for the tool call. Populated by the OpenClaw daemon at
101
- * dispatch time.
105
+ * Calling context for the tool call. This is the production OpenClaw hook
106
+ * shape (verified against the installed runtime), not an aspirational Alfe
107
+ * authorization envelope.
102
108
  */
103
109
  interface ToolCallContext {
104
- /** Required: the tenant (`org_*`) that owns the agent. */
105
- readonly tenantId: string;
106
- /** Required: the agent (`agt_*`) that is about to call the tool. */
107
- readonly agentId: string;
108
- /** Required: how the caller authenticated. */
109
- readonly authMethod: ToolCallAuthMethod;
110
- /** Required: what initiated the call. */
111
- readonly trigger: ToolCallTrigger;
110
+ readonly toolName: string;
111
+ readonly agentId?: string;
112
+ readonly sessionKey?: string;
113
+ readonly sessionId?: string;
114
+ readonly runId?: string;
115
+ readonly toolCallId?: string;
116
+ /**
117
+ * Compatibility fields for an Alfe-augmented runtime. Stock OpenClaw does
118
+ * not currently populate these; callers must not depend on their presence.
119
+ */
120
+ readonly tenantId?: string;
121
+ readonly authMethod?: ToolCallAuthMethod;
122
+ readonly trigger?: ToolCallTrigger;
112
123
  /**
113
124
  * The identity (`idn_*`) the agent is acting on behalf of. Resolution
114
125
  * order:
@@ -136,25 +147,26 @@ interface ToolCallContext {
136
147
  readonly channelId?: string;
137
148
  }
138
149
  /**
139
- * Return value of the `before_tool_call` hook.
140
- * - `undefined` — allow.
141
- * - `{ block: true, blockReason: string }` — deny with reason surfaced to
142
- * the agent's response (Stage E behaviour).
150
+ * Relevant subset of OpenClaw's `before_tool_call` return value.
151
+ * - `undefined` — allow without changing parameters.
152
+ * - `{ params }` — allow with parameters merged into the tool invocation.
153
+ * - `{ block: true, blockReason }` — deny with a surfaced reason.
143
154
  */
144
155
  type ToolCallHookResult = undefined | {
156
+ params: Record<string, unknown>;
157
+ } | {
145
158
  block: true;
146
159
  blockReason: string;
147
160
  };
148
161
  /**
149
- * Strongly-typed `before_tool_call` hook signature. The plugin's stub uses
150
- * this signature today; Stage E swaps the stub for the real `agent:exec` +
151
- * sift gate against `@auriclabs/roles`.
162
+ * Strongly-typed `before_tool_call` hook signature used by the live
163
+ * `agent:exec` + sift gate against `@auriclabs/roles`.
152
164
  */
153
165
  type BeforeToolCallHook = (event: ToolCallEvent, ctx: ToolCallContext) => Promise<ToolCallHookResult>;
154
166
  /**
155
167
  * Build the gate context object used by sift evaluation. This is the
156
168
  * round-6 "strict namespacing" shape — `args` is a top-level field, not
157
- * spread, so an attacker-controlled `tool` field inside `toolArgs` cannot
169
+ * spread, so an attacker-controlled `tool` field inside `params` cannot
158
170
  * override the gate's `tool` value.
159
171
  *
160
172
  * Stage E's gate calls:
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import plugin from "./plugin.js";
1
+ import { t as plugin } from "./plugin.js";
2
2
 
3
3
  //#region src/runtime-contract.d.ts
4
4
 
@@ -11,18 +11,19 @@ import plugin from "./plugin.js";
11
11
  * permit/deny decision via `@auriclabs/roles`.
12
12
  *
13
13
  * Contract:
14
- * - `ToolCallEvent` describes the tool being called (name + args).
15
- * - `ToolCallContext` describes the calling context (tenant, agent, actor).
14
+ * - `ToolCallEvent` describes the tool being called (name + params).
15
+ * - `ToolCallContext` mirrors the fields OpenClaw actually supplies.
16
16
  *
17
- * The hook receives `(event, ctx)`. Both arguments are required. The daemon
18
- * is responsible for populating every required field; the plugin's gate
19
- * applies the per-agent `IdentityFailureMode` when an optional field is
20
- * absent and a permission decision can't be made cleanly.
17
+ * The hook receives `(event, ctx)`. OpenClaw currently supplies tool identity,
18
+ * run/session identity, and an optional agent id. It does not supply tenant,
19
+ * conversation, actor, auth-method, or token-permission fields. The plugin
20
+ * bridges the active conversation from `message_received` into the run instead
21
+ * of pretending those absent fields are runtime guarantees.
21
22
  *
22
23
  * Round 6 note (gate context shape): the gate context passed to `sift` is
23
- * `{ tool: event.toolName, args: event.toolArgs }` with strict namespacing
24
+ * `{ tool: event.toolName, args: event.params }` with strict namespacing
24
25
  * (no spread). This prevents an attacker-controlled `tool` field inside
25
- * `toolArgs` from overriding the gate's value.
26
+ * `params` from overriding the gate's value.
26
27
  */
27
28
  /**
28
29
  * Per-agent fallback policy when an optional `ctx.actingIdentityId` is
@@ -47,7 +48,11 @@ interface ToolCallEvent {
47
48
  /** Namespaced tool name, e.g. "gmail:send_email". */
48
49
  readonly toolName: string;
49
50
  /** Arbitrary argument bag passed to the tool's `execute` function. */
50
- readonly toolArgs: Record<string, unknown>;
51
+ readonly params: Record<string, unknown>;
52
+ /** Stable run identifier for this invocation, when supplied. */
53
+ readonly runId?: string;
54
+ /** Provider-specific tool-call identifier, when supplied. */
55
+ readonly toolCallId?: string;
51
56
  }
52
57
  /**
53
58
  * What initiated the tool call. Three buckets:
@@ -97,18 +102,24 @@ interface RuntimePermission {
97
102
  readonly type?: "can" | "cannot";
98
103
  }
99
104
  /**
100
- * Calling context for the tool call. Populated by the OpenClaw daemon at
101
- * dispatch time.
105
+ * Calling context for the tool call. This is the production OpenClaw hook
106
+ * shape (verified against the installed runtime), not an aspirational Alfe
107
+ * authorization envelope.
102
108
  */
103
109
  interface ToolCallContext {
104
- /** Required: the tenant (`org_*`) that owns the agent. */
105
- readonly tenantId: string;
106
- /** Required: the agent (`agt_*`) that is about to call the tool. */
107
- readonly agentId: string;
108
- /** Required: how the caller authenticated. */
109
- readonly authMethod: ToolCallAuthMethod;
110
- /** Required: what initiated the call. */
111
- readonly trigger: ToolCallTrigger;
110
+ readonly toolName: string;
111
+ readonly agentId?: string;
112
+ readonly sessionKey?: string;
113
+ readonly sessionId?: string;
114
+ readonly runId?: string;
115
+ readonly toolCallId?: string;
116
+ /**
117
+ * Compatibility fields for an Alfe-augmented runtime. Stock OpenClaw does
118
+ * not currently populate these; callers must not depend on their presence.
119
+ */
120
+ readonly tenantId?: string;
121
+ readonly authMethod?: ToolCallAuthMethod;
122
+ readonly trigger?: ToolCallTrigger;
112
123
  /**
113
124
  * The identity (`idn_*`) the agent is acting on behalf of. Resolution
114
125
  * order:
@@ -136,25 +147,26 @@ interface ToolCallContext {
136
147
  readonly channelId?: string;
137
148
  }
138
149
  /**
139
- * Return value of the `before_tool_call` hook.
140
- * - `undefined` — allow.
141
- * - `{ block: true, blockReason: string }` — deny with reason surfaced to
142
- * the agent's response (Stage E behaviour).
150
+ * Relevant subset of OpenClaw's `before_tool_call` return value.
151
+ * - `undefined` — allow without changing parameters.
152
+ * - `{ params }` — allow with parameters merged into the tool invocation.
153
+ * - `{ block: true, blockReason }` — deny with a surfaced reason.
143
154
  */
144
155
  type ToolCallHookResult = undefined | {
156
+ params: Record<string, unknown>;
157
+ } | {
145
158
  block: true;
146
159
  blockReason: string;
147
160
  };
148
161
  /**
149
- * Strongly-typed `before_tool_call` hook signature. The plugin's stub uses
150
- * this signature today; Stage E swaps the stub for the real `agent:exec` +
151
- * sift gate against `@auriclabs/roles`.
162
+ * Strongly-typed `before_tool_call` hook signature used by the live
163
+ * `agent:exec` + sift gate against `@auriclabs/roles`.
152
164
  */
153
165
  type BeforeToolCallHook = (event: ToolCallEvent, ctx: ToolCallContext) => Promise<ToolCallHookResult>;
154
166
  /**
155
167
  * Build the gate context object used by sift evaluation. This is the
156
168
  * round-6 "strict namespacing" shape — `args` is a top-level field, not
157
- * spread, so an attacker-controlled `tool` field inside `toolArgs` cannot
169
+ * spread, so an attacker-controlled `tool` field inside `params` cannot
158
170
  * override the gate's `tool` value.
159
171
  *
160
172
  * Stage E's gate calls:
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import { t as plugin } from "./plugin2.js";
3
3
  /**
4
4
  * Build the gate context object used by sift evaluation. This is the
5
5
  * round-6 "strict namespacing" shape — `args` is a top-level field, not
6
- * spread, so an attacker-controlled `tool` field inside `toolArgs` cannot
6
+ * spread, so an attacker-controlled `tool` field inside `params` cannot
7
7
  * override the gate's `tool` value.
8
8
  *
9
9
  * Stage E's gate calls:
@@ -15,7 +15,7 @@ import { t as plugin } from "./plugin2.js";
15
15
  function buildGateContext(event) {
16
16
  return {
17
17
  tool: event.toolName,
18
- args: event.toolArgs
18
+ args: event.params
19
19
  };
20
20
  }
21
21
  //#endregion
package/dist/plugin.cjs CHANGED
@@ -1,2 +1,6 @@
1
+ Object.defineProperties(exports, {
2
+ __esModule: { value: true },
3
+ [Symbol.toStringTag]: { value: "Module" }
4
+ });
1
5
  const require_plugin = require("./plugin2.cjs");
2
- module.exports = require_plugin.plugin;
6
+ exports.default = require_plugin.plugin;
package/dist/plugin.d.cts CHANGED
@@ -1,5 +1,28 @@
1
1
  import { TSchema } from "@sinclair/typebox";
2
2
 
3
+ //#region ../openclaw-plugin-kit/dist/index.d.ts
4
+
5
+ //# sourceMappingURL=types.d.ts.map
6
+ //#endregion
7
+ //#region src/tools.d.ts
8
+ /** Shape returned to OpenClaw from a tool `execute`. */
9
+ interface ToolResult {
10
+ content: {
11
+ type: "text";
12
+ text: string;
13
+ }[];
14
+ details: unknown;
15
+ isError?: boolean;
16
+ }
17
+ interface ToolDef<TParameters = unknown> {
18
+ name: string;
19
+ description: string;
20
+ label: string;
21
+ parameters: TParameters;
22
+ execute: (toolCallId: string, params: Record<string, unknown>) => Promise<ToolResult>;
23
+ }
24
+ /** Deliberately model-safe validation/usage failure. Other exceptions stay private. */
25
+ //#endregion
3
26
  //#region src/plugin.d.ts
4
27
 
5
28
  interface PluginLogger {
@@ -8,23 +31,10 @@ interface PluginLogger {
8
31
  error: (...args: unknown[]) => void;
9
32
  debug: (...args: unknown[]) => void;
10
33
  }
11
- interface ToolDef {
12
- name: string;
13
- description: string;
14
- label: string;
15
- parameters: TSchema;
16
- execute: (toolCallId: string, params: Record<string, unknown>) => Promise<{
17
- content: {
18
- type: "text";
19
- text: string;
20
- }[];
21
- details: unknown;
22
- }>;
23
- }
24
34
  interface PluginApi {
25
35
  logger: PluginLogger;
26
36
  registrationMode?: "full" | "setup-only" | "setup-runtime" | "cli-metadata";
27
- registerTool: (tool: ToolDef) => void;
37
+ registerTool: (tool: ToolDef<TSchema>) => void;
28
38
  on: (event: string, handler: (...args: unknown[]) => Promise<unknown>, options?: {
29
39
  priority?: number;
30
40
  }) => void;
@@ -38,4 +48,4 @@ declare const plugin: {
38
48
  deactivate(api: PluginApi): void;
39
49
  };
40
50
  //#endregion
41
- export { plugin as default };
51
+ export { plugin as t };
package/dist/plugin.d.ts CHANGED
@@ -1,5 +1,28 @@
1
1
  import { TSchema } from "@sinclair/typebox";
2
2
 
3
+ //#region ../openclaw-plugin-kit/dist/index.d.ts
4
+
5
+ //# sourceMappingURL=types.d.ts.map
6
+ //#endregion
7
+ //#region src/tools.d.ts
8
+ /** Shape returned to OpenClaw from a tool `execute`. */
9
+ interface ToolResult {
10
+ content: {
11
+ type: "text";
12
+ text: string;
13
+ }[];
14
+ details: unknown;
15
+ isError?: boolean;
16
+ }
17
+ interface ToolDef<TParameters = unknown> {
18
+ name: string;
19
+ description: string;
20
+ label: string;
21
+ parameters: TParameters;
22
+ execute: (toolCallId: string, params: Record<string, unknown>) => Promise<ToolResult>;
23
+ }
24
+ /** Deliberately model-safe validation/usage failure. Other exceptions stay private. */
25
+ //#endregion
3
26
  //#region src/plugin.d.ts
4
27
 
5
28
  interface PluginLogger {
@@ -8,23 +31,10 @@ interface PluginLogger {
8
31
  error: (...args: unknown[]) => void;
9
32
  debug: (...args: unknown[]) => void;
10
33
  }
11
- interface ToolDef {
12
- name: string;
13
- description: string;
14
- label: string;
15
- parameters: TSchema;
16
- execute: (toolCallId: string, params: Record<string, unknown>) => Promise<{
17
- content: {
18
- type: "text";
19
- text: string;
20
- }[];
21
- details: unknown;
22
- }>;
23
- }
24
34
  interface PluginApi {
25
35
  logger: PluginLogger;
26
36
  registrationMode?: "full" | "setup-only" | "setup-runtime" | "cli-metadata";
27
- registerTool: (tool: ToolDef) => void;
37
+ registerTool: (tool: ToolDef<TSchema>) => void;
28
38
  on: (event: string, handler: (...args: unknown[]) => Promise<unknown>, options?: {
29
39
  priority?: number;
30
40
  }) => void;
@@ -38,4 +48,4 @@ declare const plugin: {
38
48
  deactivate(api: PluginApi): void;
39
49
  };
40
50
  //#endregion
41
- export { plugin as default };
51
+ export { plugin as t };