@tenuo/core 0.2.4-beta.0 → 0.3.0-beta.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 +49 -5
- package/dist/api.d.ts +416 -17
- package/dist/api.js.map +1 -1
- package/dist/client.d.ts +59 -2
- package/dist/client.js +700 -70
- package/dist/client.js.map +1 -1
- package/dist/connect.d.ts +53 -0
- package/dist/connect.js +177 -0
- package/dist/connect.js.map +1 -0
- package/dist/constraints.d.ts +54 -3
- package/dist/constraints.js +154 -6
- package/dist/constraints.js.map +1 -1
- package/dist/errors.d.ts +8 -3
- package/dist/errors.js +10 -1
- package/dist/errors.js.map +1 -1
- package/dist/generated/tenuo_wasm.d.ts +136 -7
- package/dist/generated/tenuo_wasm.js +398 -9
- package/dist/generated/tenuo_wasm_bg.wasm +0 -0
- package/dist/generated/tenuo_wasm_bg.wasm.d.ts +40 -22
- package/dist/identity.d.ts +25 -0
- package/dist/identity.js +61 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +9 -3
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp.d.ts +18 -3
- package/dist/mcp.js +67 -59
- package/dist/mcp.js.map +1 -1
- package/dist/nonce.d.ts +6 -1
- package/dist/nonce.js +12 -1
- package/dist/nonce.js.map +1 -1
- package/dist/receipts.d.ts +27 -0
- package/dist/receipts.js +128 -0
- package/dist/receipts.js.map +1 -0
- package/dist/runtime.d.ts +51 -0
- package/dist/runtime.js +102 -0
- package/dist/runtime.js.map +1 -0
- package/dist/session.d.ts +9 -2
- package/dist/session.js +56 -0
- package/dist/session.js.map +1 -1
- package/dist/wasm.d.ts +207 -5
- package/dist/wasm.js +62 -4
- package/dist/wasm.js.map +1 -1
- package/package.json +3 -2
- package/dist/api.d.ts.map +0 -1
- package/dist/client.d.ts.map +0 -1
- package/dist/constraints.d.ts.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/mcp.d.ts.map +0 -1
- package/dist/nonce.d.ts.map +0 -1
- package/dist/session.d.ts.map +0 -1
- package/dist/wasm.d.ts.map +0 -1
package/dist/constraints.js
CHANGED
|
@@ -1,32 +1,180 @@
|
|
|
1
|
+
import { TenuoConfigurationError } from "./errors.js";
|
|
2
|
+
/**
|
|
3
|
+
* Constraint builders. These produce plain marker objects; every one is
|
|
4
|
+
* evaluated by the Rust core, never in TypeScript. The set matches the
|
|
5
|
+
* Python SDK and the core `Constraint` enum one for one. Builders that
|
|
6
|
+
* validate their input throw `TenuoConfigurationError` at the call site.
|
|
7
|
+
* Deeper checks, such as regex syntax, run in the core when `session()`
|
|
8
|
+
* compiles the policy. Nothing here makes an authorization decision.
|
|
9
|
+
*/
|
|
1
10
|
/** Directory prefix. Evaluated in core as Subpath — not a string prefix check in TS. */
|
|
2
|
-
export function under(root) {
|
|
11
|
+
export function under(root, options) {
|
|
3
12
|
if (!root.startsWith("/")) {
|
|
4
|
-
throw new
|
|
13
|
+
throw new TenuoConfigurationError("tenuo.under() expects an absolute path (start with /)");
|
|
5
14
|
}
|
|
6
|
-
|
|
15
|
+
const out = {
|
|
16
|
+
kind: "under",
|
|
17
|
+
root,
|
|
18
|
+
};
|
|
19
|
+
if (options?.caseSensitive !== undefined) {
|
|
20
|
+
out.caseSensitive = options.caseSensitive;
|
|
21
|
+
}
|
|
22
|
+
if (options?.allowEqual !== undefined) {
|
|
23
|
+
out.allowEqual = options.allowEqual;
|
|
24
|
+
}
|
|
25
|
+
return out;
|
|
7
26
|
}
|
|
8
27
|
export function email(options) {
|
|
9
28
|
return { kind: "email", domain: options.domain };
|
|
10
29
|
}
|
|
11
30
|
export function max(value) {
|
|
12
31
|
if (!Number.isFinite(value)) {
|
|
13
|
-
throw new
|
|
32
|
+
throw new TenuoConfigurationError("tenuo.max() requires a finite number");
|
|
14
33
|
}
|
|
15
34
|
return { kind: "max", value };
|
|
16
35
|
}
|
|
36
|
+
export function min(value) {
|
|
37
|
+
if (!Number.isFinite(value)) {
|
|
38
|
+
throw new TenuoConfigurationError("tenuo.min() requires a finite number");
|
|
39
|
+
}
|
|
40
|
+
return { kind: "min", value };
|
|
41
|
+
}
|
|
42
|
+
/** Numeric interval. Bounds are inclusive unless `minExclusive` / `maxExclusive`. */
|
|
43
|
+
export function range(options) {
|
|
44
|
+
if (options.min === undefined && options.max === undefined) {
|
|
45
|
+
throw new TenuoConfigurationError("tenuo.range() requires min, max, or both");
|
|
46
|
+
}
|
|
47
|
+
for (const bound of [options.min, options.max]) {
|
|
48
|
+
if (bound !== undefined && !Number.isFinite(bound)) {
|
|
49
|
+
throw new TenuoConfigurationError("tenuo.range() bounds must be finite numbers");
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (options.min !== undefined && options.max !== undefined && options.min > options.max) {
|
|
53
|
+
throw new TenuoConfigurationError("tenuo.range() min must not exceed max");
|
|
54
|
+
}
|
|
55
|
+
const out = { kind: "range" };
|
|
56
|
+
if (options.min !== undefined) {
|
|
57
|
+
out.min = options.min;
|
|
58
|
+
}
|
|
59
|
+
if (options.max !== undefined) {
|
|
60
|
+
out.max = options.max;
|
|
61
|
+
}
|
|
62
|
+
if (options.minExclusive === true) {
|
|
63
|
+
out.minExclusive = true;
|
|
64
|
+
}
|
|
65
|
+
if (options.maxExclusive === true) {
|
|
66
|
+
out.maxExclusive = true;
|
|
67
|
+
}
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
17
70
|
export function oneOf(values) {
|
|
18
71
|
if (values.length === 0) {
|
|
19
|
-
throw new
|
|
72
|
+
throw new TenuoConfigurationError("tenuo.oneOf() requires at least one value");
|
|
20
73
|
}
|
|
21
74
|
return { kind: "oneOf", values };
|
|
22
75
|
}
|
|
76
|
+
/** Any value except these. */
|
|
77
|
+
export function notOneOf(values) {
|
|
78
|
+
if (values.length === 0) {
|
|
79
|
+
throw new TenuoConfigurationError("tenuo.notOneOf() requires at least one value");
|
|
80
|
+
}
|
|
81
|
+
return { kind: "notOneOf", values };
|
|
82
|
+
}
|
|
23
83
|
export function pattern(pattern) {
|
|
24
84
|
if (pattern.length === 0) {
|
|
25
|
-
throw new
|
|
85
|
+
throw new TenuoConfigurationError("tenuo.pattern() requires a non-empty pattern");
|
|
26
86
|
}
|
|
27
87
|
return { kind: "pattern", pattern };
|
|
28
88
|
}
|
|
89
|
+
/** Regular expression, compiled and evaluated in core. */
|
|
90
|
+
export function regex(source) {
|
|
91
|
+
if (source.length === 0) {
|
|
92
|
+
throw new TenuoConfigurationError("tenuo.regex() requires a non-empty expression");
|
|
93
|
+
}
|
|
94
|
+
return { kind: "regex", source };
|
|
95
|
+
}
|
|
29
96
|
export function exact(value) {
|
|
30
97
|
return { kind: "exact", value };
|
|
31
98
|
}
|
|
99
|
+
/** Any value at all. Name it in a zero-trust policy to allow an argument without constraining it. */
|
|
100
|
+
export function wildcard() {
|
|
101
|
+
return { kind: "wildcard" };
|
|
102
|
+
}
|
|
103
|
+
/** IP address inside a network, e.g. `cidr("10.0.0.0/8")`. */
|
|
104
|
+
export function cidr(network) {
|
|
105
|
+
if (!network.includes("/")) {
|
|
106
|
+
throw new TenuoConfigurationError("tenuo.cidr() expects CIDR notation like 10.0.0.0/8");
|
|
107
|
+
}
|
|
108
|
+
return { kind: "cidr", network };
|
|
109
|
+
}
|
|
110
|
+
/** URL glob, e.g. `urlPattern("https://*.example.com/api/*")`. Parsed as a URL, not a string. */
|
|
111
|
+
export function urlPattern(pattern) {
|
|
112
|
+
if (pattern.length === 0) {
|
|
113
|
+
throw new TenuoConfigurationError("tenuo.urlPattern() requires a non-empty pattern");
|
|
114
|
+
}
|
|
115
|
+
return { kind: "urlPattern", pattern };
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* SSRF-aware URL check: http/https only by default, private and link-local
|
|
119
|
+
* hosts rejected, optional allow and deny domain lists (`*.example.com`).
|
|
120
|
+
*/
|
|
121
|
+
export function urlSafe(options) {
|
|
122
|
+
const out = { kind: "urlSafe" };
|
|
123
|
+
if (options?.schemes !== undefined) {
|
|
124
|
+
out.schemes = options.schemes;
|
|
125
|
+
}
|
|
126
|
+
if (options?.allowDomains !== undefined) {
|
|
127
|
+
out.allowDomains = options.allowDomains;
|
|
128
|
+
}
|
|
129
|
+
if (options?.denyDomains !== undefined) {
|
|
130
|
+
out.denyDomains = options.denyDomains;
|
|
131
|
+
}
|
|
132
|
+
return out;
|
|
133
|
+
}
|
|
134
|
+
/** Shell command whose first word must be one of `allow`. Parsed with shell quoting rules in core. */
|
|
135
|
+
export function shlex(allow) {
|
|
136
|
+
if (allow.length === 0) {
|
|
137
|
+
throw new TenuoConfigurationError("tenuo.shlex() requires at least one allowed command");
|
|
138
|
+
}
|
|
139
|
+
return { kind: "shlex", allow };
|
|
140
|
+
}
|
|
141
|
+
/** List argument that must include every one of these values. */
|
|
142
|
+
export function contains(values) {
|
|
143
|
+
if (values.length === 0) {
|
|
144
|
+
throw new TenuoConfigurationError("tenuo.contains() requires at least one value");
|
|
145
|
+
}
|
|
146
|
+
return { kind: "contains", values };
|
|
147
|
+
}
|
|
148
|
+
/** List argument whose every element must be one of these values. */
|
|
149
|
+
export function subset(values) {
|
|
150
|
+
if (values.length === 0) {
|
|
151
|
+
throw new TenuoConfigurationError("tenuo.subset() requires at least one value");
|
|
152
|
+
}
|
|
153
|
+
return { kind: "subset", values };
|
|
154
|
+
}
|
|
155
|
+
/** Satisfied when at least one inner constraint is. */
|
|
156
|
+
export function anyOf(constraints) {
|
|
157
|
+
if (constraints.length === 0) {
|
|
158
|
+
throw new TenuoConfigurationError("tenuo.anyOf() requires at least one constraint");
|
|
159
|
+
}
|
|
160
|
+
return { kind: "anyOf", constraints };
|
|
161
|
+
}
|
|
162
|
+
/** Satisfied only when every inner constraint is. */
|
|
163
|
+
export function all(constraints) {
|
|
164
|
+
if (constraints.length === 0) {
|
|
165
|
+
throw new TenuoConfigurationError("tenuo.all() requires at least one constraint");
|
|
166
|
+
}
|
|
167
|
+
return { kind: "all", constraints };
|
|
168
|
+
}
|
|
169
|
+
/** Satisfied when the inner constraint is not. Delegation cannot narrow a `not`; prefer `notOneOf`. */
|
|
170
|
+
export function not(constraint) {
|
|
171
|
+
return { kind: "not", constraint };
|
|
172
|
+
}
|
|
173
|
+
/** Common Expression Language predicate over the argument value, evaluated in core. */
|
|
174
|
+
export function cel(expression) {
|
|
175
|
+
if (expression.trim().length === 0) {
|
|
176
|
+
throw new TenuoConfigurationError("tenuo.cel() requires a non-empty expression");
|
|
177
|
+
}
|
|
178
|
+
return { kind: "cel", expression };
|
|
179
|
+
}
|
|
32
180
|
//# sourceMappingURL=constraints.js.map
|
package/dist/constraints.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constraints.js","sourceRoot":"","sources":["../src/constraints.ts"],"names":[],"mappings":"AASA,wFAAwF;AACxF,MAAM,UAAU,KAAK,CAAC,IAAY;IAChC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,OAA2B;IAC/C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,KAAa;IAC/B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,MAAyB;IAC7C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,OAAe;IACrC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,KAAgC;IACpD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAClC,CAAC"}
|
|
1
|
+
{"version":3,"file":"constraints.js","sourceRoot":"","sources":["../src/constraints.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AllConstraint,\n AnyOfConstraint,\n CelConstraint,\n CidrConstraint,\n ConstraintExpr,\n ContainsConstraint,\n EmailConstraint,\n ExactConstraint,\n MaxConstraint,\n MinConstraint,\n NotConstraint,\n NotOneOfConstraint,\n OneOfConstraint,\n PatternConstraint,\n RangeConstraint,\n RegexConstraint,\n ShlexConstraint,\n SubsetConstraint,\n UnderConstraint,\n UrlPatternConstraint,\n UrlSafeConstraint,\n WildcardConstraint,\n} from \"./api.ts\";\nimport { TenuoConfigurationError } from \"./errors.ts\";\n\n/**\n * Constraint builders. These produce plain marker objects; every one is\n * evaluated by the Rust core, never in TypeScript. The set matches the\n * Python SDK and the core `Constraint` enum one for one. Builders that\n * validate their input throw `TenuoConfigurationError` at the call site.\n * Deeper checks, such as regex syntax, run in the core when `session()`\n * compiles the policy. Nothing here makes an authorization decision.\n */\n\n/** Directory prefix. Evaluated in core as Subpath — not a string prefix check in TS. */\nexport function under(\n root: string,\n options?: { readonly caseSensitive?: boolean; readonly allowEqual?: boolean },\n): UnderConstraint {\n if (!root.startsWith(\"/\")) {\n throw new TenuoConfigurationError(\"tenuo.under() expects an absolute path (start with /)\");\n }\n const out: { kind: \"under\"; root: string; caseSensitive?: boolean; allowEqual?: boolean } = {\n kind: \"under\",\n root,\n };\n if (options?.caseSensitive !== undefined) {\n out.caseSensitive = options.caseSensitive;\n }\n if (options?.allowEqual !== undefined) {\n out.allowEqual = options.allowEqual;\n }\n return out;\n}\n\nexport function email(options: { domain: string }): EmailConstraint {\n return { kind: \"email\", domain: options.domain };\n}\n\nexport function max(value: number): MaxConstraint {\n if (!Number.isFinite(value)) {\n throw new TenuoConfigurationError(\"tenuo.max() requires a finite number\");\n }\n return { kind: \"max\", value };\n}\n\nexport function min(value: number): MinConstraint {\n if (!Number.isFinite(value)) {\n throw new TenuoConfigurationError(\"tenuo.min() requires a finite number\");\n }\n return { kind: \"min\", value };\n}\n\n/** Numeric interval. Bounds are inclusive unless `minExclusive` / `maxExclusive`. */\nexport function range(options: {\n readonly min?: number;\n readonly max?: number;\n readonly minExclusive?: boolean;\n readonly maxExclusive?: boolean;\n}): RangeConstraint {\n if (options.min === undefined && options.max === undefined) {\n throw new TenuoConfigurationError(\"tenuo.range() requires min, max, or both\");\n }\n for (const bound of [options.min, options.max]) {\n if (bound !== undefined && !Number.isFinite(bound)) {\n throw new TenuoConfigurationError(\"tenuo.range() bounds must be finite numbers\");\n }\n }\n if (options.min !== undefined && options.max !== undefined && options.min > options.max) {\n throw new TenuoConfigurationError(\"tenuo.range() min must not exceed max\");\n }\n const out: {\n kind: \"range\";\n min?: number;\n max?: number;\n minExclusive?: boolean;\n maxExclusive?: boolean;\n } = { kind: \"range\" };\n if (options.min !== undefined) {\n out.min = options.min;\n }\n if (options.max !== undefined) {\n out.max = options.max;\n }\n if (options.minExclusive === true) {\n out.minExclusive = true;\n }\n if (options.maxExclusive === true) {\n out.maxExclusive = true;\n }\n return out;\n}\n\nexport function oneOf(values: readonly string[]): OneOfConstraint {\n if (values.length === 0) {\n throw new TenuoConfigurationError(\"tenuo.oneOf() requires at least one value\");\n }\n return { kind: \"oneOf\", values };\n}\n\n/** Any value except these. */\nexport function notOneOf(values: readonly string[]): NotOneOfConstraint {\n if (values.length === 0) {\n throw new TenuoConfigurationError(\"tenuo.notOneOf() requires at least one value\");\n }\n return { kind: \"notOneOf\", values };\n}\n\nexport function pattern(pattern: string): PatternConstraint {\n if (pattern.length === 0) {\n throw new TenuoConfigurationError(\"tenuo.pattern() requires a non-empty pattern\");\n }\n return { kind: \"pattern\", pattern };\n}\n\n/** Regular expression, compiled and evaluated in core. */\nexport function regex(source: string): RegexConstraint {\n if (source.length === 0) {\n throw new TenuoConfigurationError(\"tenuo.regex() requires a non-empty expression\");\n }\n return { kind: \"regex\", source };\n}\n\nexport function exact(value: string | number | boolean): ExactConstraint {\n return { kind: \"exact\", value };\n}\n\n/** Any value at all. Name it in a zero-trust policy to allow an argument without constraining it. */\nexport function wildcard(): WildcardConstraint {\n return { kind: \"wildcard\" };\n}\n\n/** IP address inside a network, e.g. `cidr(\"10.0.0.0/8\")`. */\nexport function cidr(network: string): CidrConstraint {\n if (!network.includes(\"/\")) {\n throw new TenuoConfigurationError(\"tenuo.cidr() expects CIDR notation like 10.0.0.0/8\");\n }\n return { kind: \"cidr\", network };\n}\n\n/** URL glob, e.g. `urlPattern(\"https://*.example.com/api/*\")`. Parsed as a URL, not a string. */\nexport function urlPattern(pattern: string): UrlPatternConstraint {\n if (pattern.length === 0) {\n throw new TenuoConfigurationError(\"tenuo.urlPattern() requires a non-empty pattern\");\n }\n return { kind: \"urlPattern\", pattern };\n}\n\n/**\n * SSRF-aware URL check: http/https only by default, private and link-local\n * hosts rejected, optional allow and deny domain lists (`*.example.com`).\n */\nexport function urlSafe(options?: {\n readonly schemes?: readonly string[];\n readonly allowDomains?: readonly string[];\n readonly denyDomains?: readonly string[];\n}): UrlSafeConstraint {\n const out: {\n kind: \"urlSafe\";\n schemes?: readonly string[];\n allowDomains?: readonly string[];\n denyDomains?: readonly string[];\n } = { kind: \"urlSafe\" };\n if (options?.schemes !== undefined) {\n out.schemes = options.schemes;\n }\n if (options?.allowDomains !== undefined) {\n out.allowDomains = options.allowDomains;\n }\n if (options?.denyDomains !== undefined) {\n out.denyDomains = options.denyDomains;\n }\n return out;\n}\n\n/** Shell command whose first word must be one of `allow`. Parsed with shell quoting rules in core. */\nexport function shlex(allow: readonly string[]): ShlexConstraint {\n if (allow.length === 0) {\n throw new TenuoConfigurationError(\"tenuo.shlex() requires at least one allowed command\");\n }\n return { kind: \"shlex\", allow };\n}\n\n/** List argument that must include every one of these values. */\nexport function contains(values: readonly (string | number | boolean)[]): ContainsConstraint {\n if (values.length === 0) {\n throw new TenuoConfigurationError(\"tenuo.contains() requires at least one value\");\n }\n return { kind: \"contains\", values };\n}\n\n/** List argument whose every element must be one of these values. */\nexport function subset(values: readonly (string | number | boolean)[]): SubsetConstraint {\n if (values.length === 0) {\n throw new TenuoConfigurationError(\"tenuo.subset() requires at least one value\");\n }\n return { kind: \"subset\", values };\n}\n\n/** Satisfied when at least one inner constraint is. */\nexport function anyOf(constraints: readonly ConstraintExpr[]): AnyOfConstraint {\n if (constraints.length === 0) {\n throw new TenuoConfigurationError(\"tenuo.anyOf() requires at least one constraint\");\n }\n return { kind: \"anyOf\", constraints };\n}\n\n/** Satisfied only when every inner constraint is. */\nexport function all(constraints: readonly ConstraintExpr[]): AllConstraint {\n if (constraints.length === 0) {\n throw new TenuoConfigurationError(\"tenuo.all() requires at least one constraint\");\n }\n return { kind: \"all\", constraints };\n}\n\n/** Satisfied when the inner constraint is not. Delegation cannot narrow a `not`; prefer `notOneOf`. */\nexport function not(constraint: ConstraintExpr): NotConstraint {\n return { kind: \"not\", constraint };\n}\n\n/** Common Expression Language predicate over the argument value, evaluated in core. */\nexport function cel(expression: string): CelConstraint {\n if (expression.trim().length === 0) {\n throw new TenuoConfigurationError(\"tenuo.cel() requires a non-empty expression\");\n }\n return { kind: \"cel\", expression };\n}\n"]}
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { TenuoErrorCode } from "./api.ts";
|
|
1
|
+
import type { ApprovalRequest, TenuoErrorCode } from "./api.ts";
|
|
2
2
|
export declare class TenuoError extends Error {
|
|
3
3
|
readonly code: TenuoErrorCode;
|
|
4
4
|
constructor(code: TenuoErrorCode, message: string);
|
|
@@ -14,6 +14,11 @@ export declare class ApprovalRequiredError extends TenuoError {
|
|
|
14
14
|
readonly tool: string;
|
|
15
15
|
readonly required: number;
|
|
16
16
|
readonly received: number;
|
|
17
|
-
|
|
17
|
+
/**
|
|
18
|
+
* What to send to an approval service, when the SDK had the session at
|
|
19
|
+
* hand. Absent on the server-side verify path, where only the caller can
|
|
20
|
+
* build it.
|
|
21
|
+
*/
|
|
22
|
+
readonly request?: ApprovalRequest;
|
|
23
|
+
constructor(tool: string, required: number, received: number, message?: string, request?: ApprovalRequest);
|
|
18
24
|
}
|
|
19
|
-
//# sourceMappingURL=errors.d.ts.map
|
package/dist/errors.js
CHANGED
|
@@ -26,12 +26,21 @@ export class ApprovalRequiredError extends TenuoError {
|
|
|
26
26
|
tool;
|
|
27
27
|
required;
|
|
28
28
|
received;
|
|
29
|
-
|
|
29
|
+
/**
|
|
30
|
+
* What to send to an approval service, when the SDK had the session at
|
|
31
|
+
* hand. Absent on the server-side verify path, where only the caller can
|
|
32
|
+
* build it.
|
|
33
|
+
*/
|
|
34
|
+
request;
|
|
35
|
+
constructor(tool, required, received, message, request) {
|
|
30
36
|
super("TENUO_APPROVAL_REQUIRED", message ?? `Approval required for ${tool}`);
|
|
31
37
|
this.name = "ApprovalRequiredError";
|
|
32
38
|
this.tool = tool;
|
|
33
39
|
this.required = required;
|
|
34
40
|
this.received = received;
|
|
41
|
+
if (request !== undefined) {
|
|
42
|
+
this.request = request;
|
|
43
|
+
}
|
|
35
44
|
}
|
|
36
45
|
}
|
|
37
46
|
//# sourceMappingURL=errors.js.map
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,UAAW,SAAQ,KAAK;IAC1B,IAAI,CAAiB;IAE9B,YAAY,IAAoB,EAAE,OAAe;QAC/C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED,MAAM,OAAO,uBAAwB,SAAQ,UAAU;IACrD,YAAY,OAAe,EAAE,OAAuB,qBAAqB;QACvE,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;IACxC,CAAC;CACF;AAED,MAAM,OAAO,wBAAyB,SAAQ,UAAU;IAC7C,KAAK,CAAU;IAExB,YAAY,IAAoB,EAAE,OAAe,EAAE,KAAc;QAC/D,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;QACvC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACrB,CAAC;IACH,CAAC;CACF;AAED,MAAM,OAAO,qBAAsB,SAAQ,UAAU;IAC1C,IAAI,CAAS;IACb,QAAQ,CAAS;IACjB,QAAQ,CAAS;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,UAAW,SAAQ,KAAK;IAC1B,IAAI,CAAiB;IAE9B,YAAY,IAAoB,EAAE,OAAe;QAC/C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED,MAAM,OAAO,uBAAwB,SAAQ,UAAU;IACrD,YAAY,OAAe,EAAE,OAAuB,qBAAqB;QACvE,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;IACxC,CAAC;CACF;AAED,MAAM,OAAO,wBAAyB,SAAQ,UAAU;IAC7C,KAAK,CAAU;IAExB,YAAY,IAAoB,EAAE,OAAe,EAAE,KAAc;QAC/D,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;QACvC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACrB,CAAC;IACH,CAAC;CACF;AAED,MAAM,OAAO,qBAAsB,SAAQ,UAAU;IAC1C,IAAI,CAAS;IACb,QAAQ,CAAS;IACjB,QAAQ,CAAS;IAC1B;;;;OAIG;IACM,OAAO,CAAmB;IAEnC,YAAY,IAAY,EAAE,QAAgB,EAAE,QAAgB,EAAE,OAAgB,EAAE,OAAyB;QACvG,KAAK,CAAC,yBAAyB,EAAE,OAAO,IAAI,yBAAyB,IAAI,EAAE,CAAC,CAAC;QAC7E,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;QACpC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACzB,CAAC;IACH,CAAC;CACF","sourcesContent":["import type { ApprovalRequest, TenuoErrorCode } from \"./api.ts\";\n\nexport class TenuoError extends Error {\n readonly code: TenuoErrorCode;\n\n constructor(code: TenuoErrorCode, message: string) {\n super(message);\n this.name = \"TenuoError\";\n this.code = code;\n }\n}\n\nexport class TenuoConfigurationError extends TenuoError {\n constructor(message: string, code: TenuoErrorCode = \"TENUO_CONFIGURATION\") {\n super(code, message);\n this.name = \"TenuoConfigurationError\";\n }\n}\n\nexport class AuthorizationDeniedError extends TenuoError {\n readonly field?: string;\n\n constructor(code: TenuoErrorCode, message: string, field?: string) {\n super(code, message);\n this.name = \"AuthorizationDeniedError\";\n if (field !== undefined) {\n this.field = field;\n }\n }\n}\n\nexport class ApprovalRequiredError extends TenuoError {\n readonly tool: string;\n readonly required: number;\n readonly received: number;\n /**\n * What to send to an approval service, when the SDK had the session at\n * hand. Absent on the server-side verify path, where only the caller can\n * build it.\n */\n readonly request?: ApprovalRequest;\n\n constructor(tool: string, required: number, received: number, message?: string, request?: ApprovalRequest) {\n super(\"TENUO_APPROVAL_REQUIRED\", message ?? `Approval required for ${tool}`);\n this.name = \"ApprovalRequiredError\";\n this.tool = tool;\n this.required = required;\n this.received = received;\n if (request !== undefined) {\n this.request = request;\n }\n }\n}\n"]}
|
|
@@ -8,6 +8,17 @@
|
|
|
8
8
|
export class SdkContext {
|
|
9
9
|
free(): void;
|
|
10
10
|
[Symbol.dispose](): void;
|
|
11
|
+
/**
|
|
12
|
+
* Signed statement from this session's holder that it is the one asking
|
|
13
|
+
* for `tool(args)`. Carried inside a control-plane approval request so
|
|
14
|
+
* the approver can tell a genuine request from a forged one.
|
|
15
|
+
*/
|
|
16
|
+
approvalContextAttestation(session: SdkSession, tool: string, args_json: any): any;
|
|
17
|
+
/**
|
|
18
|
+
* Everything an approval service needs to present `tool(args)` to a
|
|
19
|
+
* human and mint a matching `SignedApproval`. Not a signed artifact.
|
|
20
|
+
*/
|
|
21
|
+
approvalRequest(session: SdkSession, tool: string, args_json: any): any;
|
|
11
22
|
/**
|
|
12
23
|
* Sign PoP and authorize in one call. Never returns allow without a core allow.
|
|
13
24
|
*
|
|
@@ -26,10 +37,36 @@ export class SdkContext {
|
|
|
26
37
|
* Null/undefined: no extra ceiling. Empty object: open.
|
|
27
38
|
*/
|
|
28
39
|
authorizePresented(warrants: any, tool: string, args_json: any, pop: string, approvals: any, tool_allow: any, request_id?: string | null): any;
|
|
40
|
+
/**
|
|
41
|
+
* Explain what the leaf would decide for `tool(args)`, field by field.
|
|
42
|
+
* No proof-of-possession is signed, so this works on any session,
|
|
43
|
+
* including one issued to another holder.
|
|
44
|
+
*/
|
|
45
|
+
explain(session: SdkSession, tool: string, args_json: any): any;
|
|
46
|
+
/**
|
|
47
|
+
* Issuer context from a stable 32-byte Ed25519 secret. Its own public
|
|
48
|
+
* key is trusted; `extra_roots` (hex) are trusted as well, so one
|
|
49
|
+
* process can verify chains from several control planes.
|
|
50
|
+
*/
|
|
51
|
+
static fromIssuerSecret(secret: Uint8Array, extra_roots: any): SdkContext;
|
|
29
52
|
/**
|
|
30
53
|
* Authorizer-only context. `mint()` fails; import a session from the wire.
|
|
31
54
|
*/
|
|
32
55
|
static fromTrustedRoots(roots: any): SdkContext;
|
|
56
|
+
/**
|
|
57
|
+
* Issue an execution session from an issuer session. The issuer
|
|
58
|
+
* session's holder signs; core checks the tools against
|
|
59
|
+
* `issuableTools`, constraints against `constraintBounds`, clearance,
|
|
60
|
+
* and issue depth. No control-plane key is involved.
|
|
61
|
+
*/
|
|
62
|
+
issue(issuer: SdkSession, options: any): SdkSession;
|
|
63
|
+
/**
|
|
64
|
+
* Public key of the local issuer, hex. Verifier-only contexts have none.
|
|
65
|
+
*
|
|
66
|
+
* This is what other processes put in `trustedRoots` to accept warrants
|
|
67
|
+
* this context mints. It is a public key: sharing it grants nothing.
|
|
68
|
+
*/
|
|
69
|
+
issuerPublicKey(): string;
|
|
33
70
|
/**
|
|
34
71
|
* Load a published SignedRevocationList. The SRL must be signed by a trusted root.
|
|
35
72
|
*/
|
|
@@ -40,12 +77,33 @@ export class SdkContext {
|
|
|
40
77
|
*
|
|
41
78
|
* `require_approval` is optional:
|
|
42
79
|
* `{ "approvers": ["hex..."], "min": 2, "tools": ["transfer"] }`
|
|
80
|
+
*
|
|
81
|
+
* `holder_hex` binds the warrant to another agent's public key. The
|
|
82
|
+
* returned session then has no holder secret: export it with `toWire()`
|
|
83
|
+
* and let that agent import it. Omit it to mint a local session with a
|
|
84
|
+
* fresh holder key.
|
|
85
|
+
*
|
|
86
|
+
* `max_depth` caps how many times the authority may be delegated below
|
|
87
|
+
* the root (0 = terminal). Omit for the protocol maximum.
|
|
88
|
+
*/
|
|
89
|
+
mint(allow_json: any, ttl_seconds: number, require_approval: any, holder_hex?: string | null, max_depth?: number | null): SdkSession;
|
|
90
|
+
/**
|
|
91
|
+
* `mint()` with every option the protocol offers: kind, clearance,
|
|
92
|
+
* session and agent ids, approval gates with messages and per-argument
|
|
93
|
+
* triggers, and issuer-warrant fields. Keys are camelCase; unknown keys
|
|
94
|
+
* are rejected.
|
|
43
95
|
*/
|
|
44
|
-
|
|
96
|
+
mintExtended(options: any): SdkSession;
|
|
45
97
|
/**
|
|
46
|
-
* Attenuate the leaf. The current holder signs
|
|
98
|
+
* Attenuate the leaf. The current holder signs.
|
|
99
|
+
*
|
|
100
|
+
* Without `options.holder` the same holder keeps the child. With it, the
|
|
101
|
+
* child is bound to that public key: this is delegation to another agent,
|
|
102
|
+
* and the returned session carries no holder secret (see `SdkSession`).
|
|
103
|
+
* Core rejects any child that is not within its parent — tools,
|
|
104
|
+
* constraints, lifetime, and depth — before a token exists.
|
|
47
105
|
*/
|
|
48
|
-
narrow(session: SdkSession, allow_json: any): SdkSession;
|
|
106
|
+
narrow(session: SdkSession, allow_json: any, options: any): SdkSession;
|
|
49
107
|
constructor();
|
|
50
108
|
/**
|
|
51
109
|
* Holder PoP only. Does not authorize. Used to fill `_meta.tenuo.signature`.
|
|
@@ -55,10 +113,25 @@ export class SdkContext {
|
|
|
55
113
|
* Test / host seam. Signs an SRL with the local issuer. Does not load it.
|
|
56
114
|
*/
|
|
57
115
|
signRevocationList(ids: any): string;
|
|
116
|
+
/**
|
|
117
|
+
* Sign a revocation list with this context's issuer key. Load it with
|
|
118
|
+
* `loadRevocationList` anywhere this issuer is a trusted root.
|
|
119
|
+
*/
|
|
120
|
+
signRevocationListVersioned(ids: any, version?: number | null): string;
|
|
121
|
+
/**
|
|
122
|
+
* Sign verifier receipts with this 32-byte holder secret instead of an
|
|
123
|
+
* ephemeral key. Used by the TypeScript `Runtime`.
|
|
124
|
+
*/
|
|
125
|
+
withReceiptSigner(secret: Uint8Array): SdkContext;
|
|
58
126
|
}
|
|
59
127
|
|
|
60
128
|
/**
|
|
61
129
|
* Opaque warrant chain (root first) + leaf holder key. Not JSON-serializable from JS.
|
|
130
|
+
*
|
|
131
|
+
* `holder` is `None` when the leaf was issued or delegated to another agent's
|
|
132
|
+
* key. Such a session can be exported with `toWire()` and handed over, but it
|
|
133
|
+
* cannot sign proof-of-possession here; the holder imports it with
|
|
134
|
+
* `SdkSession.fromWire` and its own secret.
|
|
62
135
|
*/
|
|
63
136
|
export class SdkSession {
|
|
64
137
|
private constructor();
|
|
@@ -69,6 +142,11 @@ export class SdkSession {
|
|
|
69
142
|
* Not a PoP. MCP replay uses the PoP signature, not this key.
|
|
70
143
|
*/
|
|
71
144
|
dedupKey(tool: string, args_json: any): string;
|
|
145
|
+
/**
|
|
146
|
+
* Public view of the leaf: holder public key, depth, ceiling, lifetime,
|
|
147
|
+
* tools. Never the holder secret.
|
|
148
|
+
*/
|
|
149
|
+
describe(): any;
|
|
72
150
|
/**
|
|
73
151
|
* Test / interop seam. Not on the public TypeScript Session type.
|
|
74
152
|
*/
|
|
@@ -99,6 +177,16 @@ export class SdkSession {
|
|
|
99
177
|
warrantIds(): any;
|
|
100
178
|
}
|
|
101
179
|
|
|
180
|
+
/**
|
|
181
|
+
* Typed preflight of a warrant's approval gates for `(tool, args)`.
|
|
182
|
+
*
|
|
183
|
+
* Returns `{ status: "not_gated"|"exempt"|"required"|"denied", tool, kind?,
|
|
184
|
+
* argument?, arguments, message?, code?, reason?, error? }`. Parse errors
|
|
185
|
+
* fail closed with `status: "required"` and `error` set (no fabricated
|
|
186
|
+
* `kind`). `denied` means the warrant's constraints refuse the call.
|
|
187
|
+
*/
|
|
188
|
+
export function approval_requirement(warrant_b64: string, tool: string, args_json: any): any;
|
|
189
|
+
|
|
102
190
|
export function check_access(warrant_b64: string, tool: string, args_json: any, trusted_root_hex: string, dry_run: boolean): any;
|
|
103
191
|
|
|
104
192
|
/**
|
|
@@ -175,6 +263,9 @@ export function decode_warrant(base64_warrant: string): any;
|
|
|
175
263
|
* Returns `{ approval_required: true/false, tool, error }`.
|
|
176
264
|
* This reads `extensions["tenuo.approval_gates"]` from the warrant, parses it,
|
|
177
265
|
* and runs the gate evaluation logic from tenuo-core.
|
|
266
|
+
*
|
|
267
|
+
* Malformed warrants, gate maps, or arguments fail closed (`approval_required: true`).
|
|
268
|
+
* Prefer `approval_requirement` when the caller must distinguish exemptions.
|
|
178
269
|
*/
|
|
179
270
|
export function evaluate_approval_gates(warrant_b64: string, tool: string, args_json: any): any;
|
|
180
271
|
|
|
@@ -186,25 +277,58 @@ export function generate_keypair(): any;
|
|
|
186
277
|
export function init_panic_hook(): void;
|
|
187
278
|
|
|
188
279
|
/**
|
|
189
|
-
*
|
|
280
|
+
* Inspect how a warrant gates `tool`, without evaluating arguments.
|
|
190
281
|
*
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
282
|
+
* Returns `{ kind: "none"|"whole_tool"|"conditional", tool, arguments, message?, error? }`.
|
|
283
|
+
* Parse errors fail closed with `kind: "unknown"` and `error` set so callers
|
|
284
|
+
* cannot treat a malformed map as ungated.
|
|
285
|
+
*/
|
|
286
|
+
export function inspect_approval_gate(warrant_b64: string, tool: string): any;
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Parse a complete `tenuo_ct_…` token into its component fields.
|
|
290
|
+
*
|
|
291
|
+
* Accepts padded and unpadded Base64URL. Version must be 1; omitted `v`
|
|
292
|
+
* is an error. Trailing `/v1` is stripped from `e`.
|
|
293
|
+
* Registration-token aliases: `t`, `r`, `registration_token`.
|
|
194
294
|
*
|
|
195
295
|
* Returns `{ endpoint, apiKey, agentId?, registrationToken?, error? }`.
|
|
196
296
|
*/
|
|
197
297
|
export function parse_connect_token(token: string): any;
|
|
198
298
|
|
|
299
|
+
/**
|
|
300
|
+
* Decode and check an approval envelope. Not authorization.
|
|
301
|
+
*/
|
|
302
|
+
export function sdkInspectApproval(envelope: string): any;
|
|
303
|
+
|
|
199
304
|
export function sdkInspectParts(payload_hex: string, signature_hex: string): any;
|
|
200
305
|
|
|
306
|
+
/**
|
|
307
|
+
* Decode a signed revocation list without loading it.
|
|
308
|
+
*/
|
|
309
|
+
export function sdkInspectRevocationList(wire: string): any;
|
|
310
|
+
|
|
201
311
|
export function sdkInspectWarrant(wire: string): any;
|
|
202
312
|
|
|
313
|
+
export function sdkProtocolLimits(): any;
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Public key (hex) for a 32-byte Ed25519 holder secret. What an agent hands
|
|
317
|
+
* to whoever will issue or delegate a warrant to it.
|
|
318
|
+
*/
|
|
319
|
+
export function sdkPublicKeyFromHolderKey(holder_secret: Uint8Array): string;
|
|
320
|
+
|
|
203
321
|
/**
|
|
204
322
|
* Test / host seam. Signs a SignedApproval envelope; does not authorize.
|
|
205
323
|
*/
|
|
206
324
|
export function sdkSignApproval(session: SdkSession, tool: string, args_json: any, approver_secret: Uint8Array, external_id: string, as_of?: number | null): string;
|
|
207
325
|
|
|
326
|
+
/**
|
|
327
|
+
* Sign an approval for a request hash. The approver never needs the
|
|
328
|
+
* warrant or the holder key; the hash already commits to both.
|
|
329
|
+
*/
|
|
330
|
+
export function sdkSignApprovalForRequest(request_hash_hex: string, approver_secret: Uint8Array, external_id: string, ttl_seconds?: number | null, warrant_expires_at?: number | null): string;
|
|
331
|
+
|
|
208
332
|
/**
|
|
209
333
|
* Test seam. Signs the published generator envelope (not the in-memory SRL codec).
|
|
210
334
|
*/
|
|
@@ -215,6 +339,11 @@ export function sdkSignPublishedRevocationList(ids: any, version: number, issuer
|
|
|
215
339
|
*/
|
|
216
340
|
export function sdkSignRevocationList(ids: any, issuer_secret: Uint8Array): string;
|
|
217
341
|
|
|
342
|
+
/**
|
|
343
|
+
* Sign a revocation list with an explicit issuer secret (control-plane path).
|
|
344
|
+
*/
|
|
345
|
+
export function sdkSignRevocationListVersioned(ids: any, version: number | null | undefined, issuer_secret: Uint8Array): string;
|
|
346
|
+
|
|
218
347
|
/**
|
|
219
348
|
* Signature authenticity only. Not authorization.
|
|
220
349
|
*/
|