@highflame/policy 2.1.0 → 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/explain.js CHANGED
@@ -29,7 +29,8 @@
29
29
  * }
30
30
  * ```
31
31
  */
32
- export function explainDecision(decision, rules, context) {
32
+ export function explainDecision(decision, rules, context, options) {
33
+ const provenance = options?.provenance;
33
34
  // Build lookup map: annotations.id → PolicyRule
34
35
  const ruleMap = new Map();
35
36
  for (const rule of rules) {
@@ -49,7 +50,7 @@ export function explainDecision(decision, rules, context) {
49
50
  // Recursive condition evaluation
50
51
  let evaluatedExpression;
51
52
  if (rule.conditionExpression) {
52
- evaluatedExpression = evaluateExpression(rule.conditionExpression, context);
53
+ evaluatedExpression = evaluateExpression(rule.conditionExpression, context, provenance);
53
54
  }
54
55
  // Populate condition_results: prefer leaf extraction from expression tree,
55
56
  // fall back to flat conditions[] for backward compat with simple policies
@@ -62,7 +63,11 @@ export function explainDecision(decision, rules, context) {
62
63
  conditionResults = conditions.map(cond => {
63
64
  const actual = context[cond.field];
64
65
  const matched = evaluateCondition(cond.operator, actual, cond.value);
65
- return { field: cond.field, operator: cond.operator, expected: cond.value, actual, matched };
66
+ const result = { field: cond.field, operator: cond.operator, expected: cond.value, actual, matched };
67
+ if (provenance?.[cond.field]) {
68
+ result.source = provenance[cond.field];
69
+ }
70
+ return result;
66
71
  });
67
72
  }
68
73
  // Surface rawCondition when there are no structured conditions and no expression tree
@@ -93,19 +98,20 @@ export function explainDecision(decision, rules, context) {
93
98
  /**
94
99
  * Recursively evaluate a ConditionExpression tree against a context map.
95
100
  * Returns an EvaluatedExpression tree with `matched` booleans and `actual` values.
101
+ * The optional provenance map links context field names to their source detectors.
96
102
  */
97
- export function evaluateExpression(expr, context) {
103
+ export function evaluateExpression(expr, context, provenance) {
98
104
  switch (expr.kind) {
99
105
  case 'and': {
100
- const children = expr.children.map(c => evaluateExpression(c, context));
106
+ const children = expr.children.map(c => evaluateExpression(c, context, provenance));
101
107
  return { kind: 'and', children, matched: children.every(c => c.matched) };
102
108
  }
103
109
  case 'or': {
104
- const children = expr.children.map(c => evaluateExpression(c, context));
110
+ const children = expr.children.map(c => evaluateExpression(c, context, provenance));
105
111
  return { kind: 'or', children, matched: children.some(c => c.matched) };
106
112
  }
107
113
  case 'not': {
108
- const child = evaluateExpression(expr.child, context);
114
+ const child = evaluateExpression(expr.child, context, provenance);
109
115
  return { kind: 'not', child, matched: !child.matched };
110
116
  }
111
117
  case 'has': {
@@ -115,17 +121,26 @@ export function evaluateExpression(expr, context) {
115
121
  case 'comparison': {
116
122
  const actual = context[expr.field];
117
123
  const matched = evaluateCondition(expr.operator, actual, expr.value);
118
- return { kind: 'comparison', field: expr.field, operator: expr.operator, expected: expr.value, actual, matched };
124
+ const result = { kind: 'comparison', field: expr.field, operator: expr.operator, expected: expr.value, actual, matched };
125
+ if (provenance?.[expr.field])
126
+ result.source = provenance[expr.field];
127
+ return result;
119
128
  }
120
129
  case 'contains': {
121
130
  const actual = context[expr.field];
122
131
  const matched = evaluateContains(actual, expr.value);
123
- return { kind: 'contains', field: expr.field, expected: expr.value, actual, matched };
132
+ const result = { kind: 'contains', field: expr.field, expected: expr.value, actual, matched };
133
+ if (provenance?.[expr.field])
134
+ result.source = provenance[expr.field];
135
+ return result;
124
136
  }
125
137
  case 'like': {
126
138
  const actual = context[expr.field];
127
139
  const matched = evaluateLike(actual, expr.pattern);
128
- return { kind: 'like', field: expr.field, pattern: expr.pattern, actual, matched };
140
+ const result = { kind: 'like', field: expr.field, pattern: expr.pattern, actual, matched };
141
+ if (provenance?.[expr.field])
142
+ result.source = provenance[expr.field];
143
+ return result;
129
144
  }
130
145
  case 'raw':
131
146
  return { kind: 'raw', text: expr.text, matched: false };
@@ -296,12 +311,24 @@ function collectLeafResults(expr) {
296
311
  case 'has':
297
312
  case 'raw':
298
313
  return [];
299
- case 'comparison':
300
- return [{ field: expr.field, operator: expr.operator, expected: expr.expected, actual: expr.actual, matched: expr.matched }];
301
- case 'contains':
302
- return [{ field: expr.field, operator: 'contains', expected: expr.expected, actual: expr.actual, matched: expr.matched }];
303
- case 'like':
304
- return [{ field: expr.field, operator: 'like', expected: expr.pattern, actual: expr.actual, matched: expr.matched }];
314
+ case 'comparison': {
315
+ const result = { field: expr.field, operator: expr.operator, expected: expr.expected, actual: expr.actual, matched: expr.matched };
316
+ if (expr.source)
317
+ result.source = expr.source;
318
+ return [result];
319
+ }
320
+ case 'contains': {
321
+ const result = { field: expr.field, operator: 'contains', expected: expr.expected, actual: expr.actual, matched: expr.matched };
322
+ if (expr.source)
323
+ result.source = expr.source;
324
+ return [result];
325
+ }
326
+ case 'like': {
327
+ const result = { field: expr.field, operator: 'like', expected: expr.pattern, actual: expr.actual, matched: expr.matched };
328
+ if (expr.source)
329
+ result.source = expr.source;
330
+ return [result];
331
+ }
305
332
  }
306
333
  }
307
334
  /**
@@ -7,40 +7,86 @@
7
7
  export declare const GuardrailsContextKey: {
8
8
  readonly BudgetExceeded: "budget_exceeded";
9
9
  readonly BudgetRemainingPct: "budget_remaining_pct";
10
+ readonly CodeLanguages: "code_languages";
11
+ readonly CodeRatio: "code_ratio";
12
+ readonly CommandInjectionDetected: "command_injection_detected";
13
+ readonly CommandInjectionScore: "command_injection_score";
14
+ readonly CommandInjectionType: "command_injection_type";
15
+ readonly ContainsCode: "contains_code";
10
16
  readonly ContainsInvisibleChars: "contains_invisible_chars";
17
+ readonly ContainsNonAscii: "contains_non_ascii";
11
18
  readonly ContainsSecrets: "contains_secrets";
19
+ readonly ContentSafetyBlocked: "content_safety_blocked";
20
+ readonly ContentSafetyScore: "content_safety_score";
12
21
  readonly ContentTopics: "content_topics";
13
22
  readonly ContentType: "content_type";
23
+ readonly ConversationTurn: "conversation_turn";
14
24
  readonly CrimeScore: "crime_score";
25
+ readonly CrossOriginDetected: "cross_origin_detected";
26
+ readonly CrossOriginScore: "cross_origin_score";
27
+ readonly CrossOriginType: "cross_origin_type";
28
+ readonly DetectedLanguage: "detected_language";
29
+ readonly DetectedScript: "detected_script";
15
30
  readonly DetectorCount: "detector_count";
16
31
  readonly Direction: "direction";
32
+ readonly EncodedContentDetected: "encoded_content_detected";
33
+ readonly EncodedCount: "encoded_count";
34
+ readonly EncodedScore: "encoded_score";
35
+ readonly EncodedTypes: "encoded_types";
36
+ readonly FactualityScore: "factuality_score";
37
+ readonly HallucinationScore: "hallucination_score";
17
38
  readonly HateSpeechScore: "hate_speech_score";
18
39
  readonly InjectionScore: "injection_score";
19
40
  readonly InjectionType: "injection_type";
20
41
  readonly InvisibleCharsScore: "invisible_chars_score";
42
+ readonly IsEnglish: "is_english";
43
+ readonly IsLatinScript: "is_latin_script";
21
44
  readonly JailbreakScore: "jailbreak_score";
45
+ readonly KeywordCategories: "keyword_categories";
46
+ readonly KeywordCount: "keyword_count";
47
+ readonly KeywordMatched: "keyword_matched";
48
+ readonly LanguageConfidence: "language_confidence";
22
49
  readonly LoopCount: "loop_count";
23
50
  readonly LoopDetected: "loop_detected";
24
51
  readonly LoopTool: "loop_tool";
52
+ readonly McpConfigRisk: "mcp_config_risk";
53
+ readonly McpRiskScore: "mcp_risk_score";
54
+ readonly McpRiskType: "mcp_risk_type";
25
55
  readonly McpServer: "mcp_server";
26
56
  readonly McpServerVerified: "mcp_server_verified";
27
57
  readonly McpTool: "mcp_tool";
58
+ readonly MultiTurnDetection: "multi_turn_detection";
59
+ readonly PathTraversalDetected: "path_traversal_detected";
60
+ readonly PathTraversalSeverity: "path_traversal_severity";
61
+ readonly PathTraversalType: "path_traversal_type";
28
62
  readonly PatternType: "pattern_type";
63
+ readonly PhishingDetected: "phishing_detected";
29
64
  readonly PiiCount: "pii_count";
30
65
  readonly PiiDetected: "pii_detected";
31
66
  readonly PiiTypes: "pii_types";
32
67
  readonly ProfanityScore: "profanity_score";
33
68
  readonly RequestId: "request_id";
69
+ readonly RugPullDetected: "rug_pull_detected";
70
+ readonly RugPullScore: "rug_pull_score";
71
+ readonly RugPullType: "rug_pull_type";
72
+ readonly ScriptConfidence: "script_confidence";
34
73
  readonly SecretCount: "secret_count";
35
74
  readonly SecretTypes: "secret_types";
75
+ readonly SentimentScore: "sentiment_score";
36
76
  readonly SequenceRisk: "sequence_risk";
37
77
  readonly SexualScore: "sexual_score";
78
+ readonly SqlInjectionDetected: "sql_injection_detected";
79
+ readonly SqlInjectionScore: "sql_injection_score";
80
+ readonly SqlInjectionType: "sql_injection_type";
38
81
  readonly SuspiciousPattern: "suspicious_pattern";
39
82
  readonly Timestamp: "timestamp";
40
83
  readonly ToolCategory: "tool_category";
41
84
  readonly ToolIsBuiltin: "tool_is_builtin";
42
85
  readonly ToolIsSensitive: "tool_is_sensitive";
43
86
  readonly ToolName: "tool_name";
87
+ readonly ToolPoisoningDetected: "tool_poisoning_detected";
88
+ readonly ToolPoisoningScore: "tool_poisoning_score";
89
+ readonly ToolPoisoningType: "tool_poisoning_type";
44
90
  readonly ToolRiskScore: "tool_risk_score";
45
91
  readonly TopicConfidence: "topic_confidence";
46
92
  readonly ViolenceScore: "violence_score";
@@ -9,40 +9,86 @@
9
9
  export const GuardrailsContextKey = {
10
10
  BudgetExceeded: 'budget_exceeded',
11
11
  BudgetRemainingPct: 'budget_remaining_pct',
12
+ CodeLanguages: 'code_languages',
13
+ CodeRatio: 'code_ratio',
14
+ CommandInjectionDetected: 'command_injection_detected',
15
+ CommandInjectionScore: 'command_injection_score',
16
+ CommandInjectionType: 'command_injection_type',
17
+ ContainsCode: 'contains_code',
12
18
  ContainsInvisibleChars: 'contains_invisible_chars',
19
+ ContainsNonAscii: 'contains_non_ascii',
13
20
  ContainsSecrets: 'contains_secrets',
21
+ ContentSafetyBlocked: 'content_safety_blocked',
22
+ ContentSafetyScore: 'content_safety_score',
14
23
  ContentTopics: 'content_topics',
15
24
  ContentType: 'content_type',
25
+ ConversationTurn: 'conversation_turn',
16
26
  CrimeScore: 'crime_score',
27
+ CrossOriginDetected: 'cross_origin_detected',
28
+ CrossOriginScore: 'cross_origin_score',
29
+ CrossOriginType: 'cross_origin_type',
30
+ DetectedLanguage: 'detected_language',
31
+ DetectedScript: 'detected_script',
17
32
  DetectorCount: 'detector_count',
18
33
  Direction: 'direction',
34
+ EncodedContentDetected: 'encoded_content_detected',
35
+ EncodedCount: 'encoded_count',
36
+ EncodedScore: 'encoded_score',
37
+ EncodedTypes: 'encoded_types',
38
+ FactualityScore: 'factuality_score',
39
+ HallucinationScore: 'hallucination_score',
19
40
  HateSpeechScore: 'hate_speech_score',
20
41
  InjectionScore: 'injection_score',
21
42
  InjectionType: 'injection_type',
22
43
  InvisibleCharsScore: 'invisible_chars_score',
44
+ IsEnglish: 'is_english',
45
+ IsLatinScript: 'is_latin_script',
23
46
  JailbreakScore: 'jailbreak_score',
47
+ KeywordCategories: 'keyword_categories',
48
+ KeywordCount: 'keyword_count',
49
+ KeywordMatched: 'keyword_matched',
50
+ LanguageConfidence: 'language_confidence',
24
51
  LoopCount: 'loop_count',
25
52
  LoopDetected: 'loop_detected',
26
53
  LoopTool: 'loop_tool',
54
+ McpConfigRisk: 'mcp_config_risk',
55
+ McpRiskScore: 'mcp_risk_score',
56
+ McpRiskType: 'mcp_risk_type',
27
57
  McpServer: 'mcp_server',
28
58
  McpServerVerified: 'mcp_server_verified',
29
59
  McpTool: 'mcp_tool',
60
+ MultiTurnDetection: 'multi_turn_detection',
61
+ PathTraversalDetected: 'path_traversal_detected',
62
+ PathTraversalSeverity: 'path_traversal_severity',
63
+ PathTraversalType: 'path_traversal_type',
30
64
  PatternType: 'pattern_type',
65
+ PhishingDetected: 'phishing_detected',
31
66
  PiiCount: 'pii_count',
32
67
  PiiDetected: 'pii_detected',
33
68
  PiiTypes: 'pii_types',
34
69
  ProfanityScore: 'profanity_score',
35
70
  RequestId: 'request_id',
71
+ RugPullDetected: 'rug_pull_detected',
72
+ RugPullScore: 'rug_pull_score',
73
+ RugPullType: 'rug_pull_type',
74
+ ScriptConfidence: 'script_confidence',
36
75
  SecretCount: 'secret_count',
37
76
  SecretTypes: 'secret_types',
77
+ SentimentScore: 'sentiment_score',
38
78
  SequenceRisk: 'sequence_risk',
39
79
  SexualScore: 'sexual_score',
80
+ SqlInjectionDetected: 'sql_injection_detected',
81
+ SqlInjectionScore: 'sql_injection_score',
82
+ SqlInjectionType: 'sql_injection_type',
40
83
  SuspiciousPattern: 'suspicious_pattern',
41
84
  Timestamp: 'timestamp',
42
85
  ToolCategory: 'tool_category',
43
86
  ToolIsBuiltin: 'tool_is_builtin',
44
87
  ToolIsSensitive: 'tool_is_sensitive',
45
88
  ToolName: 'tool_name',
89
+ ToolPoisoningDetected: 'tool_poisoning_detected',
90
+ ToolPoisoningScore: 'tool_poisoning_score',
91
+ ToolPoisoningType: 'tool_poisoning_type',
46
92
  ToolRiskScore: 'tool_risk_score',
47
93
  TopicConfidence: 'topic_confidence',
48
94
  ViolenceScore: 'violence_score',
@@ -423,6 +423,111 @@ forbid (
423
423
  context.budget_remaining_pct < 5 &&
424
424
  context.budget_remaining_pct > 0
425
425
  };
426
+
427
+ // =============================================================================
428
+ // Agent Security — Supply Chain & Behavioral Drift
429
+ // =============================================================================
430
+
431
+ @id("agentic-block-tool-poisoning")
432
+ @name("Block tool poisoning attacks")
433
+ @description("Forbids tool calls or server connections when hidden instructions or authority hijack patterns are detected in tool descriptions or arguments")
434
+ @severity("critical")
435
+ @tags("agentic,tool-poisoning,supply-chain")
436
+ forbid (
437
+ principal,
438
+ action in [Guardrails::Action::"call_tool", Guardrails::Action::"connect_server"],
439
+ resource
440
+ ) when {
441
+ context has tool_poisoning_score && context.tool_poisoning_score >= 70
442
+ };
443
+
444
+ @id("agentic-block-rug-pull")
445
+ @name("Block rug pull attacks")
446
+ @description("Forbids tool calls when significant behavioral drift is detected (tool output deviates from established patterns)")
447
+ @severity("high")
448
+ @tags("agentic,rug-pull,behavioral-drift")
449
+ forbid (
450
+ principal,
451
+ action == Guardrails::Action::"call_tool",
452
+ resource
453
+ ) when {
454
+ context has rug_pull_detected && context.rug_pull_detected == true &&
455
+ context has rug_pull_score && context.rug_pull_score >= 70
456
+ };
457
+
458
+ @id("agentic-block-mcp-config-risk")
459
+ @name("Block risky MCP configurations")
460
+ @description("Forbids tool calls or server connections when MCP configuration risks are detected (inline execution, suspicious URLs, cross-origin issues)")
461
+ @severity("high")
462
+ @tags("agentic,mcp-risk,supply-chain")
463
+ forbid (
464
+ principal,
465
+ action in [Guardrails::Action::"call_tool", Guardrails::Action::"connect_server"],
466
+ resource
467
+ ) when {
468
+ context has mcp_config_risk && context.mcp_config_risk == true &&
469
+ context has mcp_risk_score && context.mcp_risk_score >= 70
470
+ };
471
+ `;
472
+ const GUARDRAILS_SECURITY_PATTERNS_DEFAULT_CEDAR = `// =============================================================================
473
+ // Security Pattern Detection Policy
474
+ // =============================================================================
475
+ // Blocks command injection, path traversal, and SQL injection attacks using
476
+ // regex-based pattern detection from Shield's security detectors.
477
+ //
478
+ // Context keys used (normalized by projection layer):
479
+ // - command_injection_detected: Bool - Command injection pattern found
480
+ // - command_injection_score: Long (0-100) - Detection confidence
481
+ // - path_traversal_detected: Bool - Path traversal pattern found
482
+ // - path_traversal_severity: String - Severity level (critical/high/medium/low)
483
+ // - sql_injection_detected: Bool - SQL injection pattern found
484
+ // - sql_injection_score: Long (0-100) - Detection confidence
485
+ //
486
+ // Category: security
487
+ // Namespace: Guardrails
488
+ // =============================================================================
489
+
490
+ @id("security-block-command-injection")
491
+ @name("Block command injection")
492
+ @description("Forbids requests containing command injection patterns such as reverse shells, privilege escalation, or destructive commands")
493
+ @severity("critical")
494
+ @tags("command-injection,security")
495
+ forbid (
496
+ principal,
497
+ action in [Guardrails::Action::"process_prompt", Guardrails::Action::"call_tool"],
498
+ resource
499
+ ) when {
500
+ context has command_injection_detected && context.command_injection_detected == true
501
+ };
502
+
503
+ @id("security-block-path-traversal")
504
+ @name("Block high-severity path traversal")
505
+ @description("Forbids requests containing path traversal patterns targeting sensitive system files or using deep directory traversal")
506
+ @severity("high")
507
+ @tags("path-traversal,security")
508
+ forbid (
509
+ principal,
510
+ action,
511
+ resource
512
+ ) when {
513
+ context has path_traversal_detected && context.path_traversal_detected == true &&
514
+ context has path_traversal_severity &&
515
+ (context.path_traversal_severity == "critical" || context.path_traversal_severity == "high")
516
+ };
517
+
518
+ @id("security-block-sql-injection")
519
+ @name("Block high-confidence SQL injection")
520
+ @description("Forbids requests with SQL injection confidence above 75% (tautologies, UNION-based, destructive queries)")
521
+ @severity("high")
522
+ @tags("sql-injection,security")
523
+ forbid (
524
+ principal,
525
+ action in [Guardrails::Action::"process_prompt", Guardrails::Action::"call_tool"],
526
+ resource
527
+ ) when {
528
+ context has sql_injection_detected && context.sql_injection_detected == true &&
529
+ context has sql_injection_score && context.sql_injection_score >= 75
530
+ };
426
531
  `;
427
532
  const GUARDRAILS_MCP_TOOL_PERMISSIONS_CEDAR = `// =============================================================================
428
533
  // MCP Tool Permissions Template
@@ -952,11 +1057,21 @@ export const GUARDRAILS_DEFAULTS = [
952
1057
  {
953
1058
  id: 'agentic-safety-default',
954
1059
  name: 'Agentic Safety',
955
- description: 'Block tool call loops, data exfiltration patterns, high-risk sequences, and budget violations',
1060
+ description: 'Block tool call loops, data exfiltration patterns, high-risk sequences, budget violations, tool poisoning, rug pull attacks, and MCP configuration risks',
956
1061
  category: 'agentic_security',
957
1062
  cedarText: GUARDRAILS_AGENTIC_SAFETY_DEFAULT_CEDAR,
958
1063
  severity: 'high',
959
- tags: ['agentic', 'safety', 'loops', 'exfiltration', 'budget'],
1064
+ tags: ['agentic', 'safety', 'loops', 'exfiltration', 'budget', 'tool-poisoning', 'rug-pull', 'mcp-risk'],
1065
+ isActive: true,
1066
+ },
1067
+ {
1068
+ id: 'security-patterns-default',
1069
+ name: 'Security Pattern Detection',
1070
+ description: 'Block command injection, path traversal, and SQL injection attacks using regex-based pattern detection',
1071
+ category: 'security',
1072
+ cedarText: GUARDRAILS_SECURITY_PATTERNS_DEFAULT_CEDAR,
1073
+ severity: 'critical',
1074
+ tags: ['command-injection', 'path-traversal', 'sql-injection', 'security'],
960
1075
  isActive: true,
961
1076
  },
962
1077
  ];
@@ -1145,11 +1260,21 @@ export const GUARDRAILS_TEMPLATES_JSON = `{
1145
1260
  {
1146
1261
  "id": "agentic-safety-default",
1147
1262
  "name": "Agentic Safety",
1148
- "description": "Block tool call loops, data exfiltration patterns, high-risk sequences, and budget violations",
1263
+ "description": "Block tool call loops, data exfiltration patterns, high-risk sequences, budget violations, tool poisoning, rug pull attacks, and MCP configuration risks",
1149
1264
  "category": "agentic_security",
1150
1265
  "file": "defaults/agentic_safety.cedar",
1151
1266
  "severity": "high",
1152
- "tags": ["agentic", "safety", "loops", "exfiltration", "budget"],
1267
+ "tags": ["agentic", "safety", "loops", "exfiltration", "budget", "tool-poisoning", "rug-pull", "mcp-risk"],
1268
+ "is_active": true
1269
+ },
1270
+ {
1271
+ "id": "security-patterns-default",
1272
+ "name": "Security Pattern Detection",
1273
+ "description": "Block command injection, path traversal, and SQL injection attacks using regex-based pattern detection",
1274
+ "category": "security",
1275
+ "file": "defaults/security_patterns.cedar",
1276
+ "severity": "critical",
1277
+ "tags": ["command-injection", "path-traversal", "sql-injection", "security"],
1153
1278
  "is_active": true
1154
1279
  }
1155
1280
  ],
@@ -1,41 +1,61 @@
1
1
  /**
2
- * Context attribute keys for Overwatch Overwatch (Guardian) IDE security & policy enforcement.
2
+ * Context attribute keys for Overwatch Overwatch IDE agent security & policy enforcement.
3
3
  *
4
4
  * These constants correspond to the context attributes defined in the
5
5
  * Overwatch Cedar schema and are used at policy evaluation time.
6
6
  */
7
7
  export declare const OverwatchContextKey: {
8
+ readonly ContainsInvisibleChars: "contains_invisible_chars";
8
9
  readonly ContainsSecrets: "contains_secrets";
9
10
  readonly Content: "content";
10
11
  readonly CrimeScore: "crime_score";
11
12
  readonly Cwd: "cwd";
13
+ readonly DetectedThreats: "detected_threats";
12
14
  readonly Event: "event";
13
15
  readonly HateSpeechScore: "hate_speech_score";
14
16
  readonly HighestSeverity: "highest_severity";
15
17
  readonly IndirectInjectionScore: "indirect_injection_score";
16
18
  readonly InjectionConfidence: "injection_confidence";
19
+ readonly InvisibleCharsScore: "invisible_chars_score";
17
20
  readonly JailbreakConfidence: "jailbreak_confidence";
21
+ readonly LoopCount: "loop_count";
22
+ readonly LoopDetected: "loop_detected";
23
+ readonly LoopTool: "loop_tool";
18
24
  readonly MaxThreatSeverity: "max_threat_severity";
25
+ readonly McpConfigRisk: "mcp_config_risk";
26
+ readonly McpRiskScore: "mcp_risk_score";
19
27
  readonly McpServer: "mcp_server";
20
28
  readonly McpServerVerified: "mcp_server_verified";
21
29
  readonly McpTool: "mcp_tool";
22
30
  readonly Path: "path";
31
+ readonly PatternType: "pattern_type";
23
32
  readonly PiiConfidence: "pii_confidence";
33
+ readonly PiiCount: "pii_count";
34
+ readonly PiiDetected: "pii_detected";
35
+ readonly PiiTypes: "pii_types";
24
36
  readonly ProfanityScore: "profanity_score";
25
37
  readonly PromptText: "prompt_text";
26
38
  readonly ResponseContent: "response_content";
39
+ readonly RugPullDetected: "rug_pull_detected";
27
40
  readonly RugPullScore: "rug_pull_score";
41
+ readonly SecretCount: "secret_count";
42
+ readonly SecretTypes: "secret_types";
43
+ readonly SequenceRisk: "sequence_risk";
28
44
  readonly SexualScore: "sexual_score";
29
45
  readonly Source: "source";
46
+ readonly SuspiciousPattern: "suspicious_pattern";
30
47
  readonly ThreatCategories: "threat_categories";
31
48
  readonly ThreatCount: "threat_count";
32
- readonly ThreatTypes: "threat_types";
49
+ readonly ToolCategory: "tool_category";
50
+ readonly ToolIsBuiltin: "tool_is_builtin";
51
+ readonly ToolIsSensitive: "tool_is_sensitive";
33
52
  readonly ToolName: "tool_name";
53
+ readonly ToolPoisoningDetected: "tool_poisoning_detected";
34
54
  readonly ToolPoisoningScore: "tool_poisoning_score";
55
+ readonly ToolRiskScore: "tool_risk_score";
35
56
  readonly UserEmail: "user_email";
36
57
  readonly ViolenceScore: "violence_score";
37
58
  readonly WeaponsScore: "weapons_score";
38
59
  readonly WorkspaceRoot: "workspace_root";
39
- readonly YaraThreats: "yara_threats";
40
60
  };
41
61
  export type OverwatchContextKey = (typeof OverwatchContextKey)[keyof typeof OverwatchContextKey];
@@ -1,42 +1,62 @@
1
1
  // Code generated by highflame-policy-codegen. DO NOT EDIT.
2
2
  // Source: schemas/overwatch/context.json
3
3
  /**
4
- * Context attribute keys for Overwatch Overwatch (Guardian) IDE security & policy enforcement.
4
+ * Context attribute keys for Overwatch Overwatch IDE agent security & policy enforcement.
5
5
  *
6
6
  * These constants correspond to the context attributes defined in the
7
7
  * Overwatch Cedar schema and are used at policy evaluation time.
8
8
  */
9
9
  export const OverwatchContextKey = {
10
+ ContainsInvisibleChars: 'contains_invisible_chars',
10
11
  ContainsSecrets: 'contains_secrets',
11
12
  Content: 'content',
12
13
  CrimeScore: 'crime_score',
13
14
  Cwd: 'cwd',
15
+ DetectedThreats: 'detected_threats',
14
16
  Event: 'event',
15
17
  HateSpeechScore: 'hate_speech_score',
16
18
  HighestSeverity: 'highest_severity',
17
19
  IndirectInjectionScore: 'indirect_injection_score',
18
20
  InjectionConfidence: 'injection_confidence',
21
+ InvisibleCharsScore: 'invisible_chars_score',
19
22
  JailbreakConfidence: 'jailbreak_confidence',
23
+ LoopCount: 'loop_count',
24
+ LoopDetected: 'loop_detected',
25
+ LoopTool: 'loop_tool',
20
26
  MaxThreatSeverity: 'max_threat_severity',
27
+ McpConfigRisk: 'mcp_config_risk',
28
+ McpRiskScore: 'mcp_risk_score',
21
29
  McpServer: 'mcp_server',
22
30
  McpServerVerified: 'mcp_server_verified',
23
31
  McpTool: 'mcp_tool',
24
32
  Path: 'path',
33
+ PatternType: 'pattern_type',
25
34
  PiiConfidence: 'pii_confidence',
35
+ PiiCount: 'pii_count',
36
+ PiiDetected: 'pii_detected',
37
+ PiiTypes: 'pii_types',
26
38
  ProfanityScore: 'profanity_score',
27
39
  PromptText: 'prompt_text',
28
40
  ResponseContent: 'response_content',
41
+ RugPullDetected: 'rug_pull_detected',
29
42
  RugPullScore: 'rug_pull_score',
43
+ SecretCount: 'secret_count',
44
+ SecretTypes: 'secret_types',
45
+ SequenceRisk: 'sequence_risk',
30
46
  SexualScore: 'sexual_score',
31
47
  Source: 'source',
48
+ SuspiciousPattern: 'suspicious_pattern',
32
49
  ThreatCategories: 'threat_categories',
33
50
  ThreatCount: 'threat_count',
34
- ThreatTypes: 'threat_types',
51
+ ToolCategory: 'tool_category',
52
+ ToolIsBuiltin: 'tool_is_builtin',
53
+ ToolIsSensitive: 'tool_is_sensitive',
35
54
  ToolName: 'tool_name',
55
+ ToolPoisoningDetected: 'tool_poisoning_detected',
36
56
  ToolPoisoningScore: 'tool_poisoning_score',
57
+ ToolRiskScore: 'tool_risk_score',
37
58
  UserEmail: 'user_email',
38
59
  ViolenceScore: 'violence_score',
39
60
  WeaponsScore: 'weapons_score',
40
61
  WorkspaceRoot: 'workspace_root',
41
- YaraThreats: 'yara_threats',
42
62
  };
@@ -2,7 +2,7 @@
2
2
  * Overwatch policy category identifiers.
3
3
  * Maps to UI tab names in Studio.
4
4
  */
5
- export type OverwatchCategory = 'secrets' | 'pii' | 'semantic' | 'tools' | 'organization' | 'trust_safety' | 'agent_security';
5
+ export type OverwatchCategory = 'secrets' | 'pii' | 'semantic' | 'tools' | 'organization' | 'trust_safety' | 'agent_security' | 'encoding' | 'behavioral';
6
6
  /**
7
7
  * Category metadata for UI display.
8
8
  */