@ory/claude-agent-sdk 0.10.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 +33 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.js +110 -0
- package/dist/types.d.ts +54 -0
- package/dist/types.js +9 -0
- package/package.json +41 -0
package/README.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# @ory/claude-agent-sdk
|
|
2
|
+
|
|
3
|
+
Ory Agent Security for the [Anthropic Claude Agent SDK](https://docs.claude.com/en/docs/claude-code/sdk).
|
|
4
|
+
|
|
5
|
+
Authorizes every tool call against Ory Permissions, traces invocations, and propagates
|
|
6
|
+
user → agent → sub-agent identity — built on [`@ory/argus`](../core).
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npm install @ory/claude-agent-sdk
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Two interchangeable wiring points:
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
16
|
+
import { createOryHooks, oryCanUseTool } from "@ory/claude-agent-sdk";
|
|
17
|
+
|
|
18
|
+
// (a) hooks: SessionStart (auth gates) + PreToolUse (authorize) + PostToolUse (trace)
|
|
19
|
+
query({ prompt, options: { hooks: createOryHooks() } });
|
|
20
|
+
|
|
21
|
+
// (b) or the permission callback
|
|
22
|
+
query({ prompt, options: { canUseTool: oryCanUseTool() } });
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`createOryHooks` runs the Ory session gates on `SessionStart`, authorizes on `PreToolUse`
|
|
26
|
+
(a deny returns `permissionDecision: "deny"`, blocking the tool), records `tool.complete` on
|
|
27
|
+
`PostToolUse`, and writes an agent→subagent delegation tuple when the `Task` tool spawns a
|
|
28
|
+
typed sub-agent. In **observe** mode (default) denies are logged but tools run; in **enforce**
|
|
29
|
+
mode (`ORY_PERMISSION_MODE=enforce`) they're blocked.
|
|
30
|
+
|
|
31
|
+
This package depends only on `@ory/argus` — the hook and permission types are defined locally
|
|
32
|
+
(no SDK dependency). Credentials come from the shared
|
|
33
|
+
`~/.config/ory-agent-plugins/config.json`. See [docs/sdk-integrations.md](../../docs/sdk-integrations.md).
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ory Agent Security for the Anthropic Claude Agent SDK.
|
|
3
|
+
*
|
|
4
|
+
* Two interchangeable wiring points, both built on the shared `@ory/argus` adapters:
|
|
5
|
+
*
|
|
6
|
+
* - {@link createOryHooks} — a `hooks` config with `SessionStart` (auth gates),
|
|
7
|
+
* `PreToolUse` (authorize; `permissionDecision: "deny"` blocks; `Task` sub-agents get a
|
|
8
|
+
* delegation tuple), and `PostToolUse` (`tool.complete`).
|
|
9
|
+
* - {@link oryCanUseTool} — a `canUseTool` callback returning allow/deny, for callers who
|
|
10
|
+
* prefer the single permission-callback surface.
|
|
11
|
+
*
|
|
12
|
+
* Pass either into the SDK's `query({ options })`. The package has no SDK dependency.
|
|
13
|
+
*/
|
|
14
|
+
import { OryAgentClient } from "@ory/argus";
|
|
15
|
+
import type { CanUseTool, HooksConfig } from "./types.js";
|
|
16
|
+
export interface OryClaudeAgentOptions {
|
|
17
|
+
/** Client to use. Defaults to `OryAgentClient.fromEnv("claude-agent-sdk")`. */
|
|
18
|
+
client?: OryAgentClient;
|
|
19
|
+
/** Override the Ory project URL for the session gates. */
|
|
20
|
+
projectUrl?: string;
|
|
21
|
+
/** Whether a denied tool is hard-blocked. Default true. */
|
|
22
|
+
canBlock?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Build a `hooks` config object for the Claude Agent SDK's `options.hooks`.
|
|
26
|
+
*/
|
|
27
|
+
export declare function createOryHooks(options?: OryClaudeAgentOptions): HooksConfig;
|
|
28
|
+
/**
|
|
29
|
+
* Build a `canUseTool` callback gated through Ory. Returns `{ behavior: "deny" }` when the
|
|
30
|
+
* tool is hard-denied, otherwise `{ behavior: "allow" }`.
|
|
31
|
+
*/
|
|
32
|
+
export declare function oryCanUseTool(options?: OryClaudeAgentOptions): CanUseTool;
|
|
33
|
+
export { OryAgentClient } from "@ory/argus";
|
|
34
|
+
export type { CanUseTool, HooksConfig, HookCallback, PermissionResult, PreToolUseHookInput, PostToolUseHookInput, } from "./types.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Ory Agent Security for the Anthropic Claude Agent SDK.
|
|
4
|
+
*
|
|
5
|
+
* Two interchangeable wiring points, both built on the shared `@ory/argus` adapters:
|
|
6
|
+
*
|
|
7
|
+
* - {@link createOryHooks} — a `hooks` config with `SessionStart` (auth gates),
|
|
8
|
+
* `PreToolUse` (authorize; `permissionDecision: "deny"` blocks; `Task` sub-agents get a
|
|
9
|
+
* delegation tuple), and `PostToolUse` (`tool.complete`).
|
|
10
|
+
* - {@link oryCanUseTool} — a `canUseTool` callback returning allow/deny, for callers who
|
|
11
|
+
* prefer the single permission-callback surface.
|
|
12
|
+
*
|
|
13
|
+
* Pass either into the SDK's `query({ options })`. The package has no SDK dependency.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.OryAgentClient = void 0;
|
|
17
|
+
exports.createOryHooks = createOryHooks;
|
|
18
|
+
exports.oryCanUseTool = oryCanUseTool;
|
|
19
|
+
const argus_1 = require("@ory/argus");
|
|
20
|
+
const HARNESS = "claude-agent-sdk";
|
|
21
|
+
function lazySession(client, projectUrl) {
|
|
22
|
+
let started = false;
|
|
23
|
+
return async () => {
|
|
24
|
+
if (started)
|
|
25
|
+
return;
|
|
26
|
+
started = true;
|
|
27
|
+
try {
|
|
28
|
+
await (0, argus_1.sessionStart)(client, { harness: HARNESS, projectUrl });
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
client.logger.warn("session_start.failed", {
|
|
32
|
+
message: err instanceof Error ? err.message : String(err),
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Build a `hooks` config object for the Claude Agent SDK's `options.hooks`.
|
|
39
|
+
*/
|
|
40
|
+
function createOryHooks(options = {}) {
|
|
41
|
+
const client = options.client ?? argus_1.OryAgentClient.fromEnv(HARNESS);
|
|
42
|
+
const canBlock = options.canBlock ?? true;
|
|
43
|
+
const ensureSession = lazySession(client, options.projectUrl);
|
|
44
|
+
const sessionStartHook = async () => {
|
|
45
|
+
await ensureSession();
|
|
46
|
+
return {};
|
|
47
|
+
};
|
|
48
|
+
const preToolUse = async (raw) => {
|
|
49
|
+
await ensureSession();
|
|
50
|
+
const input = raw;
|
|
51
|
+
const toolName = input.tool_name;
|
|
52
|
+
if ((toolName === "Task" || toolName === "Agent") && typeof input.subagent_type === "string") {
|
|
53
|
+
await (0, argus_1.registerSubagent)(client, {
|
|
54
|
+
harness: HARNESS,
|
|
55
|
+
subAgentType: input.subagent_type,
|
|
56
|
+
projectUrl: options.projectUrl,
|
|
57
|
+
}).catch(() => undefined);
|
|
58
|
+
}
|
|
59
|
+
const result = await (0, argus_1.gate)(client, {
|
|
60
|
+
harness: HARNESS,
|
|
61
|
+
toolName,
|
|
62
|
+
toolArgs: input.tool_input,
|
|
63
|
+
canBlock,
|
|
64
|
+
});
|
|
65
|
+
if (result.kind === "deny" && result.blocked) {
|
|
66
|
+
return {
|
|
67
|
+
hookSpecificOutput: {
|
|
68
|
+
hookEventName: "PreToolUse",
|
|
69
|
+
permissionDecision: "deny",
|
|
70
|
+
permissionDecisionReason: result.denialMessage ?? "Ory: permission denied",
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
return {};
|
|
75
|
+
};
|
|
76
|
+
const postToolUse = async (raw) => {
|
|
77
|
+
const input = raw;
|
|
78
|
+
(0, argus_1.complete)(client, { toolName: input.tool_name, output: input.tool_response });
|
|
79
|
+
return {};
|
|
80
|
+
};
|
|
81
|
+
return {
|
|
82
|
+
SessionStart: [{ hooks: [sessionStartHook] }],
|
|
83
|
+
PreToolUse: [{ hooks: [preToolUse] }],
|
|
84
|
+
PostToolUse: [{ hooks: [postToolUse] }],
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Build a `canUseTool` callback gated through Ory. Returns `{ behavior: "deny" }` when the
|
|
89
|
+
* tool is hard-denied, otherwise `{ behavior: "allow" }`.
|
|
90
|
+
*/
|
|
91
|
+
function oryCanUseTool(options = {}) {
|
|
92
|
+
const client = options.client ?? argus_1.OryAgentClient.fromEnv(HARNESS);
|
|
93
|
+
const canBlock = options.canBlock ?? true;
|
|
94
|
+
const ensureSession = lazySession(client, options.projectUrl);
|
|
95
|
+
return async (toolName, input) => {
|
|
96
|
+
await ensureSession();
|
|
97
|
+
const result = await (0, argus_1.gate)(client, {
|
|
98
|
+
harness: HARNESS,
|
|
99
|
+
toolName,
|
|
100
|
+
toolArgs: input,
|
|
101
|
+
canBlock,
|
|
102
|
+
});
|
|
103
|
+
if (result.kind === "deny" && result.blocked) {
|
|
104
|
+
return { behavior: "deny", message: result.denialMessage ?? "Ory: permission denied" };
|
|
105
|
+
}
|
|
106
|
+
return { behavior: "allow", updatedInput: input };
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
var argus_2 = require("@ory/argus");
|
|
110
|
+
Object.defineProperty(exports, "OryAgentClient", { enumerable: true, get: function () { return argus_2.OryAgentClient; } });
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal Claude Agent SDK hook/permission shapes.
|
|
3
|
+
*
|
|
4
|
+
* Defined here (not imported from `@anthropic-ai/claude-agent-sdk`) so the package has no
|
|
5
|
+
* SDK dependency — same policy as the harness plugins. These mirror the documented
|
|
6
|
+
* `hooks` + `canUseTool` contracts closely enough to wire the gate.
|
|
7
|
+
*/
|
|
8
|
+
export interface PreToolUseHookInput {
|
|
9
|
+
hook_event_name?: "PreToolUse";
|
|
10
|
+
tool_name: string;
|
|
11
|
+
tool_input?: unknown;
|
|
12
|
+
/** Present on the `Task` sub-agent tool. */
|
|
13
|
+
subagent_type?: string;
|
|
14
|
+
session_id?: string;
|
|
15
|
+
[key: string]: unknown;
|
|
16
|
+
}
|
|
17
|
+
export interface PostToolUseHookInput {
|
|
18
|
+
hook_event_name?: "PostToolUse";
|
|
19
|
+
tool_name: string;
|
|
20
|
+
tool_input?: unknown;
|
|
21
|
+
tool_response?: unknown;
|
|
22
|
+
[key: string]: unknown;
|
|
23
|
+
}
|
|
24
|
+
export interface HookJSONOutput {
|
|
25
|
+
decision?: "block";
|
|
26
|
+
reason?: string;
|
|
27
|
+
hookSpecificOutput?: {
|
|
28
|
+
hookEventName?: string;
|
|
29
|
+
permissionDecision?: "allow" | "deny" | "ask";
|
|
30
|
+
permissionDecisionReason?: string;
|
|
31
|
+
[key: string]: unknown;
|
|
32
|
+
};
|
|
33
|
+
[key: string]: unknown;
|
|
34
|
+
}
|
|
35
|
+
export type HookCallback = (input: Record<string, unknown>, toolUseId: string | undefined, context: {
|
|
36
|
+
signal?: AbortSignal;
|
|
37
|
+
}) => Promise<HookJSONOutput> | HookJSONOutput;
|
|
38
|
+
export interface HookMatcher {
|
|
39
|
+
matcher?: string;
|
|
40
|
+
hooks: HookCallback[];
|
|
41
|
+
}
|
|
42
|
+
export type HooksConfig = Record<string, HookMatcher[]>;
|
|
43
|
+
/** `canUseTool` permission-callback result. */
|
|
44
|
+
export type PermissionResult = {
|
|
45
|
+
behavior: "allow";
|
|
46
|
+
updatedInput?: unknown;
|
|
47
|
+
} | {
|
|
48
|
+
behavior: "deny";
|
|
49
|
+
message: string;
|
|
50
|
+
};
|
|
51
|
+
export type CanUseTool = (toolName: string, input: Record<string, unknown>, context: {
|
|
52
|
+
signal?: AbortSignal;
|
|
53
|
+
suggestions?: unknown;
|
|
54
|
+
}) => Promise<PermissionResult>;
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Minimal Claude Agent SDK hook/permission shapes.
|
|
4
|
+
*
|
|
5
|
+
* Defined here (not imported from `@anthropic-ai/claude-agent-sdk`) so the package has no
|
|
6
|
+
* SDK dependency — same policy as the harness plugins. These mirror the documented
|
|
7
|
+
* `hooks` + `canUseTool` contracts closely enough to wire the gate.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ory/claude-agent-sdk",
|
|
3
|
+
"version": "0.10.0",
|
|
4
|
+
"description": "Ory Agent Security for the Anthropic Claude Agent SDK — per-tool authorization, tracing, and identity propagation via PreToolUse hooks and canUseTool. Built on @ory/argus.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"!dist/**/*.tsbuildinfo"
|
|
17
|
+
],
|
|
18
|
+
"keywords": [
|
|
19
|
+
"ory",
|
|
20
|
+
"anthropic",
|
|
21
|
+
"claude",
|
|
22
|
+
"agent-sdk",
|
|
23
|
+
"authorization",
|
|
24
|
+
"agent",
|
|
25
|
+
"ai"
|
|
26
|
+
],
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@ory/argus": "0.10.0"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"typescript": "^6.0.2",
|
|
32
|
+
"vitest": "4.1.4"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "tsc",
|
|
36
|
+
"clean": "rm -rf dist *.tsbuildinfo",
|
|
37
|
+
"test": "vitest run",
|
|
38
|
+
"test:watch": "vitest",
|
|
39
|
+
"typecheck": "tsc --noEmit"
|
|
40
|
+
}
|
|
41
|
+
}
|