@oxdeai/sdk 1.3.1 → 2.0.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/CHANGELOG.md +101 -0
- package/LICENSE +213 -0
- package/README.md +68 -8
- package/dist/adapters.js +1 -0
- package/dist/adapters.js.map +1 -1
- package/dist/builders.js.map +1 -1
- package/dist/client.d.ts +29 -2
- package/dist/client.js +44 -4
- package/dist/client.js.map +1 -1
- package/dist/guard.d.ts +18 -4
- package/dist/guard.js +26 -4
- package/dist/guard.js.map +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +2 -2
- package/package.json +22 -4
- package/dist/guard.test.d.ts +0 -1
- package/dist/guard.test.js +0 -139
- package/dist/guard.test.js.map +0 -1
- package/dist/sdk.test.d.ts +0 -1
- package/dist/sdk.test.js +0 -71
- package/dist/sdk.test.js.map +0 -1
- package/src/adapters.ts +0 -109
- package/src/builders.ts +0 -80
- package/src/client.ts +0 -106
- package/src/guard.test.ts +0 -165
- package/src/guard.ts +0 -138
- package/src/index.ts +0 -7
- package/src/sdk.test.ts +0 -83
- package/src/types.ts +0 -70
- package/tsconfig.json +0 -9
package/dist/guard.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { Intent, PolicyEngine, State,
|
|
1
|
+
import type { Intent, PolicyEngine, State, AuthorizationV1 } from "@oxdeai/core";
|
|
2
2
|
import type { AuditAdapter, ClockAdapter, MaybePromise, StateAdapter, IntentBuilderInput } from "./types.js";
|
|
3
3
|
export type GuardDecision = {
|
|
4
4
|
decision: "ALLOW";
|
|
5
5
|
reasons: [];
|
|
6
|
-
authorization:
|
|
6
|
+
authorization: AuthorizationV1;
|
|
7
7
|
} | {
|
|
8
8
|
decision: "DENY";
|
|
9
9
|
reasons: string[];
|
|
@@ -12,7 +12,7 @@ export type GuardAllowResult<T> = {
|
|
|
12
12
|
output: GuardDecision & {
|
|
13
13
|
decision: "ALLOW";
|
|
14
14
|
reasons: [];
|
|
15
|
-
authorization:
|
|
15
|
+
authorization: AuthorizationV1;
|
|
16
16
|
};
|
|
17
17
|
intent: Intent;
|
|
18
18
|
state: State;
|
|
@@ -38,13 +38,27 @@ export type GuardOptions = {
|
|
|
38
38
|
auditAdapter?: AuditAdapter;
|
|
39
39
|
clock?: ClockAdapter;
|
|
40
40
|
mode?: "fail-fast" | "collect-all";
|
|
41
|
+
/**
|
|
42
|
+
* Engine-level HMAC binding check between the issued intent and authorization.
|
|
43
|
+
* This is the PDP's own internal consistency check — distinct from PEP-side
|
|
44
|
+
* cryptographic signature verification via `verifyAuthorization` from @oxdeai/core.
|
|
45
|
+
* Defaults to true. Set to false only in test scenarios.
|
|
46
|
+
*/
|
|
41
47
|
verifyAuthorization?: boolean;
|
|
42
48
|
};
|
|
43
49
|
type GuardExecuteContext = {
|
|
44
50
|
intent: Intent;
|
|
45
|
-
authorization:
|
|
51
|
+
authorization: AuthorizationV1;
|
|
46
52
|
state: State;
|
|
47
53
|
};
|
|
48
54
|
export type GuardFn = <T>(input: GuardInputIntent, execute: (ctx: GuardExecuteContext) => MaybePromise<T>) => Promise<GuardResult<T>>;
|
|
55
|
+
/**
|
|
56
|
+
* Creates a guard that evaluates intents against policy and executes the callback
|
|
57
|
+
* only when the decision is ALLOW (PDP + inline PEP path).
|
|
58
|
+
*
|
|
59
|
+
* This is the issuing side of the authorization boundary: it evaluates policy and
|
|
60
|
+
* produces authorizations. For relying-party (PEP) verification of artifacts issued
|
|
61
|
+
* by an external party, use `createVerifier` with explicit `trustedKeySets` instead.
|
|
62
|
+
*/
|
|
49
63
|
export declare function createGuard(opts: GuardOptions): GuardFn;
|
|
50
64
|
export {};
|
package/dist/guard.js
CHANGED
|
@@ -9,21 +9,38 @@ function isIntent(value) {
|
|
|
9
9
|
typeof value.action_type === "string" &&
|
|
10
10
|
typeof value.signature === "string");
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Creates a guard that evaluates intents against policy and executes the callback
|
|
14
|
+
* only when the decision is ALLOW (PDP + inline PEP path).
|
|
15
|
+
*
|
|
16
|
+
* This is the issuing side of the authorization boundary: it evaluates policy and
|
|
17
|
+
* produces authorizations. For relying-party (PEP) verification of artifacts issued
|
|
18
|
+
* by an external party, use `createVerifier` with explicit `trustedKeySets` instead.
|
|
19
|
+
*/
|
|
12
20
|
export function createGuard(opts) {
|
|
13
21
|
const clock = opts.clock ?? { now: () => Math.floor(Date.now() / 1000) };
|
|
14
22
|
let auditCursor = 0;
|
|
15
23
|
return async function guard(input, execute) {
|
|
16
24
|
const state = await opts.stateAdapter.load();
|
|
25
|
+
// Single clock sample, reused for both the timestamp fallback below and
|
|
26
|
+
// evaluationTime — the trusted-time freshness gate requires evaluationTime
|
|
27
|
+
// to be sampled exactly once per evaluation (spec §2.1), and clock is the
|
|
28
|
+
// same trusted-context boundary already responsible for the timestamp
|
|
29
|
+
// fallback. Never derived from intent.timestamp itself (which may be
|
|
30
|
+
// attacker-supplied). Note: clock defaults to Date.now()/1000 unless the
|
|
31
|
+
// caller supplies an independent ClockAdapter; an explicitly supplied
|
|
32
|
+
// value here is not necessarily independently trusted time.
|
|
33
|
+
const evaluationTime = clock.now();
|
|
17
34
|
const intent = isIntent(input)
|
|
18
35
|
? {
|
|
19
36
|
...input,
|
|
20
|
-
timestamp: input.timestamp === 0 ?
|
|
37
|
+
timestamp: input.timestamp === 0 ? evaluationTime : input.timestamp,
|
|
21
38
|
}
|
|
22
39
|
: buildIntent({
|
|
23
40
|
...input,
|
|
24
|
-
timestamp: input.timestamp ??
|
|
41
|
+
timestamp: input.timestamp ?? evaluationTime,
|
|
25
42
|
});
|
|
26
|
-
const out = opts.engine.evaluatePure(intent, state, { mode: opts.mode ?? "fail-fast" });
|
|
43
|
+
const out = opts.engine.evaluatePure(intent, state, evaluationTime, { mode: opts.mode ?? "fail-fast" });
|
|
27
44
|
const emitted = collectNewEvents(opts.engine, auditCursor);
|
|
28
45
|
auditCursor = emitted.nextCursor;
|
|
29
46
|
if (opts.auditAdapter)
|
|
@@ -47,7 +64,12 @@ export function createGuard(opts) {
|
|
|
47
64
|
};
|
|
48
65
|
}
|
|
49
66
|
if (opts.verifyAuthorization !== false) {
|
|
50
|
-
|
|
67
|
+
// Cast as Authorization: runtime object retains internal engine fields even
|
|
68
|
+
// though the TypeScript type was narrowed to AuthorizationV1 at the evaluatePure boundary.
|
|
69
|
+
// Verifier time is the single trusted `evaluationTime` sample taken above, never
|
|
70
|
+
// intent.timestamp — that value is attacker-supplied, so reading it as "now" would
|
|
71
|
+
// let the intent decide whether its own authorization has expired.
|
|
72
|
+
const authCheck = opts.engine.verifyAuthorization(intent, out.authorization, out.nextState, evaluationTime);
|
|
51
73
|
if (!authCheck.valid) {
|
|
52
74
|
return {
|
|
53
75
|
output: { decision: "DENY", reasons: [`AUTH_INVALID:${authCheck.reason ?? "unknown"}`] },
|
package/dist/guard.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guard.js","sourceRoot":"","sources":["../src/guard.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"guard.js","sourceRoot":"","sources":["../src/guard.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* OxDeAI SDK — integration layer on top of @oxdeai/core.
|
|
3
|
+
*
|
|
4
|
+
* For PEP-side verification of externally issued authorization artifacts, use
|
|
5
|
+
* `createVerifier` (re-exported from @oxdeai/core below) with explicit `trustedKeySets`.
|
|
6
|
+
* In strict mode, verification fails closed when `trustedKeySets` is not configured
|
|
7
|
+
* (`TRUSTED_KEYSETS_REQUIRED`). A cryptographically valid artifact is not trusted by
|
|
8
|
+
* default — trust is configured explicitly by the verifier.
|
|
9
|
+
*/
|
|
2
10
|
export * from "@oxdeai/core";
|
|
3
11
|
export * from "./types.js";
|
|
4
12
|
export * from "./builders.js";
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
/**
|
|
3
|
+
* OxDeAI SDK — integration layer on top of @oxdeai/core.
|
|
4
|
+
*
|
|
5
|
+
* For PEP-side verification of externally issued authorization artifacts, use
|
|
6
|
+
* `createVerifier` (re-exported from @oxdeai/core below) with explicit `trustedKeySets`.
|
|
7
|
+
* In strict mode, verification fails closed when `trustedKeySets` is not configured
|
|
8
|
+
* (`TRUSTED_KEYSETS_REQUIRED`). A cryptographically valid artifact is not trusted by
|
|
9
|
+
* default — trust is configured explicitly by the verifier.
|
|
10
|
+
*/
|
|
2
11
|
export * from "@oxdeai/core";
|
|
3
12
|
export * from "./types.js";
|
|
4
13
|
export * from "./builders.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC;;;;;;;;GAQG;AACH,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AuthorizationV1, Intent, State, VerificationResult } from "@oxdeai/core";
|
|
2
2
|
export type MaybePromise<T> = T | Promise<T>;
|
|
3
3
|
export type EvaluateDecision = {
|
|
4
4
|
decision: "ALLOW";
|
|
5
5
|
reasons: [];
|
|
6
|
-
authorization:
|
|
6
|
+
authorization: AuthorizationV1;
|
|
7
7
|
} | {
|
|
8
8
|
decision: "DENY";
|
|
9
9
|
reasons: string[];
|
package/package.json
CHANGED
|
@@ -1,15 +1,33 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oxdeai/sdk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"license": "Apache-2.0",
|
|
4
5
|
"type": "module",
|
|
5
6
|
"main": "dist/index.js",
|
|
6
7
|
"types": "dist/index.d.ts",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/oxdeai/oxdeai.git",
|
|
11
|
+
"directory": "packages/sdk"
|
|
12
|
+
},
|
|
13
|
+
"homepage": "https://github.com/oxdeai/oxdeai",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/oxdeai/oxdeai/issues"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"!dist/**/*.test.*",
|
|
20
|
+
"README.md",
|
|
21
|
+
"CHANGELOG.md",
|
|
22
|
+
"LICENSE"
|
|
23
|
+
],
|
|
7
24
|
"dependencies": {
|
|
8
|
-
"@oxdeai/core": "
|
|
25
|
+
"@oxdeai/core": "2.0.0"
|
|
9
26
|
},
|
|
10
27
|
"scripts": {
|
|
11
28
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
12
29
|
"build": "rm -rf dist && tsc -p tsconfig.json",
|
|
13
|
-
"test": "
|
|
30
|
+
"build:test": "rm -rf dist && tsc -p tsconfig.test.json",
|
|
31
|
+
"test": "pnpm build:test && node --test \"dist/**/*.test.js\""
|
|
14
32
|
}
|
|
15
|
-
}
|
|
33
|
+
}
|
package/dist/guard.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/guard.test.js
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
import test from "node:test";
|
|
2
|
-
import assert from "node:assert/strict";
|
|
3
|
-
import { PolicyEngine } from "@oxdeai/core";
|
|
4
|
-
import { InMemoryAuditAdapter, InMemoryStateAdapter } from "./adapters.js";
|
|
5
|
-
import { buildIntent, buildState } from "./builders.js";
|
|
6
|
-
import { createGuard } from "./guard.js";
|
|
7
|
-
function makeEngine() {
|
|
8
|
-
return new PolicyEngine({
|
|
9
|
-
policy_version: "v1",
|
|
10
|
-
engine_secret: "dev-secret",
|
|
11
|
-
authorization_ttl_seconds: 60,
|
|
12
|
-
authorization_issuer: "issuer-A",
|
|
13
|
-
authorization_audience: "rp-A",
|
|
14
|
-
policyId: "a".repeat(64),
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
function makeAllowState() {
|
|
18
|
-
return buildState({
|
|
19
|
-
policy_version: "v1",
|
|
20
|
-
agent_id: "agent-1",
|
|
21
|
-
allow_action_types: ["PROVISION"],
|
|
22
|
-
allow_targets: ["us-east-1"],
|
|
23
|
-
budget_limit: 1000n,
|
|
24
|
-
spent_in_period: 0n,
|
|
25
|
-
max_amount_per_action: 500n,
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
test("guard executes callback on ALLOW", async () => {
|
|
29
|
-
const engine = makeEngine();
|
|
30
|
-
const stateAdapter = new InMemoryStateAdapter(makeAllowState());
|
|
31
|
-
const auditAdapter = new InMemoryAuditAdapter();
|
|
32
|
-
const guard = createGuard({
|
|
33
|
-
engine,
|
|
34
|
-
stateAdapter,
|
|
35
|
-
auditAdapter,
|
|
36
|
-
clock: { now: () => 1_770_000_000 },
|
|
37
|
-
});
|
|
38
|
-
let called = 0;
|
|
39
|
-
const result = await guard(buildIntent({
|
|
40
|
-
intent_id: "intent-allow-1",
|
|
41
|
-
agent_id: "agent-1",
|
|
42
|
-
action_type: "PROVISION",
|
|
43
|
-
amount: 500n,
|
|
44
|
-
target: "us-east-1",
|
|
45
|
-
nonce: 1n,
|
|
46
|
-
}), async () => {
|
|
47
|
-
called++;
|
|
48
|
-
return "ok";
|
|
49
|
-
});
|
|
50
|
-
assert.equal(called, 1);
|
|
51
|
-
assert.equal(result.executed, true);
|
|
52
|
-
assert.equal(result.output.decision, "ALLOW");
|
|
53
|
-
if (result.executed)
|
|
54
|
-
assert.equal(result.executionResult, "ok");
|
|
55
|
-
assert.ok(auditAdapter.snapshot().length > 0);
|
|
56
|
-
});
|
|
57
|
-
test("guard does not execute callback on DENY", async () => {
|
|
58
|
-
const engine = makeEngine();
|
|
59
|
-
const stateAdapter = new InMemoryStateAdapter(makeAllowState());
|
|
60
|
-
const guard = createGuard({
|
|
61
|
-
engine,
|
|
62
|
-
stateAdapter,
|
|
63
|
-
clock: { now: () => 1_770_000_000 },
|
|
64
|
-
});
|
|
65
|
-
let called = 0;
|
|
66
|
-
const result = await guard(buildIntent({
|
|
67
|
-
intent_id: "intent-deny-1",
|
|
68
|
-
agent_id: "agent-1",
|
|
69
|
-
action_type: "PROVISION",
|
|
70
|
-
amount: 900n,
|
|
71
|
-
target: "us-east-1",
|
|
72
|
-
nonce: 2n,
|
|
73
|
-
}), async () => {
|
|
74
|
-
called++;
|
|
75
|
-
return "should-not-run";
|
|
76
|
-
});
|
|
77
|
-
assert.equal(called, 0);
|
|
78
|
-
assert.equal(result.executed, false);
|
|
79
|
-
assert.equal(result.output.decision, "DENY");
|
|
80
|
-
});
|
|
81
|
-
test("guard enforces authorization verification at callback boundary", async () => {
|
|
82
|
-
const engine = makeEngine();
|
|
83
|
-
const original = engine.verifyAuthorization.bind(engine);
|
|
84
|
-
engine.verifyAuthorization = () => ({ valid: false, reason: "forced-test-failure" });
|
|
85
|
-
const stateAdapter = new InMemoryStateAdapter(makeAllowState());
|
|
86
|
-
const guard = createGuard({
|
|
87
|
-
engine,
|
|
88
|
-
stateAdapter,
|
|
89
|
-
clock: { now: () => 1_770_000_000 },
|
|
90
|
-
});
|
|
91
|
-
let called = 0;
|
|
92
|
-
const result = await guard(buildIntent({
|
|
93
|
-
intent_id: "intent-allow-auth-check",
|
|
94
|
-
agent_id: "agent-1",
|
|
95
|
-
action_type: "PROVISION",
|
|
96
|
-
amount: 500n,
|
|
97
|
-
target: "us-east-1",
|
|
98
|
-
nonce: 3n,
|
|
99
|
-
}), async () => {
|
|
100
|
-
called++;
|
|
101
|
-
return "should-not-run";
|
|
102
|
-
});
|
|
103
|
-
assert.equal(called, 0);
|
|
104
|
-
assert.equal(result.executed, false);
|
|
105
|
-
assert.equal(result.output.decision, "DENY");
|
|
106
|
-
assert.ok(result.output.reasons.some((r) => r.startsWith("AUTH_INVALID:")));
|
|
107
|
-
engine.verifyAuthorization = original;
|
|
108
|
-
});
|
|
109
|
-
test("guard output is deterministic for equivalent inputs", async () => {
|
|
110
|
-
const intent = buildIntent({
|
|
111
|
-
intent_id: "intent-deterministic-1",
|
|
112
|
-
agent_id: "agent-1",
|
|
113
|
-
action_type: "PROVISION",
|
|
114
|
-
amount: 500n,
|
|
115
|
-
target: "us-east-1",
|
|
116
|
-
nonce: 10n,
|
|
117
|
-
timestamp: 1_770_000_000,
|
|
118
|
-
});
|
|
119
|
-
const g1 = createGuard({
|
|
120
|
-
engine: makeEngine(),
|
|
121
|
-
stateAdapter: new InMemoryStateAdapter(makeAllowState()),
|
|
122
|
-
clock: { now: () => 1_770_000_000 },
|
|
123
|
-
});
|
|
124
|
-
const g2 = createGuard({
|
|
125
|
-
engine: makeEngine(),
|
|
126
|
-
stateAdapter: new InMemoryStateAdapter(makeAllowState()),
|
|
127
|
-
clock: { now: () => 1_770_000_000 },
|
|
128
|
-
});
|
|
129
|
-
const r1 = await g1(intent, async () => "ok");
|
|
130
|
-
const r2 = await g2(intent, async () => "ok");
|
|
131
|
-
assert.equal(r1.output.decision, "ALLOW");
|
|
132
|
-
assert.equal(r2.output.decision, "ALLOW");
|
|
133
|
-
if (r1.output.decision === "ALLOW" && r2.output.decision === "ALLOW") {
|
|
134
|
-
assert.equal(r1.output.authorization.auth_id, r2.output.authorization.auth_id);
|
|
135
|
-
assert.equal(r1.output.authorization.state_hash, r2.output.authorization.state_hash);
|
|
136
|
-
assert.equal(r1.output.authorization.intent_hash, r2.output.authorization.intent_hash);
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
|
-
//# sourceMappingURL=guard.test.js.map
|
package/dist/guard.test.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"guard.test.js","sourceRoot":"","sources":["../src/guard.test.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,oBAAoB,CAAC;AAExC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,SAAS,UAAU;IACjB,OAAO,IAAI,YAAY,CAAC;QACtB,cAAc,EAAE,IAAI;QACpB,aAAa,EAAE,YAAY;QAC3B,yBAAyB,EAAE,EAAE;QAC7B,oBAAoB,EAAE,UAAU;QAChC,sBAAsB,EAAE,MAAM;QAC9B,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;KACzB,CAAC,CAAC;AACL,CAAC;AAED,SAAS,cAAc;IACrB,OAAO,UAAU,CAAC;QAChB,cAAc,EAAE,IAAI;QACpB,QAAQ,EAAE,SAAS;QACnB,kBAAkB,EAAE,CAAC,WAAW,CAAC;QACjC,aAAa,EAAE,CAAC,WAAW,CAAC;QAC5B,YAAY,EAAE,KAAM;QACpB,eAAe,EAAE,EAAE;QACnB,qBAAqB,EAAE,IAAI;KAC5B,CAAC,CAAC;AACL,CAAC;AAED,IAAI,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;IAClD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,YAAY,GAAG,IAAI,oBAAoB,CAAC,cAAc,EAAE,CAAC,CAAC;IAChE,MAAM,YAAY,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAChD,MAAM,KAAK,GAAG,WAAW,CAAC;QACxB,MAAM;QACN,YAAY;QACZ,YAAY;QACZ,KAAK,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,aAAa,EAAE;KACpC,CAAC,CAAC;IAEH,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,MAAM,MAAM,GAAG,MAAM,KAAK,CACxB,WAAW,CAAC;QACV,SAAS,EAAE,gBAAgB;QAC3B,QAAQ,EAAE,SAAS;QACnB,WAAW,EAAE,WAAW;QACxB,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE,WAAW;QACnB,KAAK,EAAE,EAAE;KACV,CAAC,EACF,KAAK,IAAI,EAAE;QACT,MAAM,EAAE,CAAC;QACT,OAAO,IAAI,CAAC;IACd,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACxB,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACpC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC9C,IAAI,MAAM,CAAC,QAAQ;QAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;IAChE,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAChD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;IACzD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,YAAY,GAAG,IAAI,oBAAoB,CAAC,cAAc,EAAE,CAAC,CAAC;IAChE,MAAM,KAAK,GAAG,WAAW,CAAC;QACxB,MAAM;QACN,YAAY;QACZ,KAAK,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,aAAa,EAAE;KACpC,CAAC,CAAC;IAEH,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,MAAM,MAAM,GAAG,MAAM,KAAK,CACxB,WAAW,CAAC;QACV,SAAS,EAAE,eAAe;QAC1B,QAAQ,EAAE,SAAS;QACnB,WAAW,EAAE,WAAW;QACxB,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE,WAAW;QACnB,KAAK,EAAE,EAAE;KACV,CAAC,EACF,KAAK,IAAI,EAAE;QACT,MAAM,EAAE,CAAC;QACT,OAAO,gBAAgB,CAAC;IAC1B,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACxB,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACrC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAC/C,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;IAChF,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,QAAQ,GAAG,MAAM,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACxD,MAAc,CAAC,mBAAmB,GAAG,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,qBAAqB,EAAE,CAAC,CAAC;IAE9F,MAAM,YAAY,GAAG,IAAI,oBAAoB,CAAC,cAAc,EAAE,CAAC,CAAC;IAChE,MAAM,KAAK,GAAG,WAAW,CAAC;QACxB,MAAM;QACN,YAAY;QACZ,KAAK,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,aAAa,EAAE;KACpC,CAAC,CAAC;IAEH,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,MAAM,MAAM,GAAG,MAAM,KAAK,CACxB,WAAW,CAAC;QACV,SAAS,EAAE,yBAAyB;QACpC,QAAQ,EAAE,SAAS;QACnB,WAAW,EAAE,WAAW;QACxB,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE,WAAW;QACnB,KAAK,EAAE,EAAE;KACV,CAAC,EACF,KAAK,IAAI,EAAE;QACT,MAAM,EAAE,CAAC;QACT,OAAO,gBAAgB,CAAC;IAC1B,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACxB,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACrC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC7C,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAE3E,MAAc,CAAC,mBAAmB,GAAG,QAAQ,CAAC;AACjD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;IACrE,MAAM,MAAM,GAAG,WAAW,CAAC;QACzB,SAAS,EAAE,wBAAwB;QACnC,QAAQ,EAAE,SAAS;QACnB,WAAW,EAAE,WAAW;QACxB,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE,WAAW;QACnB,KAAK,EAAE,GAAG;QACV,SAAS,EAAE,aAAa;KACzB,CAAC,CAAC;IAEH,MAAM,EAAE,GAAG,WAAW,CAAC;QACrB,MAAM,EAAE,UAAU,EAAE;QACpB,YAAY,EAAE,IAAI,oBAAoB,CAAC,cAAc,EAAE,CAAC;QACxD,KAAK,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,aAAa,EAAE;KACpC,CAAC,CAAC;IACH,MAAM,EAAE,GAAG,WAAW,CAAC;QACrB,MAAM,EAAE,UAAU,EAAE;QACpB,YAAY,EAAE,IAAI,oBAAoB,CAAC,cAAc,EAAE,CAAC;QACxD,KAAK,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,aAAa,EAAE;KACpC,CAAC,CAAC;IAEH,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC;IAE9C,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC1C,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC1C,IAAI,EAAE,CAAC,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,EAAE,CAAC,MAAM,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACrE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAC/E,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,UAAU,EAAE,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QACrF,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,WAAW,EAAE,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IACzF,CAAC;AACH,CAAC,CAAC,CAAC"}
|
package/dist/sdk.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/sdk.test.js
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import test from "node:test";
|
|
2
|
-
import assert from "node:assert/strict";
|
|
3
|
-
import { PolicyEngine } from "@oxdeai/core";
|
|
4
|
-
import { InMemoryAuditAdapter, InMemoryStateAdapter } from "./adapters.js";
|
|
5
|
-
import { buildIntent, buildState } from "./builders.js";
|
|
6
|
-
import { OxDeAIClient } from "./client.js";
|
|
7
|
-
test("builder helpers create engine-compatible intent/state", () => {
|
|
8
|
-
const state = buildState({
|
|
9
|
-
policy_version: "v1",
|
|
10
|
-
agent_id: "agent-1",
|
|
11
|
-
allow_action_types: ["PROVISION"],
|
|
12
|
-
allow_targets: ["us-east-1"]
|
|
13
|
-
});
|
|
14
|
-
const intent = buildIntent({
|
|
15
|
-
intent_id: "intent-1",
|
|
16
|
-
agent_id: "agent-1",
|
|
17
|
-
action_type: "PROVISION",
|
|
18
|
-
amount: 100n,
|
|
19
|
-
target: "us-east-1",
|
|
20
|
-
nonce: 1n,
|
|
21
|
-
timestamp: 1_770_000_000
|
|
22
|
-
});
|
|
23
|
-
const engine = new PolicyEngine({
|
|
24
|
-
policy_version: "v1",
|
|
25
|
-
engine_secret: "dev-secret",
|
|
26
|
-
authorization_ttl_seconds: 60
|
|
27
|
-
});
|
|
28
|
-
const out = engine.evaluatePure(intent, state, { mode: "fail-fast" });
|
|
29
|
-
assert.equal(out.decision, "ALLOW");
|
|
30
|
-
});
|
|
31
|
-
test("OxDeAIClient evaluate+persist+verify flow", async () => {
|
|
32
|
-
const engine = new PolicyEngine({
|
|
33
|
-
policy_version: "v1",
|
|
34
|
-
engine_secret: "dev-secret",
|
|
35
|
-
authorization_ttl_seconds: 60
|
|
36
|
-
});
|
|
37
|
-
const stateAdapter = new InMemoryStateAdapter(buildState({
|
|
38
|
-
policy_version: "v1",
|
|
39
|
-
agent_id: "agent-1",
|
|
40
|
-
allow_action_types: ["PROVISION"],
|
|
41
|
-
allow_targets: ["us-east-1"]
|
|
42
|
-
}));
|
|
43
|
-
const auditAdapter = new InMemoryAuditAdapter();
|
|
44
|
-
const client = new OxDeAIClient({
|
|
45
|
-
engine,
|
|
46
|
-
stateAdapter,
|
|
47
|
-
auditAdapter,
|
|
48
|
-
clock: { now: () => 1_770_000_000 }
|
|
49
|
-
});
|
|
50
|
-
const intent = buildIntent({
|
|
51
|
-
intent_id: "intent-2",
|
|
52
|
-
agent_id: "agent-1",
|
|
53
|
-
action_type: "PROVISION",
|
|
54
|
-
amount: 320n,
|
|
55
|
-
target: "us-east-1",
|
|
56
|
-
nonce: 2n
|
|
57
|
-
});
|
|
58
|
-
const res = await client.evaluateAndCommit(intent);
|
|
59
|
-
assert.equal(res.output.decision, "ALLOW");
|
|
60
|
-
if (res.output.decision !== "ALLOW")
|
|
61
|
-
return;
|
|
62
|
-
assert.ok(res.auditEvents.length >= 3);
|
|
63
|
-
assert.equal(auditAdapter.snapshot().length, res.auditEvents.length);
|
|
64
|
-
const auth = await client.verifyAuthorization({ ...intent, timestamp: 1_770_000_000 }, res.output.authorization);
|
|
65
|
-
assert.equal(auth.valid, true);
|
|
66
|
-
const verify = await client.verifyCurrentArtifacts({ mode: "best-effort" });
|
|
67
|
-
assert.equal(verify.snapshot.status, "ok");
|
|
68
|
-
assert.equal(verify.audit.status, "ok");
|
|
69
|
-
assert.equal(verify.envelope.status, "ok");
|
|
70
|
-
});
|
|
71
|
-
//# sourceMappingURL=sdk.test.js.map
|
package/dist/sdk.test.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.test.js","sourceRoot":"","sources":["../src/sdk.test.ts"],"names":[],"mappings":"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"}
|
package/src/adapters.ts
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { appendFile, mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
2
|
-
import { dirname } from "node:path";
|
|
3
|
-
import { randomUUID } from "node:crypto";
|
|
4
|
-
|
|
5
|
-
import type { State } from "@oxdeai/core";
|
|
6
|
-
|
|
7
|
-
import type { AuditAdapter, StateAdapter } from "./types.js";
|
|
8
|
-
|
|
9
|
-
function canonicalize(value: unknown): unknown {
|
|
10
|
-
if (value === null || typeof value === "boolean" || typeof value === "number" || typeof value === "string") return value;
|
|
11
|
-
if (typeof value === "bigint") return `${value.toString()}n`;
|
|
12
|
-
if (Array.isArray(value)) return value.map((v) => canonicalize(v));
|
|
13
|
-
if (typeof value === "object") {
|
|
14
|
-
const obj = value as Record<string, unknown>;
|
|
15
|
-
const out: Record<string, unknown> = {};
|
|
16
|
-
for (const key of Object.keys(obj).sort()) out[key] = canonicalize(obj[key]);
|
|
17
|
-
return out;
|
|
18
|
-
}
|
|
19
|
-
return String(value);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function stringifyCanonical(value: unknown): string {
|
|
23
|
-
return JSON.stringify(canonicalize(value));
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function parseBigIntLike(value: unknown): bigint {
|
|
27
|
-
if (typeof value === "bigint") return value;
|
|
28
|
-
if (typeof value === "number") return BigInt(value);
|
|
29
|
-
if (typeof value === "string") {
|
|
30
|
-
const s = value.endsWith("n") ? value.slice(0, -1) : value;
|
|
31
|
-
return BigInt(s);
|
|
32
|
-
}
|
|
33
|
-
throw new Error("invalid bigint-like value");
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function mapRecordBigInt(input: unknown): Record<string, bigint> {
|
|
37
|
-
const rec = (input ?? {}) as Record<string, unknown>;
|
|
38
|
-
const out: Record<string, bigint> = {};
|
|
39
|
-
for (const key of Object.keys(rec)) out[key] = parseBigIntLike(rec[key]);
|
|
40
|
-
return out;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function normalizeStateBigInts(raw: unknown): State {
|
|
44
|
-
const s = raw as State;
|
|
45
|
-
return {
|
|
46
|
-
...s,
|
|
47
|
-
budget: {
|
|
48
|
-
...s.budget,
|
|
49
|
-
budget_limit: mapRecordBigInt((s as any).budget?.budget_limit),
|
|
50
|
-
spent_in_period: mapRecordBigInt((s as any).budget?.spent_in_period)
|
|
51
|
-
},
|
|
52
|
-
max_amount_per_action: mapRecordBigInt((s as any).max_amount_per_action)
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export class InMemoryStateAdapter implements StateAdapter {
|
|
57
|
-
private state: State;
|
|
58
|
-
|
|
59
|
-
constructor(initial: State) {
|
|
60
|
-
this.state = structuredClone(initial);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
load(): State {
|
|
64
|
-
return structuredClone(this.state);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
save(state: State): void {
|
|
68
|
-
this.state = structuredClone(state);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export class InMemoryAuditAdapter implements AuditAdapter {
|
|
73
|
-
private readonly events: unknown[] = [];
|
|
74
|
-
|
|
75
|
-
append(events: readonly unknown[]): void {
|
|
76
|
-
for (const event of events) this.events.push(structuredClone(event));
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
snapshot(): unknown[] {
|
|
80
|
-
return structuredClone(this.events);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export class JsonFileStateAdapter implements StateAdapter {
|
|
85
|
-
constructor(private readonly path: string) {}
|
|
86
|
-
|
|
87
|
-
async load(): Promise<State> {
|
|
88
|
-
const txt = await readFile(this.path, "utf8");
|
|
89
|
-
return normalizeStateBigInts(JSON.parse(txt));
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
async save(state: State): Promise<void> {
|
|
93
|
-
await mkdir(dirname(this.path), { recursive: true });
|
|
94
|
-
const tmp = `${this.path}.tmp-${randomUUID()}`;
|
|
95
|
-
await writeFile(tmp, `${stringifyCanonical(state)}\n`, "utf8");
|
|
96
|
-
await rename(tmp, this.path);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export class NdjsonFileAuditAdapter implements AuditAdapter {
|
|
101
|
-
constructor(private readonly path: string) {}
|
|
102
|
-
|
|
103
|
-
async append(events: readonly unknown[]): Promise<void> {
|
|
104
|
-
if (events.length === 0) return;
|
|
105
|
-
await mkdir(dirname(this.path), { recursive: true });
|
|
106
|
-
const body = events.map((e) => stringifyCanonical(e)).join("\n") + "\n";
|
|
107
|
-
await appendFile(this.path, body, "utf8");
|
|
108
|
-
}
|
|
109
|
-
}
|
package/src/builders.ts
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import type { Intent, State } from "@oxdeai/core";
|
|
2
|
-
import type { IntentBuilderInput, StateBuilderInput } from "./types.js";
|
|
3
|
-
|
|
4
|
-
export function buildIntent(input: IntentBuilderInput): Intent {
|
|
5
|
-
const base = {
|
|
6
|
-
intent_id: input.intent_id,
|
|
7
|
-
agent_id: input.agent_id,
|
|
8
|
-
action_type: input.action_type,
|
|
9
|
-
amount: input.amount,
|
|
10
|
-
asset: input.asset,
|
|
11
|
-
target: input.target,
|
|
12
|
-
timestamp: input.timestamp ?? 0,
|
|
13
|
-
metadata_hash: input.metadata_hash ?? "0x" + "0".repeat(64),
|
|
14
|
-
nonce: input.nonce,
|
|
15
|
-
signature: input.signature ?? "sdk-signature-placeholder",
|
|
16
|
-
depth: input.depth,
|
|
17
|
-
tool: input.tool,
|
|
18
|
-
tool_call: input.tool_call
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
if (input.type === "RELEASE") {
|
|
22
|
-
if (!input.authorization_id) throw new Error("authorization_id is required for RELEASE intent");
|
|
23
|
-
return {
|
|
24
|
-
...base,
|
|
25
|
-
type: "RELEASE",
|
|
26
|
-
authorization_id: input.authorization_id
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return {
|
|
31
|
-
...base,
|
|
32
|
-
type: "EXECUTE",
|
|
33
|
-
authorization_id: input.authorization_id
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function buildState(input: StateBuilderInput): State {
|
|
38
|
-
const agent = input.agent_id;
|
|
39
|
-
return {
|
|
40
|
-
policy_version: input.policy_version ?? "v1",
|
|
41
|
-
period_id: input.period_id ?? "default-period",
|
|
42
|
-
kill_switch: { global: false, agents: {} },
|
|
43
|
-
allowlists: {
|
|
44
|
-
action_types: input.allow_action_types ?? ["PROVISION"],
|
|
45
|
-
assets: input.allow_assets ?? [],
|
|
46
|
-
targets: input.allow_targets ?? []
|
|
47
|
-
},
|
|
48
|
-
budget: {
|
|
49
|
-
budget_limit: { [agent]: input.budget_limit ?? 1_000_000n },
|
|
50
|
-
spent_in_period: { [agent]: input.spent_in_period ?? 0n }
|
|
51
|
-
},
|
|
52
|
-
max_amount_per_action: { [agent]: input.max_amount_per_action ?? 1_000_000n },
|
|
53
|
-
velocity: {
|
|
54
|
-
config: {
|
|
55
|
-
window_seconds: input.velocity_window_seconds ?? 60,
|
|
56
|
-
max_actions: input.velocity_max_actions ?? 1000
|
|
57
|
-
},
|
|
58
|
-
counters: {}
|
|
59
|
-
},
|
|
60
|
-
replay: {
|
|
61
|
-
window_seconds: input.replay_window_seconds ?? 3600,
|
|
62
|
-
max_nonces_per_agent: input.replay_max_nonces_per_agent ?? 256,
|
|
63
|
-
nonces: {}
|
|
64
|
-
},
|
|
65
|
-
concurrency: {
|
|
66
|
-
max_concurrent: { [agent]: input.max_concurrent ?? 16 },
|
|
67
|
-
active: {},
|
|
68
|
-
active_auths: {}
|
|
69
|
-
},
|
|
70
|
-
recursion: {
|
|
71
|
-
max_depth: { [agent]: input.max_depth ?? 8 }
|
|
72
|
-
},
|
|
73
|
-
tool_limits: {
|
|
74
|
-
window_seconds: input.tool_window_seconds ?? 60,
|
|
75
|
-
max_calls: { [agent]: input.tool_max_calls ?? 1000 },
|
|
76
|
-
max_calls_by_tool: {},
|
|
77
|
-
calls: {}
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
}
|