@highflame/policy 2.2.36 → 2.2.38

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.
Files changed (82) hide show
  1. package/_schemas/agent_ops/context.json +792 -0
  2. package/_schemas/agent_ops/schema.cedarschema +127 -109
  3. package/_schemas/agent_ops/templates/ported/agent-security/agent_identity_a2a_cross_origin.cedar +6 -4
  4. package/_schemas/agent_ops/templates/ported/agent-security/agent_identity_a2a_escalation.cedar +5 -4
  5. package/_schemas/agent_ops/templates/ported/agent-security/agent_identity_a2a_inter_agent_injection.cedar +9 -8
  6. package/_schemas/agent_ops/templates/ported/agent-security/agent_identity_claude_block_injection.cedar +2 -2
  7. package/_schemas/agent_ops/templates/ported/agent-security/agent_identity_defaults.cedar +3 -3
  8. package/_schemas/agent_ops/templates/ported/agent-security/agent_identity_multi_agent_trust.cedar +6 -6
  9. package/_schemas/agent_ops/templates/ported/content-safety/trust_safety_chat_assistant.cedar +5 -4
  10. package/_schemas/agent_ops/templates/ported/content-safety/trust_safety_defaults.cedar +18 -12
  11. package/_schemas/agent_ops/templates/ported/content-safety/trust_safety_semantic.cedar +6 -6
  12. package/_schemas/agent_ops/templates/ported/content-safety/trust_safety_toxicity.cedar +4 -4
  13. package/_schemas/agent_ops/templates/ported/data-protection/data_protection_advanced_secrets.cedar +4 -2
  14. package/_schemas/agent_ops/templates/ported/data-protection/data_protection_data_pipeline.cedar +2 -1
  15. package/_schemas/agent_ops/templates/ported/data-protection/data_protection_defaults.cedar +4 -2
  16. package/_schemas/agent_ops/templates/ported/data-protection/privacy_advanced_pii.cedar +42 -21
  17. package/_schemas/agent_ops/templates/ported/data-protection/privacy_defaults.cedar +14 -7
  18. package/_schemas/agent_ops/templates/ported/data-protection/privacy_pii_model.cedar +10 -5
  19. package/_schemas/agent_ops/templates/ported/organization/organization_team_permissions.cedar +3 -2
  20. package/_schemas/agent_ops/templates/ported/threat-detection/security_advanced_block_critical_severity.cedar +3 -3
  21. package/_schemas/agent_ops/templates/ported/threat-detection/security_chat_assistant.cedar +5 -4
  22. package/_schemas/agent_ops/templates/ported/threat-detection/security_data_pipeline_block_injection.cedar +3 -2
  23. package/_schemas/agent_ops/templates/ported/threat-detection/security_injection.cedar +9 -8
  24. package/_schemas/agent_ops/templates/ported/threat-detection/security_patterns.cedar +5 -3
  25. package/_schemas/agent_ops/templates/ported/threat-detection/semantic_defaults.cedar +9 -7
  26. package/_schemas/ai_gateway/context.json +278 -0
  27. package/_schemas/ai_gateway/schema.cedarschema +37 -7
  28. package/_schemas/ai_gateway/templates/defaults/agent_security.cedar +5 -16
  29. package/_schemas/ai_gateway/templates/defaults/pii.cedar +14 -7
  30. package/_schemas/ai_gateway/templates/defaults/pii_advanced.cedar +42 -21
  31. package/_schemas/ai_gateway/templates/defaults/pii_model.cedar +10 -5
  32. package/_schemas/ai_gateway/templates/defaults/semantic.cedar +9 -74
  33. package/_schemas/ai_gateway/templates/defaults/tools.cedar +7 -38
  34. package/_schemas/ai_gateway/templates/secrets.cedar +3 -3
  35. package/_schemas/guardrails/context.json +671 -0
  36. package/_schemas/guardrails/schema.cedarschema +23 -2
  37. package/_schemas/guardrails/templates/defaults/agent_identity.cedar +3 -3
  38. package/_schemas/guardrails/templates/defaults/injection.cedar +9 -8
  39. package/_schemas/guardrails/templates/defaults/pii.cedar +14 -7
  40. package/_schemas/guardrails/templates/defaults/pii_model.cedar +10 -5
  41. package/_schemas/guardrails/templates/defaults/secrets.cedar +4 -2
  42. package/_schemas/guardrails/templates/defaults/security_patterns.cedar +5 -3
  43. package/_schemas/guardrails/templates/defaults/semantic.cedar +6 -6
  44. package/_schemas/guardrails/templates/defaults/toxicity.cedar +6 -6
  45. package/_schemas/guardrails/templates/profiles/a2a_security/cross_origin.cedar +6 -4
  46. package/_schemas/guardrails/templates/profiles/a2a_security/escalation_detection.cedar +5 -4
  47. package/_schemas/guardrails/templates/profiles/a2a_security/inter_agent_injection.cedar +9 -8
  48. package/_schemas/guardrails/templates/profiles/advanced_detection/pii.cedar +42 -21
  49. package/_schemas/guardrails/templates/profiles/advanced_detection/secrets.cedar +4 -2
  50. package/_schemas/guardrails/templates/profiles/chat_assistant/security.cedar +5 -4
  51. package/_schemas/guardrails/templates/profiles/chat_assistant/trust_safety.cedar +5 -4
  52. package/_schemas/guardrails/templates/profiles/data_pipeline/data_protection.cedar +2 -1
  53. package/_schemas/guardrails/templates/profiles/data_pipeline/security.cedar +3 -2
  54. package/_schemas/guardrails/templates/profiles/multi_agent/agent_trust.cedar +6 -6
  55. package/_schemas/guardrails/templates/templates.json +0 -9
  56. package/dist/agent_ops-defaults.gen.js +177 -120
  57. package/dist/agent_ops-entities.gen.js +5 -1
  58. package/dist/ai_gateway-defaults.gen.js +90 -164
  59. package/dist/ai_gateway-entities.gen.js +6 -2
  60. package/dist/engine.d.ts +10 -0
  61. package/dist/engine.js +25 -1
  62. package/dist/guardrails-defaults.gen.js +144 -145
  63. package/dist/guardrails-entities.gen.js +5 -1
  64. package/dist/service-schemas.gen.d.ts +3 -3
  65. package/dist/service-schemas.gen.js +480 -118
  66. package/package.json +1 -1
  67. package/_schemas/guardrails/templates/profiles/advanced_detection/threat_severity.cedar +0 -30
  68. package/_schemas/mcp_gateway/context.json +0 -655
  69. package/_schemas/mcp_gateway/schema.cedarschema +0 -342
  70. package/_schemas/mcp_gateway/templates/defaults/agent_security.cedar +0 -140
  71. package/_schemas/mcp_gateway/templates/defaults/baseline.cedar +0 -23
  72. package/_schemas/mcp_gateway/templates/defaults/semantic.cedar +0 -105
  73. package/_schemas/mcp_gateway/templates/defaults/tools.cedar +0 -92
  74. package/_schemas/mcp_gateway/templates/mcp_server_allowlist.cedar +0 -33
  75. package/_schemas/mcp_gateway/templates/mcp_tool_permissions.cedar +0 -77
  76. package/_schemas/mcp_gateway/templates/templates.json +0 -89
  77. package/dist/mcp_gateway-context.gen.d.ts +0 -51
  78. package/dist/mcp_gateway-context.gen.js +0 -52
  79. package/dist/mcp_gateway-defaults.gen.d.ts +0 -61
  80. package/dist/mcp_gateway-defaults.gen.js +0 -668
  81. package/dist/mcp_gateway-entities.gen.d.ts +0 -11
  82. package/dist/mcp_gateway-entities.gen.js +0 -37
@@ -78,13 +78,23 @@ namespace AgentOps {
78
78
  // Actions
79
79
  // =========================================================================
80
80
 
81
- /// Process user prompts and AI responses for security threats and content violations
81
+ /// Process user prompts for security threats and content violations
82
82
  action "process_prompt" appliesTo {
83
83
  principal: [User, Agent],
84
84
  resource: [App, Agent, Session],
85
85
  context: ProcessPromptContext
86
86
  };
87
87
 
88
+ /// Process model responses for security threats and content violations.
89
+ /// Distinct trigger from process_prompt (ADR 0031). Declared ahead of a
90
+ /// caller: no AgentOps producer emits model responses today, so this is
91
+ /// namespace symmetry with ai_gateway/guardrails until one does.
92
+ action "process_response" appliesTo {
93
+ principal: [User, Agent],
94
+ resource: [App, Agent, Session],
95
+ context: ProcessResponseContext
96
+ };
97
+
88
98
  /// Execute tool calls (shell, file operations, MCP tools)
89
99
  action "call_tool" appliesTo {
90
100
  principal: [User, Agent],
@@ -130,7 +140,15 @@ namespace AgentOps {
130
140
  // Context Types (Action-Specific)
131
141
  // =========================================================================
132
142
 
133
- /// Context for process_prompt action (user prompts & AI responses)
143
+ /// Context for the process_response action.
144
+ ///
145
+ /// An alias, not a copy: prompts and responses are inspected by the same
146
+ /// detector pipeline and carry the same keys — only the trigger differs
147
+ /// (ADR 0031). Aliasing means a new detector key cannot land on one
148
+ /// direction and go missing on the other.
149
+ type ProcessResponseContext = ProcessPromptContext;
150
+
151
+ /// Context for process_prompt action (user prompts)
134
152
  type ProcessPromptContext = {
135
153
  // Identity (AARM R6 / CAP-IDN-011) — projected from the principal's token; optional.
136
154
  "role"?: String,
@@ -166,12 +184,12 @@ namespace AgentOps {
166
184
  "indirect_injection_score"?: Long, // Indirect injection via tool outputs (0-100)
167
185
 
168
186
  // Privacy - Secrets (optional)
169
- "secrets_detected"?: Boolean,
187
+ "secrets_detected"?: Bool,
170
188
  "secret_count"?: Long,
171
189
  "secret_types"?: Set<String>, // ["aws_access_key", "github_token", ...]
172
190
 
173
191
  // Privacy - PII (optional)
174
- "pii_detected"?: Boolean,
192
+ "pii_detected"?: Bool,
175
193
  "pii_count"?: Long,
176
194
  "pii_types"?: Set<String>, // ["email", "phone", "ssn", "credit_card", ...]
177
195
  "pii_score"?: Long, // PII ML classifier confidence (0-100)
@@ -195,65 +213,65 @@ namespace AgentOps {
195
213
  "topic_confidence"?: Long, // 0-100
196
214
 
197
215
  // Security - Invisible Character Detection (optional)
198
- "invisible_chars_detected"?: Boolean,
216
+ "invisible_chars_detected"?: Bool,
199
217
  "invisible_chars_score"?: Long, // 0-100
200
218
 
201
219
  // Security - Pattern Detection (optional)
202
- "command_injection_detected"?: Boolean,
220
+ "command_injection_detected"?: Bool,
203
221
  "command_injection_type"?: String, // "reverse_shell" | "privilege_escalation" | ...
204
222
  "command_injection_score"?: Long, // 0-100
205
- "path_traversal_detected"?: Boolean,
223
+ "path_traversal_detected"?: Bool,
206
224
  "path_traversal_severity"?: String, // "critical" | "high" | "medium" | "low" | "none"
207
225
  "path_traversal_type"?: String,
208
- "sql_injection_detected"?: Boolean,
226
+ "sql_injection_detected"?: Bool,
209
227
  "sql_injection_type"?: String, // "tautology" | "union_based" | "destructive" | ...
210
228
  "sql_injection_score"?: Long, // 0-100
211
229
 
212
230
  // Security - Cross-Origin Escalation (optional)
213
- "cross_origin_detected"?: Boolean,
231
+ "cross_origin_detected"?: Bool,
214
232
  "cross_origin_type"?: String, // "cross_origin_tool" | "cross_origin_server" | "none"
215
233
  "cross_origin_score"?: Long, // 0-100
216
234
 
217
235
  // Security - Encoded Injection (optional)
218
- "encoded_content_detected"?: Boolean,
236
+ "encoded_content_detected"?: Bool,
219
237
  "encoded_types"?: Set<String>, // ["base64", "hex", "unicode", "url", ...]
220
238
  "encoded_count"?: Long,
221
239
  "encoded_score"?: Long, // 0-100
222
240
 
223
241
  // Language & Script Detection (optional)
224
242
  "detected_language"?: String, // ISO language code
225
- "is_english"?: Boolean,
243
+ "is_english"?: Bool,
226
244
  "language_confidence"?: Long, // 0-100
227
245
  "detected_script"?: String, // "latin" | "cyrillic" | "arabic" | "unknown" | ...
228
- "is_latin_script"?: Boolean,
246
+ "is_latin_script"?: Bool,
229
247
  "script_confidence"?: Long, // 0-100
230
248
 
231
249
  // Content Analysis (optional)
232
250
  "hallucination_score"?: Long,
233
251
  "factuality_score"?: Long, // 0-100
234
252
  "sentiment_score"?: Long,
235
- "contains_code"?: Boolean,
253
+ "contains_code"?: Bool,
236
254
  "code_languages"?: Set<String>,
237
255
  "code_ratio"?: Long, // 0-100
238
- "keyword_matched"?: Boolean,
256
+ "keyword_matched"?: Bool,
239
257
  "keyword_categories"?: Set<String>,
240
258
  "keyword_count"?: Long,
241
- "contains_non_ascii"?: Boolean,
242
- "phishing_detected"?: Boolean,
259
+ "contains_non_ascii"?: Bool,
260
+ "phishing_detected"?: Bool,
243
261
  "content_safety_score"?: Long, // 0-100
244
- "content_safety_blocked"?: Boolean,
262
+ "content_safety_blocked"?: Bool,
245
263
 
246
264
  // Agentic - Multi-Turn Context (optional)
247
265
  "conversation_turn"?: Long,
248
- "multi_turn_detection"?: Boolean,
266
+ "multi_turn_detection"?: Bool,
249
267
 
250
268
  // Session Detection History — cross-turn sticky flags (optional)
251
- "session_pii_detected"?: Boolean,
269
+ "session_pii_detected"?: Bool,
252
270
  "session_pii_types"?: Set<String>,
253
- "session_secrets_detected"?: Boolean,
271
+ "session_secrets_detected"?: Bool,
254
272
  "session_secret_types"?: Set<String>,
255
- "session_injection_detected"?: Boolean,
256
- "session_command_injection"?: Boolean,
273
+ "session_injection_detected"?: Bool,
274
+ "session_command_injection"?: Bool,
257
275
  "session_threat_turns"?: Long,
258
276
  "session_max_injection_score"?: Long,
259
277
  "session_max_jailbreak_score"?: Long,
@@ -283,14 +301,14 @@ namespace AgentOps {
283
301
  "flow_resolution_status"?: String, // "known" | "inferred" | "unknown" | "conflicted"
284
302
  "flow_origins"?: Set<String>, // "mcp_tool_result" | "model" | "file" | "database" | "user"
285
303
  "flow_sink"?: String, // "external_model" | "local_model" | "external_mcp" | "trusted_mcp" | "user_secure_output" | "public_network" | "file"
286
- "flow_sink_is_external"?: Boolean,
304
+ "flow_sink_is_external"?: Bool,
287
305
  "flow_sink_effects"?: Set<String>, // "network.send" | "financial.transfer" | "filesystem.write" | ...
288
306
  "principal_clearances"?: Set<String>, // ADR 0020 D8 — clearances AuthN mints for the principal
289
307
  "principal_compartments"?: Set<String>, // ADR 0020 D8 — compartments the principal is admitted to
290
308
 
291
309
  // Usage Budget — multi-window token & cost enforcement (optional)
292
310
  "budget_remaining_pct"?: Long,
293
- "budget_exceeded"?: Boolean,
311
+ "budget_exceeded"?: Bool,
294
312
  "budget_cost_micros_this_turn"?: Long,
295
313
  "budget_model"?: String,
296
314
  "budget_tokens_pct_session"?: Long,
@@ -298,15 +316,15 @@ namespace AgentOps {
298
316
  "budget_tokens_pct_monthly"?: Long,
299
317
  "budget_cost_pct_daily"?: Long,
300
318
  "budget_cost_pct_monthly"?: Long,
301
- "budget_exceeded_session"?: Boolean,
302
- "budget_exceeded_daily"?: Boolean,
303
- "budget_exceeded_monthly"?: Boolean,
319
+ "budget_exceeded_session"?: Bool,
320
+ "budget_exceeded_daily"?: Bool,
321
+ "budget_exceeded_monthly"?: Bool,
304
322
 
305
323
  // Rate Limiting — gateway-metered, Shield-decided (ADR 0014)
306
324
  "rpm_remaining_pct"?: Long,
307
- "rpm_exceeded"?: Boolean,
325
+ "rpm_exceeded"?: Bool,
308
326
  "tpm_remaining_pct"?: Long,
309
- "tpm_exceeded"?: Boolean,
327
+ "tpm_exceeded"?: Bool,
310
328
 
311
329
  // Agent Identity — authenticated agent principal metadata (optional)
312
330
  "agent_id"?: String,
@@ -318,8 +336,8 @@ namespace AgentOps {
318
336
  // Supply-chain / package safety + aggregate threat severity (optional —
319
337
  // ADR 0012 unified port). Projected by Shield's malicious-package and
320
338
  // threat-severity detectors; every read is \`has\`-guarded in policy.
321
- "malicious_package_detected"?: Boolean,
322
- "package_install_detected"?: Boolean,
339
+ "malicious_package_detected"?: Bool,
340
+ "package_install_detected"?: Bool,
323
341
  "package_check_status"?: String,
324
342
  "max_threat_severity"?: Long,
325
343
 
@@ -346,9 +364,9 @@ namespace AgentOps {
346
364
  // Tool Risk (optional)
347
365
  "tool_name"?: String,
348
366
  "tool_risk_score"?: Long, // 0-100
349
- "tool_is_sensitive"?: Boolean,
367
+ "tool_is_sensitive"?: Bool,
350
368
  "tool_category"?: String, // "safe" | "sensitive" | "dangerous"
351
- "tool_is_builtin"?: Boolean,
369
+ "tool_is_builtin"?: Bool,
352
370
 
353
371
  // AARM R3 (CAP-ENF-007) — Action Parameter Validation
354
372
  "action_params"?: {
@@ -361,29 +379,29 @@ namespace AgentOps {
361
379
  "target"?: String,
362
380
  "query"?: String,
363
381
  },
364
- "param_type_violation"?: Boolean,
382
+ "param_type_violation"?: Bool,
365
383
  "param_type_violations"?: Set<String>,
366
384
 
367
385
  // MCP context (optional)
368
386
  "mcp_server"?: String,
369
387
  "mcp_tool"?: String,
370
- "mcp_server_verified"?: Boolean,
388
+ "mcp_server_verified"?: Bool,
371
389
 
372
390
  // Agentic - Behavioral Patterns (optional)
373
- "suspicious_pattern"?: Boolean,
391
+ "suspicious_pattern"?: Bool,
374
392
  "pattern_type"?: String, // "data_exfiltration" | "secret_exfiltration" | ...
375
393
  "sequence_risk"?: Long, // 0-100
376
394
 
377
395
  // Agentic - Loop Detection (optional)
378
- "loop_detected"?: Boolean,
396
+ "loop_detected"?: Bool,
379
397
  "loop_count"?: Long,
380
398
  "loop_tool"?: String,
381
399
 
382
400
  // Security checks on tool arguments (optional)
383
- "secrets_detected"?: Boolean,
401
+ "secrets_detected"?: Bool,
384
402
  "secret_count"?: Long,
385
403
  "secret_types"?: Set<String>,
386
- "pii_detected"?: Boolean,
404
+ "pii_detected"?: Bool,
387
405
  "pii_types"?: Set<String>,
388
406
  "pii_count"?: Long,
389
407
  "pii_score"?: Long,
@@ -398,41 +416,41 @@ namespace AgentOps {
398
416
  "topic_confidence"?: Long, // 0-100
399
417
 
400
418
  // Security - Pattern Detection (optional)
401
- "command_injection_detected"?: Boolean,
419
+ "command_injection_detected"?: Bool,
402
420
  "command_injection_type"?: String,
403
421
  "command_injection_score"?: Long,
404
- "path_traversal_detected"?: Boolean,
422
+ "path_traversal_detected"?: Bool,
405
423
  "path_traversal_severity"?: String,
406
424
  "path_traversal_type"?: String,
407
- "sql_injection_detected"?: Boolean,
425
+ "sql_injection_detected"?: Bool,
408
426
  "sql_injection_type"?: String,
409
427
  "sql_injection_score"?: Long,
410
428
 
411
429
  // Security - Cross-Origin Escalation (optional)
412
- "cross_origin_detected"?: Boolean,
430
+ "cross_origin_detected"?: Bool,
413
431
  "cross_origin_type"?: String,
414
432
  "cross_origin_score"?: Long,
415
433
 
416
434
  // Security - Invisible Character Detection (optional)
417
- "invisible_chars_detected"?: Boolean,
435
+ "invisible_chars_detected"?: Bool,
418
436
  "invisible_chars_score"?: Long,
419
437
 
420
438
  // Security - Encoded Injection (optional)
421
- "encoded_content_detected"?: Boolean,
439
+ "encoded_content_detected"?: Bool,
422
440
  "encoded_types"?: Set<String>,
423
441
  "encoded_count"?: Long,
424
442
  "encoded_score"?: Long,
425
443
 
426
444
  // Agentic - Agent Security (optional)
427
- "tool_poisoning_detected"?: Boolean,
445
+ "tool_poisoning_detected"?: Bool,
428
446
  "tool_poisoning_score"?: Long,
429
447
  "tool_poisoning_type"?: String,
430
- "rug_pull_detected"?: Boolean,
448
+ "rug_pull_detected"?: Bool,
431
449
  "rug_pull_score"?: Long,
432
450
  "rug_pull_type"?: String,
433
451
 
434
452
  // Agentic - MCP Risk (optional)
435
- "mcp_config_risk"?: Boolean,
453
+ "mcp_config_risk"?: Bool,
436
454
  "mcp_risk_type"?: String,
437
455
  "mcp_risk_score"?: Long,
438
456
 
@@ -448,15 +466,15 @@ namespace AgentOps {
448
466
 
449
467
  // Agentic - Multi-Turn Context (optional)
450
468
  "conversation_turn"?: Long,
451
- "multi_turn_detection"?: Boolean,
469
+ "multi_turn_detection"?: Bool,
452
470
 
453
471
  // Session Detection History — cross-turn sticky flags (optional)
454
- "session_pii_detected"?: Boolean,
472
+ "session_pii_detected"?: Bool,
455
473
  "session_pii_types"?: Set<String>,
456
- "session_secrets_detected"?: Boolean,
474
+ "session_secrets_detected"?: Bool,
457
475
  "session_secret_types"?: Set<String>,
458
- "session_injection_detected"?: Boolean,
459
- "session_command_injection"?: Boolean,
476
+ "session_injection_detected"?: Bool,
477
+ "session_command_injection"?: Bool,
460
478
  "session_threat_turns"?: Long,
461
479
  "session_max_injection_score"?: Long,
462
480
  "session_max_jailbreak_score"?: Long,
@@ -486,14 +504,14 @@ namespace AgentOps {
486
504
  "flow_resolution_status"?: String, // "known" | "inferred" | "unknown" | "conflicted"
487
505
  "flow_origins"?: Set<String>, // "mcp_tool_result" | "model" | "file" | "database" | "user"
488
506
  "flow_sink"?: String, // "external_model" | "local_model" | "external_mcp" | "trusted_mcp" | "user_secure_output" | "public_network" | "file"
489
- "flow_sink_is_external"?: Boolean,
507
+ "flow_sink_is_external"?: Bool,
490
508
  "flow_sink_effects"?: Set<String>, // "network.send" | "financial.transfer" | "filesystem.write" | ...
491
509
  "principal_clearances"?: Set<String>, // ADR 0020 D8 — clearances AuthN mints for the principal
492
510
  "principal_compartments"?: Set<String>, // ADR 0020 D8 — compartments the principal is admitted to
493
511
 
494
512
  // Usage Budget (optional)
495
513
  "budget_remaining_pct"?: Long,
496
- "budget_exceeded"?: Boolean,
514
+ "budget_exceeded"?: Bool,
497
515
  "budget_cost_micros_this_turn"?: Long,
498
516
  "budget_model"?: String,
499
517
  "budget_tokens_pct_session"?: Long,
@@ -501,15 +519,15 @@ namespace AgentOps {
501
519
  "budget_tokens_pct_monthly"?: Long,
502
520
  "budget_cost_pct_daily"?: Long,
503
521
  "budget_cost_pct_monthly"?: Long,
504
- "budget_exceeded_session"?: Boolean,
505
- "budget_exceeded_daily"?: Boolean,
506
- "budget_exceeded_monthly"?: Boolean,
522
+ "budget_exceeded_session"?: Bool,
523
+ "budget_exceeded_daily"?: Bool,
524
+ "budget_exceeded_monthly"?: Bool,
507
525
 
508
526
  // Rate Limiting — gateway-metered, Shield-decided (ADR 0014)
509
527
  "rpm_remaining_pct"?: Long,
510
- "rpm_exceeded"?: Boolean,
528
+ "rpm_exceeded"?: Bool,
511
529
  "tpm_remaining_pct"?: Long,
512
- "tpm_exceeded"?: Boolean,
530
+ "tpm_exceeded"?: Bool,
513
531
 
514
532
  // Aggregated threat summary (optional)
515
533
  "highest_severity"?: String,
@@ -529,8 +547,8 @@ namespace AgentOps {
529
547
  // Supply-chain / package safety + aggregate threat severity (optional —
530
548
  // ADR 0012 unified port). Projected by Shield's malicious-package and
531
549
  // threat-severity detectors; every read is \`has\`-guarded in policy.
532
- "malicious_package_detected"?: Boolean,
533
- "package_install_detected"?: Boolean,
550
+ "malicious_package_detected"?: Bool,
551
+ "package_install_detected"?: Bool,
534
552
  "package_check_status"?: String,
535
553
  "max_threat_severity"?: Long,
536
554
 
@@ -558,14 +576,14 @@ namespace AgentOps {
558
576
  "path"?: String,
559
577
 
560
578
  // Security checks on file content (optional)
561
- "secrets_detected"?: Boolean,
579
+ "secrets_detected"?: Bool,
562
580
  "secret_count"?: Long,
563
581
  "secret_types"?: Set<String>,
564
- "pii_detected"?: Boolean,
582
+ "pii_detected"?: Bool,
565
583
  "pii_types"?: Set<String>,
566
584
 
567
585
  // Security - Path Traversal (optional)
568
- "path_traversal_detected"?: Boolean,
586
+ "path_traversal_detected"?: Bool,
569
587
  "path_traversal_severity"?: String,
570
588
  "path_traversal_type"?: String,
571
589
 
@@ -575,12 +593,12 @@ namespace AgentOps {
575
593
  "detected_threats"?: Set<String>,
576
594
 
577
595
  // Session Detection History (optional)
578
- "session_pii_detected"?: Boolean,
596
+ "session_pii_detected"?: Bool,
579
597
  "session_pii_types"?: Set<String>,
580
- "session_secrets_detected"?: Boolean,
598
+ "session_secrets_detected"?: Bool,
581
599
  "session_secret_types"?: Set<String>,
582
- "session_injection_detected"?: Boolean,
583
- "session_command_injection"?: Boolean,
600
+ "session_injection_detected"?: Bool,
601
+ "session_command_injection"?: Bool,
584
602
  "session_threat_turns"?: Long,
585
603
  "session_max_injection_score"?: Long,
586
604
  "session_max_jailbreak_score"?: Long,
@@ -610,14 +628,14 @@ namespace AgentOps {
610
628
  "flow_resolution_status"?: String, // "known" | "inferred" | "unknown" | "conflicted"
611
629
  "flow_origins"?: Set<String>, // "mcp_tool_result" | "model" | "file" | "database" | "user"
612
630
  "flow_sink"?: String, // "external_model" | "local_model" | "external_mcp" | "trusted_mcp" | "user_secure_output" | "public_network" | "file"
613
- "flow_sink_is_external"?: Boolean,
631
+ "flow_sink_is_external"?: Bool,
614
632
  "flow_sink_effects"?: Set<String>, // "network.send" | "financial.transfer" | "filesystem.write" | ...
615
633
  "principal_clearances"?: Set<String>, // ADR 0020 D8 — clearances AuthN mints for the principal
616
634
  "principal_compartments"?: Set<String>, // ADR 0020 D8 — compartments the principal is admitted to
617
635
 
618
636
  // Usage Budget (optional)
619
637
  "budget_remaining_pct"?: Long,
620
- "budget_exceeded"?: Boolean,
638
+ "budget_exceeded"?: Bool,
621
639
  "budget_cost_micros_this_turn"?: Long,
622
640
  "budget_model"?: String,
623
641
  "budget_tokens_pct_session"?: Long,
@@ -625,15 +643,15 @@ namespace AgentOps {
625
643
  "budget_tokens_pct_monthly"?: Long,
626
644
  "budget_cost_pct_daily"?: Long,
627
645
  "budget_cost_pct_monthly"?: Long,
628
- "budget_exceeded_session"?: Boolean,
629
- "budget_exceeded_daily"?: Boolean,
630
- "budget_exceeded_monthly"?: Boolean,
646
+ "budget_exceeded_session"?: Bool,
647
+ "budget_exceeded_daily"?: Bool,
648
+ "budget_exceeded_monthly"?: Bool,
631
649
 
632
650
  // Rate Limiting — gateway-metered, Shield-decided (ADR 0014)
633
651
  "rpm_remaining_pct"?: Long,
634
- "rpm_exceeded"?: Boolean,
652
+ "rpm_exceeded"?: Bool,
635
653
  "tpm_remaining_pct"?: Long,
636
- "tpm_exceeded"?: Boolean,
654
+ "tpm_exceeded"?: Bool,
637
655
 
638
656
  // Agent Identity (optional)
639
657
  "agent_id"?: String,
@@ -666,18 +684,18 @@ namespace AgentOps {
666
684
  "path"?: String,
667
685
 
668
686
  // Security - Invisible Character Detection in write content (optional)
669
- "invisible_chars_detected"?: Boolean,
687
+ "invisible_chars_detected"?: Bool,
670
688
  "invisible_chars_score"?: Long,
671
689
 
672
690
  // Security checks on content being written (optional)
673
- "secrets_detected"?: Boolean,
691
+ "secrets_detected"?: Bool,
674
692
  "secret_count"?: Long,
675
693
  "secret_types"?: Set<String>,
676
- "pii_detected"?: Boolean,
694
+ "pii_detected"?: Bool,
677
695
  "pii_types"?: Set<String>,
678
696
 
679
697
  // Security - Path Traversal (optional)
680
- "path_traversal_detected"?: Boolean,
698
+ "path_traversal_detected"?: Bool,
681
699
  "path_traversal_severity"?: String,
682
700
  "path_traversal_type"?: String,
683
701
 
@@ -687,12 +705,12 @@ namespace AgentOps {
687
705
  "detected_threats"?: Set<String>,
688
706
 
689
707
  // Session Detection History (optional)
690
- "session_pii_detected"?: Boolean,
708
+ "session_pii_detected"?: Bool,
691
709
  "session_pii_types"?: Set<String>,
692
- "session_secrets_detected"?: Boolean,
710
+ "session_secrets_detected"?: Bool,
693
711
  "session_secret_types"?: Set<String>,
694
- "session_injection_detected"?: Boolean,
695
- "session_command_injection"?: Boolean,
712
+ "session_injection_detected"?: Bool,
713
+ "session_command_injection"?: Bool,
696
714
  "session_threat_turns"?: Long,
697
715
  "session_max_injection_score"?: Long,
698
716
  "session_max_jailbreak_score"?: Long,
@@ -722,14 +740,14 @@ namespace AgentOps {
722
740
  "flow_resolution_status"?: String, // "known" | "inferred" | "unknown" | "conflicted"
723
741
  "flow_origins"?: Set<String>, // "mcp_tool_result" | "model" | "file" | "database" | "user"
724
742
  "flow_sink"?: String, // "external_model" | "local_model" | "external_mcp" | "trusted_mcp" | "user_secure_output" | "public_network" | "file"
725
- "flow_sink_is_external"?: Boolean,
743
+ "flow_sink_is_external"?: Bool,
726
744
  "flow_sink_effects"?: Set<String>, // "network.send" | "financial.transfer" | "filesystem.write" | ...
727
745
  "principal_clearances"?: Set<String>, // ADR 0020 D8 — clearances AuthN mints for the principal
728
746
  "principal_compartments"?: Set<String>, // ADR 0020 D8 — compartments the principal is admitted to
729
747
 
730
748
  // Usage Budget (optional)
731
749
  "budget_remaining_pct"?: Long,
732
- "budget_exceeded"?: Boolean,
750
+ "budget_exceeded"?: Bool,
733
751
  "budget_cost_micros_this_turn"?: Long,
734
752
  "budget_model"?: String,
735
753
  "budget_tokens_pct_session"?: Long,
@@ -737,15 +755,15 @@ namespace AgentOps {
737
755
  "budget_tokens_pct_monthly"?: Long,
738
756
  "budget_cost_pct_daily"?: Long,
739
757
  "budget_cost_pct_monthly"?: Long,
740
- "budget_exceeded_session"?: Boolean,
741
- "budget_exceeded_daily"?: Boolean,
742
- "budget_exceeded_monthly"?: Boolean,
758
+ "budget_exceeded_session"?: Bool,
759
+ "budget_exceeded_daily"?: Bool,
760
+ "budget_exceeded_monthly"?: Bool,
743
761
 
744
762
  // Rate Limiting — gateway-metered, Shield-decided (ADR 0014)
745
763
  "rpm_remaining_pct"?: Long,
746
- "rpm_exceeded"?: Boolean,
764
+ "rpm_exceeded"?: Bool,
747
765
  "tpm_remaining_pct"?: Long,
748
- "tpm_exceeded"?: Boolean,
766
+ "tpm_exceeded"?: Bool,
749
767
 
750
768
  // Agent Identity (optional)
751
769
  "agent_id"?: String,
@@ -776,20 +794,20 @@ namespace AgentOps {
776
794
 
777
795
  // MCP context (optional)
778
796
  "mcp_server"?: String,
779
- "mcp_server_verified"?: Boolean,
797
+ "mcp_server_verified"?: Bool,
780
798
 
781
799
  // Agentic - Agent Security (optional)
782
- "tool_poisoning_detected"?: Boolean,
800
+ "tool_poisoning_detected"?: Bool,
783
801
  "tool_poisoning_score"?: Long,
784
802
  "tool_poisoning_type"?: String,
785
803
 
786
804
  // Agentic - MCP Risk (optional)
787
- "mcp_config_risk"?: Boolean,
805
+ "mcp_config_risk"?: Bool,
788
806
  "mcp_risk_type"?: String,
789
807
  "mcp_risk_score"?: Long,
790
808
 
791
809
  // Security - Cross-Origin Escalation (optional)
792
- "cross_origin_detected"?: Boolean,
810
+ "cross_origin_detected"?: Bool,
793
811
  "cross_origin_type"?: String,
794
812
  "cross_origin_score"?: Long,
795
813
 
@@ -799,12 +817,12 @@ namespace AgentOps {
799
817
  "detected_threats"?: Set<String>,
800
818
 
801
819
  // Session Detection History (optional)
802
- "session_pii_detected"?: Boolean,
820
+ "session_pii_detected"?: Bool,
803
821
  "session_pii_types"?: Set<String>,
804
- "session_secrets_detected"?: Boolean,
822
+ "session_secrets_detected"?: Bool,
805
823
  "session_secret_types"?: Set<String>,
806
- "session_injection_detected"?: Boolean,
807
- "session_command_injection"?: Boolean,
824
+ "session_injection_detected"?: Bool,
825
+ "session_command_injection"?: Bool,
808
826
  "session_threat_turns"?: Long,
809
827
  "session_max_injection_score"?: Long,
810
828
  "session_max_jailbreak_score"?: Long,
@@ -834,14 +852,14 @@ namespace AgentOps {
834
852
  "flow_resolution_status"?: String, // "known" | "inferred" | "unknown" | "conflicted"
835
853
  "flow_origins"?: Set<String>, // "mcp_tool_result" | "model" | "file" | "database" | "user"
836
854
  "flow_sink"?: String, // "external_model" | "local_model" | "external_mcp" | "trusted_mcp" | "user_secure_output" | "public_network" | "file"
837
- "flow_sink_is_external"?: Boolean,
855
+ "flow_sink_is_external"?: Bool,
838
856
  "flow_sink_effects"?: Set<String>, // "network.send" | "financial.transfer" | "filesystem.write" | ...
839
857
  "principal_clearances"?: Set<String>, // ADR 0020 D8 — clearances AuthN mints for the principal
840
858
  "principal_compartments"?: Set<String>, // ADR 0020 D8 — compartments the principal is admitted to
841
859
 
842
860
  // Usage Budget (optional)
843
861
  "budget_remaining_pct"?: Long,
844
- "budget_exceeded"?: Boolean,
862
+ "budget_exceeded"?: Bool,
845
863
  "budget_cost_micros_this_turn"?: Long,
846
864
  "budget_model"?: String,
847
865
  "budget_tokens_pct_session"?: Long,
@@ -849,15 +867,15 @@ namespace AgentOps {
849
867
  "budget_tokens_pct_monthly"?: Long,
850
868
  "budget_cost_pct_daily"?: Long,
851
869
  "budget_cost_pct_monthly"?: Long,
852
- "budget_exceeded_session"?: Boolean,
853
- "budget_exceeded_daily"?: Boolean,
854
- "budget_exceeded_monthly"?: Boolean,
870
+ "budget_exceeded_session"?: Bool,
871
+ "budget_exceeded_daily"?: Bool,
872
+ "budget_exceeded_monthly"?: Bool,
855
873
 
856
874
  // Rate Limiting — gateway-metered, Shield-decided (ADR 0014)
857
875
  "rpm_remaining_pct"?: Long,
858
- "rpm_exceeded"?: Boolean,
876
+ "rpm_exceeded"?: Bool,
859
877
  "tpm_remaining_pct"?: Long,
860
- "tpm_exceeded"?: Boolean,
878
+ "tpm_exceeded"?: Bool,
861
879
 
862
880
  // Agent Identity (optional)
863
881
  "agent_id"?: String,
@@ -869,8 +887,8 @@ namespace AgentOps {
869
887
  // Supply-chain / package safety + aggregate threat severity (optional —
870
888
  // ADR 0012 unified port). Projected by Shield's malicious-package and
871
889
  // threat-severity detectors; every read is \`has\`-guarded in policy.
872
- "malicious_package_detected"?: Boolean,
873
- "package_install_detected"?: Boolean,
890
+ "malicious_package_detected"?: Bool,
891
+ "package_install_detected"?: Bool,
874
892
  "package_check_status"?: String,
875
893
  "max_threat_severity"?: Long,
876
894
 
@@ -916,7 +934,7 @@ namespace AgentOps {
916
934
  // requested (i.e. whenever egress_hosts is non-empty), so a "no network"
917
935
  // profile can gate on this single boolean. egress_hosts then narrows the
918
936
  // host allowlist for profiles that DO permit egress.
919
- "network_egress"?: Boolean,
937
+ "network_egress"?: Bool,
920
938
  "egress_hosts"?: Set<String>, // Host allowlist for egress, e.g. {"pypi.org"}
921
939
  "exec_allowlist"?: Set<String>, // Executables the sandbox may run, e.g. {"python", "python3"}
922
940
  // Curated mechanism toggles (ADR 0017 D1.3) — authorization facts only;
@@ -993,6 +1011,13 @@ entity Server in [Project];
993
1011
  /// MCP prompt -- resource for process_prompt action
994
1012
  entity LlmPrompt in [Project];
995
1013
 
1014
+ /// Model response -- resource for process_response action.
1015
+ /// Parented to Project like every other resource: Shield injects
1016
+ /// \`when { resource in <Ns>::Project::"<id>" }\` into every synced rule
1017
+ /// (shield#428), so a resource outside the project hierarchy would make
1018
+ /// every policy written against it unsatisfiable.
1019
+ entity LlmResponse in [Project];
1020
+
996
1021
  /// File/resource path -- resource for read_file/write_file actions
997
1022
  entity FilePath in [Project];
998
1023
 
@@ -1200,12 +1225,13 @@ action connect_server appliesTo {
1200
1225
  },
1201
1226
  };
1202
1227
 
1203
- // Process a prompt (MCP prompts/get or LLM chat completions)
1204
- // Threat focus: injection, jailbreak, secrets, PII, content safety
1205
- action process_prompt appliesTo {
1206
- principal: [User, MCP_Client],
1207
- resource: [LlmPrompt],
1208
- context: {
1228
+ // Shared content-inspection context.
1229
+ //
1230
+ // Prompts and responses are inspected by the same detector pipeline and so
1231
+ // carry the same context keys; only the TRIGGER differs (ADR 0031). Declaring
1232
+ // the shape once means a new detector key cannot land on one direction and go
1233
+ // missing on the other — the drift class shield#393 / shield#387 were about.
1234
+ type ContentInspectionContext = {
1209
1235
  // Identity (AARM R6 / CAP-IDN-011) — projected from the principal's token; optional.
1210
1236
  role?: String,
1211
1237
  privilege_scope?: Set<String>,
@@ -1284,7 +1310,29 @@ action process_prompt appliesTo {
1284
1310
  rpm_exceeded?: Bool,
1285
1311
  tpm_remaining_pct?: Long,
1286
1312
  tpm_exceeded?: Bool,
1287
- },
1313
+ };
1314
+
1315
+ // Process a prompt (MCP prompts/get or LLM chat completions)
1316
+ // Threat focus: injection, jailbreak, secrets, PII, content safety
1317
+ action process_prompt appliesTo {
1318
+ principal: [User, MCP_Client],
1319
+ resource: [LlmPrompt],
1320
+ context: ContentInspectionContext,
1321
+ };
1322
+
1323
+ // Process a model response (LLM chat completion output, streamed or buffered)
1324
+ // Threat focus: data leakage in output, harmful content, hallucination,
1325
+ // indirect injection carried back to the caller.
1326
+ //
1327
+ // Distinct from process_prompt so that (a) a policy can be scoped to one
1328
+ // direction from its head alone and (b) Shield's action-scoped detector
1329
+ // scheduling (INV-DET-001) can keep prompt-only detectors off the egress
1330
+ // path — before this action existed, a prompt-scoped dlp/model_armor/webhook
1331
+ // rule shipped response bodies downstream. See ADR 0031.
1332
+ action process_response appliesTo {
1333
+ principal: [User, MCP_Client],
1334
+ resource: [LlmResponse],
1335
+ context: ContentInspectionContext,
1288
1336
  };
1289
1337
 
1290
1338
  // Read an MCP resource (resources/read, resources/list)
@@ -1485,13 +1533,24 @@ namespace Guardrails {
1485
1533
  // Actions
1486
1534
  // =========================================================================
1487
1535
 
1488
- /// Process user prompts and AI responses for security threats and content violations
1536
+ /// Process user prompts for security threats and content violations
1489
1537
  action "process_prompt" appliesTo {
1490
1538
  principal: [User, Agent],
1491
1539
  resource: [App, Agent, Session],
1492
1540
  context: ProcessPromptContext
1493
1541
  };
1494
1542
 
1543
+ /// Process model responses for security threats and content violations.
1544
+ /// Distinct trigger from process_prompt (ADR 0031) so a policy can be
1545
+ /// scoped to one direction from its head, and so Shield's action-scoped
1546
+ /// detector scheduling (INV-DET-001) keeps prompt-only detectors off the
1547
+ /// egress path.
1548
+ action "process_response" appliesTo {
1549
+ principal: [User, Agent],
1550
+ resource: [App, Agent, Session],
1551
+ context: ProcessResponseContext
1552
+ };
1553
+
1495
1554
  /// Execute tool calls (shell, file operations, MCP tools)
1496
1555
  action "call_tool" appliesTo {
1497
1556
  principal: [User, Agent],
@@ -1524,7 +1583,17 @@ namespace Guardrails {
1524
1583
  // Context Types (Action-Specific)
1525
1584
  // =========================================================================
1526
1585
 
1527
- /// Context for process_prompt action (user prompts & AI responses)
1586
+ /// Context for the process_response action.
1587
+ ///
1588
+ /// An alias, not a copy: prompts and responses are inspected by the same
1589
+ /// detector pipeline and carry the same keys — only the trigger differs
1590
+ /// (ADR 0031). Aliasing means a new detector key cannot land on one
1591
+ /// direction and go missing on the other, and it guarantees no policy
1592
+ /// loses a context key at the cutover, since this is byte-for-byte the
1593
+ /// shape responses were already evaluated against under process_prompt.
1594
+ type ProcessResponseContext = ProcessPromptContext;
1595
+
1596
+ /// Context for process_prompt action (user prompts)
1528
1597
  type ProcessPromptContext = {
1529
1598
  // Identity (AARM R6 / CAP-IDN-011) — projected from the principal's token; optional.
1530
1599
  "role"?: String,
@@ -3331,6 +3400,137 @@ export const AGENT_OPS_CONTEXT = {
3331
3400
  { "key": "max_threat_severity", "type": "number", "required": false, "description": "Aggregate max threat severity across detectors (0=none,1=low,2=medium,3=high,4=critical)." }
3332
3401
  ]
3333
3402
  },
3403
+ {
3404
+ "name": "process_response",
3405
+ "description": "Process a model response (LLM chat completion output) — threat focus: data leakage in output, harmful content, hallucination, indirect injection carried back to the caller. Distinct trigger from process_prompt (ADR 0031) so a policy can be scoped to one direction from its head and prompt-only detectors stay off the egress path.",
3406
+ "context_attributes": [
3407
+ { "key": "role", "type": "string", "required": false, "description": "Caller\'s RBAC role projected from the principal\'s token (AARM R6 / CAP-IDN-011)" },
3408
+ { "key": "privilege_scope", "type": "array", "required": false, "description": "Privilege-scope strings granted to the caller, projected from the token (AARM R6 / CAP-IDN-011)" },
3409
+ { "key": "identity_type", "type": "string", "required": false, "description": "Principal identity class projected from the token: \'human\', \'agent\', \'service\', or \'mcp_server\'" },
3410
+ { "key": "principal", "type": "string", "required": false, "description": "Stable principal identifier projected from the token (e.g. a ZeroID / WIMSE URI or user id)" },
3411
+ { "key": "request_id", "type": "string", "required": true, "description": "Unique identifier for this request, useful for audit trails and debugging" },
3412
+ { "key": "timestamp", "type": "number", "required": true, "description": "Unix timestamp in milliseconds when the request was processed" },
3413
+ { "key": "direction", "type": "string", "required": true, "description": "Content flow direction: \'input\' for user prompts, \'output\' for AI responses" },
3414
+ { "key": "content_type", "type": "string", "required": true, "description": "Type of content being analyzed: \'prompt\', \'response\', \'tool_call\', \'file\', or \'clipboard\'" },
3415
+ { "key": "detector_count", "type": "number", "required": true, "description": "Number of detectors that were executed for this request" },
3416
+ { "key": "source", "type": "string", "required": false, "description": "Traffic origin: \'ide\' | \'cli\' | \'api\' | \'browser\'. Present for Overwatch/code-agent traffic." },
3417
+ { "key": "event", "type": "string", "required": false, "description": "Event type: \'prompt\' | \'tool_call\' | \'file_read\' | \'file_write\' | \'connect_server\'. Present for Overwatch traffic." },
3418
+ { "key": "user_email", "type": "string", "required": false, "description": "Human operator email (IDE sessions)" },
3419
+ { "key": "cwd", "type": "string", "required": false, "description": "Current working directory (IDE sessions)" },
3420
+ { "key": "workspace_root", "type": "string", "required": false, "description": "IDE workspace root path" },
3421
+ { "key": "model_name", "type": "string", "required": false, "description": "LLM model name: \'claude-3-5-sonnet\', \'gpt-4o\', etc. Present for AI Gateway traffic." },
3422
+ { "key": "model_provider", "type": "string", "required": false, "description": "Model provider: \'anthropic\' | \'openai\' | \'google\' | \'meta\'. Present for AI Gateway traffic." },
3423
+ { "key": "injection_score", "type": "number", "required": false, "description": "Combined prompt injection confidence (0-100). MAX of all detector scores." },
3424
+ { "key": "jailbreak_score", "type": "number", "required": false, "description": "Combined jailbreak detection confidence (0-100). MAX of all detector scores." },
3425
+ { "key": "injection_pulse_score", "type": "number", "required": false, "description": "Highflame single-turn classifier score for prompt injection (0-100)." },
3426
+ { "key": "injection_deep_context_score", "type": "number", "required": false, "description": "DeepContext multi-turn analyzer score for prompt injection (0-100)." },
3427
+ { "key": "jailbreak_pulse_score", "type": "number", "required": false, "description": "Highflame single-turn classifier score for jailbreak attempts (0-100)." },
3428
+ { "key": "jailbreak_deep_context_score", "type": "number", "required": false, "description": "DeepContext multi-turn analyzer score for jailbreak attempts (0-100)." },
3429
+ { "key": "injection_type", "type": "string", "required": false, "description": "Type of injection detected: \'prompt\', \'sql\', \'command\', or \'none\'" },
3430
+ { "key": "indirect_injection_score", "type": "number", "required": false, "description": "Indirect prompt injection risk score (0-100) — injection via tool outputs, retrieved documents, or external content." },
3431
+ { "key": "indirect_injection_type", "type": "string", "required": false, "description": "Type of indirect injection detected in content (e.g., instruction override, authority hijack)" },
3432
+ { "key": "secrets_detected", "type": "boolean", "required": false, "description": "Whether any API keys, tokens, passwords, or credentials were detected" },
3433
+ { "key": "secret_count", "type": "number", "required": false, "description": "Total number of secret matches found" },
3434
+ { "key": "secret_types", "type": "array", "required": false, "description": "Array of secret types found (e.g., [\'aws_access_key\', \'github_token\'])" },
3435
+ { "key": "pii_detected", "type": "boolean", "required": false, "description": "Whether personally identifiable information (PII) was found" },
3436
+ { "key": "pii_count", "type": "number", "required": false, "description": "Total number of PII matches found" },
3437
+ { "key": "pii_types", "type": "array", "required": false, "description": "Array of PII types detected (e.g., [\'email\', \'phone\', \'ssn\', \'credit_card\'])" },
3438
+ { "key": "pii_score", "type": "number", "required": false, "description": "PII detection ML classifier confidence (0-100)." },
3439
+ { "key": "highest_severity", "type": "string", "required": false, "description": "Highest severity level: \'critical\', \'high\', \'medium\', \'low\', or \'none\'" },
3440
+ { "key": "threat_count", "type": "number", "required": false, "description": "Total number of threats detected across all detectors" },
3441
+ { "key": "threat_categories", "type": "array", "required": false, "description": "Array of threat category names detected (e.g., [\'injection\', \'pii\', \'secrets\'])" },
3442
+ { "key": "detected_threats", "type": "array", "required": false, "description": "Array of specific threat names detected" },
3443
+ { "key": "violence_score", "type": "number", "required": false, "description": "ML-based score for violent content references (0-100)." },
3444
+ { "key": "hate_speech_score", "type": "number", "required": false, "description": "ML-based score for hate speech or discriminatory language (0-100)." },
3445
+ { "key": "sexual_score", "type": "number", "required": false, "description": "ML-based score for sexual or adult content (0-100)." },
3446
+ { "key": "weapons_score", "type": "number", "required": false, "description": "ML-based score for weapons references (0-100)." },
3447
+ { "key": "crime_score", "type": "number", "required": false, "description": "ML-based score for criminal activity discussions (0-100)." },
3448
+ { "key": "profanity_score", "type": "number", "required": false, "description": "ML-based score for profanity and vulgar language (0-100)." },
3449
+ { "key": "content_topics", "type": "array", "required": false, "description": "Semantic topics detected in content (e.g., [\'controlled_substances\', \'weapons_manufacturing\'])" },
3450
+ { "key": "topic_confidence", "type": "number", "required": false, "description": "Confidence score from topic classifier (0-100)." },
3451
+ { "key": "invisible_chars_detected", "type": "boolean", "required": false, "description": "Whether invisible Unicode characters were detected in the content" },
3452
+ { "key": "invisible_chars_score", "type": "number", "required": false, "description": "Density score for invisible characters (0-100)." },
3453
+ { "key": "command_injection_detected", "type": "boolean", "required": false, "description": "Whether command injection patterns were detected" },
3454
+ { "key": "command_injection_type", "type": "string", "required": false, "description": "Type of command injection: \'reverse_shell\', \'privilege_escalation\', \'code_execution\', \'destructive_command\', or \'data_exfiltration\'" },
3455
+ { "key": "command_injection_score", "type": "number", "required": false, "description": "Confidence score for command injection detection (0-100)." },
3456
+ { "key": "path_traversal_detected", "type": "boolean", "required": false, "description": "Whether path traversal patterns were detected" },
3457
+ { "key": "path_traversal_severity", "type": "string", "required": false, "description": "Severity of path traversal: \'critical\', \'high\', \'medium\', \'low\', or \'none\'" },
3458
+ { "key": "path_traversal_type", "type": "string", "required": false, "description": "Type of path traversal detected" },
3459
+ { "key": "sql_injection_detected", "type": "boolean", "required": false, "description": "Whether SQL injection patterns were detected" },
3460
+ { "key": "sql_injection_type", "type": "string", "required": false, "description": "Type of SQL injection: \'tautology\', \'union_based\', \'destructive\', \'blind\', or \'error_based\'" },
3461
+ { "key": "sql_injection_score", "type": "number", "required": false, "description": "Confidence score for SQL injection detection (0-100)." },
3462
+ { "key": "cross_origin_detected", "type": "boolean", "required": false, "description": "Whether cross-origin escalation patterns were detected" },
3463
+ { "key": "cross_origin_type", "type": "string", "required": false, "description": "Type of cross-origin escalation: \'cross_origin_tool\', \'cross_origin_server\', or \'none\'" },
3464
+ { "key": "cross_origin_score", "type": "number", "required": false, "description": "Risk score for cross-origin escalation (0-100)." },
3465
+ { "key": "encoded_content_detected", "type": "boolean", "required": false, "description": "Whether encoded content was detected (base64, hex, unicode, URL encoding)" },
3466
+ { "key": "encoded_types", "type": "array", "required": false, "description": "Array of encoding types detected (e.g., [\'base64\', \'hex\', \'unicode\', \'url\'])" },
3467
+ { "key": "encoded_count", "type": "number", "required": false, "description": "Number of encoded segments found" },
3468
+ { "key": "encoded_score", "type": "number", "required": false, "description": "Risk score for encoded injection attempts (0-100)." },
3469
+ { "key": "detected_language", "type": "string", "required": false, "description": "ISO language code of the detected language (e.g., \'en\', \'fr\', \'zh\')" },
3470
+ { "key": "is_english", "type": "boolean", "required": false, "description": "Whether the content is in English" },
3471
+ { "key": "language_confidence", "type": "number", "required": false, "description": "Confidence score for language detection (0-100)." },
3472
+ { "key": "detected_script", "type": "string", "required": false, "description": "Writing script detected: \'latin\', \'cyrillic\', \'arabic\', \'cjk\', \'unknown\', etc." },
3473
+ { "key": "is_latin_script", "type": "boolean", "required": false, "description": "Whether the content uses Latin script" },
3474
+ { "key": "script_confidence", "type": "number", "required": false, "description": "Confidence score for script detection (0-100)." },
3475
+ { "key": "hallucination_score", "type": "number", "required": false, "description": "ML-based score for hallucinated or fabricated content (0-100)." },
3476
+ { "key": "factuality_score", "type": "number", "required": false, "description": "ML-based factuality assessment score (0-100)." },
3477
+ { "key": "sentiment_score", "type": "number", "required": false, "description": "Sentiment analysis score." },
3478
+ { "key": "contains_code", "type": "boolean", "required": false, "description": "Whether code snippets were detected in the content" },
3479
+ { "key": "code_languages", "type": "array", "required": false, "description": "Array of programming languages detected in code snippets" },
3480
+ { "key": "code_ratio", "type": "number", "required": false, "description": "Percentage of content that consists of code (0-100)." },
3481
+ { "key": "keyword_matched", "type": "boolean", "required": false, "description": "Whether any configured keywords or phrases were matched" },
3482
+ { "key": "keyword_categories", "type": "array", "required": false, "description": "Array of keyword categories matched (e.g., [\'competitor_names\', \'restricted_topics\'])" },
3483
+ { "key": "keyword_count", "type": "number", "required": false, "description": "Number of keyword matches found" },
3484
+ { "key": "contains_non_ascii", "type": "boolean", "required": false, "description": "Whether non-ASCII characters were detected" },
3485
+ { "key": "phishing_detected", "type": "boolean", "required": false, "description": "Whether phishing patterns were detected" },
3486
+ { "key": "content_safety_score", "type": "number", "required": false, "description": "Aggregate content safety score (0-100)." },
3487
+ { "key": "content_safety_blocked", "type": "boolean", "required": false, "description": "Whether content was flagged for blocking by the content safety system" },
3488
+ { "key": "conversation_turn", "type": "number", "required": false, "description": "Current conversation turn number" },
3489
+ { "key": "multi_turn_detection", "type": "boolean", "required": false, "description": "Whether multi-turn injection patterns were detected" },
3490
+ { "key": "budget_remaining_pct", "type": "number", "required": false, "description": "Remaining token budget as percentage (0-100)." },
3491
+ { "key": "budget_exceeded", "type": "boolean", "required": false, "description": "Whether the token budget has been exceeded" },
3492
+ { "key": "rpm_remaining_pct", "type": "number", "required": false, "description": "Remaining RPM percentage (0-100). Gateway-metered, Shield-decided (ADR 0014)." },
3493
+ { "key": "rpm_exceeded", "type": "boolean", "required": false, "description": "Whether the RPM limit has been exceeded" },
3494
+ { "key": "tpm_remaining_pct", "type": "number", "required": false, "description": "Remaining TPM percentage (0-100). Gateway-metered, Shield-decided (ADR 0014)." },
3495
+ { "key": "tpm_exceeded", "type": "boolean", "required": false, "description": "Whether the TPM limit has been exceeded" },
3496
+ { "key": "session_pii_detected", "type": "boolean", "required": false, "description": "Whether PII was detected in any previous turn of the session" },
3497
+ { "key": "session_pii_types", "type": "array", "required": false, "description": "PII types detected across the session (accumulated)" },
3498
+ { "key": "session_secrets_detected", "type": "boolean", "required": false, "description": "Whether secrets were detected in any previous turn of the session" },
3499
+ { "key": "session_secret_types", "type": "array", "required": false, "description": "Secret types detected across the session (accumulated)" },
3500
+ { "key": "session_injection_detected", "type": "boolean", "required": false, "description": "Whether prompt injection was detected in any previous turn of the session" },
3501
+ { "key": "session_command_injection", "type": "boolean", "required": false, "description": "Whether command injection was detected in any previous turn of the session" },
3502
+ { "key": "session_threat_turns", "type": "number", "required": false, "description": "Number of turns in the session where threats were detected" },
3503
+ { "key": "session_max_injection_score", "type": "number", "required": false, "description": "Highest prompt injection score seen in any turn of the session (0-100). Use for tiered responses: >75 hard block, >50 restrict permissions" },
3504
+ { "key": "session_max_jailbreak_score", "type": "number", "required": false, "description": "Highest jailbreak detection score seen in any turn of the session (0-100)" },
3505
+ { "key": "session_max_command_injection_score", "type": "number", "required": false, "description": "Highest command injection score seen in any turn of the session (0-100)" },
3506
+ { "key": "session_max_pii_score", "type": "number", "required": false, "description": "Highest PII risk score seen in any turn of the session (0-100)" },
3507
+ { "key": "session_max_secret_score", "type": "number", "required": false, "description": "Highest secret detection score seen in any turn of the session (0-100)" },
3508
+ { "key": "session_cumulative_risk_score", "type": "number", "required": false, "description": "Sum of per-turn risk scores across the session. Catches death-by-a-thousand-cuts where no single turn is high but cumulative risk is significant" },
3509
+ { "key": "session_max_sensitivity", "type": "string", "required": false, "description": "Highest data-sensitivity tier observed across the session (e.g. \'public\', \'internal\', \'confidential\', \'restricted\')" },
3510
+ { "key": "session_original_request", "type": "string", "required": false, "description": "The session\'s first user request, retained for drift / goal-hijack policies that compare later turns against the original intent" },
3511
+ { "key": "agent_id", "type": "string", "required": false, "description": "Unique identifier of the authenticated AI agent making this request. Empty string for human user requests." },
3512
+ { "key": "agent_type", "type": "string", "required": false, "description": "Type of the authenticated agent: \'orchestrator\', \'autonomous\', \'tool_agent\', or \'human_proxy\'. Empty string for human users." },
3513
+ { "key": "agent_trust_level", "type": "string", "required": false, "description": "Trust level of the authenticated agent: \'first_party\', \'verified_third_party\', or \'unverified\'." },
3514
+ { "key": "agent_framework", "type": "string", "required": false, "description": "Framework or SDK the agent is built with (e.g., \'claude-code\', \'langchain\', \'crewai\', \'autogen\')." },
3515
+ { "key": "agent_publisher", "type": "string", "required": false, "description": "Organization that published the agent (e.g., \'anthropic\', \'internal\', \'acme-corp\')." },
3516
+ { "key": "flow_confidentiality", "type": "string", "required": false, "description": "Confidentiality tier of the data this action carries or targets (ADR 0020): \'public\', \'internal\', \'confidential\', \'restricted\', or \'unknown\'. Shares the ladder with session_max_sensitivity but is a per-value fact, not a session scalar. \'unknown\' MUST NOT be treated as \'public\' — guard with has and let policy DENY/STEP_UP/DEFER per flow_resolution_status." },
3517
+ { "key": "flow_integrity", "type": "string", "required": false, "description": "Integrity/influence tier of the data this action carries (ADR 0020): \'trusted\', \'untrusted\', \'mixed\', or \'unknown\'. Orthogonal to confidentiality: untrusted content may inform a pure analysis but MUST NOT authorize a side-effecting sink. Least-trusted contributor wins on join." },
3518
+ { "key": "flow_data_types", "type": "array", "required": false, "description": "Sensitive data categories present in the value (ADR 0020), e.g. \'pii\', \'secrets\', \'source_code\', \'financial\', \'health\'. Union of all contributing inputs. Set<String>." },
3519
+ { "key": "flow_compartments", "type": "array", "required": false, "description": "Compartments the value belongs to (ADR 0020), e.g. \'tenant:acme\', \'customer:123\', \'project:x\'. Union of all contributing inputs — cross-compartment composition is expressible by cardinality. Set<String>." },
3520
+ { "key": "flow_resolution_status", "type": "string", "required": false, "description": "How the flow label was resolved (ADR 0020): \'known\', \'inferred\', \'unknown\', or \'conflicted\'. Policy authors choose the posture for \'unknown\' per sink (DENY external, STEP_UP, DEFER while a classifier runs, or allow-and-record). Never silently resolves to public." },
3521
+ { "key": "flow_origins", "type": "array", "required": false, "description": "Origin kinds that produced or influenced the value (ADR 0020): \'mcp_tool_result\', \'model\', \'file\', \'database\', \'user\'. Provenance fact for lineage-aware policy. Set<String>." },
3522
+ { "key": "flow_sink", "type": "string", "required": false, "description": "Logical destination this action releases the value to (ADR 0020), e.g. \'external_model\', \'local_model\', \'external_mcp\', \'trusted_mcp\', \'user_secure_output\', \'public_network\', \'file\'. The \'where\' half of a flow decision — pair with flow_confidentiality/flow_integrity." },
3523
+ { "key": "flow_sink_is_external", "type": "boolean", "required": false, "description": "Whether the destination is outside the tenant trust boundary (ADR 0020). Lets a single policy express \'confidential data MUST NOT leave to any external sink\' without enumerating sink ids." },
3524
+ { "key": "flow_sink_effects", "type": "array", "required": false, "description": "Side effects the destination can exercise (ADR 0020), e.g. \'network.send\', \'financial.transfer\', \'filesystem.write\'. Enables \'untrusted content MUST NOT reach a financial.transfer sink\'. Set<String>." },
3525
+ { "key": "principal_clearances", "type": "array", "required": false, "description": "Clearances AuthN/ZeroID mints for the principal (ADR 0020 D8), e.g. \'restricted\', \'pii\'. Coarse scopes gate the capability; clearances gate which protected data that capability may touch. Set<String>." },
3526
+ { "key": "principal_compartments", "type": "array", "required": false, "description": "Compartments the principal is admitted to (ADR 0020 D8), e.g. \'tenant:acme\', \'customer:123\'. A flow into a compartment the principal lacks is deniable independent of confidentiality tier. Set<String>." },
3527
+ { "key": "surface", "type": "string", "required": true, "description": "Origin surface of the request (ADR 0012 D14.2) — REQUIRED; projected by Shield from the ingress product, never user-supplied. Values are the product identifiers: \'guardrails\', \'overwatch\', \'ai_gateway\' (\'sentry\' joins at D17 phase 2). The \'Applies to\' narrowing target: test with an ordinary condition (context.surface == \'ai_gateway\'); no \'has\' guard needed because it is required. A policy with no surface condition applies to every surface, including ones added later." },
3528
+ { "key": "malicious_package_detected", "type": "boolean", "required": false, "description": "Whether a referenced package carries a known-malicious osv.dev (MAL-) advisory." },
3529
+ { "key": "package_install_detected", "type": "boolean", "required": false, "description": "Whether the request installs or downloads a package (pip/npm/cargo/etc.)." },
3530
+ { "key": "package_check_status", "type": "string", "required": false, "description": "Malicious-package lookup status: empty (ok) or degraded (OSV unavailable, fail-open)." },
3531
+ { "key": "max_threat_severity", "type": "number", "required": false, "description": "Aggregate max threat severity across detectors (0=none,1=low,2=medium,3=high,4=critical)." }
3532
+ ]
3533
+ },
3334
3534
  {
3335
3535
  "name": "call_tool",
3336
3536
  "description": "Execute agentic tool calls, including shell commands, file operations, and MCP tools",
@@ -3886,6 +4086,57 @@ export const AI_GATEWAY_CONTEXT = {
3886
4086
  { "key": "tpm_exceeded", "type": "boolean", "required": false, "description": "Whether the TPM limit has been exceeded. Use this to enforce token rate limits via Cedar policy" }
3887
4087
  ]
3888
4088
  },
4089
+ {
4090
+ "name": "process_response",
4091
+ "description": "Process a model response (LLM chat completion output) — threat focus: data leakage in output, harmful content, hallucination, indirect injection carried back to the caller. Distinct trigger from process_prompt (ADR 0031) so a policy can be scoped to one direction from its head and prompt-only detectors stay off the egress path.",
4092
+ "context_attributes": [
4093
+ { "key": "role", "type": "string", "required": false, "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." },
4094
+ { "key": "privilege_scope", "type": "array", "required": false, "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." },
4095
+ { "key": "content", "type": "string", "required": true, "description": "Raw content being scanned" },
4096
+ { "key": "mcp_server", "type": "string", "required": false, "description": "MCP server name" },
4097
+ { "key": "threat_count", "type": "number", "required": false, "description": "Total threats detected" },
4098
+ { "key": "highest_severity", "type": "string", "required": false, "description": "Highest threat severity" },
4099
+ { "key": "threat_categories", "type": "array", "required": false, "description": "Threat category names" },
4100
+ { "key": "detected_threats", "type": "array", "required": false, "description": "Detection rule names that matched" },
4101
+ { "key": "max_threat_severity", "type": "number", "required": false, "description": "Numeric severity (0-4)" },
4102
+ { "key": "secrets_detected", "type": "boolean", "required": false, "description": "Whether secrets/credentials detected" },
4103
+ { "key": "secret_types", "type": "array", "required": false, "description": "Types of secrets found" },
4104
+ { "key": "secret_count", "type": "number", "required": false, "description": "Number of distinct secrets" },
4105
+ { "key": "pii_detected", "type": "boolean", "required": false, "description": "Whether PII detected" },
4106
+ { "key": "pii_types", "type": "array", "required": false, "description": "Types of PII detected" },
4107
+ { "key": "pii_count", "type": "number", "required": false, "description": "Number of PII matches" },
4108
+ { "key": "pii_score", "type": "number", "required": false, "description": "PII classifier confidence (0-100)" },
4109
+ { "key": "injection_score", "type": "number", "required": false, "description": "Injection classifier confidence (0-100)" },
4110
+ { "key": "jailbreak_score", "type": "number", "required": false, "description": "Jailbreak classifier confidence (0-100)" },
4111
+ { "key": "violence_score", "type": "number", "required": false, "description": "Violence content score (0-100)" },
4112
+ { "key": "weapons_score", "type": "number", "required": false, "description": "Weapons content score (0-100)" },
4113
+ { "key": "hate_speech_score", "type": "number", "required": false, "description": "Hate speech score (0-100)" },
4114
+ { "key": "crime_score", "type": "number", "required": false, "description": "Crime content score (0-100)" },
4115
+ { "key": "sexual_score", "type": "number", "required": false, "description": "Sexual content score (0-100)" },
4116
+ { "key": "profanity_score", "type": "number", "required": false, "description": "Profanity score (0-100)" },
4117
+ { "key": "invisible_chars_detected", "type": "boolean", "required": false, "description": "Invisible Unicode chars detected" },
4118
+ { "key": "invisible_chars_score", "type": "number", "required": false, "description": "Unicode attack severity (0-100)" },
4119
+ { "key": "model_name", "type": "string", "required": false, "description": "Target model name (e.g., gpt-4, claude-3-opus)" },
4120
+ { "key": "model_provider", "type": "string", "required": false, "description": "Provider name (e.g., openai, anthropic, bedrock)" },
4121
+ { "key": "session_threat_turns", "type": "number", "required": false, "description": "Count of turns with detected threats in this session" },
4122
+ { "key": "session_cumulative_risk_score", "type": "number", "required": false, "description": "Cumulative risk score across session turns" },
4123
+ { "key": "session_injection_detected", "type": "boolean", "required": false, "description": "Injection seen in any prior turn of this session" },
4124
+ { "key": "session_command_injection", "type": "boolean", "required": false, "description": "Command injection seen in any prior turn of this session" },
4125
+ { "key": "session_pii_detected", "type": "boolean", "required": false, "description": "PII seen in any prior turn of this session" },
4126
+ { "key": "session_pii_types", "type": "array", "required": false, "description": "PII types accumulated across session" },
4127
+ { "key": "session_secrets_detected", "type": "boolean", "required": false, "description": "Secrets seen in any prior turn of this session" },
4128
+ { "key": "session_secret_types", "type": "array", "required": false, "description": "Secret types accumulated across session" },
4129
+ { "key": "session_max_injection_score", "type": "number", "required": false, "description": "Max injection score across session turns" },
4130
+ { "key": "session_max_jailbreak_score", "type": "number", "required": false, "description": "Max jailbreak score across session turns" },
4131
+ { "key": "session_max_command_injection_score", "type": "number", "required": false, "description": "Max command-injection score across session turns" },
4132
+ { "key": "session_max_pii_score", "type": "number", "required": false, "description": "Max pii score across session turns" },
4133
+ { "key": "session_max_secret_score", "type": "number", "required": false, "description": "Max secret score across session turns" },
4134
+ { "key": "rpm_remaining_pct", "type": "number", "required": false, "description": "Remaining RPM (requests per minute) as percentage (0-100). Gateway-metered, Shield-decided (ADR 0014)" },
4135
+ { "key": "rpm_exceeded", "type": "boolean", "required": false, "description": "Whether the RPM limit has been exceeded. Use this to enforce rate limits via Cedar policy" },
4136
+ { "key": "tpm_remaining_pct", "type": "number", "required": false, "description": "Remaining TPM (tokens per minute) as percentage (0-100). Gateway-metered, Shield-decided (ADR 0014)" },
4137
+ { "key": "tpm_exceeded", "type": "boolean", "required": false, "description": "Whether the TPM limit has been exceeded. Use this to enforce token rate limits via Cedar policy" }
4138
+ ]
4139
+ },
3889
4140
  {
3890
4141
  "name": "read_file",
3891
4142
  "description": "Read an MCP resource — threat focus: secrets exposure, PII exposure",
@@ -4085,6 +4336,117 @@ export const GUARDRAILS_CONTEXT = {
4085
4336
  { "key": "agent_publisher", "type": "string", "required": false, "description": "Organization that published the agent (e.g., \'anthropic\', \'internal\', \'acme-corp\'). Use this for organization-level trust policies" }
4086
4337
  ]
4087
4338
  },
4339
+ {
4340
+ "name": "process_response",
4341
+ "description": "Process a model response (LLM chat completion output) — threat focus: data leakage in output, harmful content, hallucination, indirect injection carried back to the caller. Distinct trigger from process_prompt (ADR 0031) so a policy can be scoped to one direction from its head and prompt-only detectors stay off the egress path.",
4342
+ "context_attributes": [
4343
+ { "key": "role", "type": "string", "required": false, "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." },
4344
+ { "key": "privilege_scope", "type": "array", "required": false, "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." },
4345
+ { "key": "identity_type", "type": "string", "required": false, "description": "Principal identity class projected from the token: \'human\', \'agent\', or \'service\'. Use to apply identity-class-specific policies" },
4346
+ { "key": "principal", "type": "string", "required": false, "description": "Stable principal identifier projected from the token (e.g. a ZeroID / WIMSE URI or user id). Absent when the token carries no principal claim" },
4347
+ { "key": "request_id", "type": "string", "required": true, "description": "Unique identifier for this request, useful for audit trails and debugging" },
4348
+ { "key": "timestamp", "type": "number", "required": true, "description": "Unix timestamp in milliseconds when the request was processed" },
4349
+ { "key": "direction", "type": "string", "required": true, "description": "Content flow direction: \'input\' for user prompts, \'output\' for AI responses. Use this to apply different policies to inputs vs outputs (e.g., block PII only in outputs)" },
4350
+ { "key": "content_type", "type": "string", "required": true, "description": "Type of content being analyzed: \'prompt\', \'response\', \'tool_call\', \'file\', or \'clipboard\'" },
4351
+ { "key": "detector_count", "type": "number", "required": true, "description": "Number of detectors that were executed for this request" },
4352
+ { "key": "injection_score", "type": "number", "required": false, "description": "Combined prompt injection confidence (0-100). MAX of all detector scores (Pulse + DeepContext). Use injection_pulse_score / injection_deep_context_score for individual detector control" },
4353
+ { "key": "jailbreak_score", "type": "number", "required": false, "description": "Combined jailbreak detection confidence (0-100). MAX of all detector scores (Pulse + DeepContext). Use jailbreak_pulse_score / jailbreak_deep_context_score for individual detector control" },
4354
+ { "key": "injection_pulse_score", "type": "number", "required": false, "description": "Highflame single-turn classifier score for prompt injection (0-100). Raw score from Pulse detector before combination with deep-context. Use for per-detector policy control" },
4355
+ { "key": "injection_deep_context_score", "type": "number", "required": false, "description": "DeepContext multi-turn analyzer score for prompt injection (0-100). Tracks injection patterns across conversation history. Generally higher confidence than single-turn" },
4356
+ { "key": "jailbreak_pulse_score", "type": "number", "required": false, "description": "Highflame single-turn classifier score for jailbreak attempts (0-100). Raw score from Pulse detector before combination with deep-context" },
4357
+ { "key": "jailbreak_deep_context_score", "type": "number", "required": false, "description": "DeepContext multi-turn analyzer score for jailbreak attempts (0-100). Detects jailbreak escalation patterns across conversation turns" },
4358
+ { "key": "injection_type", "type": "string", "required": false, "description": "Type of injection detected: \'prompt\', \'sql\', \'command\', or \'none\'. Use this to apply different policies per injection type" },
4359
+ { "key": "secrets_detected", "type": "boolean", "required": false, "description": "Whether any API keys, tokens, passwords, or credentials were detected in the content. True indicates presence of secrets" },
4360
+ { "key": "secret_count", "type": "number", "required": false, "description": "Total number of secret matches found. Multiple matches may indicate data dumps or accidental credential exposure" },
4361
+ { "key": "secret_types", "type": "array", "required": false, "description": "Array of secret types found (e.g., [\'aws_access_key\', \'github_token\']). Use set operations like .contains() to check for specific types" },
4362
+ { "key": "pii_detected", "type": "boolean", "required": false, "description": "Whether personally identifiable information (PII) was found in the content. Commonly used to block PII in outputs to prevent data leakage" },
4363
+ { "key": "pii_count", "type": "number", "required": false, "description": "Total number of PII matches found (emails, phone numbers, SSNs, etc.)" },
4364
+ { "key": "pii_types", "type": "array", "required": false, "description": "Array of PII types detected (e.g., [\'email\', \'phone\', \'ssn\', \'credit_card\']). Use .contains() to block specific sensitive types" },
4365
+ { "key": "pii_score", "type": "number", "required": false, "description": "PII detection ML classifier confidence (0-100). Catches novel PII patterns including names, addresses, and identifiers that regex rules may miss. Typical threshold: >=80 for high-confidence blocking" },
4366
+ { "key": "highest_severity", "type": "string", "required": false, "description": "Highest severity level across all detection engines: \'critical\', \'high\', \'medium\', \'low\', or \'none\'. Use for severity-based catch-all policies (e.g., block any content flagged as critical)" },
4367
+ { "key": "violence_score", "type": "number", "required": false, "description": "ML-based score for violent content references (0-100). Typical threshold: >90 for critical blocks, >60 for warnings" },
4368
+ { "key": "hate_speech_score", "type": "number", "required": false, "description": "ML-based score for hate speech, discriminatory language, or targeted harassment (0-100). Typical threshold: >75 for blocks" },
4369
+ { "key": "sexual_score", "type": "number", "required": false, "description": "ML-based score for sexual or adult content (0-100). Adjust thresholds based on your application\'s audience" },
4370
+ { "key": "weapons_score", "type": "number", "required": false, "description": "ML-based score for weapons references or violent imagery (0-100)" },
4371
+ { "key": "crime_score", "type": "number", "required": false, "description": "ML-based score for criminal activity discussions (0-100)" },
4372
+ { "key": "profanity_score", "type": "number", "required": false, "description": "ML-based score for profanity and vulgar language (0-100)" },
4373
+ { "key": "content_topics", "type": "array", "required": false, "description": "Semantic topics detected in content (e.g., [\'controlled_substances\', \'weapons_manufacturing\']). Use .contains() to block specific topics per application" },
4374
+ { "key": "topic_confidence", "type": "number", "required": false, "description": "Confidence score from topic classifier (0-100). Use with content_topics to tune sensitivity — higher thresholds reduce false positives" },
4375
+ { "key": "invisible_chars_detected", "type": "boolean", "required": false, "description": "Whether invisible Unicode characters (zero-width joiners, RTL marks, etc.) were detected in the content. Commonly used for prompt injection evasion" },
4376
+ { "key": "invisible_chars_score", "type": "number", "required": false, "description": "Density score for invisible characters in the content (0-100). Higher scores indicate more invisible characters, suggesting evasion attempts" },
4377
+ { "key": "command_injection_detected", "type": "boolean", "required": false, "description": "Whether command injection patterns were detected in the content (reverse shells, privilege escalation, destructive commands)" },
4378
+ { "key": "command_injection_type", "type": "string", "required": false, "description": "Type of command injection: \'reverse_shell\', \'privilege_escalation\', \'code_execution\', \'destructive_command\', or \'data_exfiltration\'" },
4379
+ { "key": "command_injection_score", "type": "number", "required": false, "description": "Confidence score for command injection detection (0-100). Higher scores indicate stronger pattern matches" },
4380
+ { "key": "path_traversal_detected", "type": "boolean", "required": false, "description": "Whether path traversal patterns were detected (e.g., ../../../etc/passwd, URL-encoded variants)" },
4381
+ { "key": "path_traversal_severity", "type": "string", "required": false, "description": "Severity of path traversal: \'critical\' (sensitive system files), \'high\' (deep traversal), \'medium\' (moderate traversal), \'low\', or \'none\'" },
4382
+ { "key": "path_traversal_type", "type": "string", "required": false, "description": "Type of path traversal detected (e.g., \'sensitive_file\', \'deep_traversal\', \'encoded_traversal\')" },
4383
+ { "key": "sql_injection_detected", "type": "boolean", "required": false, "description": "Whether SQL injection patterns were detected (tautologies, UNION-based, destructive queries)" },
4384
+ { "key": "sql_injection_type", "type": "string", "required": false, "description": "Type of SQL injection: \'tautology\', \'union_based\', \'destructive\', \'blind\', or \'error_based\'" },
4385
+ { "key": "sql_injection_score", "type": "number", "required": false, "description": "Confidence score for SQL injection detection (0-100). Typical threshold: >=75 for blocks" },
4386
+ { "key": "cross_origin_detected", "type": "boolean", "required": false, "description": "Whether cross-origin escalation patterns were detected (tool calls or references crossing trust boundaries)" },
4387
+ { "key": "cross_origin_type", "type": "string", "required": false, "description": "Type of cross-origin escalation: \'cross_origin_tool\', \'cross_origin_server\', or \'none\'" },
4388
+ { "key": "cross_origin_score", "type": "number", "required": false, "description": "Risk score for cross-origin escalation (0-100). Higher scores indicate more suspicious cross-boundary activity" },
4389
+ { "key": "package_install_detected", "type": "boolean", "required": false, "description": "Whether the event contains a recognized package install/download command (pip, npm, yarn, pnpm, bun, uv, gem, cargo, go, composer)" },
4390
+ { "key": "packages_checked", "type": "number", "required": false, "description": "Number of unique packages checked against the osv.dev database for this event" },
4391
+ { "key": "malicious_package_detected", "type": "boolean", "required": false, "description": "Whether any referenced package has a known-malicious OSV advisory (OpenSSF MAL- ID). Use to block supply-chain attacks at install time" },
4392
+ { "key": "malicious_package_score", "type": "number", "required": false, "description": "100 when a malicious package was detected, 0 otherwise" },
4393
+ { "key": "malicious_packages", "type": "array", "required": false, "description": "Malicious packages as ecosystem/name[@version] strings (e.g. \'PyPI/evil-pkg@1.0.0\')" },
4394
+ { "key": "package_names", "type": "array", "required": false, "description": "Names of all packages parsed from the install command (without ecosystem prefix), e.g. [\'requests\', \'left-pad\']. Available even when the osv.dev lookup fails." },
4395
+ { "key": "package_ecosystems", "type": "array", "required": false, "description": "Unique package ecosystems seen in this event, e.g. [\'PyPI\', \'npm\']. Useful for policy rules that restrict which ecosystems are permitted." },
4396
+ { "key": "package_advisory_count", "type": "number", "required": false, "description": "Total number of non-malicious OSV advisories (GHSA- / CVE- IDs) found across all checked packages. Excludes MAL- entries counted in malicious_package_detected." },
4397
+ { "key": "package_risk_score", "type": "number", "required": false, "description": "Graduated supply-chain risk score (0-100). 100 when any malicious package is found; proportional to advisory_count for advisory-only packages; 0 when all packages are clean." },
4398
+ { "key": "package_check_status", "type": "string", "required": false, "description": "Set to \'degraded\' when the osv.dev lookup failed and packages could not be verified (fail-open). Combine with package_install_detected to fail closed" },
4399
+ { "key": "encoded_content_detected", "type": "boolean", "required": false, "description": "Whether encoded content was detected (base64, hex, unicode, URL encoding) that may hide malicious payloads" },
4400
+ { "key": "encoded_types", "type": "array", "required": false, "description": "Array of encoding types detected (e.g., [\'base64\', \'hex\', \'unicode\', \'url\']). Use .contains() to check for specific encoding types" },
4401
+ { "key": "encoded_count", "type": "number", "required": false, "description": "Number of encoded segments found in the content" },
4402
+ { "key": "encoded_score", "type": "number", "required": false, "description": "Risk score for encoded injection attempts (0-100). Considers encoding density and decoded content patterns" },
4403
+ { "key": "detected_language", "type": "string", "required": false, "description": "ISO language code of the detected language (e.g., \'en\', \'fr\', \'zh\'). Use this for language-specific policy enforcement" },
4404
+ { "key": "is_english", "type": "boolean", "required": false, "description": "Whether the content is in English. Useful for applying English-only policies or flagging non-English content" },
4405
+ { "key": "language_confidence", "type": "number", "required": false, "description": "Confidence score for language detection (0-100). Use with detected_language to tune sensitivity" },
4406
+ { "key": "detected_script", "type": "string", "required": false, "description": "Writing script detected in content: \'latin\', \'cyrillic\', \'arabic\', \'cjk\', \'unknown\', etc. Use to detect script-switching attacks" },
4407
+ { "key": "is_latin_script", "type": "boolean", "required": false, "description": "Whether the content uses Latin script. Useful for detecting non-Latin script injection attempts" },
4408
+ { "key": "script_confidence", "type": "number", "required": false, "description": "Confidence score for script detection (0-100)" },
4409
+ { "key": "hallucination_score", "type": "number", "required": false, "description": "ML-based score for hallucinated or fabricated content (0-100). Higher scores indicate higher likelihood of non-factual claims" },
4410
+ { "key": "factuality_score", "type": "number", "required": false, "description": "ML-based factuality assessment score (0-100). Higher scores indicate more factually grounded content" },
4411
+ { "key": "sentiment_score", "type": "number", "required": false, "description": "Sentiment analysis score. Use to detect overly negative or manipulative tone in prompts or responses" },
4412
+ { "key": "contains_code", "type": "boolean", "required": false, "description": "Whether code snippets were detected in the content" },
4413
+ { "key": "code_languages", "type": "array", "required": false, "description": "Array of programming languages detected in code snippets (e.g., [\'python\', \'javascript\'])" },
4414
+ { "key": "code_ratio", "type": "number", "required": false, "description": "Percentage of content that consists of code (0-100). High values may indicate code dumps or automated content" },
4415
+ { "key": "keyword_matched", "type": "boolean", "required": false, "description": "Whether any configured keywords or phrases were matched in the content" },
4416
+ { "key": "keyword_categories", "type": "array", "required": false, "description": "Array of keyword categories matched (e.g., [\'competitor_names\', \'restricted_topics\']). Use .contains() for category-specific policies" },
4417
+ { "key": "keyword_count", "type": "number", "required": false, "description": "Number of keyword matches found in the content" },
4418
+ { "key": "contains_non_ascii", "type": "boolean", "required": false, "description": "Whether non-ASCII characters were detected. May indicate obfuscation or encoding-based evasion attempts" },
4419
+ { "key": "phishing_detected", "type": "boolean", "required": false, "description": "Whether phishing patterns were detected in the content (suspicious URLs, impersonation, credential requests)" },
4420
+ { "key": "content_safety_score", "type": "number", "required": false, "description": "Aggregate content safety score (0-100). Combines multiple safety signals into a single risk indicator" },
4421
+ { "key": "content_safety_blocked", "type": "boolean", "required": false, "description": "Whether content was flagged for blocking by the content safety system" },
4422
+ { "key": "conversation_turn", "type": "number", "required": false, "description": "Current conversation turn number. Use for policies that escalate strictness over long conversations" },
4423
+ { "key": "multi_turn_detection", "type": "boolean", "required": false, "description": "Whether multi-turn injection patterns were detected (attack spread across multiple conversation turns)" },
4424
+ { "key": "rpm_remaining_pct", "type": "number", "required": false, "description": "Remaining RPM (requests per minute) as percentage (0-100). Gateway-metered, Shield-decided (ADR 0014)" },
4425
+ { "key": "rpm_exceeded", "type": "boolean", "required": false, "description": "Whether the RPM limit has been exceeded. Use this to enforce rate limits via Cedar policy" },
4426
+ { "key": "tpm_remaining_pct", "type": "number", "required": false, "description": "Remaining TPM (tokens per minute) as percentage (0-100). Gateway-metered, Shield-decided (ADR 0014)" },
4427
+ { "key": "tpm_exceeded", "type": "boolean", "required": false, "description": "Whether the TPM limit has been exceeded. Use this to enforce token rate limits via Cedar policy" },
4428
+ { "key": "session_pii_detected", "type": "boolean", "required": false, "description": "Whether PII was detected in any previous turn of the session" },
4429
+ { "key": "session_pii_types", "type": "array", "required": false, "description": "PII types detected across the session (accumulated)" },
4430
+ { "key": "session_secrets_detected", "type": "boolean", "required": false, "description": "Whether secrets were detected in any previous turn of the session" },
4431
+ { "key": "session_secret_types", "type": "array", "required": false, "description": "Secret types detected across the session (accumulated)" },
4432
+ { "key": "session_injection_detected", "type": "boolean", "required": false, "description": "Whether prompt injection was detected in any previous turn of the session" },
4433
+ { "key": "session_command_injection", "type": "boolean", "required": false, "description": "Whether command injection was detected in any previous turn of the session" },
4434
+ { "key": "session_threat_turns", "type": "number", "required": false, "description": "Number of turns in the session where threats were detected" },
4435
+ { "key": "session_max_injection_score", "type": "number", "required": false, "description": "Highest prompt injection score seen in any turn of the session (0-100). Use for tiered responses: >75 hard block, >50 restrict permissions" },
4436
+ { "key": "session_max_jailbreak_score", "type": "number", "required": false, "description": "Highest jailbreak detection score seen in any turn of the session (0-100)" },
4437
+ { "key": "session_max_command_injection_score", "type": "number", "required": false, "description": "Highest command injection score seen in any turn of the session (0-100)" },
4438
+ { "key": "session_max_pii_score", "type": "number", "required": false, "description": "Highest PII risk score seen in any turn of the session (0-100)" },
4439
+ { "key": "session_max_secret_score", "type": "number", "required": false, "description": "Highest secret detection score seen in any turn of the session (0-100)" },
4440
+ { "key": "session_cumulative_risk_score", "type": "number", "required": false, "description": "Sum of per-turn risk scores across the session. Catches death-by-a-thousand-cuts where no single turn is high but cumulative risk is significant" },
4441
+ { "key": "session_max_sensitivity", "type": "string", "required": false, "description": "Highest data-sensitivity tier observed across the session (e.g. \'public\', \'internal\', \'confidential\', \'restricted\'). Use for session-level escalation policies" },
4442
+ { "key": "session_original_request", "type": "string", "required": false, "description": "The session\'s first user request, retained for drift / goal-hijack policies that compare later turns against the original intent" },
4443
+ { "key": "agent_id", "type": "string", "required": false, "description": "Unique identifier of the authenticated AI agent making this request (e.g., \'agent_research_v3\'). Empty string for human user requests. Use this to write agent-specific policies" },
4444
+ { "key": "agent_type", "type": "string", "required": false, "description": "Type of the authenticated agent: \'orchestrator\' (coordinates sub-agents), \'autonomous\' (self-directed), \'tool_agent\' (single-purpose tool), or \'human_proxy\' (acts on behalf of a human). Empty string for human users" },
4445
+ { "key": "agent_trust_level", "type": "string", "required": false, "description": "Trust level of the authenticated agent: \'first_party\' (your own agents), \'verified_third_party\' (audited external agents), or \'unverified\' (unknown agents). Use this for tiered access control — e.g., only first_party agents can call dangerous tools" },
4446
+ { "key": "agent_framework", "type": "string", "required": false, "description": "Framework or SDK the agent is built with (e.g., \'claude-code\', \'langchain\', \'crewai\', \'autogen\'). Use this to apply framework-specific policies" },
4447
+ { "key": "agent_publisher", "type": "string", "required": false, "description": "Organization that published the agent (e.g., \'anthropic\', \'internal\', \'acme-corp\'). Use this for organization-level trust policies" }
4448
+ ]
4449
+ },
4088
4450
  {
4089
4451
  "name": "call_tool",
4090
4452
  "description": "Execute agentic tool calls, including shell commands, file operations, and MCP tools",