@traffic-twin/sdk 0.0.0-stage → 0.1.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/LICENSE +202 -0
- package/README.md +171 -2
- package/dist/cjs/agent.d.ts +143 -0
- package/dist/cjs/agent.js +927 -0
- package/dist/cjs/capture/body.d.ts +11 -0
- package/dist/cjs/capture/body.js +73 -0
- package/dist/cjs/capture/common.d.ts +75 -0
- package/dist/cjs/capture/common.js +180 -0
- package/dist/cjs/capture/context.d.ts +28 -0
- package/dist/cjs/capture/context.js +92 -0
- package/dist/cjs/capture/inbound.d.ts +12 -0
- package/dist/cjs/capture/inbound.js +195 -0
- package/dist/cjs/capture/outbound-http.d.ts +4 -0
- package/dist/cjs/capture/outbound-http.js +200 -0
- package/dist/cjs/capture/outbound-undici.d.ts +2 -0
- package/dist/cjs/capture/outbound-undici.js +242 -0
- package/dist/cjs/capture/wire.d.ts +27 -0
- package/dist/cjs/capture/wire.js +68 -0
- package/dist/cjs/export/event.d.ts +46 -0
- package/dist/cjs/export/event.js +91 -0
- package/dist/cjs/export/exporter.d.ts +50 -0
- package/dist/cjs/export/exporter.js +192 -0
- package/dist/cjs/export/pipeline.d.ts +20 -0
- package/dist/cjs/export/pipeline.js +40 -0
- package/dist/cjs/fleet/asn1.d.ts +44 -0
- package/dist/cjs/fleet/asn1.js +150 -0
- package/dist/cjs/fleet/client.d.ts +84 -0
- package/dist/cjs/fleet/client.js +216 -0
- package/dist/cjs/fleet/http.d.ts +17 -0
- package/dist/cjs/fleet/http.js +80 -0
- package/dist/cjs/fleet/store.d.ts +18 -0
- package/dist/cjs/fleet/store.js +115 -0
- package/dist/cjs/index.d.ts +14 -0
- package/dist/cjs/index.js +69 -0
- package/dist/cjs/log.d.ts +4 -0
- package/dist/cjs/log.js +30 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/register.d.ts +1 -0
- package/dist/cjs/register.js +18 -0
- package/dist/cjs/sanitizer/bodies.d.ts +55 -0
- package/dist/cjs/sanitizer/bodies.js +710 -0
- package/dist/cjs/sanitizer/formats.d.ts +26 -0
- package/dist/cjs/sanitizer/formats.js +110 -0
- package/dist/cjs/sanitizer/graphql.d.ts +23 -0
- package/dist/cjs/sanitizer/graphql.js +478 -0
- package/dist/cjs/sanitizer/hostpat.d.ts +15 -0
- package/dist/cjs/sanitizer/hostpat.js +129 -0
- package/dist/cjs/sanitizer/json.d.ts +60 -0
- package/dist/cjs/sanitizer/json.js +460 -0
- package/dist/cjs/sanitizer/policy.d.ts +224 -0
- package/dist/cjs/sanitizer/policy.js +820 -0
- package/dist/cjs/sanitizer/sanitizer.d.ts +149 -0
- package/dist/cjs/sanitizer/sanitizer.js +1473 -0
- package/dist/cjs/sanitizer/utf8.d.ts +22 -0
- package/dist/cjs/sanitizer/utf8.js +180 -0
- package/dist/cjs/sanitizer/vectors.d.ts +22 -0
- package/dist/cjs/sanitizer/vectors.js +130 -0
- package/dist/cjs/version.d.ts +2 -0
- package/dist/cjs/version.js +5 -0
- package/dist/cjs/worker/dir.d.ts +1 -0
- package/dist/cjs/worker/dir.js +8 -0
- package/dist/cjs/worker/pool.d.ts +47 -0
- package/dist/cjs/worker/pool.js +179 -0
- package/dist/cjs/worker/protocol.d.ts +37 -0
- package/dist/cjs/worker/protocol.js +3 -0
- package/dist/cjs/worker/sanitizer-worker.d.ts +1 -0
- package/dist/cjs/worker/sanitizer-worker.js +53 -0
- package/dist/esm/agent.d.ts +143 -0
- package/dist/esm/agent.js +921 -0
- package/dist/esm/capture/body.d.ts +11 -0
- package/dist/esm/capture/body.js +69 -0
- package/dist/esm/capture/common.d.ts +75 -0
- package/dist/esm/capture/common.js +166 -0
- package/dist/esm/capture/context.d.ts +28 -0
- package/dist/esm/capture/context.js +84 -0
- package/dist/esm/capture/inbound.d.ts +12 -0
- package/dist/esm/capture/inbound.js +187 -0
- package/dist/esm/capture/outbound-http.d.ts +4 -0
- package/dist/esm/capture/outbound-http.js +193 -0
- package/dist/esm/capture/outbound-undici.d.ts +2 -0
- package/dist/esm/capture/outbound-undici.js +236 -0
- package/dist/esm/capture/wire.d.ts +27 -0
- package/dist/esm/capture/wire.js +65 -0
- package/dist/esm/export/event.d.ts +46 -0
- package/dist/esm/export/event.js +85 -0
- package/dist/esm/export/exporter.d.ts +50 -0
- package/dist/esm/export/exporter.js +188 -0
- package/dist/esm/export/pipeline.d.ts +20 -0
- package/dist/esm/export/pipeline.js +37 -0
- package/dist/esm/fleet/asn1.d.ts +44 -0
- package/dist/esm/fleet/asn1.js +128 -0
- package/dist/esm/fleet/client.d.ts +84 -0
- package/dist/esm/fleet/client.js +204 -0
- package/dist/esm/fleet/http.d.ts +17 -0
- package/dist/esm/fleet/http.js +73 -0
- package/dist/esm/fleet/store.d.ts +18 -0
- package/dist/esm/fleet/store.js +110 -0
- package/dist/esm/index.d.ts +14 -0
- package/dist/esm/index.js +48 -0
- package/dist/esm/log.d.ts +4 -0
- package/dist/esm/log.js +25 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/register.d.ts +1 -0
- package/dist/esm/register.js +16 -0
- package/dist/esm/sanitizer/bodies.d.ts +55 -0
- package/dist/esm/sanitizer/bodies.js +694 -0
- package/dist/esm/sanitizer/formats.d.ts +26 -0
- package/dist/esm/sanitizer/formats.js +101 -0
- package/dist/esm/sanitizer/graphql.d.ts +23 -0
- package/dist/esm/sanitizer/graphql.js +472 -0
- package/dist/esm/sanitizer/hostpat.d.ts +15 -0
- package/dist/esm/sanitizer/hostpat.js +122 -0
- package/dist/esm/sanitizer/json.d.ts +60 -0
- package/dist/esm/sanitizer/json.js +447 -0
- package/dist/esm/sanitizer/policy.d.ts +224 -0
- package/dist/esm/sanitizer/policy.js +800 -0
- package/dist/esm/sanitizer/sanitizer.d.ts +149 -0
- package/dist/esm/sanitizer/sanitizer.js +1459 -0
- package/dist/esm/sanitizer/utf8.d.ts +22 -0
- package/dist/esm/sanitizer/utf8.js +166 -0
- package/dist/esm/sanitizer/vectors.d.ts +22 -0
- package/dist/esm/sanitizer/vectors.js +125 -0
- package/dist/esm/version.d.ts +2 -0
- package/dist/esm/version.js +2 -0
- package/dist/esm/worker/dir.d.ts +1 -0
- package/dist/esm/worker/dir.js +5 -0
- package/dist/esm/worker/pool.d.ts +47 -0
- package/dist/esm/worker/pool.js +175 -0
- package/dist/esm/worker/protocol.d.ts +37 -0
- package/dist/esm/worker/protocol.js +2 -0
- package/dist/esm/worker/sanitizer-worker.d.ts +1 -0
- package/dist/esm/worker/sanitizer-worker.js +51 -0
- package/package.json +75 -4
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { type KeyObject } from 'node:crypto';
|
|
2
|
+
import { lexemeWithinLimits, type Plain } from './json.js';
|
|
3
|
+
import { cmpUtf8 } from './utf8.js';
|
|
4
|
+
export declare class Refused extends Error {
|
|
5
|
+
readonly code: 'no_policy' | 'policy_rejected' | 'expired_policy' | 'key_missing' | 'key_mismatch';
|
|
6
|
+
readonly detail: string;
|
|
7
|
+
constructor(code: 'no_policy' | 'policy_rejected' | 'expired_policy' | 'key_missing' | 'key_mismatch', detail?: string);
|
|
8
|
+
}
|
|
9
|
+
export declare const RESERVED_DOMAINS: Set<string>;
|
|
10
|
+
export declare const BODY_FORMAT = "tt.policy.body/v1";
|
|
11
|
+
export declare const ENVELOPE_FORMAT = "tt.policy.compiled/v1";
|
|
12
|
+
export declare const SIGNATURE_PREFIX: Buffer<ArrayBuffer>;
|
|
13
|
+
export interface Bound {
|
|
14
|
+
canon: string;
|
|
15
|
+
d: number;
|
|
16
|
+
}
|
|
17
|
+
export interface Action {
|
|
18
|
+
action: 'drop' | 'keep' | 'code' | 'graphql' | 'hmac' | 'bucket';
|
|
19
|
+
domain?: string;
|
|
20
|
+
kind?: 'num' | 'time';
|
|
21
|
+
bounds?: Bound[];
|
|
22
|
+
unit?: 'year' | 'month' | 'day' | 'hour';
|
|
23
|
+
/** code only (spec v1.19, sanitizer.md 5.6): the alnum shape. */
|
|
24
|
+
shape?: 'alnum';
|
|
25
|
+
}
|
|
26
|
+
export type Step = {
|
|
27
|
+
t: 'name';
|
|
28
|
+
name: string;
|
|
29
|
+
} | {
|
|
30
|
+
t: 'any';
|
|
31
|
+
} | {
|
|
32
|
+
t: 'idx';
|
|
33
|
+
};
|
|
34
|
+
export interface BodyRule {
|
|
35
|
+
path: string;
|
|
36
|
+
steps: Step[];
|
|
37
|
+
names: number;
|
|
38
|
+
action: Action;
|
|
39
|
+
}
|
|
40
|
+
export interface Part {
|
|
41
|
+
query: Map<string, Action>;
|
|
42
|
+
headers: Map<string, Action>;
|
|
43
|
+
cookies: Map<string, Action>;
|
|
44
|
+
path: Map<string, Action>;
|
|
45
|
+
body: BodyRule[];
|
|
46
|
+
}
|
|
47
|
+
export interface TemplateSeg {
|
|
48
|
+
lit?: string;
|
|
49
|
+
param?: string;
|
|
50
|
+
}
|
|
51
|
+
export interface Op {
|
|
52
|
+
key: string;
|
|
53
|
+
method: string;
|
|
54
|
+
segs: TemplateSeg[];
|
|
55
|
+
literals: number;
|
|
56
|
+
request?: Part;
|
|
57
|
+
response?: Part;
|
|
58
|
+
}
|
|
59
|
+
export interface Service {
|
|
60
|
+
name: string;
|
|
61
|
+
inbound: boolean;
|
|
62
|
+
internal: boolean;
|
|
63
|
+
base?: {
|
|
64
|
+
origin: string;
|
|
65
|
+
segs: string[];
|
|
66
|
+
};
|
|
67
|
+
request?: Part;
|
|
68
|
+
response?: Part;
|
|
69
|
+
errors?: Part;
|
|
70
|
+
ops: Op[];
|
|
71
|
+
/** Candidate ops by `METHOD/segment-count`, in policy order (built on first use; same result as scanning `ops`). */
|
|
72
|
+
opIndex?: Map<string, Op[]>;
|
|
73
|
+
}
|
|
74
|
+
export interface Limits {
|
|
75
|
+
maxBodyBytes: number;
|
|
76
|
+
maxDepth: number;
|
|
77
|
+
maxArray: number;
|
|
78
|
+
maxKeys: number;
|
|
79
|
+
keepMaxBytes: number;
|
|
80
|
+
}
|
|
81
|
+
/** Spec v1.19 (sanitizer.md 22.1): `bodies` of the compiled body; absent = every switch off. */
|
|
82
|
+
export interface Bodies {
|
|
83
|
+
xml: boolean;
|
|
84
|
+
multipart: boolean;
|
|
85
|
+
docs: boolean;
|
|
86
|
+
maxLargeBodyBytes: number;
|
|
87
|
+
largeArray: number;
|
|
88
|
+
largeNestedArray: number;
|
|
89
|
+
}
|
|
90
|
+
export declare const BODIES_OFF: Bodies;
|
|
91
|
+
export declare const DEFAULT_LIMITS: Limits;
|
|
92
|
+
/** `jsonPath` (spec v1.18): dotted path of members inside a header whose value is a JSON object or base64/base64url of one. */
|
|
93
|
+
export interface SubjectSpec {
|
|
94
|
+
from: 'header' | 'cookie';
|
|
95
|
+
name: string;
|
|
96
|
+
jwtClaim?: string;
|
|
97
|
+
jsonPath?: string;
|
|
98
|
+
}
|
|
99
|
+
/** Ready-to-use compiled policy. */
|
|
100
|
+
export declare class Policy {
|
|
101
|
+
readonly body: {
|
|
102
|
+
[k: string]: Plain;
|
|
103
|
+
};
|
|
104
|
+
readonly policyId: string;
|
|
105
|
+
readonly version: number;
|
|
106
|
+
readonly issuedSeq: number;
|
|
107
|
+
readonly createdAt: number;
|
|
108
|
+
readonly notAfter: number;
|
|
109
|
+
readonly groups: string[];
|
|
110
|
+
readonly kid: string;
|
|
111
|
+
readonly acceptKids: string[];
|
|
112
|
+
readonly epoch: string;
|
|
113
|
+
readonly subject?: SubjectSpec;
|
|
114
|
+
readonly rateBp: number;
|
|
115
|
+
readonly trustBaggage: boolean;
|
|
116
|
+
readonly propagateTo: Set<string>;
|
|
117
|
+
readonly autoWords: boolean;
|
|
118
|
+
readonly autoWordsExpiresAt: number;
|
|
119
|
+
readonly allow: Set<string>;
|
|
120
|
+
readonly hostsAllow: Set<string>;
|
|
121
|
+
/** Spec v1.5 `hosts.discovery`: true = `auto` (default, also when `hosts` is absent), false = `off` (strict mode). */
|
|
122
|
+
readonly hostsAuto: boolean;
|
|
123
|
+
readonly limits: Limits;
|
|
124
|
+
readonly bodies: Bodies;
|
|
125
|
+
/**
|
|
126
|
+
* Bytes of a body a source keeps (sanitizer.md 9.0 and 22.5): max(max_body_bytes,
|
|
127
|
+
* bodies.max_large_body_bytes) + 1. The rest is only counted.
|
|
128
|
+
*/
|
|
129
|
+
readonly captureLimit: number;
|
|
130
|
+
readonly discoveryEnabled: boolean;
|
|
131
|
+
readonly discoveryExpiresAt: number;
|
|
132
|
+
readonly global: {
|
|
133
|
+
request?: Part;
|
|
134
|
+
response?: Part;
|
|
135
|
+
errors?: Part;
|
|
136
|
+
};
|
|
137
|
+
readonly services: Service[];
|
|
138
|
+
readonly inbound: Map<string, Service>;
|
|
139
|
+
readonly baseHosts: Set<string>;
|
|
140
|
+
/** SHA-256 of the body bytes, when known (`sha256:<hex>`). */
|
|
141
|
+
hash: string;
|
|
142
|
+
/** Signed body bytes, when known: lets a worker thread rebuild this policy. */
|
|
143
|
+
bodyBytes?: Buffer;
|
|
144
|
+
constructor(body: {
|
|
145
|
+
[k: string]: Plain;
|
|
146
|
+
});
|
|
147
|
+
/** 4.3: auto words active at `now` (ms). */
|
|
148
|
+
autoWordsActive(now: number | undefined): boolean;
|
|
149
|
+
/** 15: discovery active at `now` (ms). */
|
|
150
|
+
discoveryActive(now: number | undefined): boolean;
|
|
151
|
+
}
|
|
152
|
+
/** RFC 3339 timestamp to epoch milliseconds; NaN when absent or malformed. */
|
|
153
|
+
export declare function parseTime(v: Plain | undefined): number;
|
|
154
|
+
/** Parses a tt-path; returns null if it does not follow the grammar. */
|
|
155
|
+
export declare function parseTtPath(p: string): Step[] | null;
|
|
156
|
+
export declare function parseOpKey(key: string): Omit<Op, 'request' | 'response'> | null;
|
|
157
|
+
/** Splits a normalized `match.base` into origin and path segments. */
|
|
158
|
+
export declare function splitBase(base: string): {
|
|
159
|
+
origin: string;
|
|
160
|
+
segs: string[];
|
|
161
|
+
};
|
|
162
|
+
/** Detail prefix of a Refused raised by the v1.3 safety subset; the agent reports it as `policy_unsafe`. */
|
|
163
|
+
export declare const UNSAFE_DETAIL = "unsafe";
|
|
164
|
+
/**
|
|
165
|
+
* Source-side safety subset (hardening.md 2.1, v1.3), applied to every signed body, whatever
|
|
166
|
+
* the validity of tt-core and keyguard:
|
|
167
|
+
* H1 keep, code (v1.11, any shape) or hmac on authorization, cookie, set-cookie, proxy-authorization (header rules of
|
|
168
|
+
* request, response and errors; global, services and operations);
|
|
169
|
+
* H2 keep, code (v1.11) or hmac on a tt-path with any wildcard step (`.*` or `[*]`) in the global body rules;
|
|
170
|
+
* H3 discovery or auto_words expiring later than created_at + 7 days.
|
|
171
|
+
* Properties of the body: neither the clock nor the group matter.
|
|
172
|
+
*/
|
|
173
|
+
export declare function checkUnsafe(b: {
|
|
174
|
+
[k: string]: Plain;
|
|
175
|
+
}): void;
|
|
176
|
+
/** Minimal body checks of the conformance runner (format.md, step 1), plus the v1.3 safety subset. */
|
|
177
|
+
export declare function checkBodyMinimal(body: Plain): {
|
|
178
|
+
[k: string]: Plain;
|
|
179
|
+
};
|
|
180
|
+
/** Full schema validation of a policy body, plus reserved domains, double bounds and the v1.3 safety subset. */
|
|
181
|
+
export declare function validateBodySchema(body: Plain): {
|
|
182
|
+
[k: string]: Plain;
|
|
183
|
+
};
|
|
184
|
+
/** Strict base64url without padding; null on any other character or impossible length. */
|
|
185
|
+
export declare function b64urlDecodeStrict(s: string): Buffer | null;
|
|
186
|
+
export declare function b64urlNoPad(b: Uint8Array): string;
|
|
187
|
+
/** Ed25519 public key object from the raw 32 bytes (base64url, no padding). */
|
|
188
|
+
export declare function ed25519PublicKey(rawB64url: string): KeyObject | null;
|
|
189
|
+
export interface VerifiedPolicy {
|
|
190
|
+
bodyBytes: Buffer;
|
|
191
|
+
body: {
|
|
192
|
+
[k: string]: Plain;
|
|
193
|
+
};
|
|
194
|
+
hash: string;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Verifies a `tt.policy.compiled/v1` envelope (policy.md 3-4 conditions 1-2). `keys` maps a
|
|
198
|
+
* pinned, non-revoked signature kid to its public key. `strict` applies the full body
|
|
199
|
+
* schema (production); otherwise only the minimal body checks of the conformance runner.
|
|
200
|
+
*/
|
|
201
|
+
export declare function verifyEnvelope(env: Plain, keys: Map<string, KeyObject>, strict: boolean): VerifiedPolicy;
|
|
202
|
+
/**
|
|
203
|
+
* policy.md 4, conditions 3-5: group, expiry, issued_seq ordering. `allowEqualSeq` lets a
|
|
204
|
+
* source re-verify the very policy it already accepted (cache at start-up).
|
|
205
|
+
*/
|
|
206
|
+
export declare function checkAcceptance(p: Policy, o: {
|
|
207
|
+
group: string;
|
|
208
|
+
now: number;
|
|
209
|
+
lastIssuedSeq: number;
|
|
210
|
+
minIssuedSeq: number;
|
|
211
|
+
allowEqualSeq?: boolean;
|
|
212
|
+
}): void;
|
|
213
|
+
export interface KeyRing {
|
|
214
|
+
keys: Map<string, Buffer>;
|
|
215
|
+
order: string[];
|
|
216
|
+
}
|
|
217
|
+
/** Parses the content of TT_HMAC_KEY / TT_HMAC_KEY_FILE. Throws Refused('key_missing'). */
|
|
218
|
+
export declare function parseKeyRing(text: string | undefined | null): KeyRing;
|
|
219
|
+
/** 7.1: picks the key for a policy (hmac.kid, then accept_kids in order). */
|
|
220
|
+
export declare function selectKey(ring: KeyRing, policy: Policy): {
|
|
221
|
+
kid: string;
|
|
222
|
+
key: Buffer;
|
|
223
|
+
};
|
|
224
|
+
export { cmpUtf8, lexemeWithinLimits };
|