@highflame/policy 2.1.41 → 2.1.42

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.
@@ -7,6 +7,18 @@
7
7
  "name": "call_tool",
8
8
  "description": "Call an MCP tool — threat focus: command injection, tool poisoning, rug pull, secrets, PII",
9
9
  "context_attributes": [
10
+ {
11
+ "key": "role",
12
+ "type": "string",
13
+ "required": false,
14
+ "description": "Caller's RBAC role projected from the principal's token (AARM R6 / CAP-IDN-011), e.g. finance_lead. Absent when the token carries no role claim."
15
+ },
16
+ {
17
+ "key": "privilege_scope",
18
+ "type": "array",
19
+ "required": false,
20
+ "description": "Privilege-scope strings granted to the caller, projected from the token (AARM R6 / CAP-IDN-011), e.g. transfer:approve. Absent when the token carries no claim."
21
+ },
10
22
  {
11
23
  "key": "content",
12
24
  "type": "string",
@@ -343,6 +355,18 @@
343
355
  "name": "connect_server",
344
356
  "description": "Connect to an MCP server — threat focus: supply chain, tool poisoning, config risk",
345
357
  "context_attributes": [
358
+ {
359
+ "key": "role",
360
+ "type": "string",
361
+ "required": false,
362
+ "description": "Caller's RBAC role projected from the principal's token (AARM R6 / CAP-IDN-011), e.g. finance_lead. Absent when the token carries no role claim."
363
+ },
364
+ {
365
+ "key": "privilege_scope",
366
+ "type": "array",
367
+ "required": false,
368
+ "description": "Privilege-scope strings granted to the caller, projected from the token (AARM R6 / CAP-IDN-011), e.g. transfer:approve. Absent when the token carries no claim."
369
+ },
346
370
  {
347
371
  "key": "content",
348
372
  "type": "string",
@@ -553,6 +577,18 @@
553
577
  "name": "process_prompt",
554
578
  "description": "Process a prompt (MCP or LLM chat completion) — threat focus: injection, jailbreak, secrets, PII, content safety",
555
579
  "context_attributes": [
580
+ {
581
+ "key": "role",
582
+ "type": "string",
583
+ "required": false,
584
+ "description": "Caller's RBAC role projected from the principal's token (AARM R6 / CAP-IDN-011), e.g. finance_lead. Absent when the token carries no role claim."
585
+ },
586
+ {
587
+ "key": "privilege_scope",
588
+ "type": "array",
589
+ "required": false,
590
+ "description": "Privilege-scope strings granted to the caller, projected from the token (AARM R6 / CAP-IDN-011), e.g. transfer:approve. Absent when the token carries no claim."
591
+ },
556
592
  {
557
593
  "key": "content",
558
594
  "type": "string",
@@ -793,6 +829,18 @@
793
829
  "name": "read_file",
794
830
  "description": "Read an MCP resource — threat focus: secrets exposure, PII exposure",
795
831
  "context_attributes": [
832
+ {
833
+ "key": "role",
834
+ "type": "string",
835
+ "required": false,
836
+ "description": "Caller's RBAC role projected from the principal's token (AARM R6 / CAP-IDN-011), e.g. finance_lead. Absent when the token carries no role claim."
837
+ },
838
+ {
839
+ "key": "privilege_scope",
840
+ "type": "array",
841
+ "required": false,
842
+ "description": "Privilege-scope strings granted to the caller, projected from the token (AARM R6 / CAP-IDN-011), e.g. transfer:approve. Absent when the token carries no claim."
843
+ },
796
844
  {
797
845
  "key": "content",
798
846
  "type": "string",
@@ -961,6 +1009,18 @@
961
1009
  "name": "write_file",
962
1010
  "description": "Write an MCP resource — threat focus: secrets in output, PII in output",
963
1011
  "context_attributes": [
1012
+ {
1013
+ "key": "role",
1014
+ "type": "string",
1015
+ "required": false,
1016
+ "description": "Caller's RBAC role projected from the principal's token (AARM R6 / CAP-IDN-011), e.g. finance_lead. Absent when the token carries no role claim."
1017
+ },
1018
+ {
1019
+ "key": "privilege_scope",
1020
+ "type": "array",
1021
+ "required": false,
1022
+ "description": "Privilege-scope strings granted to the caller, projected from the token (AARM R6 / CAP-IDN-011), e.g. transfer:approve. Absent when the token carries no claim."
1023
+ },
964
1024
  {
965
1025
  "key": "content",
966
1026
  "type": "string",
@@ -73,6 +73,9 @@ action call_tool appliesTo {
73
73
  principal: [User, MCP_Client],
74
74
  resource: [Tool],
75
75
  context: {
76
+ // Identity (AARM R6 / CAP-IDN-011) — projected from the principal's token; optional.
77
+ role?: String,
78
+ privilege_scope?: Set<String>,
76
79
  // --- Content ---
77
80
  content: String, // Raw content being scanned
78
81
 
@@ -179,6 +182,9 @@ action connect_server appliesTo {
179
182
  principal: [User, MCP_Client],
180
183
  resource: [Server],
181
184
  context: {
185
+ // Identity (AARM R6 / CAP-IDN-011) — projected from the principal's token; optional.
186
+ role?: String,
187
+ privilege_scope?: Set<String>,
182
188
  content?: String, // Server config content (if available)
183
189
  mcp_server?: String,
184
190
 
@@ -248,6 +254,9 @@ action process_prompt appliesTo {
248
254
  principal: [User, MCP_Client],
249
255
  resource: [LlmPrompt],
250
256
  context: {
257
+ // Identity (AARM R6 / CAP-IDN-011) — projected from the principal's token; optional.
258
+ role?: String,
259
+ privilege_scope?: Set<String>,
251
260
  content: String,
252
261
  mcp_server?: String,
253
262
 
@@ -326,6 +335,9 @@ action read_file appliesTo {
326
335
  principal: [User, MCP_Client],
327
336
  resource: [FilePath],
328
337
  context: {
338
+ // Identity (AARM R6 / CAP-IDN-011) — projected from the principal's token; optional.
339
+ role?: String,
340
+ privilege_scope?: Set<String>,
329
341
  content: String,
330
342
  mcp_server?: String,
331
343
 
@@ -384,6 +396,9 @@ action write_file appliesTo {
384
396
  principal: [User, MCP_Client],
385
397
  resource: [FilePath],
386
398
  context: {
399
+ // Identity (AARM R6 / CAP-IDN-011) — projected from the principal's token; optional.
400
+ role?: String,
401
+ privilege_scope?: Set<String>,
387
402
  content: String,
388
403
  mcp_server?: String,
389
404
 
@@ -7,6 +7,18 @@
7
7
  "name": "process_prompt",
8
8
  "description": "Analyze user prompts and AI responses for security threats, PII, and content violations",
9
9
  "context_attributes": [
10
+ {
11
+ "key": "role",
12
+ "type": "string",
13
+ "required": false,
14
+ "description": "Caller's RBAC role projected from the principal's token (AARM R6 / CAP-IDN-011), e.g. finance_lead. Absent when the token carries no role claim."
15
+ },
16
+ {
17
+ "key": "privilege_scope",
18
+ "type": "array",
19
+ "required": false,
20
+ "description": "Privilege-scope strings granted to the caller, projected from the token (AARM R6 / CAP-IDN-011), e.g. transfer:approve. Absent when the token carries no claim."
21
+ },
10
22
  {
11
23
  "key": "request_id",
12
24
  "type": "string",
@@ -523,6 +535,18 @@
523
535
  "name": "call_tool",
524
536
  "description": "Execute agentic tool calls, including shell commands, file operations, and MCP tools",
525
537
  "context_attributes": [
538
+ {
539
+ "key": "role",
540
+ "type": "string",
541
+ "required": false,
542
+ "description": "Caller's RBAC role projected from the principal's token (AARM R6 / CAP-IDN-011), e.g. finance_lead. Absent when the token carries no role claim."
543
+ },
544
+ {
545
+ "key": "privilege_scope",
546
+ "type": "array",
547
+ "required": false,
548
+ "description": "Privilege-scope strings granted to the caller, projected from the token (AARM R6 / CAP-IDN-011), e.g. transfer:approve. Absent when the token carries no claim."
549
+ },
526
550
  {
527
551
  "key": "request_id",
528
552
  "type": "string",
@@ -1015,6 +1039,18 @@
1015
1039
  "name": "read_file",
1016
1040
  "description": "Read file operations for analyzing file content before allowing access",
1017
1041
  "context_attributes": [
1042
+ {
1043
+ "key": "role",
1044
+ "type": "string",
1045
+ "required": false,
1046
+ "description": "Caller's RBAC role projected from the principal's token (AARM R6 / CAP-IDN-011), e.g. finance_lead. Absent when the token carries no role claim."
1047
+ },
1048
+ {
1049
+ "key": "privilege_scope",
1050
+ "type": "array",
1051
+ "required": false,
1052
+ "description": "Privilege-scope strings granted to the caller, projected from the token (AARM R6 / CAP-IDN-011), e.g. transfer:approve. Absent when the token carries no claim."
1053
+ },
1018
1054
  {
1019
1055
  "key": "request_id",
1020
1056
  "type": "string",
@@ -1195,6 +1231,18 @@
1195
1231
  "name": "write_file",
1196
1232
  "description": "Write file operations for preventing writes of sensitive content",
1197
1233
  "context_attributes": [
1234
+ {
1235
+ "key": "role",
1236
+ "type": "string",
1237
+ "required": false,
1238
+ "description": "Caller's RBAC role projected from the principal's token (AARM R6 / CAP-IDN-011), e.g. finance_lead. Absent when the token carries no role claim."
1239
+ },
1240
+ {
1241
+ "key": "privilege_scope",
1242
+ "type": "array",
1243
+ "required": false,
1244
+ "description": "Privilege-scope strings granted to the caller, projected from the token (AARM R6 / CAP-IDN-011), e.g. transfer:approve. Absent when the token carries no claim."
1245
+ },
1198
1246
  {
1199
1247
  "key": "request_id",
1200
1248
  "type": "string",
@@ -1387,6 +1435,18 @@
1387
1435
  "name": "connect_server",
1388
1436
  "description": "Connect to an MCP server, used to control which MCP servers are allowed",
1389
1437
  "context_attributes": [
1438
+ {
1439
+ "key": "role",
1440
+ "type": "string",
1441
+ "required": false,
1442
+ "description": "Caller's RBAC role projected from the principal's token (AARM R6 / CAP-IDN-011), e.g. finance_lead. Absent when the token carries no role claim."
1443
+ },
1444
+ {
1445
+ "key": "privilege_scope",
1446
+ "type": "array",
1447
+ "required": false,
1448
+ "description": "Privilege-scope strings granted to the caller, projected from the token (AARM R6 / CAP-IDN-011), e.g. transfer:approve. Absent when the token carries no claim."
1449
+ },
1390
1450
  {
1391
1451
  "key": "request_id",
1392
1452
  "type": "string",
@@ -96,6 +96,9 @@ namespace Guardrails {
96
96
 
97
97
  /// Context for process_prompt action (user prompts & AI responses)
98
98
  type ProcessPromptContext = {
99
+ // Identity (AARM R6 / CAP-IDN-011) — projected from the principal's token; optional.
100
+ "role"?: String,
101
+ "privilege_scope"?: Set<String>,
99
102
  // Core metadata (required)
100
103
  "request_id": String,
101
104
  "timestamp": Long,
@@ -235,6 +238,9 @@ namespace Guardrails {
235
238
 
236
239
  /// Context for call_tool action (agentic tool execution)
237
240
  type CallToolContext = {
241
+ // Identity (AARM R6 / CAP-IDN-011) — projected from the principal's token; optional.
242
+ "role"?: String,
243
+ "privilege_scope"?: Set<String>,
238
244
  // Core metadata (required)
239
245
  "request_id": String,
240
246
  "timestamp": Long,
@@ -371,6 +377,9 @@ namespace Guardrails {
371
377
 
372
378
  /// Context for read_file action
373
379
  type FileReadContext = {
380
+ // Identity (AARM R6 / CAP-IDN-011) — projected from the principal's token; optional.
381
+ "role"?: String,
382
+ "privilege_scope"?: Set<String>,
374
383
  // Core metadata (required)
375
384
  "request_id": String,
376
385
  "timestamp": Long,
@@ -431,6 +440,9 @@ namespace Guardrails {
431
440
 
432
441
  /// Context for write_file action
433
442
  type FileWriteContext = {
443
+ // Identity (AARM R6 / CAP-IDN-011) — projected from the principal's token; optional.
444
+ "role"?: String,
445
+ "privilege_scope"?: Set<String>,
434
446
  // Core metadata (required)
435
447
  "request_id": String,
436
448
  "timestamp": Long,
@@ -495,6 +507,9 @@ namespace Guardrails {
495
507
 
496
508
  /// Context for connect_server action (MCP server connections)
497
509
  type ConnectServerContext = {
510
+ // Identity (AARM R6 / CAP-IDN-011) — projected from the principal's token; optional.
511
+ "role"?: String,
512
+ "privilege_scope"?: Set<String>,
498
513
  // Core metadata (required)
499
514
  "request_id": String,
500
515
  "timestamp": Long,
@@ -7,6 +7,18 @@
7
7
  "name": "process_prompt",
8
8
  "description": "User submits a prompt or receives AI response",
9
9
  "context_attributes": [
10
+ {
11
+ "key": "role",
12
+ "type": "string",
13
+ "required": false,
14
+ "description": "Caller's RBAC role projected from the principal's token (AARM R6 / CAP-IDN-011), e.g. finance_lead. Absent when the token carries no role claim."
15
+ },
16
+ {
17
+ "key": "privilege_scope",
18
+ "type": "array",
19
+ "required": false,
20
+ "description": "Privilege-scope strings granted to the caller, projected from the token (AARM R6 / CAP-IDN-011), e.g. transfer:approve. Absent when the token carries no claim."
21
+ },
10
22
  {
11
23
  "key": "content",
12
24
  "type": "string",
@@ -301,6 +313,18 @@
301
313
  "name": "call_tool",
302
314
  "description": "User calls a tool (native IDE tool or MCP tool)",
303
315
  "context_attributes": [
316
+ {
317
+ "key": "role",
318
+ "type": "string",
319
+ "required": false,
320
+ "description": "Caller's RBAC role projected from the principal's token (AARM R6 / CAP-IDN-011), e.g. finance_lead. Absent when the token carries no role claim."
321
+ },
322
+ {
323
+ "key": "privilege_scope",
324
+ "type": "array",
325
+ "required": false,
326
+ "description": "Privilege-scope strings granted to the caller, projected from the token (AARM R6 / CAP-IDN-011), e.g. transfer:approve. Absent when the token carries no claim."
327
+ },
304
328
  {
305
329
  "key": "content",
306
330
  "type": "string",
@@ -709,6 +733,18 @@
709
733
  "name": "connect_server",
710
734
  "description": "Connect to an MCP server",
711
735
  "context_attributes": [
736
+ {
737
+ "key": "role",
738
+ "type": "string",
739
+ "required": false,
740
+ "description": "Caller's RBAC role projected from the principal's token (AARM R6 / CAP-IDN-011), e.g. finance_lead. Absent when the token carries no role claim."
741
+ },
742
+ {
743
+ "key": "privilege_scope",
744
+ "type": "array",
745
+ "required": false,
746
+ "description": "Privilege-scope strings granted to the caller, projected from the token (AARM R6 / CAP-IDN-011), e.g. transfer:approve. Absent when the token carries no claim."
747
+ },
712
748
  {
713
749
  "key": "content",
714
750
  "type": "string",
@@ -901,6 +937,18 @@
901
937
  "name": "read_file",
902
938
  "description": "Read a file from disk",
903
939
  "context_attributes": [
940
+ {
941
+ "key": "role",
942
+ "type": "string",
943
+ "required": false,
944
+ "description": "Caller's RBAC role projected from the principal's token (AARM R6 / CAP-IDN-011), e.g. finance_lead. Absent when the token carries no role claim."
945
+ },
946
+ {
947
+ "key": "privilege_scope",
948
+ "type": "array",
949
+ "required": false,
950
+ "description": "Privilege-scope strings granted to the caller, projected from the token (AARM R6 / CAP-IDN-011), e.g. transfer:approve. Absent when the token carries no claim."
951
+ },
904
952
  {
905
953
  "key": "content",
906
954
  "type": "string",
@@ -1093,6 +1141,18 @@
1093
1141
  "name": "write_file",
1094
1142
  "description": "Write a file to disk",
1095
1143
  "context_attributes": [
1144
+ {
1145
+ "key": "role",
1146
+ "type": "string",
1147
+ "required": false,
1148
+ "description": "Caller's RBAC role projected from the principal's token (AARM R6 / CAP-IDN-011), e.g. finance_lead. Absent when the token carries no role claim."
1149
+ },
1150
+ {
1151
+ "key": "privilege_scope",
1152
+ "type": "array",
1153
+ "required": false,
1154
+ "description": "Privilege-scope strings granted to the caller, projected from the token (AARM R6 / CAP-IDN-011), e.g. transfer:approve. Absent when the token carries no claim."
1155
+ },
1096
1156
  {
1097
1157
  "key": "content",
1098
1158
  "type": "string",
@@ -79,6 +79,9 @@ action process_prompt appliesTo {
79
79
  principal: [User, Agent],
80
80
  resource: [LlmPrompt],
81
81
  context: {
82
+ // Identity (AARM R6 / CAP-IDN-011) — projected from the principal's token; optional.
83
+ role?: String,
84
+ privilege_scope?: Set<String>,
82
85
  // --- Event & Source ---
83
86
  content: String, // Raw content being scanned
84
87
  source: String, // IDE source: "cursor", "claudecode", "github_copilot"
@@ -157,6 +160,9 @@ action call_tool appliesTo {
157
160
  principal: [User, Agent],
158
161
  resource: [Tool, FilePath],
159
162
  context: {
163
+ // Identity (AARM R6 / CAP-IDN-011) — projected from the principal's token; optional.
164
+ role?: String,
165
+ privilege_scope?: Set<String>,
160
166
  // --- Event & Source ---
161
167
  content: String, // Raw content being scanned (e.g., shell command, tool args)
162
168
  source: String, // IDE source
@@ -266,6 +272,9 @@ action connect_server appliesTo {
266
272
  principal: [User, Agent],
267
273
  resource: [Server],
268
274
  context: {
275
+ // Identity (AARM R6 / CAP-IDN-011) — projected from the principal's token; optional.
276
+ role?: String,
277
+ privilege_scope?: Set<String>,
269
278
  content?: String, // Server config content (if available)
270
279
  source: String,
271
280
  event: String,
@@ -313,6 +322,9 @@ action read_file appliesTo {
313
322
  principal: [User, Agent],
314
323
  resource: [FilePath],
315
324
  context: {
325
+ // Identity (AARM R6 / CAP-IDN-011) — projected from the principal's token; optional.
326
+ role?: String,
327
+ privilege_scope?: Set<String>,
316
328
  content: String,
317
329
  source: String,
318
330
  event: String,
@@ -364,6 +376,9 @@ action write_file appliesTo {
364
376
  principal: [User, Agent],
365
377
  resource: [FilePath],
366
378
  context: {
379
+ // Identity (AARM R6 / CAP-IDN-011) — projected from the principal's token; optional.
380
+ role?: String,
381
+ privilege_scope?: Set<String>,
367
382
  content: String,
368
383
  source: String,
369
384
  event: String,
@@ -7,6 +7,18 @@
7
7
  "name": "process_prompt",
8
8
  "description": "User sends a message (prompt) to an AI chat service via the browser",
9
9
  "context_attributes": [
10
+ {
11
+ "key": "role",
12
+ "type": "string",
13
+ "required": false,
14
+ "description": "Caller's RBAC role projected from the principal's token (AARM R6 / CAP-IDN-011), e.g. finance_lead. Absent when the token carries no role claim."
15
+ },
16
+ {
17
+ "key": "privilege_scope",
18
+ "type": "array",
19
+ "required": false,
20
+ "description": "Privilege-scope strings granted to the caller, projected from the token (AARM R6 / CAP-IDN-011), e.g. transfer:approve. Absent when the token carries no claim."
21
+ },
10
22
  {
11
23
  "key": "content",
12
24
  "type": "string",
@@ -331,6 +343,18 @@
331
343
  "name": "receive_response",
332
344
  "description": "AI service responds to the user — scan response content for harmful output",
333
345
  "context_attributes": [
346
+ {
347
+ "key": "role",
348
+ "type": "string",
349
+ "required": false,
350
+ "description": "Caller's RBAC role projected from the principal's token (AARM R6 / CAP-IDN-011), e.g. finance_lead. Absent when the token carries no role claim."
351
+ },
352
+ {
353
+ "key": "privilege_scope",
354
+ "type": "array",
355
+ "required": false,
356
+ "description": "Privilege-scope strings granted to the caller, projected from the token (AARM R6 / CAP-IDN-011), e.g. transfer:approve. Absent when the token carries no claim."
357
+ },
334
358
  {
335
359
  "key": "content",
336
360
  "type": "string",
@@ -565,6 +589,18 @@
565
589
  "name": "paste_content",
566
590
  "description": "User pastes content into an AI chat (clipboard, cross-tab, cross-app)",
567
591
  "context_attributes": [
592
+ {
593
+ "key": "role",
594
+ "type": "string",
595
+ "required": false,
596
+ "description": "Caller's RBAC role projected from the principal's token (AARM R6 / CAP-IDN-011), e.g. finance_lead. Absent when the token carries no role claim."
597
+ },
598
+ {
599
+ "key": "privilege_scope",
600
+ "type": "array",
601
+ "required": false,
602
+ "description": "Privilege-scope strings granted to the caller, projected from the token (AARM R6 / CAP-IDN-011), e.g. transfer:approve. Absent when the token carries no claim."
603
+ },
568
604
  {
569
605
  "key": "content",
570
606
  "type": "string",
@@ -853,6 +889,18 @@
853
889
  "name": "upload_file",
854
890
  "description": "User uploads a file or document into an AI chat service",
855
891
  "context_attributes": [
892
+ {
893
+ "key": "role",
894
+ "type": "string",
895
+ "required": false,
896
+ "description": "Caller's RBAC role projected from the principal's token (AARM R6 / CAP-IDN-011), e.g. finance_lead. Absent when the token carries no role claim."
897
+ },
898
+ {
899
+ "key": "privilege_scope",
900
+ "type": "array",
901
+ "required": false,
902
+ "description": "Privilege-scope strings granted to the caller, projected from the token (AARM R6 / CAP-IDN-011), e.g. transfer:approve. Absent when the token carries no claim."
903
+ },
856
904
  {
857
905
  "key": "content",
858
906
  "type": "string",
@@ -78,6 +78,9 @@ action process_prompt appliesTo {
78
78
  principal: [User],
79
79
  resource: [ChatSession],
80
80
  context: {
81
+ // Identity (AARM R6 / CAP-IDN-011) — projected from the principal's token; optional.
82
+ role?: String,
83
+ privilege_scope?: Set<String>,
81
84
  // --- Core Metadata ---
82
85
  content: String, // Raw message content being sent
83
86
  source: String, // Browser extension identifier: "sentry"
@@ -165,6 +168,9 @@ action receive_response appliesTo {
165
168
  principal: [User],
166
169
  resource: [ChatSession],
167
170
  context: {
171
+ // Identity (AARM R6 / CAP-IDN-011) — projected from the principal's token; optional.
172
+ role?: String,
173
+ privilege_scope?: Set<String>,
168
174
  // --- Core Metadata ---
169
175
  content: String, // AI response content
170
176
  source: String,
@@ -231,6 +237,9 @@ action paste_content appliesTo {
231
237
  principal: [User],
232
238
  resource: [ChatSession, Document],
233
239
  context: {
240
+ // Identity (AARM R6 / CAP-IDN-011) — projected from the principal's token; optional.
241
+ role?: String,
242
+ privilege_scope?: Set<String>,
234
243
  // --- Core Metadata ---
235
244
  content: String, // Pasted content
236
245
  source: String,
@@ -308,6 +317,9 @@ action upload_file appliesTo {
308
317
  principal: [User],
309
318
  resource: [Document, ChatSession],
310
319
  context: {
320
+ // Identity (AARM R6 / CAP-IDN-011) — projected from the principal's token; optional.
321
+ role?: String,
322
+ privilege_scope?: Set<String>,
311
323
  // --- Core Metadata ---
312
324
  content: String, // Extracted file text content (for scanning)
313
325
  source: String,
@@ -0,0 +1,120 @@
1
+ /**
2
+ * AARM-Aware Annotation Parser (TypeScript)
3
+ *
4
+ * Runtime layer over the generated AARM annotation registry
5
+ * (aarm-annotations.gen.ts). Ported from packages/go/aarm_annotation.go to
6
+ * give Studio's policy editor the SAME parse + validation rules Shield runs
7
+ * at policy sync time (Go's ValidateAARMAnnotations). The two
8
+ * implementations share a test corpus — see aarm-annotation.test.ts and its
9
+ * Go twin aarm_annotation_test.go.
10
+ *
11
+ * Takes the `Record<string, string>` of a policy's @-annotations and
12
+ * produces:
13
+ *
14
+ * - typed directives Studio (and any TS consumer) can switch on
15
+ * (StepUpRequiredDirective, DeferBelowConfidenceDirective, ...) and
16
+ * - a list of typed validation errors (AARMAnnotationError).
17
+ *
18
+ * Three encoding shapes are accepted, matching the value_encoding block in
19
+ * schemas/annotations.json:
20
+ *
21
+ * 1. Marker: `@defer_on_conflict("")` → no params
22
+ * 2. Single-param positional: `@defer_below_confidence("0.7")` → bare value
23
+ * binds to the single required-positional parameter declared in the
24
+ * registry. Fails closed if no such parameter exists.
25
+ * 3. Multi-param key=value: `@step_up_required("role=finance_lead,timeout_seconds=3600")`
26
+ * parameters are comma-separated key=value pairs. Unknown keys error;
27
+ * missing required parameters error.
28
+ *
29
+ * Generic Cedar annotations (@id, @name, @severity, @tags, arbitrary custom
30
+ * KV pairs) are NOT parsed here — those live in annotations.ts and remain
31
+ * free-form. AARM annotations are a strict subset whose key MUST appear in
32
+ * AARM_ANNOTATION_BY_KEY.
33
+ *
34
+ * Validation is fail-closed (AARM R3/R4): a malformed AARM annotation never
35
+ * silently degrades to a no-op — the caller is told exactly which
36
+ * annotation, which parameter, and what was wrong, so Admin can reject the
37
+ * policy at deploy time and Studio's lint can surface it inline.
38
+ */
39
+ /**
40
+ * Parsed form of `@step_up_required`. Suspends the action pending approval
41
+ * from an approver carrying `role`; fail-closed DENY after `timeoutSeconds`.
42
+ */
43
+ export interface StepUpRequiredDirective {
44
+ /** AuthN role the approver must carry (validated against authn.roles at deploy). */
45
+ role: string;
46
+ /** Seconds the action waits before fail-closed DENY. Defaults to the registry default (86400). */
47
+ timeoutSeconds: number;
48
+ }
49
+ /** Parsed form of `@defer_on_conflict`. Marker — presence is the signal. */
50
+ export interface DeferOnConflictDirective {
51
+ }
52
+ /** Parsed form of `@defer_below_confidence`. Defers when a detector confidence < threshold. */
53
+ export interface DeferBelowConfidenceDirective {
54
+ /** Threshold in [0.0, 1.0]. Detector scores strictly below trigger a deferral. */
55
+ threshold: number;
56
+ }
57
+ /** Parsed form of `@defer_until_context`. Defers when the named context field is empty/missing. */
58
+ export interface DeferUntilContextDirective {
59
+ /** Dotted Cedar context-attribute path (e.g. "session_max_sensitivity"). */
60
+ field: string;
61
+ }
62
+ /**
63
+ * Every typed AARM directive parsed from a single policy's annotation map.
64
+ * Each field is present iff the corresponding annotation was present and
65
+ * parsed successfully.
66
+ */
67
+ export interface AARMDirectives {
68
+ stepUpRequired?: StepUpRequiredDirective;
69
+ deferOnConflict?: DeferOnConflictDirective;
70
+ deferBelowConfidence?: DeferBelowConfidenceDirective;
71
+ deferUntilContext?: DeferUntilContextDirective;
72
+ }
73
+ /** True iff at least one AARM directive was parsed. */
74
+ export declare function hasAnyAARMDirective(d: AARMDirectives | null | undefined): boolean;
75
+ export interface AARMAnnotationErrorInit {
76
+ /** Annotation key (e.g. "step_up_required"). */
77
+ key: string;
78
+ /** Parameter where the failure occurred; omit for annotation-level failures. */
79
+ parameter?: string;
80
+ /** Raw Cedar value (or parameter substring) that was rejected. */
81
+ rawValue?: string;
82
+ /** Short, actionable human-readable message. */
83
+ reason: string;
84
+ }
85
+ /**
86
+ * Structured error for a malformed AARM annotation. Mirrors Go's
87
+ * AARMAnnotationError. Studio's lint surfaces these inline; Admin serializes
88
+ * them in the policy-create rejection.
89
+ */
90
+ export declare class AARMAnnotationError extends Error {
91
+ readonly key: string;
92
+ readonly parameter: string;
93
+ readonly rawValue: string;
94
+ readonly reason: string;
95
+ constructor(init: AARMAnnotationErrorInit);
96
+ }
97
+ /** True iff err is an AARMAnnotationError. */
98
+ export declare function isAARMAnnotationError(err: unknown): err is AARMAnnotationError;
99
+ export interface ParseAARMResult {
100
+ directives: AARMDirectives;
101
+ errors: AARMAnnotationError[];
102
+ }
103
+ /**
104
+ * Walks the raw annotation map and extracts every AARM-recognized annotation
105
+ * into typed directives. Non-AARM keys are ignored (handled by the generic
106
+ * annotation surface in annotations.ts).
107
+ *
108
+ * Errors are COLLECTED, not fail-fast, so a single call surfaces every
109
+ * offending annotation at once — Studio shows all squiggles in one pass.
110
+ * Keys are processed in sorted order for stable error reporting.
111
+ */
112
+ export declare function parseAARMAnnotations(raw: Record<string, string> | null | undefined): ParseAARMResult;
113
+ /**
114
+ * Validate-only variant: returns the error list without the typed
115
+ * directives. Suitable for Admin's policy-create endpoint, which only needs
116
+ * the yes/no verdict + error list.
117
+ */
118
+ export declare function validateAARMAnnotations(raw: Record<string, string> | null | undefined): AARMAnnotationError[];
119
+ /** True iff key is a platform-recognized AARM annotation. */
120
+ export declare function isAARMAnnotationKey(key: string): boolean;