@armoriq/policy-ir 0.1.2 → 0.1.4

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/dist/index.d.cts CHANGED
@@ -1,105 +1,5 @@
1
- /**
2
- * `armor.policy.v2` intermediate representation.
3
- *
4
- * Data, never a program: the same JSON is evaluated by conmap, the Armor CLI
5
- * daemon, the SDK pre-check and OPA. The document is the hashing and signing
6
- * boundary, so every field here is part of `policyHash` except `policyHash`.
7
- */
8
- declare const SCHEMA_VERSION: "armor.policy.v2";
9
- type Verdict = 'allow' | 'hold' | 'block';
10
- /** Where a document sits in the layering ladder. A boundary is a floor: it can only tighten. */
11
- type Layer = 'floor' | 'group' | 'agent' | 'member' | 'local';
12
- type PolicyTarget = {
13
- org: '*';
14
- } | {
15
- group: string;
16
- } | {
17
- agent: string;
18
- mcpServers?: string[];
19
- } | {
20
- device: 'local';
21
- products?: string[];
22
- };
23
- interface Defaults {
24
- tools: Verdict;
25
- network: Verdict;
26
- files: Verdict;
27
- skills: Verdict;
28
- }
29
- interface Capture {
30
- arguments: boolean;
31
- redact: string[];
32
- maxBytesPerCall: number;
33
- sample: number;
34
- }
35
- type KeyTier = 'exact' | 'glob';
36
- type StatementMatch = {
37
- tool: string;
38
- keyTier: KeyTier;
39
- order: number;
40
- } | {
41
- capability: string;
42
- };
43
- type ConditionOp = 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'in' | 'notIn' | 'glob' | 'regex' | 'notRegex' | 'startsWith' | 'exists';
44
- interface SchemaBinding {
45
- /** `sha256:` of the tool's canonical input schema at compile time; null when the inventory had none. */
46
- schemaHash: string | null;
47
- }
48
- interface Condition {
49
- /** Dotpath into the call: `args.amount`, `args.command.program`, `path`. */
50
- field: string;
51
- op: ConditionOp;
52
- value?: unknown;
53
- schemaBinding?: SchemaBinding;
54
- }
55
- interface Approval {
56
- approvers: number;
57
- roles?: string[];
58
- members?: string[];
59
- anyMember?: boolean;
60
- }
61
- /** Who a statement applies to. Absent means everyone the document targets. */
62
- type Subject = {
63
- membershipId: string;
64
- } | {
65
- email: string;
66
- } | {
67
- group: string;
68
- } | {
69
- product: string;
70
- };
71
- interface Provenance {
72
- ruleKey: string;
73
- variant: number;
74
- source: 'yaml' | 'converter' | 'compose' | 'settings-import';
75
- layer: Layer;
76
- }
77
- interface Statement {
78
- id: string;
79
- subject: Subject | null;
80
- match: StatementMatch;
81
- effect: Verdict;
82
- conditions: Condition[];
83
- approval?: Approval;
84
- /** ISO date-time, or the literal `never`. Always present. */
85
- expiresAt: string | 'never';
86
- controls?: string[];
87
- provenance: Provenance;
88
- }
89
- interface PolicyDocument {
90
- schemaVersion: typeof SCHEMA_VERSION;
91
- policyId: string;
92
- /** `sha256:` over the canonical document without this field. */
93
- policyHash?: string;
94
- target: PolicyTarget;
95
- layer: Layer;
96
- defaults: Defaults;
97
- capture: Capture;
98
- /** ISO date-time, or the literal `never`. Always present. */
99
- expiresAt: string | 'never';
100
- statements: Statement[];
101
- }
102
- declare function layerOfTarget(target: PolicyTarget): Layer;
1
+ import { P as PolicyDocument, V as Verdict, A as Approval, L as Layer, C as Condition, S as Statement, a as SourceTarget, b as PolicySource, D as Diagnostics } from './document-entry-CDOQVeis.cjs';
2
+ export { c as Capture, d as ConditionOp, e as ConditionSpec, f as Defaults, g as Diagnostic, K as KeyTier, N as NEVER, h as NetworkEntry, O as Overlay, i as ParseResult, j as PolicySpec, k as PolicyTarget, l as Provenance, R as RuleValue, m as RuleVariant, n as SCHEMA_VERSION, o as SOURCE_OPERATORS, p as SchemaBinding, q as Severity, r as SourceOperator, s as StatementMatch, t as Subject, T as ToolsSection, u as VERDICTS, v as layerOfTarget, w as parseDocument, x as parseYaml, y as serialize, z as validate } from './document-entry-CDOQVeis.cjs';
103
3
 
104
4
  /**
105
5
  * Canonical JSON: sorted keys, no whitespace, ASCII escapes for anything
@@ -228,123 +128,6 @@ declare function conditionHolds(input: CallInput, condition: Condition): boolean
228
128
  */
229
129
  declare function selectRuleKey(statements: Statement[], tool: string): string | null;
230
130
 
231
- type Severity = 'error' | 'warning';
232
- interface Diagnostic {
233
- code: string;
234
- severity: Severity;
235
- /** JSON-pointer-like path into the source document, `/spec/tools/rules/Bash/0`. */
236
- path: string;
237
- message: string;
238
- }
239
- declare class Diagnostics {
240
- readonly items: Diagnostic[];
241
- error(code: string, path: string, message: string): void;
242
- warning(code: string, path: string, message: string): void;
243
- get hasErrors(): boolean;
244
- }
245
-
246
- /** The `armor.io/v2` source document after strict parsing, before lowering. */
247
- interface PolicySource {
248
- apiVersion: 'armor.io/v2';
249
- kind: 'Policy';
250
- metadata: {
251
- name: string;
252
- description?: string;
253
- orgId?: string;
254
- labels?: Record<string, string>;
255
- };
256
- target: SourceTarget;
257
- precedence?: 'device-first' | 'agent-first';
258
- spec: PolicySpec;
259
- }
260
- type SourceTarget = {
261
- agent: string;
262
- mcpServers?: string[];
263
- } | {
264
- group: string;
265
- } | {
266
- org: '*';
267
- } | {
268
- device: 'local';
269
- };
270
- interface PolicySpec {
271
- tools: ToolsSection;
272
- files?: {
273
- deny?: string[];
274
- allowOutsideWorkspace?: boolean;
275
- };
276
- network?: {
277
- default?: Verdict;
278
- allow?: NetworkEntry[];
279
- deny?: NetworkEntry[];
280
- };
281
- skills?: {
282
- default?: Verdict;
283
- hold?: string[];
284
- block?: string[];
285
- };
286
- secrets?: {
287
- envBlocklist?: string[];
288
- };
289
- members?: Record<string, Overlay>;
290
- products?: Record<string, Overlay>;
291
- capture?: {
292
- arguments?: boolean;
293
- redact?: string[];
294
- maxBytesPerCall?: number;
295
- sample?: number;
296
- };
297
- approvalDefaults?: Approval;
298
- expiresAt: string;
299
- }
300
- type NetworkEntry = string | {
301
- host: string;
302
- reason?: string;
303
- };
304
- interface ToolsSection {
305
- default: Verdict;
306
- rules?: Record<string, RuleValue>;
307
- }
308
- interface Overlay {
309
- tools?: {
310
- default?: Verdict;
311
- rules?: Record<string, RuleValue>;
312
- };
313
- expiresAt: string;
314
- }
315
- /** A scalar verdict is shorthand for one unconditional variant. */
316
- type RuleValue = Verdict | RuleVariant[];
317
- interface RuleVariant {
318
- action: Verdict;
319
- when?: Record<string, ConditionSpec>;
320
- approval?: Approval;
321
- reason?: string;
322
- controls?: string[];
323
- expiresAt: string;
324
- }
325
- /** `{gt: 5000}`, `{in: [a, b]}`, `{matches: '^x'}`, `{exists: true}`. Exactly one operator. */
326
- type ConditionSpec = Partial<Record<SourceOperator, unknown>>;
327
- declare const SOURCE_OPERATORS: readonly ["eq", "neq", "in", "notIn", "gt", "gte", "lt", "lte", "matches", "notMatches", "startsWith", "glob", "withinWorkspace", "exists"];
328
- type SourceOperator = (typeof SOURCE_OPERATORS)[number];
329
- declare const VERDICTS: readonly Verdict[];
330
- declare const NEVER = "never";
331
-
332
- interface ParseResult {
333
- source: PolicySource | null;
334
- diagnostics: Diagnostics;
335
- }
336
- /** Parse `armor.io/v2` YAML text strictly. */
337
- declare function parseYaml(text: string): ParseResult;
338
- /** Parse an already-loaded YAML/JSON value strictly. */
339
- declare function parseDocument(value: unknown): ParseResult;
340
-
341
- /**
342
- * Everything that can be checked without an inventory. Inventory-dependent
343
- * checks (roster clamp, glob collisions on real tools, schema binding) live in
344
- * the compiler.
345
- */
346
- declare function validate(source: PolicySource): Diagnostics;
347
-
348
131
  /** One tool the target can reach, as the inventory knows it. */
349
132
  interface InventoryTool {
350
133
  /** The wire name the model sees; for an MCP tool the host may also supply the qualified `mcp__<server>__<tool>` form as `qualifiedName`. */
@@ -394,14 +177,6 @@ interface CompileResult {
394
177
  declare function compile(source: PolicySource, inventory: InventoryTool[], options: CompileOptions): CompileResult;
395
178
  declare function compileWithPort(source: PolicySource, port: InventoryPort, options: CompileOptions): Promise<CompileResult>;
396
179
 
397
- /**
398
- * PolicySource back to YAML such that `parse(serialize(x))` equals `x`
399
- * (VC-10). A single unconditional variant with no other fields is written as
400
- * the scalar shorthand; `expiresAt: never` is written only where the parser
401
- * would not materialize it identically anyway (everywhere), so it is kept.
402
- */
403
- declare function serialize(source: PolicySource): string;
404
-
405
180
  type KeyKind = 'exact' | 'glob' | 'capability';
406
181
  interface ResolvedKey {
407
182
  kind: KeyKind;
@@ -423,4 +198,4 @@ declare function checkArgumentKeys(fields: string[], tool: InventoryTool, diag:
423
198
 
424
199
  declare const KNOWN_CONTROLS: ReadonlySet<string>;
425
200
 
426
- export { type Approval, type BoundDocuments, CAPABILITY_KEYS, type CallInput, type Capture, type CompileOptions, type CompileResult, type Condition, type ConditionOp, type ConditionSpec, type Defaults, type Diagnostic, Diagnostics, type Enforceability, type EnforceabilityReport, type Evaluation, HASH_PREFIX, type InventoryPort, type InventoryTool, KNOWN_CONTROLS, type KeyTier, type Layer, NEVER, type NetworkEntry, type Obligation, type Overlay, type ParseResult, type PolicyDocument, type PolicySource, type PolicySpec, type PolicyTarget, type Principal, type Provenance, type RuleValue, type RuleVariant, SCHEMA_VERSION, SOURCE_OPERATORS, type SchemaBinding, type SchemaDriftObligation, type Section, type Severity, type SourceOperator, type SourceTarget, type Statement, type StatementMatch, type Subject, type ToolsSection, VERDICTS, VERDICT_RANK, type Verdict, type VerdictProvenance, canonicalJson, checkArgumentKeys, checkGlobCollisions, compile, compileWithPort, conditionHolds, conditionsHold, enforceabilityReport, evaluate, globToRegExp, isGlob, layerOfTarget, matchGlob, parseDocument, parseYaml, policyHash, resolveField, resolveKey, schemaHash, selectRuleKey, serialize, sha256Canonical, stricter, validate, verifyPolicyHash };
201
+ export { Approval, type BoundDocuments, CAPABILITY_KEYS, type CallInput, type CompileOptions, type CompileResult, Condition, Diagnostics, type Enforceability, type EnforceabilityReport, type Evaluation, HASH_PREFIX, type InventoryPort, type InventoryTool, KNOWN_CONTROLS, Layer, type Obligation, PolicyDocument, PolicySource, type Principal, type SchemaDriftObligation, type Section, SourceTarget, Statement, VERDICT_RANK, Verdict, type VerdictProvenance, canonicalJson, checkArgumentKeys, checkGlobCollisions, compile, compileWithPort, conditionHolds, conditionsHold, enforceabilityReport, evaluate, globToRegExp, isGlob, matchGlob, policyHash, resolveField, resolveKey, schemaHash, selectRuleKey, sha256Canonical, stricter, verifyPolicyHash };
package/dist/index.d.ts CHANGED
@@ -1,105 +1,5 @@
1
- /**
2
- * `armor.policy.v2` intermediate representation.
3
- *
4
- * Data, never a program: the same JSON is evaluated by conmap, the Armor CLI
5
- * daemon, the SDK pre-check and OPA. The document is the hashing and signing
6
- * boundary, so every field here is part of `policyHash` except `policyHash`.
7
- */
8
- declare const SCHEMA_VERSION: "armor.policy.v2";
9
- type Verdict = 'allow' | 'hold' | 'block';
10
- /** Where a document sits in the layering ladder. A boundary is a floor: it can only tighten. */
11
- type Layer = 'floor' | 'group' | 'agent' | 'member' | 'local';
12
- type PolicyTarget = {
13
- org: '*';
14
- } | {
15
- group: string;
16
- } | {
17
- agent: string;
18
- mcpServers?: string[];
19
- } | {
20
- device: 'local';
21
- products?: string[];
22
- };
23
- interface Defaults {
24
- tools: Verdict;
25
- network: Verdict;
26
- files: Verdict;
27
- skills: Verdict;
28
- }
29
- interface Capture {
30
- arguments: boolean;
31
- redact: string[];
32
- maxBytesPerCall: number;
33
- sample: number;
34
- }
35
- type KeyTier = 'exact' | 'glob';
36
- type StatementMatch = {
37
- tool: string;
38
- keyTier: KeyTier;
39
- order: number;
40
- } | {
41
- capability: string;
42
- };
43
- type ConditionOp = 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'in' | 'notIn' | 'glob' | 'regex' | 'notRegex' | 'startsWith' | 'exists';
44
- interface SchemaBinding {
45
- /** `sha256:` of the tool's canonical input schema at compile time; null when the inventory had none. */
46
- schemaHash: string | null;
47
- }
48
- interface Condition {
49
- /** Dotpath into the call: `args.amount`, `args.command.program`, `path`. */
50
- field: string;
51
- op: ConditionOp;
52
- value?: unknown;
53
- schemaBinding?: SchemaBinding;
54
- }
55
- interface Approval {
56
- approvers: number;
57
- roles?: string[];
58
- members?: string[];
59
- anyMember?: boolean;
60
- }
61
- /** Who a statement applies to. Absent means everyone the document targets. */
62
- type Subject = {
63
- membershipId: string;
64
- } | {
65
- email: string;
66
- } | {
67
- group: string;
68
- } | {
69
- product: string;
70
- };
71
- interface Provenance {
72
- ruleKey: string;
73
- variant: number;
74
- source: 'yaml' | 'converter' | 'compose' | 'settings-import';
75
- layer: Layer;
76
- }
77
- interface Statement {
78
- id: string;
79
- subject: Subject | null;
80
- match: StatementMatch;
81
- effect: Verdict;
82
- conditions: Condition[];
83
- approval?: Approval;
84
- /** ISO date-time, or the literal `never`. Always present. */
85
- expiresAt: string | 'never';
86
- controls?: string[];
87
- provenance: Provenance;
88
- }
89
- interface PolicyDocument {
90
- schemaVersion: typeof SCHEMA_VERSION;
91
- policyId: string;
92
- /** `sha256:` over the canonical document without this field. */
93
- policyHash?: string;
94
- target: PolicyTarget;
95
- layer: Layer;
96
- defaults: Defaults;
97
- capture: Capture;
98
- /** ISO date-time, or the literal `never`. Always present. */
99
- expiresAt: string | 'never';
100
- statements: Statement[];
101
- }
102
- declare function layerOfTarget(target: PolicyTarget): Layer;
1
+ import { P as PolicyDocument, V as Verdict, A as Approval, L as Layer, C as Condition, S as Statement, a as SourceTarget, b as PolicySource, D as Diagnostics } from './document-entry-CDOQVeis.js';
2
+ export { c as Capture, d as ConditionOp, e as ConditionSpec, f as Defaults, g as Diagnostic, K as KeyTier, N as NEVER, h as NetworkEntry, O as Overlay, i as ParseResult, j as PolicySpec, k as PolicyTarget, l as Provenance, R as RuleValue, m as RuleVariant, n as SCHEMA_VERSION, o as SOURCE_OPERATORS, p as SchemaBinding, q as Severity, r as SourceOperator, s as StatementMatch, t as Subject, T as ToolsSection, u as VERDICTS, v as layerOfTarget, w as parseDocument, x as parseYaml, y as serialize, z as validate } from './document-entry-CDOQVeis.js';
103
3
 
104
4
  /**
105
5
  * Canonical JSON: sorted keys, no whitespace, ASCII escapes for anything
@@ -228,123 +128,6 @@ declare function conditionHolds(input: CallInput, condition: Condition): boolean
228
128
  */
229
129
  declare function selectRuleKey(statements: Statement[], tool: string): string | null;
230
130
 
231
- type Severity = 'error' | 'warning';
232
- interface Diagnostic {
233
- code: string;
234
- severity: Severity;
235
- /** JSON-pointer-like path into the source document, `/spec/tools/rules/Bash/0`. */
236
- path: string;
237
- message: string;
238
- }
239
- declare class Diagnostics {
240
- readonly items: Diagnostic[];
241
- error(code: string, path: string, message: string): void;
242
- warning(code: string, path: string, message: string): void;
243
- get hasErrors(): boolean;
244
- }
245
-
246
- /** The `armor.io/v2` source document after strict parsing, before lowering. */
247
- interface PolicySource {
248
- apiVersion: 'armor.io/v2';
249
- kind: 'Policy';
250
- metadata: {
251
- name: string;
252
- description?: string;
253
- orgId?: string;
254
- labels?: Record<string, string>;
255
- };
256
- target: SourceTarget;
257
- precedence?: 'device-first' | 'agent-first';
258
- spec: PolicySpec;
259
- }
260
- type SourceTarget = {
261
- agent: string;
262
- mcpServers?: string[];
263
- } | {
264
- group: string;
265
- } | {
266
- org: '*';
267
- } | {
268
- device: 'local';
269
- };
270
- interface PolicySpec {
271
- tools: ToolsSection;
272
- files?: {
273
- deny?: string[];
274
- allowOutsideWorkspace?: boolean;
275
- };
276
- network?: {
277
- default?: Verdict;
278
- allow?: NetworkEntry[];
279
- deny?: NetworkEntry[];
280
- };
281
- skills?: {
282
- default?: Verdict;
283
- hold?: string[];
284
- block?: string[];
285
- };
286
- secrets?: {
287
- envBlocklist?: string[];
288
- };
289
- members?: Record<string, Overlay>;
290
- products?: Record<string, Overlay>;
291
- capture?: {
292
- arguments?: boolean;
293
- redact?: string[];
294
- maxBytesPerCall?: number;
295
- sample?: number;
296
- };
297
- approvalDefaults?: Approval;
298
- expiresAt: string;
299
- }
300
- type NetworkEntry = string | {
301
- host: string;
302
- reason?: string;
303
- };
304
- interface ToolsSection {
305
- default: Verdict;
306
- rules?: Record<string, RuleValue>;
307
- }
308
- interface Overlay {
309
- tools?: {
310
- default?: Verdict;
311
- rules?: Record<string, RuleValue>;
312
- };
313
- expiresAt: string;
314
- }
315
- /** A scalar verdict is shorthand for one unconditional variant. */
316
- type RuleValue = Verdict | RuleVariant[];
317
- interface RuleVariant {
318
- action: Verdict;
319
- when?: Record<string, ConditionSpec>;
320
- approval?: Approval;
321
- reason?: string;
322
- controls?: string[];
323
- expiresAt: string;
324
- }
325
- /** `{gt: 5000}`, `{in: [a, b]}`, `{matches: '^x'}`, `{exists: true}`. Exactly one operator. */
326
- type ConditionSpec = Partial<Record<SourceOperator, unknown>>;
327
- declare const SOURCE_OPERATORS: readonly ["eq", "neq", "in", "notIn", "gt", "gte", "lt", "lte", "matches", "notMatches", "startsWith", "glob", "withinWorkspace", "exists"];
328
- type SourceOperator = (typeof SOURCE_OPERATORS)[number];
329
- declare const VERDICTS: readonly Verdict[];
330
- declare const NEVER = "never";
331
-
332
- interface ParseResult {
333
- source: PolicySource | null;
334
- diagnostics: Diagnostics;
335
- }
336
- /** Parse `armor.io/v2` YAML text strictly. */
337
- declare function parseYaml(text: string): ParseResult;
338
- /** Parse an already-loaded YAML/JSON value strictly. */
339
- declare function parseDocument(value: unknown): ParseResult;
340
-
341
- /**
342
- * Everything that can be checked without an inventory. Inventory-dependent
343
- * checks (roster clamp, glob collisions on real tools, schema binding) live in
344
- * the compiler.
345
- */
346
- declare function validate(source: PolicySource): Diagnostics;
347
-
348
131
  /** One tool the target can reach, as the inventory knows it. */
349
132
  interface InventoryTool {
350
133
  /** The wire name the model sees; for an MCP tool the host may also supply the qualified `mcp__<server>__<tool>` form as `qualifiedName`. */
@@ -394,14 +177,6 @@ interface CompileResult {
394
177
  declare function compile(source: PolicySource, inventory: InventoryTool[], options: CompileOptions): CompileResult;
395
178
  declare function compileWithPort(source: PolicySource, port: InventoryPort, options: CompileOptions): Promise<CompileResult>;
396
179
 
397
- /**
398
- * PolicySource back to YAML such that `parse(serialize(x))` equals `x`
399
- * (VC-10). A single unconditional variant with no other fields is written as
400
- * the scalar shorthand; `expiresAt: never` is written only where the parser
401
- * would not materialize it identically anyway (everywhere), so it is kept.
402
- */
403
- declare function serialize(source: PolicySource): string;
404
-
405
180
  type KeyKind = 'exact' | 'glob' | 'capability';
406
181
  interface ResolvedKey {
407
182
  kind: KeyKind;
@@ -423,4 +198,4 @@ declare function checkArgumentKeys(fields: string[], tool: InventoryTool, diag:
423
198
 
424
199
  declare const KNOWN_CONTROLS: ReadonlySet<string>;
425
200
 
426
- export { type Approval, type BoundDocuments, CAPABILITY_KEYS, type CallInput, type Capture, type CompileOptions, type CompileResult, type Condition, type ConditionOp, type ConditionSpec, type Defaults, type Diagnostic, Diagnostics, type Enforceability, type EnforceabilityReport, type Evaluation, HASH_PREFIX, type InventoryPort, type InventoryTool, KNOWN_CONTROLS, type KeyTier, type Layer, NEVER, type NetworkEntry, type Obligation, type Overlay, type ParseResult, type PolicyDocument, type PolicySource, type PolicySpec, type PolicyTarget, type Principal, type Provenance, type RuleValue, type RuleVariant, SCHEMA_VERSION, SOURCE_OPERATORS, type SchemaBinding, type SchemaDriftObligation, type Section, type Severity, type SourceOperator, type SourceTarget, type Statement, type StatementMatch, type Subject, type ToolsSection, VERDICTS, VERDICT_RANK, type Verdict, type VerdictProvenance, canonicalJson, checkArgumentKeys, checkGlobCollisions, compile, compileWithPort, conditionHolds, conditionsHold, enforceabilityReport, evaluate, globToRegExp, isGlob, layerOfTarget, matchGlob, parseDocument, parseYaml, policyHash, resolveField, resolveKey, schemaHash, selectRuleKey, serialize, sha256Canonical, stricter, validate, verifyPolicyHash };
201
+ export { Approval, type BoundDocuments, CAPABILITY_KEYS, type CallInput, type CompileOptions, type CompileResult, Condition, Diagnostics, type Enforceability, type EnforceabilityReport, type Evaluation, HASH_PREFIX, type InventoryPort, type InventoryTool, KNOWN_CONTROLS, Layer, type Obligation, PolicyDocument, PolicySource, type Principal, type SchemaDriftObligation, type Section, SourceTarget, Statement, VERDICT_RANK, Verdict, type VerdictProvenance, canonicalJson, checkArgumentKeys, checkGlobCollisions, compile, compileWithPort, conditionHolds, conditionsHold, enforceabilityReport, evaluate, globToRegExp, isGlob, matchGlob, policyHash, resolveField, resolveKey, schemaHash, selectRuleKey, sha256Canonical, stricter, verifyPolicyHash };
package/dist/index.js CHANGED
@@ -173,11 +173,11 @@ function escapeRegExp(ch) {
173
173
  // src/evaluate/conditions.ts
174
174
  function resolveField(input, field) {
175
175
  const [root, ...rest] = field.split(".");
176
- const base = root === "args" ? input.arguments : input.derived?.[root ?? ""];
176
+ const base = root === "args" ? input.arguments : childOf2(input.derived, root ?? "");
177
177
  return rest.reduce(childOf2, base);
178
178
  }
179
179
  function childOf2(node, key) {
180
- if (node === null || typeof node !== "object") return void 0;
180
+ if (node === null || typeof node !== "object" || !Object.hasOwn(node, key)) return void 0;
181
181
  return node[key];
182
182
  }
183
183
  function conditionsHold(input, conditions) {
@@ -769,6 +769,119 @@ function parseCapture(r, value) {
769
769
  return out;
770
770
  }
771
771
 
772
+ // src/document/portable-regex.ts
773
+ function isPortablePattern(pattern) {
774
+ if (typeof pattern !== "string") return false;
775
+ try {
776
+ new RegExp(pattern);
777
+ } catch {
778
+ return false;
779
+ }
780
+ const parser = new Parser(pattern);
781
+ return parser.alternatives() && parser.done();
782
+ }
783
+ var ESCAPED_PUNCTUATION = new Set("\\/.*+?()[]{}|^$-");
784
+ var CONTROL_ESCAPES = new Set("tnrfv");
785
+ var SET_ESCAPES = new Set("dwsDWS");
786
+ var CLASS_SET_ESCAPES = new Set("dws");
787
+ var BARE_SPECIALS = new Set("]{}*+?");
788
+ var QUANTIFIER = /^\{\d+(,\d*)?\}/;
789
+ var Parser = class {
790
+ constructor(p) {
791
+ this.p = p;
792
+ }
793
+ p;
794
+ i = 0;
795
+ done() {
796
+ return this.i === this.p.length;
797
+ }
798
+ alternatives() {
799
+ while (!this.done() && this.p[this.i] !== ")") {
800
+ if (this.p[this.i] === "|") this.i++;
801
+ else if (!this.term()) return false;
802
+ }
803
+ return true;
804
+ }
805
+ term() {
806
+ const atom = this.atom();
807
+ return atom !== null && this.quantifier(atom === "quantifiable");
808
+ }
809
+ atom() {
810
+ const c = this.p[this.i++];
811
+ if (c === "^" || c === "$") return "assertion";
812
+ if (c === "\\") return this.escape();
813
+ if (c === "[") return this.charClass() ? "quantifiable" : null;
814
+ if (c === "(") return this.group() ? "quantifiable" : null;
815
+ return BARE_SPECIALS.has(c) ? null : "quantifiable";
816
+ }
817
+ escape() {
818
+ const e = this.p[this.i++] ?? "";
819
+ if (e === "b" || e === "B") return "assertion";
820
+ if (SET_ESCAPES.has(e) || CONTROL_ESCAPES.has(e) || ESCAPED_PUNCTUATION.has(e)) return "quantifiable";
821
+ return this.hexEscape(e) ? "quantifiable" : null;
822
+ }
823
+ hexEscape(e) {
824
+ const width = e === "x" ? 2 : e === "u" ? 4 : 0;
825
+ const digits = this.p.slice(this.i, this.i + width);
826
+ if (width === 0 || !/^[0-9a-fA-F]+$/.test(digits) || digits.length !== width) return false;
827
+ this.i += width;
828
+ return true;
829
+ }
830
+ group() {
831
+ if (this.p[this.i] === "?") {
832
+ if (this.p[this.i + 1] !== ":") return false;
833
+ this.i += 2;
834
+ }
835
+ if (!this.alternatives() || this.p[this.i] !== ")") return false;
836
+ this.i++;
837
+ return true;
838
+ }
839
+ charClass() {
840
+ if (this.p[this.i] === "^") this.i++;
841
+ if (this.p[this.i] === "]") return false;
842
+ while (!this.done() && this.p[this.i] !== "]") {
843
+ if (!this.classItem()) return false;
844
+ }
845
+ if (this.done()) return false;
846
+ this.i++;
847
+ return true;
848
+ }
849
+ classItem() {
850
+ const start = this.classAtom();
851
+ if (start === null) return false;
852
+ if (this.p[this.i] !== "-" || this.p[this.i + 1] === "]") return true;
853
+ this.i++;
854
+ return start === "char" && this.classAtom() === "char";
855
+ }
856
+ classAtom() {
857
+ const c = this.p[this.i++];
858
+ if (c === "[") return null;
859
+ if (c !== "\\") return isSurrogate(c) ? null : "char";
860
+ const e = this.p[this.i++] ?? "";
861
+ if (CLASS_SET_ESCAPES.has(e)) return "set";
862
+ if (CONTROL_ESCAPES.has(e) || ESCAPED_PUNCTUATION.has(e)) return "char";
863
+ return this.hexEscape(e) ? "char" : null;
864
+ }
865
+ quantifier(quantifiable) {
866
+ const length = this.quantifierLength();
867
+ if (length === 0) return true;
868
+ if (length < 0 || !quantifiable) return false;
869
+ this.i += length;
870
+ if (this.p[this.i] === "?") this.i++;
871
+ return true;
872
+ }
873
+ quantifierLength() {
874
+ const c = this.p[this.i];
875
+ if (c === "*" || c === "+" || c === "?") return 1;
876
+ if (c !== "{") return 0;
877
+ return QUANTIFIER.exec(this.p.slice(this.i))?.[0].length ?? -1;
878
+ }
879
+ };
880
+ function isSurrogate(c) {
881
+ const code = c.charCodeAt(0);
882
+ return code >= 55296 && code <= 57343;
883
+ }
884
+
772
885
  // src/document/validate.ts
773
886
  function validate(source) {
774
887
  const diag = new Diagnostics();
@@ -835,8 +948,8 @@ var OPERANDS = {
835
948
  gte: [isNumber, "a number"],
836
949
  lt: [isNumber, "a number"],
837
950
  lte: [isNumber, "a number"],
838
- matches: [isRe2Pattern, "an RE2-compatible regular expression"],
839
- notMatches: [isRe2Pattern, "an RE2-compatible regular expression"],
951
+ matches: [isPortablePattern, "a regular expression in the portable subset"],
952
+ notMatches: [isPortablePattern, "a regular expression in the portable subset"],
840
953
  startsWith: [isString, "a string"],
841
954
  glob: [isString, "a glob"],
842
955
  withinWorkspace: [isBoolean, "true or false"],
@@ -856,16 +969,6 @@ function isString(v) {
856
969
  function isBoolean(v) {
857
970
  return typeof v === "boolean";
858
971
  }
859
- function isRe2Pattern(v) {
860
- if (typeof v !== "string") return false;
861
- if (/\\[1-9]|\(\?[=!<]/.test(v)) return false;
862
- try {
863
- new RegExp(v);
864
- return true;
865
- } catch {
866
- return false;
867
- }
868
- }
869
972
  function validateOverlays(ctx, overlays2, path) {
870
973
  for (const [key, overlay] of Object.entries(overlays2 ?? {})) {
871
974
  const opath = `${path}/${key}`;
@@ -1108,7 +1211,25 @@ var HIPAA = [
1108
1211
  "164.312(d)",
1109
1212
  "164.312(e)(1)"
1110
1213
  ].map((c) => `HIPAA-${c}`);
1111
- var KNOWN_CONTROLS = /* @__PURE__ */ new Set([...SOC2, ...HIPAA]);
1214
+ var FERPA = ["99.10", "99.20", "99.30", "99.31", "99.32", "99.33", "99.34", "99.35", "99.36", "99.37"].map((c) => `FERPA-${c}`);
1215
+ var ITAR = [
1216
+ "120.11",
1217
+ "120.31",
1218
+ "120.32",
1219
+ "120.33",
1220
+ "120.34",
1221
+ "120.43",
1222
+ "120.50",
1223
+ "120.51",
1224
+ "120.52",
1225
+ "120.54",
1226
+ "120.55",
1227
+ "120.56",
1228
+ "120.62",
1229
+ "120.63"
1230
+ ].map((c) => `ITAR-${c}`);
1231
+ var EAR = ["734.3", "734.7", "734.8", "734.9", "734.13", "734.14", "734.15", "734.16", "734.17", "734.18", "734.19", "734.20"].map((c) => `EAR-${c}`);
1232
+ var KNOWN_CONTROLS = /* @__PURE__ */ new Set([...SOC2, ...HIPAA, ...FERPA, ...ITAR, ...EAR]);
1112
1233
 
1113
1234
  // src/compile/lower-rules.ts
1114
1235
  function lowerRules(rules, ctx, path, subject, scopeExpiry) {