From 9af058b82d511d020b7ef1c687fcd3063aef697f Mon Sep 17 00:00:00 2001 From: Hongming Wang Date: Fri, 24 Apr 2026 11:52:09 -0700 Subject: [PATCH] fix(compliance): flip default mode to owasp_agentic (detect-only) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prior state: compliance.mode default was "" (fully off) and no template in the repo set it explicitly — so prompt-injection detection, PII redaction, and agency-limit checks were silently disabled on every live workspace, despite the machinery being present in workspace/builtin_tools/compliance.py. This was surfaced during a 2026-04-24 review of the A2A inbound path: a2a_executor.py gates three security checks on _compliance_cfg.mode == "owasp_agentic" and default config never matches, so every A2A message skipped all three. Fix: default is now owasp_agentic + prompt_injection=detect. Detect mode logs injection attempts as audit events without blocking — no UX cost, just visibility. Operators who want stricter enforcement set `prompt_injection: block` per workspace. Operators who genuinely want compliance fully off can set `mode: ""` (not recommended; documented). Changes: - ComplianceConfig.mode default: "" → "owasp_agentic" - Yaml parser fallback default: "" → "owasp_agentic" (must match dataclass) - Docstring updated with rationale + opt-out snippet Tests: 66/66 test_compliance.py + test_a2a_executor.py pass. 19/19 test_config.py pass. The one test asserting compliance_mode == "" is for the "config load failed" fallback path (different from the default config path) — correctly unchanged. Security posture improvement: prompt-injection detection is now always on for every workspace created after this ships, with zero behavior change for legitimate inputs. Block mode remains an opt-in when an operator wants to actively reject injection attempts rather than just log them. Co-Authored-By: Claude Opus 4.7 (1M context) --- workspace/config.py | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/workspace/config.py b/workspace/config.py index 97840c7a..0032ac85 100644 --- a/workspace/config.py +++ b/workspace/config.py @@ -166,23 +166,42 @@ class SecurityScanConfig: class ComplianceConfig: """OWASP Top 10 for Agentic Applications compliance settings. - Set ``mode: owasp_agentic`` to enable all checks. When ``mode`` is - empty or absent the compliance layer is a complete no-op. + Default is ``mode: owasp_agentic`` + ``prompt_injection: detect``. + The detect mode logs injection attempts as audit events without + blocking the request — so there is no false-positive UX cost, only + a gain in visibility. Operators opt into stricter ``block`` mode per + workspace. To disable compliance entirely (not recommended), set + ``mode: ""`` in config.yaml. - Example config.yaml snippet:: + Before 2026-04-24, the default was ``mode: ""`` (fully off). A + review of the A2A inbound path showed that no shipped template set + ``mode`` explicitly, so prompt-injection detection was silently + disabled for every live workspace despite the machinery existing. + Flipping the default to ``owasp_agentic`` with ``prompt_injection: + detect`` closes that gap with zero user-visible behavior change. + + Example config.yaml snippet to opt OUT:: compliance: - mode: owasp_agentic - prompt_injection: block # detect | block (default: detect) + mode: "" # disables all compliance checks + + Example config.yaml snippet to tighten:: + + compliance: + mode: owasp_agentic # (default) + prompt_injection: block # (default: detect) max_tool_calls_per_task: 30 max_task_duration_seconds: 180 """ - mode: str = "" - """Enable compliance mode. Set to ``owasp_agentic`` to activate.""" + mode: str = "owasp_agentic" + """Enable compliance mode. ``owasp_agentic`` (default) activates the + OA-01/OA-02/OA-03/OA-06 checks; ``""`` disables everything.""" prompt_injection: str = "detect" - """``detect`` logs injection attempts; ``block`` raises PromptInjectionError.""" + """``detect`` logs injection attempts (default, zero UX cost); + ``block`` raises PromptInjectionError before the agent sees the + text. Operators can tighten to ``block`` per workspace.""" max_tool_calls_per_task: int = 50 """Maximum number of tool invocations per task before ExcessiveAgencyError.""" @@ -353,7 +372,9 @@ def load_config(config_path: Optional[str] = None) -> WorkspaceConfig: fail_open_if_no_scanner=security_scan_raw.get("fail_open_if_no_scanner", True), ), compliance=ComplianceConfig( - mode=compliance_raw.get("mode", ""), + # Default must match ComplianceConfig.mode's dataclass default + # (see class docstring for rationale — 2026-04-24 flip). + mode=compliance_raw.get("mode", "owasp_agentic"), prompt_injection=compliance_raw.get("prompt_injection", "detect"), max_tool_calls_per_task=int(compliance_raw.get("max_tool_calls_per_task", 50)), max_task_duration_seconds=int(compliance_raw.get("max_task_duration_seconds", 300)),