@highflame/policy 2.2.32 → 2.2.34

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.
@@ -1805,6 +1805,19 @@ namespace Guardrails {
1805
1805
  "mcp_risk_type"?: String, // "inline_execution" | "suspicious_url" | "cross_origin"
1806
1806
  "mcp_risk_score"?: Long, // 0-100
1807
1807
 
1808
+ // Agentic - MCP Input Requests (optional) — an MCP server asking the CLIENT to act
1809
+ // on its behalf: elicitation/create (prompt a human), sampling/createMessage (drive
1810
+ // the client's model), roots/list (enumerate its filesystem). Carried in-band as
1811
+ // InputRequiredResult.inputRequests under the MRTR pattern (MCP 2026-07-28), and
1812
+ // out-of-band by the gateway relay for earlier peers. INV-DET-002.
1813
+ "mcp_input_request_detected"?: Bool,
1814
+ "mcp_input_request_score"?: Long, // 0-100
1815
+ "mcp_input_request_types"?: Set<String>, // subset of {"credential_elicitation", "sampling_injection", "root_probe"}
1816
+ // The requested methods, independent of content. Lets a policy refuse a capability
1817
+ // outright ("never permit sampling/createMessage from an unverified server") rather
1818
+ // than only reacting to a payload we managed to classify.
1819
+ "mcp_input_request_methods"?: Set<String>, // subset of {"elicitation/create", "sampling/createMessage", "roots/list"}
1820
+
1808
1821
  // Tool Operation Classifier (optional) — populated by AST-based classifiers (bash, python, etc.)
1809
1822
  "tool_operation_classes"?: Set<String>, // subset of {"readonly", "write_enabling", "execute_enabling", "network_access", "unknown"}
1810
1823
 
@@ -2339,6 +2352,78 @@ action call_tool appliesTo {
2339
2352
  },
2340
2353
  };
2341
2354
 
2355
+ // Inspect the OUTPUT of a tool that has already run.
2356
+ // Threat focus: a credential or PII printed by a tool entering the agent's
2357
+ // context. The tool has run, so a permission verdict is meaningless here — the
2358
+ // only enforcement available is rewriting or withholding what the model sees,
2359
+ // which is why transform rules (@redaction_strategy) are the point of this
2360
+ // action. Context is deliberately narrower than call_tool: pre-execution
2361
+ // signals (tool risk, loop, sequence) belong to the call, not its result.
2362
+ action post_tool_call appliesTo {
2363
+ principal: [User, Agent],
2364
+ resource: [Tool, FilePath, LlmPrompt],
2365
+ context: {
2366
+ // Identity (AARM R6 / CAP-IDN-011) — projected from the principal's token; optional.
2367
+ role?: String,
2368
+ privilege_scope?: Set<String>,
2369
+ // --- Event & Source ---
2370
+ content: String, // The tool's OUTPUT (stdout+stderr, or serialized response)
2371
+ source: String, // IDE source
2372
+ event: String, // Hook event name
2373
+ user_email: String, // User identifier
2374
+
2375
+ // --- Tool & MCP ---
2376
+ tool_name?: String,
2377
+ mcp_server?: String,
2378
+ mcp_tool?: String,
2379
+
2380
+ // --- Result ---
2381
+ exit_code?: Long, // Absent when the IDE does not propagate it
2382
+
2383
+ // --- File & Path ---
2384
+ path?: String,
2385
+
2386
+ // --- Workspace ---
2387
+ cwd?: String,
2388
+ workspace_root?: String,
2389
+
2390
+ // --- Threat Detection ---
2391
+ threat_count?: Long,
2392
+ highest_severity?: String,
2393
+ threat_categories?: Set<String>,
2394
+ detected_threats?: Set<String>,
2395
+ max_threat_severity?: Long,
2396
+
2397
+ // --- Secrets --- the primary signal for this surface
2398
+ secrets_detected?: Bool,
2399
+ secret_types?: Set<String>,
2400
+ secret_count?: Long,
2401
+
2402
+ // --- PII Detection ---
2403
+ pii_detected?: Bool,
2404
+ pii_types?: Set<String>,
2405
+ pii_count?: Long,
2406
+ pii_score?: Long,
2407
+
2408
+ // --- Indirect injection via tool output --- (OWASP ASI01)
2409
+ indirect_injection_score?: Long,
2410
+
2411
+ // --- Encoding & Unicode Attacks ---
2412
+ invisible_chars_detected?: Bool,
2413
+ invisible_chars_score?: Long,
2414
+
2415
+ // --- Session Detection History (cross-turn sticky flags) ---
2416
+ session_pii_detected?: Bool,
2417
+ session_pii_types?: Set<String>,
2418
+ session_secrets_detected?: Bool,
2419
+ session_secret_types?: Set<String>,
2420
+ session_threat_turns?: Long,
2421
+ session_max_secret_score?: Long,
2422
+ session_max_pii_score?: Long,
2423
+ session_cumulative_risk_score?: Long,
2424
+ },
2425
+ };
2426
+
2342
2427
  // Connect to an MCP server
2343
2428
  // Threat focus: supply chain, tool poisoning, rug pull, config risk
2344
2429
  action connect_server appliesTo {
@@ -4023,6 +4108,10 @@ export const GUARDRAILS_CONTEXT = {
4023
4108
  { "key": "mcp_config_risk", "type": "boolean", "required": false, "description": "Whether MCP configuration risk was detected (inline code execution, suspicious URLs, cross-origin issues)" },
4024
4109
  { "key": "mcp_risk_type", "type": "string", "required": false, "description": "Type of MCP risk: \'inline_execution\', \'suspicious_url\', or \'cross_origin\'" },
4025
4110
  { "key": "mcp_risk_score", "type": "number", "required": false, "description": "Risk score for MCP configuration issues (0-100). Typical threshold: >=70 for blocks" },
4111
+ { "key": "mcp_input_request_detected", "type": "boolean", "required": false, "description": "Whether an MCP server-to-client input request was flagged. These ask the CLIENT to act on the server\'s behalf — elicitation/create prompts a human, sampling/createMessage drives the client\'s own model, roots/list enumerates its filesystem" },
4112
+ { "key": "mcp_input_request_score", "type": "number", "required": false, "description": "Risk score for the MCP input request (0-100). Credential-soliciting elicitation and injection aimed at the client\'s model score highest" },
4113
+ { "key": "mcp_input_request_types", "type": "array", "required": false, "description": "Threat shapes found in the input request (e.g. [\'credential_elicitation\', \'sampling_injection\', \'root_probe\']). Use .contains() to block a specific shape" },
4114
+ { "key": "mcp_input_request_methods", "type": "array", "required": false, "description": "MCP methods the server asked the client to perform (e.g. [\'elicitation/create\', \'sampling/createMessage\', \'roots/list\']). Independent of content, so a policy can refuse a capability outright — e.g. mcp_input_request_methods.contains(\"sampling/createMessage\") on an unverified server — rather than only reacting to a payload that was successfully classified" },
4026
4115
  { "key": "tool_operation_classes", "type": "array", "required": false, "description": "All operation classes observed in the tool call, emitted by the AST command classifiers. Subset of: \'readonly\', \'write_enabling\', \'execute_enabling\', \'network_access\', \'unknown\'. A single command can carry several classes; combine with contains() to match shapes — e.g. tool_operation_classes.contains(\"network_access\") && tool_operation_classes.contains(\"execute_enabling\") catches download-and-run (curl | sh). \'unknown\' appears when any unrecognized or variable-expanded command was seen and should be treated as deny-worthy." },
4027
4116
  { "key": "cross_origin_detected", "type": "boolean", "required": false, "description": "Whether cross-origin escalation patterns were detected in tool calls crossing trust boundaries" },
4028
4117
  { "key": "cross_origin_type", "type": "string", "required": false, "description": "Type of cross-origin escalation detected in tool call" },
@@ -4368,6 +4457,48 @@ export const OVERWATCH_CONTEXT = {
4368
4457
  { "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" }
4369
4458
  ]
4370
4459
  },
4460
+ {
4461
+ "name": "post_tool_call",
4462
+ "description": "Inspect the output of a tool that has already run. The tool has run, so enforcement is limited to rewriting or withholding what the model sees.",
4463
+ "context_attributes": [
4464
+ { "key": "role", "type": "string", "required": false, "description": "role projected for the post_tool_call surface." },
4465
+ { "key": "privilege_scope", "type": "array", "required": false, "description": "privilege_scope projected for the post_tool_call surface." },
4466
+ { "key": "content", "type": "string", "required": true, "description": "The tool\'s OUTPUT (stdout+stderr, or serialized response)" },
4467
+ { "key": "source", "type": "string", "required": true, "description": "IDE source" },
4468
+ { "key": "event", "type": "string", "required": true, "description": "Hook event name" },
4469
+ { "key": "user_email", "type": "string", "required": true, "description": "User identifier" },
4470
+ { "key": "tool_name", "type": "string", "required": false, "description": "tool_name projected for the post_tool_call surface." },
4471
+ { "key": "mcp_server", "type": "string", "required": false, "description": "mcp_server projected for the post_tool_call surface." },
4472
+ { "key": "mcp_tool", "type": "string", "required": false, "description": "mcp_tool projected for the post_tool_call surface." },
4473
+ { "key": "exit_code", "type": "number", "required": false, "description": "Absent when the IDE does not propagate it" },
4474
+ { "key": "path", "type": "string", "required": false, "description": "path projected for the post_tool_call surface." },
4475
+ { "key": "cwd", "type": "string", "required": false, "description": "cwd projected for the post_tool_call surface." },
4476
+ { "key": "workspace_root", "type": "string", "required": false, "description": "workspace_root projected for the post_tool_call surface." },
4477
+ { "key": "threat_count", "type": "number", "required": false, "description": "threat_count projected for the post_tool_call surface." },
4478
+ { "key": "highest_severity", "type": "string", "required": false, "description": "highest_severity projected for the post_tool_call surface." },
4479
+ { "key": "threat_categories", "type": "array", "required": false, "description": "threat_categories projected for the post_tool_call surface." },
4480
+ { "key": "detected_threats", "type": "array", "required": false, "description": "detected_threats projected for the post_tool_call surface." },
4481
+ { "key": "max_threat_severity", "type": "number", "required": false, "description": "max_threat_severity projected for the post_tool_call surface." },
4482
+ { "key": "secrets_detected", "type": "boolean", "required": false, "description": "secrets_detected projected for the post_tool_call surface." },
4483
+ { "key": "secret_types", "type": "array", "required": false, "description": "secret_types projected for the post_tool_call surface." },
4484
+ { "key": "secret_count", "type": "number", "required": false, "description": "secret_count projected for the post_tool_call surface." },
4485
+ { "key": "pii_detected", "type": "boolean", "required": false, "description": "pii_detected projected for the post_tool_call surface." },
4486
+ { "key": "pii_types", "type": "array", "required": false, "description": "pii_types projected for the post_tool_call surface." },
4487
+ { "key": "pii_count", "type": "number", "required": false, "description": "pii_count projected for the post_tool_call surface." },
4488
+ { "key": "pii_score", "type": "number", "required": false, "description": "pii_score projected for the post_tool_call surface." },
4489
+ { "key": "indirect_injection_score", "type": "number", "required": false, "description": "indirect_injection_score projected for the post_tool_call surface." },
4490
+ { "key": "invisible_chars_detected", "type": "boolean", "required": false, "description": "invisible_chars_detected projected for the post_tool_call surface." },
4491
+ { "key": "invisible_chars_score", "type": "number", "required": false, "description": "invisible_chars_score projected for the post_tool_call surface." },
4492
+ { "key": "session_pii_detected", "type": "boolean", "required": false, "description": "session_pii_detected projected for the post_tool_call surface." },
4493
+ { "key": "session_pii_types", "type": "array", "required": false, "description": "session_pii_types projected for the post_tool_call surface." },
4494
+ { "key": "session_secrets_detected", "type": "boolean", "required": false, "description": "session_secrets_detected projected for the post_tool_call surface." },
4495
+ { "key": "session_secret_types", "type": "array", "required": false, "description": "session_secret_types projected for the post_tool_call surface." },
4496
+ { "key": "session_threat_turns", "type": "number", "required": false, "description": "session_threat_turns projected for the post_tool_call surface." },
4497
+ { "key": "session_max_secret_score", "type": "number", "required": false, "description": "session_max_secret_score projected for the post_tool_call surface." },
4498
+ { "key": "session_max_pii_score", "type": "number", "required": false, "description": "session_max_pii_score projected for the post_tool_call surface." },
4499
+ { "key": "session_cumulative_risk_score", "type": "number", "required": false, "description": "session_cumulative_risk_score projected for the post_tool_call surface." }
4500
+ ]
4501
+ },
4371
4502
  {
4372
4503
  "name": "connect_server",
4373
4504
  "description": "Connect to an MCP server",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@highflame/policy",
3
- "version": "2.2.32",
3
+ "version": "2.2.34",
4
4
  "engines": {
5
5
  "node": ">=18"
6
6
  },