From 348af49c187274d1f608e44bf104e70afb6a883b Mon Sep 17 00:00:00 2001 From: Ayo Omotayo Date: Sat, 4 Jul 2026 11:05:03 +0100 Subject: [PATCH 1/8] feat(examples): add UK regulatory policy pack (UK GDPR, ICO ADM, FCA) Add governance starter policies for GB jurisdiction covering UK GDPR/DPA 2018, DUAA 2025 automated decision-making safeguards, and FCA principles-based financial conduct, with OPA Rego references and jurisdiction router wiring. Signed-off-by: Ayo Omotayo --- examples/policies/README.md | 57 +++-- .../rego/jurisdiction-router.rego | 12 +- examples/policies/uk-regulatory/README.md | 75 +++++++ .../uk-regulatory/fca-financial-conduct.yaml | 112 ++++++++++ .../ico-automated-decisions.yaml | 130 ++++++++++++ .../rego/fca-financial-conduct.rego | 100 +++++++++ .../rego/ico-automated-decisions.rego | 117 ++++++++++ .../rego/uk-gdpr-data-protection.rego | 164 +++++++++++++++ .../uk-gdpr-data-protection.yaml | 199 ++++++++++++++++++ 9 files changed, 941 insertions(+), 25 deletions(-) create mode 100644 examples/policies/uk-regulatory/README.md create mode 100644 examples/policies/uk-regulatory/fca-financial-conduct.yaml create mode 100644 examples/policies/uk-regulatory/ico-automated-decisions.yaml create mode 100644 examples/policies/uk-regulatory/rego/fca-financial-conduct.rego create mode 100644 examples/policies/uk-regulatory/rego/ico-automated-decisions.rego create mode 100644 examples/policies/uk-regulatory/rego/uk-gdpr-data-protection.rego create mode 100644 examples/policies/uk-regulatory/uk-gdpr-data-protection.yaml diff --git a/examples/policies/README.md b/examples/policies/README.md index 77657a43f..a4ac365aa 100644 --- a/examples/policies/README.md +++ b/examples/policies/README.md @@ -1,20 +1,41 @@ -# Policy Examples - -Sample YAML governance policy files for AgentMesh. - -Each file in this directory is a self-contained policy configuration that demonstrates how to express a particular class of security or compliance control using the policy engine. They are intended as starting points — review and adapt them for your environment before deploying to production. - -## Using this directory - -1. **Browse** the `.yaml` files to find a scenario close to what you need. Each file opens with a comment block describing what it covers and any caveats. -2. **Copy** the file into your own project (or reference it by path) and edit the rules, thresholds, and matchers to fit your requirements. -3. **Load** the policy into an agent workflow via the governance runtime. The [Quickstart](../quickstart/) shows runnable end-to-end examples that consume policies from this directory. - -## Policy format - -All files here follow the schema defined in [`policy-engine/spec`](../../policy-engine/spec/). Refer to that spec for the full list of supported fields, matchers, and enforcement actions. +# Policies Example + +Sample YAML governance policy files for AgentMesh. Each file provides an example configuration covering a specific security or compliance scenario. + +## Policies + +| File | Description | +|------|-------------| +| `adk-governance.yaml` | Tool restrictions and delegation controls for Google ADK agents | +| `cli-security-rules.yaml` | Blocks dangerous shell and CLI patterns | +| `conversation-guardian.yaml` | Content safety rules for conversational agents | +| `mcp-security.yaml` | Security controls for MCP tool usage | +| `pii-detection.yaml` | Detects and blocks personally identifiable information | +| `prompt-injection-safety.yaml` | Guards against prompt injection attacks | +| `sandbox-safety.yaml` | Restrictions for sandboxed agent execution | +| `semantic-policy.yaml` | Semantic similarity-based policy enforcement | +| `sql-readonly.yaml` | Restricts agents to read-only SQL operations | +| `sql-safety.yaml` | Blocks destructive SQL patterns | +| `sql-strict.yaml` | Strict SQL allowlist for production databases | + +## Policy Packs + +Multi-file policy libraries for specific regulatory or enterprise scenarios. Each pack has its own README with file listings, usage, and jurisdiction details. + +| Directory | Policies | Description | +|-----------|----------|-------------| +| [`african-regulatory/`](african-regulatory/) | 15 | African regulatory and universal agent safety controls for Nigeria, Kenya, South Africa, Uganda, Tanzania, and Ethiopia. Includes OPA Rego reference implementations and a jurisdiction router. | +| [`production/`](production/) | 5 | Ready-to-use enterprise policies (`minimal`, `enterprise`, `healthcare`, `financial`, `strict`) with graduated risk levels. | +| [`uk-regulatory/`](uk-regulatory/) | 3 | UK regulatory controls for UK GDPR/DPA 2018, ICO automated decision-making (Arts. 22A–22D), and FCA principles-based financial conduct. Includes OPA Rego reference implementations. | + +## How to Use + +These policy files can be applied to agent workflows to enforce governance rules. + +```bash +scripts/check-policy.sh --action "web_search" --tokens 1500 --policy examples/policies/sql-safety.yaml +``` ## Related - -- [Quickstart](../quickstart/) — runnable examples that load policies from this directory -- [Policy Engine tutorial](../../docs/tutorials/01-policy-engine.md) — walkthrough of how policies are evaluated + +- [Quickstart](../quickstart/) - Runnable examples that use these policies \ No newline at end of file diff --git a/examples/policies/african-regulatory/rego/jurisdiction-router.rego b/examples/policies/african-regulatory/rego/jurisdiction-router.rego index afc328c43..941644eee 100644 --- a/examples/policies/african-regulatory/rego/jurisdiction-router.rego +++ b/examples/policies/african-regulatory/rego/jurisdiction-router.rego @@ -10,7 +10,7 @@ # 1. Universal agent safety controls — apply to ALL agents regardless of country # (prompt_injection, pii_leakage, tool_permissions, human_approval, model_routing) # 2. Jurisdiction-specific regulatory packs — apply based on customer_country -# (cbn, bvn_nin, ndpa, nfiu for NG; kdpa for KE; popia for ZA) +# (cbn, bvn_nin, ndpa, nfiu for NG; kdpa for KE; popia for ZA; uk_gdpr, ico_adm, fca_conduct for GB) # # Input schema expected: # { @@ -50,7 +50,7 @@ jurisdiction_policies := { "UG": {"uganda_dppa"}, "TZ": {"tanzania_pdpa"}, "ET": {"ethiopia_pdp"}, - "IN": {"dpdp", "certin", "rbi", "sebi", "aadhaar"}, + "GB": {"uk_gdpr", "ico_adm", "fca_conduct"}, } # ── Policy pack → OPA query path ───────────────────────────────── @@ -65,11 +65,9 @@ policy_queries := { "uganda_dppa": "data.agt_policies_africa.uganda_dppa.decision", "tanzania_pdpa": "data.agt_policies_africa.tanzania_pdpa.decision", "ethiopia_pdp": "data.agt_policies_africa.ethiopia_pdp.decision", - "dpdp": "data.agt_policies_india.dpdp.decision", - "certin": "data.agt_policies_india.certin.decision", - "rbi": "data.agt_policies_india.rbi.decision", - "sebi": "data.agt_policies_india.sebi.decision", - "aadhaar": "data.agt_policies_india.aadhaar.decision", + "uk_gdpr": "data.agt_policies_uk.uk_gdpr.decision", + "ico_adm": "data.agt_policies_uk.ico_adm.decision", + "fca_conduct": "data.agt_policies_uk.fca_conduct.decision", "prompt_injection": "data.agt_policies_agent.prompt_injection.decision", "pii_leakage": "data.agt_policies_agent.pii_leakage.decision", "tool_permissions": "data.agt_policies_agent.tool_permissions.decision", diff --git a/examples/policies/uk-regulatory/README.md b/examples/policies/uk-regulatory/README.md new file mode 100644 index 000000000..22e27ee34 --- /dev/null +++ b/examples/policies/uk-regulatory/README.md @@ -0,0 +1,75 @@ +# UK Regulatory Policy Pack + +Reference Policy-as-Code for governing AI agents under UK regulation: data protection, +automated decision-making, and financial-sector principles-based controls. + +> Community-maintained governance starter policies. NOT certified legal compliance instruments. +> Perform your own assessment with qualified advisors before deploying in regulated environments. +> Regulatory status is noted per file (binding vs advisory/draft). + +## Coverage + +| Policy file | Regulation | Authority | Status | +|---|---|---|---| +| `uk-gdpr-data-protection.yaml` | UK GDPR + DPA 2018 + DUAA 2025 (transfer/complaints reforms) | ICO | Binding | +| `ico-automated-decisions.yaml` | UK GDPR Arts. 22A–22D (DUAA 2025 s.80, in force 5 Feb 2026) | ICO | Binding; ICO ADM guidance draft (final expected summer 2026) | +| `fca-financial-conduct.yaml` | FCA Handbook PRIN 2A (Consumer Duty), SM&CR | FCA | Principles-based — no AI-specific binding rules as of 2026 | + +## Regulatory context (2026) + +- **Data (Use and Access) Act 2025 (DUAA)** received Royal Assent on 19 June 2025. Key data-protection reforms commenced 5 February 2026, including replacement of UK GDPR Art. 22 with Arts. 22A–22D (safeguard-led automated decision-making) and updated international transfer rules using the **"not materially lower"** data protection test. +- **Breach notification** remains UK GDPR Art. 33 / DPA 2018 s.67: notify the ICO without undue delay and, where feasible, within **72 hours** of becoming aware. Inform individuals without undue delay where the breach poses high risk (Art. 34). +- **Complaints procedure**: DPA 2018 s.164A (inserted by DUAA s.103) requires all controllers to maintain a formal data protection complaints procedure by **19 June 2026**. Data subjects must raise complaints with the controller before escalating to the ICO. +- **FCA**: No AI-specific binding regulation as of 2026. The FCA applies its existing principles-based framework (Consumer Duty, SM&CR, operational resilience). The Mills Review reports to the FCA Board in summer 2026. + +## What these rules detect (and what they do not) + +Output-side rules match intent phrases (for example "store PII unencrypted", "don't report the breach", "no human review"). They catch an agent that narrates or proposes a violation in its output; they do not observe the underlying system action. Treat them as a starting point, pair them with real action-level enforcement, and run your own compliance assessment. + +## Not covered (known gaps) + +Material obligations the pack does not represent yet: + +- **UK GDPR**: Art. 13–14 privacy notices; Art. 15–22 full data-subject rights workflow; Art. 27 UK representative requirement; children's code (Age Appropriate Design Code). +- **DUAA**: Recognised legitimate interests lawful basis; full cookie/PECR reforms; ICO statutory objectives. +- **NIS2 / UK cyber**: Network and information security incident reporting for in-scope entities. +- **Online Safety Act 2023**: Platform duties for user-generated content (out of scope for generic agent policies). +- **NHS / healthcare**: NHS DSPT, Caldicott principles, and health-sector-specific controls. +- **FCA**: Detailed SYSC mapping, operational resilience impact tolerances, and forthcoming AI good/poor practice benchmarks (expected 2026). + +## Two layers + +Universal agent-safety controls (prompt_injection, pii_leakage, tool_permissions, human_approval, model_routing) apply to all agents and are evaluated via the shared jurisdiction router in `../african-regulatory/rego/jurisdiction-router.rego`. These UK national packs add jurisdiction-specific regulatory controls, selected by `context.customer_country = "GB"`. + +## Rego + +`rego/` holds OPA reference implementations (NOT loaded by the Agent-OS Python runtime). Each pack exposes `data.agt_policies_uk..decision`. The shared router maps `GB` to `uk_gdpr`, `ico_adm`, and `fca_conduct`. + +To evaluate with OPA: + +```bash +# Run all UK Rego tests (includes jurisdiction router checks) +./examples/policies/uk-regulatory/rego/run_tests.sh + +# Or manually: +opa test examples/policies/african-regulatory/rego examples/policies/uk-regulatory/rego -v + +# Evaluate applicable policies for GB +opa eval \ + -d examples/policies/african-regulatory/rego/ \ + -d examples/policies/uk-regulatory/rego/ \ + -i '{"context": {"customer_country": "GB"}}' \ + "data.agt_policies.router.applicable_policies" +``` + +## Loading policies in Agent-OS + +```python +from agent_os.policies.schema import PolicyDocument + +policy = PolicyDocument.from_yaml("uk-gdpr-data-protection.yaml") +``` + +## Disclaimer + +These policies are community-maintained governance starter packs. They are **not certified legal compliance instruments**. Organisations must perform their own compliance assessments with qualified legal and regulatory advisors before deploying in regulated environments. diff --git a/examples/policies/uk-regulatory/fca-financial-conduct.yaml b/examples/policies/uk-regulatory/fca-financial-conduct.yaml new file mode 100644 index 000000000..39bfad2ba --- /dev/null +++ b/examples/policies/uk-regulatory/fca-financial-conduct.yaml @@ -0,0 +1,112 @@ +# agt-policies-uk +# FCA Principles-Based AI Governance Policy +# +# Regulatory reference: FCA Handbook PRIN (Principles for Businesses); Consumer Duty (PRIN 2A); +# Senior Managers and Certification Regime (SM&CR); FCA AI Update 2024 +# Enforcing authority: Financial Conduct Authority (FCA) +# Status: Binding (existing principles-based framework); FCA has no AI-specific binding rules +# as of 2026 — Mills Review reporting summer 2026; AI good/poor practice publication expected 2026 +# +# Community-maintained governance starter policy. NOT a certified legal compliance instrument. +# Perform your own compliance assessment with qualified advisors before deploying. +# +# Key obligations encoded (principles-based, not AI-specific statute): +# PRIN 2A Consumer Duty — good outcomes, fair value, appropriate support +# SM&CR Senior manager accountability for AI risks and customer outcomes +# SYSC Systems and controls for AI-influenced customer journeys +# +# Rego reference implementation: rego/fca-financial-conduct.rego (NOT loaded at runtime) + +version: "1.0" +name: fca-financial-conduct +description: > + FCA principles-based governance policy for AI agents in UK financial services. + Enforces Consumer Duty outcome checks, SM&CR accountability signals, and audit + requirements for AI-influenced pricing, eligibility, and customer communications. + +metadata: + source_regulation: "FCA Handbook PRIN (incl. PRIN 2A Consumer Duty); SM&CR; FCA AI Update 2024" + jurisdiction: "GB" + enforcing_authority: "Financial Conduct Authority (FCA)" + regulatory_status: "principles-based — no AI-specific binding rules as of 2026" + +rules: + + # ========================================================================= + # PRIN 2A — Consumer Duty: Good Outcomes + # ========================================================================= + + - name: fca-consumer-harm-deny + condition: + field: output + operator: matches + value: "(?i)(mislead\\s+(the\\s+)?customer|hide\\s+(fees|charges|risks)|exploit\\s+vulnerabilit|target\\s+vulnerable\\s+customer|dark\\s+pattern|push\\s+unsuitable\\s+product)" + action: deny + priority: 1 + message: "FCA Consumer Duty (PRIN 2A): agent cannot propose actions that foreseeably harm customers or obscure material information" + + - name: fca-fair-value-bypass-deny + condition: + field: output + operator: matches + value: "(?i)(skip\\s+fair\\s+value|bypass\\s+value\\s+assessment|no\\s+need\\s+to\\s+(check|assess)\\s+(fair\\s+)?value|ignore\\s+consumer\\s+duty)" + action: deny + priority: 1 + message: "FCA Consumer Duty (PRIN 2A.1): firms must ensure products and services provide fair value — agent cannot bypass value assessment" + + # ========================================================================= + # SM&CR — Senior Manager Accountability + # ========================================================================= + + - name: fca-accountability-delegation-deny + condition: + field: output + operator: matches + value: "(?i)(the\\s+ai\\s+(decides|is\\s+responsible)|algorithm\\s+accountable|no\\s+senior\\s+manager\\s+(needed|required)|delegate\\s+accountability\\s+to\\s+(the\\s+)?(model|ai|algorithm))" + action: deny + priority: 1 + message: "FCA SM&CR: senior managers remain accountable for AI risks and outcomes — delegating to an algorithm does not transfer regulatory responsibility" + + # ========================================================================= + # AI-Influenced Customer Journeys — Audit + # ========================================================================= + + - name: fca-pricing-decision-audit + condition: + field: action + operator: matches + value: "^(set_price|adjust_rate|calculate_premium|score_creditworthiness|determine_eligibility)$" + action: audit + priority: 2 + message: "FCA Consumer Duty: AI-influenced pricing or eligibility decision — document testing for fairness, suitability, and foreseeable harm" + + - name: fca-customer-communication-audit + condition: + field: action + operator: matches + value: "^(send_financial_advice|generate_customer_communication|draft_product_recommendation|create_marketing_content)$" + action: audit + priority: 2 + message: "FCA Consumer Duty: AI-generated customer communication — verify clarity, accuracy, and alignment with target customer information needs" + + - name: fca-third-party-ai-audit + condition: + field: action + operator: matches + value: "^(invoke_external_ai|call_third_party_model|use_vendor_ai|deploy_critical_third_party_ai)$" + action: audit + priority: 2 + message: "FCA operational resilience / outsourcing: third-party AI component — map to governance, testing, and critical third-party risk requirements" + + # ========================================================================= + # Agentic / Autonomous Trading — Block without approval + # ========================================================================= + + - name: fca-autonomous-trading-block + condition: + field: action + operator: matches + value: "^(autonomous_trade|execute_trade_without_approval|self_directed_trading|agent_place_order)$" + action: block + priority: 1 + message: "FCA market conduct: autonomous agent trading requires documented governance, testing, and senior manager approval before execution" diff --git a/examples/policies/uk-regulatory/ico-automated-decisions.yaml b/examples/policies/uk-regulatory/ico-automated-decisions.yaml new file mode 100644 index 000000000..e028238b3 --- /dev/null +++ b/examples/policies/uk-regulatory/ico-automated-decisions.yaml @@ -0,0 +1,130 @@ +# agt-policies-uk +# UK GDPR Arts. 22A–22D — Automated Decision-Making Policy +# +# Regulatory reference: UK GDPR Arts. 22A–22D (substituted by DUAA 2025 s.80, in force 5 Feb 2026); +# ICO draft guidance on automated decision-making and profiling (consultation closed 29 May 2026) +# Enforcing authority: Information Commissioner's Office (ICO) +# Status: Binding (Arts. 22A–22D); ICO ADM guidance draft (final expected summer 2026) +# +# Community-maintained governance starter policy. NOT a certified legal compliance instrument. +# Perform your own compliance assessment with qualified advisors before deploying. +# +# Key obligations encoded: +# Art. 22A Solely automated decisions with legal or similarly significant effects +# Art. 22C Safeguards: information, representations, human intervention, contest +# Art. 35 DPIA for high-risk processing (including agentic orchestration chains) +# +# Agentic AI note (ICO tech futures / March 2026 recruitment statement): safeguards apply at +# every pipeline step that takes a solely automated significant decision, not only the final output. +# +# Rego reference implementation: rego/ico-automated-decisions.rego (NOT loaded at runtime) + +version: "1.0" +name: ico-automated-decisions +description: > + UK GDPR automated decision-making policy for AI agents. Enforces Art. 22C safeguards + (transparency, representations, human intervention, contest) for solely automated + significant decisions, including multi-agent orchestration steps. + +metadata: + source_regulation: "UK GDPR Arts. 22A–22D (DUAA 2025 s.80); ICO ADM guidance (draft, 2026)" + jurisdiction: "GB" + enforcing_authority: "Information Commissioner's Office (ICO)" + +rules: + + # ========================================================================= + # Art. 22C — Safeguard: Information about the decision + # ========================================================================= + + - name: adm-withhold-explanation-deny + condition: + field: output + operator: matches + value: "(?i)(don'?t\\s+explain|no\\s+explanation|withhold\\s+(the\\s+)?(reason|rationale)|hide\\s+how\\s+(the\\s+)?decision|refuse\\s+to\\s+explain)" + action: deny + priority: 1 + message: "UK GDPR Art. 22C(1): individuals must receive decision-specific information explaining how and why the outcome was reached" + + # ========================================================================= + # Art. 22C — Safeguard: Representations and human intervention + # ========================================================================= + + - name: adm-block-human-review-deny + condition: + field: output + operator: matches + value: "(?i)(no\\s+human\\s+(review|intervention|oversight)|refuse\\s+human\\s+review|cannot\\s+request\\s+human|deny\\s+human\\s+intervention|automated\\s+only\\s+—\\s+no\\s+appeal)" + action: deny + priority: 1 + message: "UK GDPR Art. 22C(2)-(3): individuals must be able to make representations and obtain genuine human intervention with authority to change the outcome" + + - name: adm-block-contest-deny + condition: + field: output + operator: matches + value: "(?i)(cannot\\s+contest|no\\s+(right\\s+to\\s+)?(appeal|challenge)|final\\s+decision\\s+—\\s+no\\s+recourse|waive\\s+(the\\s+)?right\\s+to\\s+contest)" + action: deny + priority: 1 + message: "UK GDPR Art. 22C(4): individuals must be able to contest the decision through an accessible process" + + # ========================================================================= + # Art. 22A — Solely Automated Significant Decisions + # ========================================================================= + + - name: adm-significant-decision-audit + condition: + field: action + operator: matches + value: "^(run_automated_decision|automated_credit_decision|automated_hiring_decision|automated_eligibility|profile_for_decision|deploy_scoring_model)$" + action: audit + priority: 2 + message: "UK GDPR Art. 22A: solely automated decision with legal or similarly significant effect — verify Art. 22C safeguards and lawful basis are in place" + + - name: adm-recruitment-decision-audit + condition: + field: output + operator: matches + value: "(?i)(reject\\s+(the\\s+)?(candidate|applicant)|hire\\s+decision|shortlist|score\\s+(the\\s+)?(candidate|applicant)).{0,40}(automated|without\\s+human|ai\\s+only)" + action: audit + priority: 2 + message: "ICO March 2026: automated recruitment decisions are in scope of Art. 22A — review safeguards and human oversight before proceeding" + + # ========================================================================= + # Art. 22A — Agentic orchestration (multi-step ADM) + # ========================================================================= + + - name: adm-agentic-delegation-audit + condition: + field: action + operator: matches + value: "delegate_decision|spawn_sub_agent|orchestrate_agent|chain_automated_step" + action: audit + priority: 2 + message: "UK GDPR Art. 22A (agentic AI): each orchestration step that takes a solely automated significant decision must meet Art. 22C safeguards and Art. 28 processor contracts" + + # ========================================================================= + # Art. 9 + 22A — Special category data in ADM (stricter conditions) + # ========================================================================= + + - name: adm-special-category-block + condition: + field: action + operator: matches + value: "^(automated_decision_on_health|automated_decision_on_biometric|automated_decision_on_special_category)$" + action: block + priority: 1 + message: "UK GDPR Art. 22A + Art. 9: automated decisions on special category data require stricter conditions beyond standard Art. 22C safeguards — human review required" + + # ========================================================================= + # Art. 35 — DPIA for high-risk ADM + # ========================================================================= + + - name: adm-dpia-required-audit + condition: + field: action + operator: matches + value: "^(deploy_model|deploy_agent|launch_automated_system|scale_automated_decisions)$" + action: audit + priority: 3 + message: "UK GDPR Art. 35: data protection impact assessment required before deploying high-risk automated decision-making (including agentic orchestration)" diff --git a/examples/policies/uk-regulatory/rego/fca-financial-conduct.rego b/examples/policies/uk-regulatory/rego/fca-financial-conduct.rego new file mode 100644 index 000000000..817dcd597 --- /dev/null +++ b/examples/policies/uk-regulatory/rego/fca-financial-conduct.rego @@ -0,0 +1,100 @@ +# agt-policies-uk - FCA Principles-Based AI Governance (Rego reference) +# FCA has no AI-specific binding rules as of 2026 — principles-based framework applies. +# NOT loaded by the Agent-OS Python runtime. +# +# Input schema: +# { "action": "set_price", +# "params": { "consumer_duty_assessed": false, "senior_manager_approved": false }, +# "output": "agent output text" } + +package agt_policies_uk.fca_conduct + +import rego.v1 + +_output_text := v if { + is_string(input.output) + v := input.output +} else := "" + +pricing_actions := { + "set_price", "adjust_rate", "calculate_premium", + "score_creditworthiness", "determine_eligibility", +} + +communication_actions := { + "send_financial_advice", "generate_customer_communication", + "draft_product_recommendation", "create_marketing_content", +} + +third_party_ai_actions := { + "invoke_external_ai", "call_third_party_model", + "use_vendor_ai", "deploy_critical_third_party_ai", +} + +autonomous_trading_actions := { + "autonomous_trade", "execute_trade_without_approval", + "self_directed_trading", "agent_place_order", +} + +# PRIN 2A: consumer harm language +deny contains msg if { + regex.match(`(?i)(mislead\s+(the\s+)?customer|hide\s+(fees|charges|risks)|exploit\s+vulnerabilit|target\s+vulnerable\s+customer|dark\s+pattern|push\s+unsuitable\s+product)`, _output_text) + msg := "FCA Consumer Duty (PRIN 2A): agent cannot propose actions that foreseeably harm customers" +} + +# PRIN 2A: fair value bypass +deny contains msg if { + regex.match(`(?i)(skip\s+fair\s+value|bypass\s+value\s+assessment|no\s+need\s+to\s+(check|assess)\s+(fair\s+)?value|ignore\s+consumer\s+duty)`, _output_text) + msg := "FCA Consumer Duty (PRIN 2A.1): firms must ensure products and services provide fair value" +} + +# SM&CR: accountability delegation to AI +deny contains msg if { + regex.match(`(?i)(the\s+ai\s+(decides|is\s+responsible)|algorithm\s+accountable|no\s+senior\s+manager\s+(needed|required)|delegate\s+accountability\s+to\s+(the\s+)?(model|ai|algorithm))`, _output_text) + msg := "FCA SM&CR: senior managers remain accountable for AI risks — delegating to an algorithm does not transfer responsibility" +} + +# Market conduct: autonomous trading without approval +deny contains msg if { + input.action in autonomous_trading_actions + not input.params.senior_manager_approved == true + msg := "FCA market conduct: autonomous agent trading requires documented governance and senior manager approval" +} + +# Consumer Duty: pricing without assessment +escalate contains msg if { + input.action in pricing_actions + not input.params.consumer_duty_assessed == true + msg := "FCA Consumer Duty: AI-influenced pricing or eligibility decision — document testing for fairness and foreseeable harm" +} + +# Consumer Duty: customer communications +audit contains msg if { + input.action in communication_actions + msg := "FCA Consumer Duty: AI-generated customer communication — verify clarity, accuracy, and information needs" +} + +# Outsourcing / operational resilience: third-party AI +audit contains msg if { + input.action in third_party_ai_actions + msg := "FCA operational resilience: third-party AI component — map to governance, testing, and critical third-party risk" +} + +decision := "deny" if count(deny) > 0 + +decision := "escalate" if { + count(deny) == 0 + count(escalate) > 0 +} + +decision := "audit" if { + count(deny) == 0 + count(escalate) == 0 + count(audit) > 0 +} + +decision := "allow" if { + count(deny) == 0 + count(escalate) == 0 + count(audit) == 0 +} diff --git a/examples/policies/uk-regulatory/rego/ico-automated-decisions.rego b/examples/policies/uk-regulatory/rego/ico-automated-decisions.rego new file mode 100644 index 000000000..a825afa74 --- /dev/null +++ b/examples/policies/uk-regulatory/rego/ico-automated-decisions.rego @@ -0,0 +1,117 @@ +# agt-policies-uk - UK GDPR Arts. 22A–22D Automated Decision-Making (Rego reference) +# DUAA 2025 s.80 in force 5 February 2026. ICO ADM guidance draft (final expected summer 2026). +# NOT loaded by the Agent-OS Python runtime. +# +# Input schema: +# { "action": "run_automated_decision", +# "params": { "human_review_available": false, "explanation_provided": false }, +# "output": "agent output text" } + +package agt_policies_uk.ico_adm + +import rego.v1 + +_output_text := v if { + is_string(input.output) + v := input.output +} else := "" + +significant_decision_actions := { + "run_automated_decision", "automated_credit_decision", + "automated_hiring_decision", "automated_eligibility", + "profile_for_decision", "deploy_scoring_model", +} + +agentic_actions := { + "delegate_decision", "spawn_sub_agent", "orchestrate_agent", "chain_automated_step", +} + +special_category_adm_actions := { + "automated_decision_on_health", "automated_decision_on_biometric", + "automated_decision_on_special_category", +} + +deployment_actions := { + "deploy_model", "deploy_agent", "launch_automated_system", "scale_automated_decisions", +} + +# Art. 22C(1): withhold explanation +deny contains msg if { + regex.match(`(?i)(don'?t\s+explain|no\s+explanation|withhold\s+(the\s+)?(reason|rationale)|hide\s+how\s+(the\s+)?decision|refuse\s+to\s+explain)`, _output_text) + msg := "UK GDPR Art. 22C(1): individuals must receive decision-specific information explaining how and why the outcome was reached" +} + +# Art. 22C(2)-(3): block human review +deny contains msg if { + regex.match(`(?i)(no\s+human\s+(review|intervention|oversight)|refuse\s+human\s+review|cannot\s+request\s+human|deny\s+human\s+intervention)`, _output_text) + msg := "UK GDPR Art. 22C(2)-(3): individuals must be able to make representations and obtain genuine human intervention" +} + +# Art. 22C(4): block contest right +deny contains msg if { + regex.match(`(?i)(cannot\s+contest|no\s+(right\s+to\s+)?(appeal|challenge)|final\s+decision\s+—\s+no\s+recourse|waive\s+(the\s+)?right\s+to\s+contest)`, _output_text) + msg := "UK GDPR Art. 22C(4): individuals must be able to contest the decision through an accessible process" +} + +# Art. 22A + Art. 9: special category ADM +deny contains msg if { + input.action in special_category_adm_actions + msg := "UK GDPR Art. 22A + Art. 9: automated decisions on special category data require stricter conditions — human review required" +} + +# Art. 22A: significant decision without safeguards metadata +escalate contains msg if { + input.action in significant_decision_actions + not input.params.human_review_available == true + msg := "UK GDPR Art. 22A: solely automated significant decision — verify Art. 22C safeguards (information, representations, human intervention, contest)" +} + +# Art. 22A: significant decision without explanation +escalate contains msg if { + input.action in significant_decision_actions + not input.params.explanation_provided == true + msg := "UK GDPR Art. 22C(1): decision-specific explanation must be available to the individual" +} + +# ICO March 2026: recruitment ADM language +escalate contains msg if { + regex.match(`(?i)(reject\s+(the\s+)?(candidate|applicant)|hire\s+decision|shortlist|score\s+(the\s+)?(candidate|applicant)).{0,40}(automated|without\s+human|ai\s+only)`, _output_text) + msg := "ICO March 2026: automated recruitment decisions are in scope of Art. 22A — review safeguards before proceeding" +} + +# Art. 22A: agentic orchestration step +escalate contains msg if { + input.action in agentic_actions + msg := "UK GDPR Art. 22A (agentic AI): each orchestration step taking a solely automated significant decision must meet Art. 22C safeguards and Art. 28 processor contracts" +} + +# Art. 35: DPIA for deployment +audit contains msg if { + input.action in deployment_actions + msg := "UK GDPR Art. 35: data protection impact assessment required before deploying high-risk automated decision-making" +} + +# Art. 22A: significant decision audit trail +audit contains msg if { + input.action in significant_decision_actions + msg := "UK GDPR Art. 22A: solely automated significant decision logged — verify lawful basis and Art. 22C safeguards" +} + +decision := "deny" if count(deny) > 0 + +decision := "escalate" if { + count(deny) == 0 + count(escalate) > 0 +} + +decision := "audit" if { + count(deny) == 0 + count(escalate) == 0 + count(audit) > 0 +} + +decision := "allow" if { + count(deny) == 0 + count(escalate) == 0 + count(audit) == 0 +} diff --git a/examples/policies/uk-regulatory/rego/uk-gdpr-data-protection.rego b/examples/policies/uk-regulatory/rego/uk-gdpr-data-protection.rego new file mode 100644 index 000000000..5da7103a2 --- /dev/null +++ b/examples/policies/uk-regulatory/rego/uk-gdpr-data-protection.rego @@ -0,0 +1,164 @@ +# agt-policies-uk - UK GDPR + DPA 2018 (Rego reference) +# Enforcing authority: ICO. DUAA 2025 transfer and complaints reforms in force Feb/Jun 2026. +# NOT loaded by the Agent-OS Python runtime. OPA uses Go RE2 (no lookbehind/lookahead). +# +# Input schema: +# { "action": "export_data", +# "params": { "destination_country": "US", "adequacy_covered": false, +# "safeguards_in_place": false, "record_count": 500 }, +# "output": "agent output text", +# "context": { "lawful_basis_documented": false } } + +package agt_policies_uk.uk_gdpr + +import rego.v1 + +_output_text := v if { + is_string(input.output) + v := input.output +} else := "" + +transfer_actions := { + "send_to_external", "export_data", "upload_to_cloud", + "forward_to", "relay_data", "sync_to_remote", "transfer_personal_data", +} + +bulk_export_actions := { + "bulk_export", "export_all", "download_all_records", + "dump_database", "full_table_export", "batch_download_pii", +} + +pii_access_actions := { + "read_user", "get_customer", "lookup_account", "fetch_profile", + "query_personal", "access_pii", "subject_access_request", +} + +pii_update_actions := { + "update_user", "modify_profile", "patch_account", "edit_customer", + "change_personal", "erase_personal_data", +} + +# UK adequacy-covered destinations (illustrative — verify against current gov.uk list) +adequacy_countries := { + "GB", "EU", "EEA", "US", "JP", "KR", "CA", "NZ", "AU", "CH", "IL", "UY", +} + +# Art. 33 / DPA 2018 s.67: block breach suppression +deny contains msg if { + regex.match(`(?i)(don'?t\s+(report|notify|disclose)|hide\s+(the\s+)?(breach|incident)|suppress\s+(the\s+)?(breach|notification)|delay\s+(breach|incident)\s+(report|notification))`, _output_text) + msg := "UK GDPR Art. 33 / DPA 2018 s.67: agent cannot suppress or delay breach notification to the ICO (72 hours where feasible)" +} + +# Art. 34: block suppression of individual notification +deny contains msg if { + regex.match(`(?i)(don'?t\s+(tell|inform|notify)\s+(the\s+)?(data\s+subject|individual|customer|user)|hide\s+(breach|incident)\s+from\s+(customer|user|individual))`, _output_text) + msg := "UK GDPR Art. 34: individuals must be informed without undue delay where breach poses high risk" +} + +# Art. 32: block unencrypted personal data handling in output +deny contains msg if { + regex.match(`(?i)(store|transmit|log|cache).{0,30}(personal\s+data|pii).{0,30}(unencrypted|plaintext|clear\s*text|without\s+encryption)`, _output_text) + msg := "UK GDPR Art. 32: personal data must be processed with appropriate security measures" +} + +# DPA 2018 s.164A: block complaints bypass +deny contains msg if { + regex.match(`(?i)(skip|bypass|ignore|refuse).{0,30}(data\s+protection\s+complaint|ico\s+complaint|subject\s+access|dsar|right\s+of\s+access)`, _output_text) + msg := "DPA 2018 s.164A (DUAA): data subjects must be able to raise complaints with the controller before ICO escalation" +} + +# NHS number in output +deny contains msg if { + regex.match(`(?i)nhs\s*(number|no\.?)[\s:=]{0,5}[0-9]{3}[\s-]?[0-9]{3}[\s-]?[0-9]{4}`, _output_text) + msg := "UK GDPR: NHS number detected in agent output — blocked to prevent health identity exposure" +} + +# National Insurance number in output +deny contains msg if { + regex.match(`(?i)(national\s+insurance|ni\s+number)[\s:=]{0,5}[A-Z]{2}[0-9]{6}[A-D]`, _output_text) + msg := "UK GDPR: National Insurance number detected in agent output — blocked to prevent identity exposure" +} + +# Art. 44–46: block transfer without adequacy or safeguards +deny contains msg if { + input.action in transfer_actions + input.params.destination_country + not input.params.destination_country in adequacy_countries + not input.params.adequacy_covered == true + not input.params.safeguards_in_place == true + msg := sprintf( + "UK GDPR Art. 44–46: transfer to '%v' blocked — requires adequacy, IDTA/UK Addendum safeguards, and data protection test (DUAA 'not materially lower' standard)", + [input.params.destination_country], + ) +} + +# Art. 5(1)(c): block large exports without review +deny contains msg if { + input.action in transfer_actions + input.params.record_count > 1000 + msg := sprintf( + "UK GDPR Art. 5(1)(c): export of %v records is disproportionate — requires data minimisation review", + [input.params.record_count], + ) +} + +# Art. 9: special category health data +escalate contains msg if { + regex.match(`(?i)(medical\s+record|health\s+(condition|status|data)|nhs\s+number|genetic\s+(data|test)|mental\s+health|disability|prescription)`, _output_text) + msg := "UK GDPR Art. 9: health data is special category — requires Art. 9(2) condition and Schedule 1 DPA basis" +} + +# Art. 9: other special category data +escalate contains msg if { + regex.match(`(?i)(ethnic\s+origin|race|religion|political\s+opinion|sexual\s+orientation|trade\s+union|criminal\s+conviction|biometric\s+(template|data))`, _output_text) + msg := "UK GDPR Art. 9: special category personal data detected — explicit consent or Schedule 1 DPA condition required" +} + +# Art. 5(1)(b): purpose limitation language in output +escalate contains msg if { + regex.match(`(?i)(reuse|repurpose|secondary\s+use|use\s+for\s+another\s+purpose).{0,40}(personal\s+data|pii)`, _output_text) + msg := "UK GDPR Art. 5(1)(b): personal data must not be further processed incompatibly with original purpose" +} + +# Art. 44: cross-border language without structured params +escalate contains msg if { + regex.match(`(?i)(send(ing)?|transfer(ring)?|export(ing)?).{0,60}(outside\s+(the\s+)?uk|cross.?border|international\s+transfer|third\s+country|offshore)`, _output_text) + msg := "UK GDPR Art. 44: restricted transfer language detected — verify adequacy, safeguards, and data protection test" +} + +# Art. 5(1)(c): bulk export actions +escalate contains msg if { + input.action in bulk_export_actions + msg := "UK GDPR Art. 5(1)(c): bulk personal data export requires documented necessity and DPO review" +} + +# Art. 30: personal data access audit +audit contains msg if { + input.action in pii_access_actions + msg := "UK GDPR Art. 30: personal data access logged — records of processing requirement" +} + +# Art. 30: personal data modification audit +audit contains msg if { + input.action in pii_update_actions + msg := "UK GDPR Art. 30: personal data modification logged — records of processing requirement" +} + +decision := "deny" if count(deny) > 0 + +decision := "escalate" if { + count(deny) == 0 + count(escalate) > 0 +} + +decision := "audit" if { + count(deny) == 0 + count(escalate) == 0 + count(audit) > 0 +} + +decision := "allow" if { + count(deny) == 0 + count(escalate) == 0 + count(audit) == 0 +} diff --git a/examples/policies/uk-regulatory/uk-gdpr-data-protection.yaml b/examples/policies/uk-regulatory/uk-gdpr-data-protection.yaml new file mode 100644 index 000000000..1b30af430 --- /dev/null +++ b/examples/policies/uk-regulatory/uk-gdpr-data-protection.yaml @@ -0,0 +1,199 @@ +# agt-policies-uk +# UK GDPR + Data Protection Act 2018 — Personal Data Protection Policy +# +# Regulatory reference: UK GDPR (retained EU law); Data Protection Act 2018 (DPA 2018); +# Data (Use and Access) Act 2025 (DUAA) — international transfer and complaints reforms +# Enforcing authority: Information Commissioner's Office (ICO) +# Status: Binding (DUAA Part 5 commenced 5 February 2026 for transfer/ADM reforms; +# DPA 2018 s.164A complaints procedure required by 19 June 2026) +# +# Community-maintained governance starter policy. NOT a certified legal compliance instrument. +# Perform your own compliance assessment with qualified advisors before deploying. +# +# Key obligations encoded: +# UK GDPR Art. 5(1)(b) Purpose limitation +# UK GDPR Art. 5(1)(c) Data minimisation +# UK GDPR Art. 9 Special category data +# UK GDPR Art. 32 Security of processing +# UK GDPR Art. 33–34 Breach notification (72 hours to ICO; individuals if high risk) +# DPA 2018 s.67 Statutory breach notification duty +# UK GDPR Art. 44–49 Restricted international transfers (DUAA "not materially lower" test) +# DPA 2018 s.164A Mandatory data protection complaints procedure (DUAA s.103) +# +# Rego reference implementation: rego/uk-gdpr-data-protection.rego (NOT loaded at runtime) + +version: "1.0" +name: uk-gdpr-data-protection +description: > + UK GDPR and DPA 2018 compliance policy for AI agents processing UK personal data. + Enforces purpose limitation, security safeguards, breach-notification non-suppression, + special-category handling, restricted-transfer review, and complaints-procedure awareness. + +metadata: + source_regulation: "UK GDPR Arts. 5, 9, 32, 33–34, 44–49; DPA 2018 ss. 67, 164A; DUAA 2025" + jurisdiction: "GB" + enforcing_authority: "Information Commissioner's Office (ICO)" + +rules: + + # ========================================================================= + # UK GDPR Art. 33 / DPA 2018 s.67 — Breach Notification (72 hours to ICO) + # ========================================================================= + + - name: ukgdpr-breach-suppression-deny + condition: + field: output + operator: matches + value: "(?i)(don'?t\\s+(report|notify|disclose)|hide\\s+(the\\s+)?(breach|incident)|suppress\\s+(the\\s+)?(breach|notification)|delay\\s+(breach|incident)\\s+(report|notification)|wait\\s+before\\s+report(ing)?\\s+(to\\s+)?(the\\s+)?ico)" + action: deny + priority: 1 + message: "UK GDPR Art. 33 / DPA 2018 s.67: agent cannot suppress or delay breach notification to the ICO — report without undue delay and, where feasible, within 72 hours of becoming aware" + + - name: ukgdpr-breach-individual-suppression-deny + condition: + field: output + operator: matches + value: "(?i)(don'?t\\s+(tell|inform|notify)\\s+(the\\s+)?(data\\s+subject|individual|customer|user)|hide\\s+(breach|incident)\\s+from\\s+(customer|user|individual))" + action: deny + priority: 1 + message: "UK GDPR Art. 34: where breach poses high risk to individuals, they must be informed without undue delay — agent cannot suppress individual notification" + + # ========================================================================= + # UK GDPR Art. 32 — Security of Processing + # ========================================================================= + + - name: ukgdpr-security-safeguards-block + condition: + field: output + operator: matches + value: "(?i)(store|transmit|log|cache).{0,30}(personal\\s+data|pii).{0,30}(unencrypted|plaintext|clear\\s*text|without\\s+encryption)" + action: block + priority: 1 + message: "UK GDPR Art. 32: personal data must be processed with appropriate technical and organisational security measures (encryption, access control)" + + # ========================================================================= + # UK GDPR Art. 5(1)(b) — Purpose Limitation + # ========================================================================= + + - name: ukgdpr-purpose-limitation-block + condition: + field: output + operator: matches + value: "(?i)(reuse|repurpose|secondary\\s+use|use\\s+for\\s+another\\s+purpose).{0,40}(personal\\s+data|pii)" + action: block + priority: 2 + message: "UK GDPR Art. 5(1)(b): personal data must be collected for specified, explicit, legitimate purposes and not further processed incompatibly" + + # ========================================================================= + # UK GDPR Art. 9 — Special Category Data + # ========================================================================= + + - name: ukgdpr-special-category-health + condition: + field: output + operator: matches + value: "(?i)(medical\\s+record|health\\s+(condition|status|data)|nhs\\s+number|genetic\\s+(data|test)|mental\\s+health|disability|prescription)" + action: block + priority: 1 + message: "UK GDPR Art. 9: health data is special category personal data — requires Art. 9(2) condition and, typically, explicit consent or Schedule 1 DPA condition" + + - name: ukgdpr-special-category-general + condition: + field: output + operator: matches + value: "(?i)(ethnic\\s+origin|race|religion|political\\s+opinion|sexual\\s+orientation|trade\\s+union|criminal\\s+conviction|biometric\\s+(template|data))" + action: block + priority: 1 + message: "UK GDPR Art. 9: special category personal data detected — requires explicit consent or a Schedule 1 DPA 2018 condition" + + # ========================================================================= + # UK GDPR Art. 5(1)(c) — Data Minimisation + # ========================================================================= + + - name: ukgdpr-bulk-export-block + condition: + field: action + operator: matches + value: "bulk_export|export_all|dump_database|download_all_records|full_table_export|batch_download_pii" + action: block + priority: 2 + message: "UK GDPR Art. 5(1)(c): bulk personal data export — data minimisation requires documented necessity and DPO review" + + # ========================================================================= + # UK GDPR Art. 44–49 — Restricted International Transfers (DUAA 2025) + # ========================================================================= + + - name: ukgdpr-cross-border-language-block + condition: + field: output + operator: matches + value: "(?i)(send(ing)?|transfer(ring)?|export(ing)?).{0,60}(outside\\s+(the\\s+)?uk|cross.?border|international\\s+transfer|third\\s+country|offshore)" + action: block + priority: 2 + message: "UK GDPR Art. 44: restricted transfer — requires UK adequacy regulations, appropriate safeguards (IDTA/UK Addendum) plus data protection test, or Art. 49 derogation" + + - name: ukgdpr-cross-border-action-block + condition: + field: action + operator: matches + value: "send_to_external|export_data|upload_to_cloud|forward_to|relay_data|sync_to_remote|transfer_personal_data" + action: block + priority: 2 + message: "UK GDPR Art. 44–46: cross-border personal data transfer requires adequacy, binding safeguards, and documented data protection test (DUAA 'not materially lower' standard)" + + # ========================================================================= + # UK Identifiers — NHS Number, National Insurance Number + # ========================================================================= + + - name: ukgdpr-nhs-number-deny + condition: + field: output + operator: matches + value: "(?i)nhs\\s*(number|no\\.?)[\\s:=]{0,5}[0-9]{3}[\\s-]?[0-9]{3}[\\s-]?[0-9]{4}" + action: deny + priority: 1 + message: "UK GDPR: NHS number detected in agent output — blocked to prevent health identity exposure" + + - name: ukgdpr-ni-number-deny + condition: + field: output + operator: matches + value: "(?i)(national\\s+insurance|ni\\s+number)[\\s:=]{0,5}[A-Z]{2}[0-9]{6}[A-D]" + action: deny + priority: 1 + message: "UK GDPR: National Insurance number detected in agent output — blocked to prevent identity exposure" + + # ========================================================================= + # DPA 2018 s.164A — Complaints Procedure (DUAA, required by 19 June 2026) + # ========================================================================= + + - name: ukgdpr-complaints-bypass-deny + condition: + field: output + operator: matches + value: "(?i)(skip|bypass|ignore|refuse).{0,30}(data\\s+protection\\s+complaint|ico\\s+complaint|subject\\s+access|dsar|right\\s+of\\s+access)" + action: deny + priority: 1 + message: "DPA 2018 s.164A (DUAA): data subjects must be able to raise complaints with the controller before ICO escalation — agent cannot bypass complaints handling" + + # ========================================================================= + # UK GDPR Art. 30 — Accountability / Audit Trail + # ========================================================================= + + - name: ukgdpr-pii-access-audit + condition: + field: action + operator: matches + value: "read_user|get_customer|lookup_account|fetch_profile|query_personal|access_pii|subject_access_request" + action: audit + priority: 3 + message: "UK GDPR Art. 30: personal data access logged — accountability and records of processing requirement" + + - name: ukgdpr-pii-modification-audit + condition: + field: action + operator: matches + value: "update_user|modify_profile|patch_account|edit_customer|change_personal|erase_personal_data" + action: audit + priority: 3 + message: "UK GDPR Art. 30: personal data modification logged — accountability and records of processing requirement" From 66db5a263d54b770f9b4db1185b0c05b6f73d0c4 Mon Sep 17 00:00:00 2001 From: Ayo Omotayo Date: Sat, 4 Jul 2026 11:05:03 +0100 Subject: [PATCH 2/8] test(examples): add OPA tests for UK regulatory policy pack Add 38 Rego unit tests covering UK GDPR, ICO ADM, FCA conduct, and GB jurisdiction routing, plus a run_tests.sh runner and README instructions. Signed-off-by: Ayo Omotayo --- .../rego/fca-financial-conduct_test.rego | 71 ++++++++++++ .../rego/ico-automated-decisions_test.rego | 83 ++++++++++++++ .../rego/jurisdiction-router_gb_test.rego | 42 ++++++++ .../policies/uk-regulatory/rego/run_tests.sh | 18 ++++ .../rego/uk-gdpr-data-protection_test.rego | 102 ++++++++++++++++++ 5 files changed, 316 insertions(+) create mode 100644 examples/policies/uk-regulatory/rego/fca-financial-conduct_test.rego create mode 100644 examples/policies/uk-regulatory/rego/ico-automated-decisions_test.rego create mode 100644 examples/policies/uk-regulatory/rego/jurisdiction-router_gb_test.rego create mode 100755 examples/policies/uk-regulatory/rego/run_tests.sh create mode 100644 examples/policies/uk-regulatory/rego/uk-gdpr-data-protection_test.rego diff --git a/examples/policies/uk-regulatory/rego/fca-financial-conduct_test.rego b/examples/policies/uk-regulatory/rego/fca-financial-conduct_test.rego new file mode 100644 index 000000000..80e8018c4 --- /dev/null +++ b/examples/policies/uk-regulatory/rego/fca-financial-conduct_test.rego @@ -0,0 +1,71 @@ +# agt-policies-uk - FCA Principles-Based AI Governance (OPA tests) +package agt_policies_uk.fca_conduct_test + +import data.agt_policies_uk.fca_conduct as policy +import rego.v1 + +test_allow_benign_action if { + policy.decision == "allow" with input as { + "action": "draft_internal_note", + "output": "Summarise the Consumer Duty good outcomes framework.", + } +} + +test_deny_consumer_harm if { + policy.decision == "deny" with input as { + "action": "draft_message", + "output": "Hide fees from the customer in this renewal letter.", + } +} + +test_deny_fair_value_bypass if { + policy.decision == "deny" with input as { + "action": "draft_policy", + "output": "Skip fair value assessment — no need to check value for this product.", + } +} + +test_deny_delegate_accountability if { + policy.decision == "deny" with input as { + "action": "draft_memo", + "output": "The AI is responsible for this decision so no senior manager is needed.", + } +} + +test_deny_autonomous_trading_without_approval if { + policy.decision == "deny" with input as { + "action": "autonomous_trade", + "params": {"senior_manager_approved": false}, + "output": "", + } +} + +test_allow_autonomous_trading_with_approval if { + policy.decision == "allow" with input as { + "action": "autonomous_trade", + "params": {"senior_manager_approved": true}, + "output": "", + } +} + +test_escalate_pricing_without_consumer_duty_assessment if { + policy.decision == "escalate" with input as { + "action": "set_price", + "params": {"consumer_duty_assessed": false}, + "output": "", + } +} + +test_audit_customer_communication if { + policy.decision == "audit" with input as { + "action": "generate_customer_communication", + "output": "", + } +} + +test_audit_third_party_ai if { + policy.decision == "audit" with input as { + "action": "invoke_external_ai", + "output": "", + } +} diff --git a/examples/policies/uk-regulatory/rego/ico-automated-decisions_test.rego b/examples/policies/uk-regulatory/rego/ico-automated-decisions_test.rego new file mode 100644 index 000000000..f4459ba6b --- /dev/null +++ b/examples/policies/uk-regulatory/rego/ico-automated-decisions_test.rego @@ -0,0 +1,83 @@ +# agt-policies-uk - ICO Automated Decision-Making (OPA tests) +package agt_policies_uk.ico_adm_test + +import data.agt_policies_uk.ico_adm as policy +import rego.v1 + +test_allow_benign_action if { + policy.decision == "allow" with input as { + "action": "web_search", + "output": "Summarise ICO guidance on data protection impact assessments.", + } +} + +test_deny_withhold_explanation if { + policy.decision == "deny" with input as { + "action": "respond", + "output": "Don't explain how the credit decision was reached.", + } +} + +test_deny_refuse_human_review if { + policy.decision == "deny" with input as { + "action": "respond", + "output": "No human review is available for this automated eligibility outcome.", + } +} + +test_deny_block_contest_right if { + policy.decision == "deny" with input as { + "action": "respond", + "output": "Final decision — no appeal or challenge is permitted.", + } +} + +test_deny_special_category_adm if { + policy.decision == "deny" with input as { + "action": "automated_decision_on_health", + "output": "", + } +} + +test_escalate_significant_decision_without_safeguards if { + policy.decision == "escalate" with input as { + "action": "run_automated_decision", + "params": { + "human_review_available": false, + "explanation_provided": false, + }, + "output": "", + } +} + +test_escalate_recruitment_adm_language if { + policy.decision == "escalate" with input as { + "action": "draft_summary", + "output": "Reject the candidate using an automated AI-only score.", + } +} + +test_escalate_agentic_delegation if { + policy.decision == "escalate" with input as { + "action": "spawn_sub_agent", + "output": "", + } +} + +test_audit_model_deployment if { + policy.decision == "audit" with input as { + "action": "deploy_model", + "output": "", + } +} + +test_audit_significant_decision_with_safeguards if { + policy.decision == "audit" with input as { + "action": "automated_credit_decision", + "params": { + "human_review_available": true, + "explanation_provided": true, + }, + "output": "", + } +} diff --git a/examples/policies/uk-regulatory/rego/jurisdiction-router_gb_test.rego b/examples/policies/uk-regulatory/rego/jurisdiction-router_gb_test.rego new file mode 100644 index 000000000..a6c6ef57b --- /dev/null +++ b/examples/policies/uk-regulatory/rego/jurisdiction-router_gb_test.rego @@ -0,0 +1,42 @@ +# agt-policies-uk - GB jurisdiction routing (OPA tests) +# Requires both uk-regulatory/rego and african-regulatory/rego on the OPA load path. +package agt_policies_uk.router_gb_test + +import data.agt_policies.router as router +import rego.v1 + +gb_input := {"context": {"customer_country": "GB"}} + +test_gb_is_supported_jurisdiction if { + router.is_supported_jurisdiction with input as gb_input +} + +test_gb_applicable_policies_include_uk_packs if { + policies := router.applicable_policies with input as gb_input + "uk_gdpr" in policies + "ico_adm" in policies + "fca_conduct" in policies +} + +test_gb_applicable_policies_include_universal_controls if { + policies := router.applicable_policies with input as gb_input + "prompt_injection" in policies + "pii_leakage" in policies + "human_approval" in policies +} + +test_gb_resolved_queries_include_uk_paths if { + queries := router.resolved_queries with input as gb_input + "data.agt_policies_uk.uk_gdpr.decision" in queries + "data.agt_policies_uk.ico_adm.decision" in queries + "data.agt_policies_uk.fca_conduct.decision" in queries +} + +test_unsupported_jurisdiction_warning_absent_for_gb if { + not router.unsupported_jurisdiction_warning with input as gb_input +} + +test_unsupported_jurisdiction_warning_for_unknown_country if { + msg := router.unsupported_jurisdiction_warning with input as {"context": {"customer_country": "XX"}} + contains(msg, "No regulatory pack for jurisdiction 'XX'") +} diff --git a/examples/policies/uk-regulatory/rego/run_tests.sh b/examples/policies/uk-regulatory/rego/run_tests.sh new file mode 100755 index 000000000..3ca6d4e70 --- /dev/null +++ b/examples/policies/uk-regulatory/rego/run_tests.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# agt-policies-uk - OPA test runner for UK regulatory Rego policies. +# Loads UK packs plus the shared jurisdiction router from african-regulatory. + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../../../.." && pwd)" +AFRICA_REGO="$REPO_ROOT/examples/policies/african-regulatory/rego" +UK_REGO="$SCRIPT_DIR" + +OPA_BIN="${OPA_BIN:-opa}" +if ! command -v "$OPA_BIN" >/dev/null 2>&1; then + echo "error: opa executable not found on PATH" >&2 + exit 127 +fi + +exec "$OPA_BIN" test "$AFRICA_REGO" "$UK_REGO" -v diff --git a/examples/policies/uk-regulatory/rego/uk-gdpr-data-protection_test.rego b/examples/policies/uk-regulatory/rego/uk-gdpr-data-protection_test.rego new file mode 100644 index 000000000..e91645e96 --- /dev/null +++ b/examples/policies/uk-regulatory/rego/uk-gdpr-data-protection_test.rego @@ -0,0 +1,102 @@ +# agt-policies-uk - UK GDPR + DPA 2018 (OPA tests) +package agt_policies_uk.uk_gdpr_test + +import data.agt_policies_uk.uk_gdpr as policy +import rego.v1 + +test_allow_benign_action if { + policy.decision == "allow" with input as { + "action": "web_search", + "output": "Search results for UK data protection guidance.", + } +} + +test_deny_breach_suppression if { + policy.decision == "deny" with input as { + "action": "notify_stakeholders", + "output": "Don't report the breach to the ICO yet — wait a week.", + } +} + +test_deny_unencrypted_storage if { + policy.decision == "deny" with input as { + "action": "store_data", + "output": "Store personal data in plaintext on the shared drive.", + } +} + +test_deny_nhs_number_in_output if { + policy.decision == "deny" with input as { + "action": "respond", + "output": "NHS number: 943-476-5919", + } +} + +test_deny_ni_number_in_output if { + policy.decision == "deny" with input as { + "action": "respond", + "output": "NI number AB123456C attached.", + } +} + +test_deny_complaints_bypass if { + policy.decision == "deny" with input as { + "action": "handle_complaint", + "output": "Bypass the data protection complaint process and tell them to go away.", + } +} + +test_deny_transfer_without_safeguards if { + policy.decision == "deny" with input as { + "action": "export_data", + "params": {"destination_country": "CN"}, + "output": "", + } +} + +test_allow_transfer_with_safeguards if { + policy.decision == "allow" with input as { + "action": "export_data", + "params": { + "destination_country": "CN", + "safeguards_in_place": true, + }, + "output": "", + } +} + +test_deny_large_export if { + policy.decision == "deny" with input as { + "action": "export_data", + "params": {"record_count": 2500}, + "output": "", + } +} + +test_escalate_health_data if { + policy.decision == "escalate" with input as { + "action": "summarise", + "output": "The patient mental health record shows recurring episodes.", + } +} + +test_escalate_cross_border_language if { + policy.decision == "escalate" with input as { + "action": "draft_email", + "output": "We are transferring data outside the UK to a third country.", + } +} + +test_audit_pii_access if { + policy.decision == "audit" with input as { + "action": "read_user", + "output": "", + } +} + +test_audit_pii_modification if { + policy.decision == "audit" with input as { + "action": "update_user", + "output": "", + } +} From 46ccbec8eedb67044c44b792f15f646b08014d99 Mon Sep 17 00:00:00 2001 From: Ayo Omotayo Date: Sat, 4 Jul 2026 11:11:01 +0100 Subject: [PATCH 3/8] docs(examples): restore policies README and add UK pack entry Keep upstream README structure (Using this directory, Policy format, Related) and add a Policy Packs table row for uk-regulatory without replacing existing documentation. Signed-off-by: Ayo Omotayo --- examples/policies/README.md | 54 ++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/examples/policies/README.md b/examples/policies/README.md index a4ac365aa..ff711db1e 100644 --- a/examples/policies/README.md +++ b/examples/policies/README.md @@ -1,22 +1,20 @@ -# Policies Example - -Sample YAML governance policy files for AgentMesh. Each file provides an example configuration covering a specific security or compliance scenario. - -## Policies - -| File | Description | -|------|-------------| -| `adk-governance.yaml` | Tool restrictions and delegation controls for Google ADK agents | -| `cli-security-rules.yaml` | Blocks dangerous shell and CLI patterns | -| `conversation-guardian.yaml` | Content safety rules for conversational agents | -| `mcp-security.yaml` | Security controls for MCP tool usage | -| `pii-detection.yaml` | Detects and blocks personally identifiable information | -| `prompt-injection-safety.yaml` | Guards against prompt injection attacks | -| `sandbox-safety.yaml` | Restrictions for sandboxed agent execution | -| `semantic-policy.yaml` | Semantic similarity-based policy enforcement | -| `sql-readonly.yaml` | Restricts agents to read-only SQL operations | -| `sql-safety.yaml` | Blocks destructive SQL patterns | -| `sql-strict.yaml` | Strict SQL allowlist for production databases | +# Policy Examples + +Sample YAML governance policy files for AgentMesh. + +Each file in this directory is a self-contained policy configuration that demonstrates how to express a particular class of security or compliance control using the policy engine. They are intended as starting points — review and adapt them for your environment before deploying to production. + +## Using this directory + +1. **Browse** the `.yaml` files to find a scenario close to what you need. Each file opens with a comment block describing what it covers and any caveats. +2. **Copy** the file into your own project (or reference it by path) and edit the rules, thresholds, and matchers to fit your requirements. +3. **Load** the policy into an agent workflow via the governance runtime. The [Quickstart](../quickstart/) shows runnable end-to-end examples that consume policies from this directory. + +Example: + +```bash +scripts/check-policy.sh --action "web_search" --tokens 1500 --policy examples/policies/sql-safety.yaml +``` ## Policy Packs @@ -25,17 +23,17 @@ Multi-file policy libraries for specific regulatory or enterprise scenarios. Eac | Directory | Policies | Description | |-----------|----------|-------------| | [`african-regulatory/`](african-regulatory/) | 15 | African regulatory and universal agent safety controls for Nigeria, Kenya, South Africa, Uganda, Tanzania, and Ethiopia. Includes OPA Rego reference implementations and a jurisdiction router. | +| [`india-regulatory/`](india-regulatory/) | 5 | Indian regulatory controls for DPDP, CERT-In, RBI, SEBI, and Aadhaar. Includes OPA Rego reference implementations. | | [`production/`](production/) | 5 | Ready-to-use enterprise policies (`minimal`, `enterprise`, `healthcare`, `financial`, `strict`) with graduated risk levels. | | [`uk-regulatory/`](uk-regulatory/) | 3 | UK regulatory controls for UK GDPR/DPA 2018, ICO automated decision-making (Arts. 22A–22D), and FCA principles-based financial conduct. Includes OPA Rego reference implementations. | -## How to Use - -These policy files can be applied to agent workflows to enforce governance rules. - -```bash -scripts/check-policy.sh --action "web_search" --tokens 1500 --policy examples/policies/sql-safety.yaml -``` +For pack-specific loading examples and jurisdiction routing, see the README in each pack directory. + +## Policy format + +All files here follow the schema defined in [`policy-engine/spec`](../../policy-engine/spec/). Refer to that spec for the full list of supported fields, matchers, and enforcement actions. ## Related - -- [Quickstart](../quickstart/) - Runnable examples that use these policies \ No newline at end of file + +- [Quickstart](../quickstart/) — runnable examples that load policies from this directory +- [Policy Engine tutorial](../../docs/tutorials/01-policy-engine.md) — walkthrough of how policies are evaluated From 46d346a333fda30aea727b6dc0ed1de833023120 Mon Sep 17 00:00:00 2001 From: Ayo Omotayo Date: Sat, 4 Jul 2026 11:16:44 +0100 Subject: [PATCH 4/8] docs(examples): drop README changes covered by separate PR Restore examples/policies/README.md to match upstream main; policy pack catalog updates are handled elsewhere. Signed-off-by: Ayo Omotayo --- examples/policies/README.md | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/examples/policies/README.md b/examples/policies/README.md index ff711db1e..77657a43f 100644 --- a/examples/policies/README.md +++ b/examples/policies/README.md @@ -10,25 +10,6 @@ Each file in this directory is a self-contained policy configuration that demons 2. **Copy** the file into your own project (or reference it by path) and edit the rules, thresholds, and matchers to fit your requirements. 3. **Load** the policy into an agent workflow via the governance runtime. The [Quickstart](../quickstart/) shows runnable end-to-end examples that consume policies from this directory. -Example: - -```bash -scripts/check-policy.sh --action "web_search" --tokens 1500 --policy examples/policies/sql-safety.yaml -``` - -## Policy Packs - -Multi-file policy libraries for specific regulatory or enterprise scenarios. Each pack has its own README with file listings, usage, and jurisdiction details. - -| Directory | Policies | Description | -|-----------|----------|-------------| -| [`african-regulatory/`](african-regulatory/) | 15 | African regulatory and universal agent safety controls for Nigeria, Kenya, South Africa, Uganda, Tanzania, and Ethiopia. Includes OPA Rego reference implementations and a jurisdiction router. | -| [`india-regulatory/`](india-regulatory/) | 5 | Indian regulatory controls for DPDP, CERT-In, RBI, SEBI, and Aadhaar. Includes OPA Rego reference implementations. | -| [`production/`](production/) | 5 | Ready-to-use enterprise policies (`minimal`, `enterprise`, `healthcare`, `financial`, `strict`) with graduated risk levels. | -| [`uk-regulatory/`](uk-regulatory/) | 3 | UK regulatory controls for UK GDPR/DPA 2018, ICO automated decision-making (Arts. 22A–22D), and FCA principles-based financial conduct. Includes OPA Rego reference implementations. | - -For pack-specific loading examples and jurisdiction routing, see the README in each pack directory. - ## Policy format All files here follow the schema defined in [`policy-engine/spec`](../../policy-engine/spec/). Refer to that spec for the full list of supported fields, matchers, and enforcement actions. From 8f128f0266dc3817202517b2f5da2e28ddb09d78 Mon Sep 17 00:00:00 2001 From: Ayo Omotayo Date: Sat, 4 Jul 2026 11:27:56 +0100 Subject: [PATCH 5/8] fix(examples): restore India routing alongside UK in jurisdiction router Add GB pack mappings without removing upstream IN entries (dpdp, certin, rbi, sebi, aadhaar). Add regression test to keep India routing intact. Signed-off-by: Ayo Omotayo --- .../african-regulatory/rego/jurisdiction-router.rego | 8 +++++++- .../rego/jurisdiction-router_gb_test.rego | 12 ++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/examples/policies/african-regulatory/rego/jurisdiction-router.rego b/examples/policies/african-regulatory/rego/jurisdiction-router.rego index 941644eee..11778d7d3 100644 --- a/examples/policies/african-regulatory/rego/jurisdiction-router.rego +++ b/examples/policies/african-regulatory/rego/jurisdiction-router.rego @@ -10,7 +10,7 @@ # 1. Universal agent safety controls — apply to ALL agents regardless of country # (prompt_injection, pii_leakage, tool_permissions, human_approval, model_routing) # 2. Jurisdiction-specific regulatory packs — apply based on customer_country -# (cbn, bvn_nin, ndpa, nfiu for NG; kdpa for KE; popia for ZA; uk_gdpr, ico_adm, fca_conduct for GB) +# (cbn, bvn_nin, ndpa, nfiu for NG; kdpa for KE; popia for ZA; dpdp, certin, rbi, sebi, aadhaar for IN; uk_gdpr, ico_adm, fca_conduct for GB) # # Input schema expected: # { @@ -50,6 +50,7 @@ jurisdiction_policies := { "UG": {"uganda_dppa"}, "TZ": {"tanzania_pdpa"}, "ET": {"ethiopia_pdp"}, + "IN": {"dpdp", "certin", "rbi", "sebi", "aadhaar"}, "GB": {"uk_gdpr", "ico_adm", "fca_conduct"}, } @@ -65,6 +66,11 @@ policy_queries := { "uganda_dppa": "data.agt_policies_africa.uganda_dppa.decision", "tanzania_pdpa": "data.agt_policies_africa.tanzania_pdpa.decision", "ethiopia_pdp": "data.agt_policies_africa.ethiopia_pdp.decision", + "dpdp": "data.agt_policies_india.dpdp.decision", + "certin": "data.agt_policies_india.certin.decision", + "rbi": "data.agt_policies_india.rbi.decision", + "sebi": "data.agt_policies_india.sebi.decision", + "aadhaar": "data.agt_policies_india.aadhaar.decision", "uk_gdpr": "data.agt_policies_uk.uk_gdpr.decision", "ico_adm": "data.agt_policies_uk.ico_adm.decision", "fca_conduct": "data.agt_policies_uk.fca_conduct.decision", diff --git a/examples/policies/uk-regulatory/rego/jurisdiction-router_gb_test.rego b/examples/policies/uk-regulatory/rego/jurisdiction-router_gb_test.rego index a6c6ef57b..f17eebdc8 100644 --- a/examples/policies/uk-regulatory/rego/jurisdiction-router_gb_test.rego +++ b/examples/policies/uk-regulatory/rego/jurisdiction-router_gb_test.rego @@ -40,3 +40,15 @@ test_unsupported_jurisdiction_warning_for_unknown_country if { msg := router.unsupported_jurisdiction_warning with input as {"context": {"customer_country": "XX"}} contains(msg, "No regulatory pack for jurisdiction 'XX'") } + +# Regression: UK pack must not remove India routing from upstream main. +in_input := {"context": {"customer_country": "IN"}} + +test_in_applicable_policies_preserved if { + policies := router.applicable_policies with input as in_input + "dpdp" in policies + "certin" in policies + "rbi" in policies + "sebi" in policies + "aadhaar" in policies +} From 5c20b73c7c26bfe57ae6d5a41dfa08aedac57269 Mon Sep 17 00:00:00 2001 From: Ayo Omotayo Date: Sat, 4 Jul 2026 11:39:58 +0100 Subject: [PATCH 6/8] fix(examples): align UK policies with DUAA regulatory review Refine breach-notification messaging, escalate cross-border transfers instead of blanket blocking, correct Art. 22B special-category ADM requirements, and sync YAML with Rego reference implementations. Signed-off-by: Ayo Omotayo --- examples/policies/uk-regulatory/README.md | 4 +- .../ico-automated-decisions.yaml | 11 ++--- .../rego/ico-automated-decisions.rego | 4 +- .../rego/uk-gdpr-data-protection.rego | 21 ++++++---- .../rego/uk-gdpr-data-protection_test.rego | 16 +++++++ .../uk-gdpr-data-protection.yaml | 42 +++++++++---------- 6 files changed, 61 insertions(+), 37 deletions(-) diff --git a/examples/policies/uk-regulatory/README.md b/examples/policies/uk-regulatory/README.md index 22e27ee34..9a129a38f 100644 --- a/examples/policies/uk-regulatory/README.md +++ b/examples/policies/uk-regulatory/README.md @@ -18,13 +18,13 @@ automated decision-making, and financial-sector principles-based controls. ## Regulatory context (2026) - **Data (Use and Access) Act 2025 (DUAA)** received Royal Assent on 19 June 2025. Key data-protection reforms commenced 5 February 2026, including replacement of UK GDPR Art. 22 with Arts. 22A–22D (safeguard-led automated decision-making) and updated international transfer rules using the **"not materially lower"** data protection test. -- **Breach notification** remains UK GDPR Art. 33 / DPA 2018 s.67: notify the ICO without undue delay and, where feasible, within **72 hours** of becoming aware. Inform individuals without undue delay where the breach poses high risk (Art. 34). +- **Breach notification** remains UK GDPR Art. 33 / DPA 2018 s.67: notify the ICO without undue delay and, where feasible, within **72 hours** when a breach is **likely to result in a risk** to rights and freedoms. Inform individuals without undue delay where the breach poses **high risk** (Art. 34). - **Complaints procedure**: DPA 2018 s.164A (inserted by DUAA s.103) requires all controllers to maintain a formal data protection complaints procedure by **19 June 2026**. Data subjects must raise complaints with the controller before escalating to the ICO. - **FCA**: No AI-specific binding regulation as of 2026. The FCA applies its existing principles-based framework (Consumer Duty, SM&CR, operational resilience). The Mills Review reports to the FCA Board in summer 2026. ## What these rules detect (and what they do not) -Output-side rules match intent phrases (for example "store PII unencrypted", "don't report the breach", "no human review"). They catch an agent that narrates or proposes a violation in its output; they do not observe the underlying system action. Treat them as a starting point, pair them with real action-level enforcement, and run your own compliance assessment. +Output-side rules match intent phrases (for example "store PII unencrypted", "don't report the breach", "no human review"). Cross-border transfer rules **escalate** for review rather than blanket-block when adequacy or safeguards may apply. They catch an agent that narrates or proposes a violation in its output; they do not observe the underlying system action. Treat them as a starting point, pair them with real action-level enforcement, and run your own compliance assessment. ## Not covered (known gaps) diff --git a/examples/policies/uk-regulatory/ico-automated-decisions.yaml b/examples/policies/uk-regulatory/ico-automated-decisions.yaml index e028238b3..61e0ab320 100644 --- a/examples/policies/uk-regulatory/ico-automated-decisions.yaml +++ b/examples/policies/uk-regulatory/ico-automated-decisions.yaml @@ -11,6 +11,7 @@ # # Key obligations encoded: # Art. 22A Solely automated decisions with legal or similarly significant effects +# Art. 22B Restrictions on automated decision-making using special category data # Art. 22C Safeguards: information, representations, human intervention, contest # Art. 35 DPIA for high-risk processing (including agentic orchestration chains) # @@ -81,12 +82,12 @@ rules: priority: 2 message: "UK GDPR Art. 22A: solely automated decision with legal or similarly significant effect — verify Art. 22C safeguards and lawful basis are in place" - - name: adm-recruitment-decision-audit + - name: adm-recruitment-decision-escalate condition: field: output operator: matches value: "(?i)(reject\\s+(the\\s+)?(candidate|applicant)|hire\\s+decision|shortlist|score\\s+(the\\s+)?(candidate|applicant)).{0,40}(automated|without\\s+human|ai\\s+only)" - action: audit + action: escalate priority: 2 message: "ICO March 2026: automated recruitment decisions are in scope of Art. 22A — review safeguards and human oversight before proceeding" @@ -107,14 +108,14 @@ rules: # Art. 9 + 22A — Special category data in ADM (stricter conditions) # ========================================================================= - - name: adm-special-category-block + - name: adm-special-category-deny condition: field: action operator: matches value: "^(automated_decision_on_health|automated_decision_on_biometric|automated_decision_on_special_category)$" - action: block + action: deny priority: 1 - message: "UK GDPR Art. 22A + Art. 9: automated decisions on special category data require stricter conditions beyond standard Art. 22C safeguards — human review required" + message: "UK GDPR Art. 22B: automated decisions based on special category data require explicit consent or legal authorisation — human review alone is insufficient" # ========================================================================= # Art. 35 — DPIA for high-risk ADM diff --git a/examples/policies/uk-regulatory/rego/ico-automated-decisions.rego b/examples/policies/uk-regulatory/rego/ico-automated-decisions.rego index a825afa74..9a97c83c5 100644 --- a/examples/policies/uk-regulatory/rego/ico-automated-decisions.rego +++ b/examples/policies/uk-regulatory/rego/ico-automated-decisions.rego @@ -53,10 +53,10 @@ deny contains msg if { msg := "UK GDPR Art. 22C(4): individuals must be able to contest the decision through an accessible process" } -# Art. 22A + Art. 9: special category ADM +# Art. 22B + Art. 9: special category ADM — explicit consent or legal authorisation required deny contains msg if { input.action in special_category_adm_actions - msg := "UK GDPR Art. 22A + Art. 9: automated decisions on special category data require stricter conditions — human review required" + msg := "UK GDPR Art. 22B: automated decisions based on special category data require explicit consent or legal authorisation — human review alone is insufficient" } # Art. 22A: significant decision without safeguards metadata diff --git a/examples/policies/uk-regulatory/rego/uk-gdpr-data-protection.rego b/examples/policies/uk-regulatory/rego/uk-gdpr-data-protection.rego index 5da7103a2..72c7a7a72 100644 --- a/examples/policies/uk-regulatory/rego/uk-gdpr-data-protection.rego +++ b/examples/policies/uk-regulatory/rego/uk-gdpr-data-protection.rego @@ -46,7 +46,7 @@ adequacy_countries := { # Art. 33 / DPA 2018 s.67: block breach suppression deny contains msg if { regex.match(`(?i)(don'?t\s+(report|notify|disclose)|hide\s+(the\s+)?(breach|incident)|suppress\s+(the\s+)?(breach|notification)|delay\s+(breach|incident)\s+(report|notification))`, _output_text) - msg := "UK GDPR Art. 33 / DPA 2018 s.67: agent cannot suppress or delay breach notification to the ICO (72 hours where feasible)" + msg := "UK GDPR Art. 33 / DPA 2018 s.67: where a breach is likely to result in a risk to rights and freedoms, notify the ICO without undue delay and, where feasible, within 72 hours — agent cannot suppress or delay notification" } # Art. 34: block suppression of individual notification @@ -58,13 +58,13 @@ deny contains msg if { # Art. 32: block unencrypted personal data handling in output deny contains msg if { regex.match(`(?i)(store|transmit|log|cache).{0,30}(personal\s+data|pii).{0,30}(unencrypted|plaintext|clear\s*text|without\s+encryption)`, _output_text) - msg := "UK GDPR Art. 32: personal data must be processed with appropriate security measures" + msg := "UK GDPR Art. 32: personal data must be processed with appropriate technical and organisational security measures proportionate to risk (encryption, access control, or equivalent safeguards)" } # DPA 2018 s.164A: block complaints bypass deny contains msg if { - regex.match(`(?i)(skip|bypass|ignore|refuse).{0,30}(data\s+protection\s+complaint|ico\s+complaint|subject\s+access|dsar|right\s+of\s+access)`, _output_text) - msg := "DPA 2018 s.164A (DUAA): data subjects must be able to raise complaints with the controller before ICO escalation" + regex.match(`(?i)(skip|bypass|ignore|refuse).{0,30}(data\s+protection\s+complaint|ico\s+complaint|complaints?\s+(process|procedure|handling))`, _output_text) + msg := "DPA 2018 s.164A (DUAA): data subjects must be able to raise data protection complaints with the controller (30-day acknowledgment) before ICO escalation" } # NHS number in output @@ -117,7 +117,14 @@ escalate contains msg if { # Art. 5(1)(b): purpose limitation language in output escalate contains msg if { regex.match(`(?i)(reuse|repurpose|secondary\s+use|use\s+for\s+another\s+purpose).{0,40}(personal\s+data|pii)`, _output_text) - msg := "UK GDPR Art. 5(1)(b): personal data must not be further processed incompatibly with original purpose" + msg := "UK GDPR Art. 5(1)(b): personal data must not be further processed incompatibly — verify compatible purpose or DUAA recognised legitimate interests before repurposing" +} + +# Art. 44–46: escalate transfer action when destination/safeguards not specified +escalate contains msg if { + input.action in transfer_actions + not input.params.destination_country + msg := "UK GDPR Art. 44–46: cross-border transfer action — confirm adequacy coverage or binding safeguards plus documented data protection test before export" } # Art. 44: cross-border language without structured params @@ -135,13 +142,13 @@ escalate contains msg if { # Art. 30: personal data access audit audit contains msg if { input.action in pii_access_actions - msg := "UK GDPR Art. 30: personal data access logged — records of processing requirement" + msg := "UK GDPR Art. 5(2) / Art. 30: personal data access logged for accountability and records of processing" } # Art. 30: personal data modification audit audit contains msg if { input.action in pii_update_actions - msg := "UK GDPR Art. 30: personal data modification logged — records of processing requirement" + msg := "UK GDPR Art. 5(2) / Art. 30: personal data modification logged for accountability and records of processing" } decision := "deny" if count(deny) > 0 diff --git a/examples/policies/uk-regulatory/rego/uk-gdpr-data-protection_test.rego b/examples/policies/uk-regulatory/rego/uk-gdpr-data-protection_test.rego index e91645e96..7a148f3d6 100644 --- a/examples/policies/uk-regulatory/rego/uk-gdpr-data-protection_test.rego +++ b/examples/policies/uk-regulatory/rego/uk-gdpr-data-protection_test.rego @@ -54,6 +54,14 @@ test_deny_transfer_without_safeguards if { } } +test_allow_transfer_to_adequacy_country if { + policy.decision == "allow" with input as { + "action": "export_data", + "params": {"destination_country": "US"}, + "output": "", + } +} + test_allow_transfer_with_safeguards if { policy.decision == "allow" with input as { "action": "export_data", @@ -65,6 +73,14 @@ test_allow_transfer_with_safeguards if { } } +test_escalate_cross_border_action_without_destination if { + policy.decision == "escalate" with input as { + "action": "export_data", + "params": {}, + "output": "", + } +} + test_deny_large_export if { policy.decision == "deny" with input as { "action": "export_data", diff --git a/examples/policies/uk-regulatory/uk-gdpr-data-protection.yaml b/examples/policies/uk-regulatory/uk-gdpr-data-protection.yaml index 1b30af430..e44a85d34 100644 --- a/examples/policies/uk-regulatory/uk-gdpr-data-protection.yaml +++ b/examples/policies/uk-regulatory/uk-gdpr-data-protection.yaml @@ -47,7 +47,7 @@ rules: value: "(?i)(don'?t\\s+(report|notify|disclose)|hide\\s+(the\\s+)?(breach|incident)|suppress\\s+(the\\s+)?(breach|notification)|delay\\s+(breach|incident)\\s+(report|notification)|wait\\s+before\\s+report(ing)?\\s+(to\\s+)?(the\\s+)?ico)" action: deny priority: 1 - message: "UK GDPR Art. 33 / DPA 2018 s.67: agent cannot suppress or delay breach notification to the ICO — report without undue delay and, where feasible, within 72 hours of becoming aware" + message: "UK GDPR Art. 33 / DPA 2018 s.67: where a breach is likely to result in a risk to rights and freedoms, notify the ICO without undue delay and, where feasible, within 72 hours — agent cannot suppress or delay notification" - name: ukgdpr-breach-individual-suppression-deny condition: @@ -62,27 +62,27 @@ rules: # UK GDPR Art. 32 — Security of Processing # ========================================================================= - - name: ukgdpr-security-safeguards-block + - name: ukgdpr-security-safeguards-deny condition: field: output operator: matches value: "(?i)(store|transmit|log|cache).{0,30}(personal\\s+data|pii).{0,30}(unencrypted|plaintext|clear\\s*text|without\\s+encryption)" - action: block + action: deny priority: 1 - message: "UK GDPR Art. 32: personal data must be processed with appropriate technical and organisational security measures (encryption, access control)" + message: "UK GDPR Art. 32: personal data must be processed with appropriate technical and organisational security measures proportionate to risk (encryption, access control, or equivalent safeguards)" # ========================================================================= # UK GDPR Art. 5(1)(b) — Purpose Limitation # ========================================================================= - - name: ukgdpr-purpose-limitation-block + - name: ukgdpr-purpose-limitation-escalate condition: field: output operator: matches value: "(?i)(reuse|repurpose|secondary\\s+use|use\\s+for\\s+another\\s+purpose).{0,40}(personal\\s+data|pii)" - action: block + action: escalate priority: 2 - message: "UK GDPR Art. 5(1)(b): personal data must be collected for specified, explicit, legitimate purposes and not further processed incompatibly" + message: "UK GDPR Art. 5(1)(b): personal data must not be further processed incompatibly — verify compatible purpose or DUAA recognised legitimate interests before repurposing" # ========================================================================= # UK GDPR Art. 9 — Special Category Data @@ -93,7 +93,7 @@ rules: field: output operator: matches value: "(?i)(medical\\s+record|health\\s+(condition|status|data)|nhs\\s+number|genetic\\s+(data|test)|mental\\s+health|disability|prescription)" - action: block + action: escalate priority: 1 message: "UK GDPR Art. 9: health data is special category personal data — requires Art. 9(2) condition and, typically, explicit consent or Schedule 1 DPA condition" @@ -102,7 +102,7 @@ rules: field: output operator: matches value: "(?i)(ethnic\\s+origin|race|religion|political\\s+opinion|sexual\\s+orientation|trade\\s+union|criminal\\s+conviction|biometric\\s+(template|data))" - action: block + action: escalate priority: 1 message: "UK GDPR Art. 9: special category personal data detected — requires explicit consent or a Schedule 1 DPA 2018 condition" @@ -110,12 +110,12 @@ rules: # UK GDPR Art. 5(1)(c) — Data Minimisation # ========================================================================= - - name: ukgdpr-bulk-export-block + - name: ukgdpr-bulk-export-escalate condition: field: action operator: matches value: "bulk_export|export_all|dump_database|download_all_records|full_table_export|batch_download_pii" - action: block + action: escalate priority: 2 message: "UK GDPR Art. 5(1)(c): bulk personal data export — data minimisation requires documented necessity and DPO review" @@ -123,23 +123,23 @@ rules: # UK GDPR Art. 44–49 — Restricted International Transfers (DUAA 2025) # ========================================================================= - - name: ukgdpr-cross-border-language-block + - name: ukgdpr-cross-border-language-escalate condition: field: output operator: matches value: "(?i)(send(ing)?|transfer(ring)?|export(ing)?).{0,60}(outside\\s+(the\\s+)?uk|cross.?border|international\\s+transfer|third\\s+country|offshore)" - action: block + action: escalate priority: 2 - message: "UK GDPR Art. 44: restricted transfer — requires UK adequacy regulations, appropriate safeguards (IDTA/UK Addendum) plus data protection test, or Art. 49 derogation" + message: "UK GDPR Art. 44: restricted transfer language detected — verify UK adequacy, IDTA/UK Addendum safeguards, and data protection test (DUAA 'not materially lower' standard) before proceeding" - - name: ukgdpr-cross-border-action-block + - name: ukgdpr-cross-border-action-escalate condition: field: action operator: matches value: "send_to_external|export_data|upload_to_cloud|forward_to|relay_data|sync_to_remote|transfer_personal_data" - action: block + action: escalate priority: 2 - message: "UK GDPR Art. 44–46: cross-border personal data transfer requires adequacy, binding safeguards, and documented data protection test (DUAA 'not materially lower' standard)" + message: "UK GDPR Art. 44–46: cross-border transfer action — confirm adequacy coverage or binding safeguards plus documented data protection test before export" # ========================================================================= # UK Identifiers — NHS Number, National Insurance Number @@ -171,10 +171,10 @@ rules: condition: field: output operator: matches - value: "(?i)(skip|bypass|ignore|refuse).{0,30}(data\\s+protection\\s+complaint|ico\\s+complaint|subject\\s+access|dsar|right\\s+of\\s+access)" + value: "(?i)(skip|bypass|ignore|refuse).{0,30}(data\\s+protection\\s+complaint|ico\\s+complaint|complaints?\\s+(process|procedure|handling))" action: deny priority: 1 - message: "DPA 2018 s.164A (DUAA): data subjects must be able to raise complaints with the controller before ICO escalation — agent cannot bypass complaints handling" + message: "DPA 2018 s.164A (DUAA): data subjects must be able to raise data protection complaints with the controller (30-day acknowledgment) before ICO escalation — agent cannot bypass complaints handling" # ========================================================================= # UK GDPR Art. 30 — Accountability / Audit Trail @@ -187,7 +187,7 @@ rules: value: "read_user|get_customer|lookup_account|fetch_profile|query_personal|access_pii|subject_access_request" action: audit priority: 3 - message: "UK GDPR Art. 30: personal data access logged — accountability and records of processing requirement" + message: "UK GDPR Art. 5(2) / Art. 30: personal data access logged for accountability and records of processing" - name: ukgdpr-pii-modification-audit condition: @@ -196,4 +196,4 @@ rules: value: "update_user|modify_profile|patch_account|edit_customer|change_personal|erase_personal_data" action: audit priority: 3 - message: "UK GDPR Art. 30: personal data modification logged — accountability and records of processing requirement" + message: "UK GDPR Art. 5(2) / Art. 30: personal data modification logged for accountability and records of processing" From b6fc9f9f11b8391d662c666fbf483b46b77c91bc Mon Sep 17 00:00:00 2001 From: Ayo Omotayo Date: Tue, 7 Jul 2026 18:54:43 +0100 Subject: [PATCH 7/8] Addressed review feedback: replaced all 7 escalate YAML actions with block, corrected PRIN 2A.4 and Art. 33 citations, removed DPA s.67 from general processing scope, removed AU from adequacy list, dropped unused Rego schema field. Validated all 3 YAMLs and 41/41 OPA tests pass Signed-off-by: Ayo Omotayo --- examples/policies/uk-regulatory/README.md | 4 +-- .../uk-regulatory/fca-financial-conduct.yaml | 2 +- .../ico-automated-decisions.yaml | 4 +-- .../rego/fca-financial-conduct.rego | 2 +- .../rego/uk-gdpr-data-protection.rego | 8 +++--- .../uk-gdpr-data-protection.yaml | 27 +++++++++---------- 6 files changed, 23 insertions(+), 24 deletions(-) diff --git a/examples/policies/uk-regulatory/README.md b/examples/policies/uk-regulatory/README.md index 9a129a38f..1cbca3046 100644 --- a/examples/policies/uk-regulatory/README.md +++ b/examples/policies/uk-regulatory/README.md @@ -18,13 +18,13 @@ automated decision-making, and financial-sector principles-based controls. ## Regulatory context (2026) - **Data (Use and Access) Act 2025 (DUAA)** received Royal Assent on 19 June 2025. Key data-protection reforms commenced 5 February 2026, including replacement of UK GDPR Art. 22 with Arts. 22A–22D (safeguard-led automated decision-making) and updated international transfer rules using the **"not materially lower"** data protection test. -- **Breach notification** remains UK GDPR Art. 33 / DPA 2018 s.67: notify the ICO without undue delay and, where feasible, within **72 hours** when a breach is **likely to result in a risk** to rights and freedoms. Inform individuals without undue delay where the breach poses **high risk** (Art. 34). +- **Breach notification** remains UK GDPR Art. 33: notify the ICO without undue delay and, where feasible, within **72 hours** when a breach is **likely to result in a risk** to rights and freedoms. Inform individuals without undue delay where the breach poses **high risk** (Art. 34). - **Complaints procedure**: DPA 2018 s.164A (inserted by DUAA s.103) requires all controllers to maintain a formal data protection complaints procedure by **19 June 2026**. Data subjects must raise complaints with the controller before escalating to the ICO. - **FCA**: No AI-specific binding regulation as of 2026. The FCA applies its existing principles-based framework (Consumer Duty, SM&CR, operational resilience). The Mills Review reports to the FCA Board in summer 2026. ## What these rules detect (and what they do not) -Output-side rules match intent phrases (for example "store PII unencrypted", "don't report the breach", "no human review"). Cross-border transfer rules **escalate** for review rather than blanket-block when adequacy or safeguards may apply. They catch an agent that narrates or proposes a violation in its output; they do not observe the underlying system action. Treat them as a starting point, pair them with real action-level enforcement, and run your own compliance assessment. +Output-side rules match intent phrases (for example "store PII unencrypted", "don't report the breach", "no human review"). YAML policies use `block` for review/hold tiers (the Agent-OS schema supports `allow`, `deny`, `audit`, and `block` only); the Rego reference implementations may use an independent `escalate` decision tier for OPA pipelines. They catch an agent that narrates or proposes a violation in its output; they do not observe the underlying system action. Treat them as a starting point, pair them with real action-level enforcement, and run your own compliance assessment. ## Not covered (known gaps) diff --git a/examples/policies/uk-regulatory/fca-financial-conduct.yaml b/examples/policies/uk-regulatory/fca-financial-conduct.yaml index 39bfad2ba..eae27ae36 100644 --- a/examples/policies/uk-regulatory/fca-financial-conduct.yaml +++ b/examples/policies/uk-regulatory/fca-financial-conduct.yaml @@ -52,7 +52,7 @@ rules: value: "(?i)(skip\\s+fair\\s+value|bypass\\s+value\\s+assessment|no\\s+need\\s+to\\s+(check|assess)\\s+(fair\\s+)?value|ignore\\s+consumer\\s+duty)" action: deny priority: 1 - message: "FCA Consumer Duty (PRIN 2A.1): firms must ensure products and services provide fair value — agent cannot bypass value assessment" + message: "FCA Consumer Duty (PRIN 2A.4): firms must ensure products and services provide fair value — agent cannot bypass value assessment" # ========================================================================= # SM&CR — Senior Manager Accountability diff --git a/examples/policies/uk-regulatory/ico-automated-decisions.yaml b/examples/policies/uk-regulatory/ico-automated-decisions.yaml index 61e0ab320..ecfbd6d81 100644 --- a/examples/policies/uk-regulatory/ico-automated-decisions.yaml +++ b/examples/policies/uk-regulatory/ico-automated-decisions.yaml @@ -82,12 +82,12 @@ rules: priority: 2 message: "UK GDPR Art. 22A: solely automated decision with legal or similarly significant effect — verify Art. 22C safeguards and lawful basis are in place" - - name: adm-recruitment-decision-escalate + - name: adm-recruitment-decision-block condition: field: output operator: matches value: "(?i)(reject\\s+(the\\s+)?(candidate|applicant)|hire\\s+decision|shortlist|score\\s+(the\\s+)?(candidate|applicant)).{0,40}(automated|without\\s+human|ai\\s+only)" - action: escalate + action: block priority: 2 message: "ICO March 2026: automated recruitment decisions are in scope of Art. 22A — review safeguards and human oversight before proceeding" diff --git a/examples/policies/uk-regulatory/rego/fca-financial-conduct.rego b/examples/policies/uk-regulatory/rego/fca-financial-conduct.rego index 817dcd597..91e5f31ac 100644 --- a/examples/policies/uk-regulatory/rego/fca-financial-conduct.rego +++ b/examples/policies/uk-regulatory/rego/fca-financial-conduct.rego @@ -45,7 +45,7 @@ deny contains msg if { # PRIN 2A: fair value bypass deny contains msg if { regex.match(`(?i)(skip\s+fair\s+value|bypass\s+value\s+assessment|no\s+need\s+to\s+(check|assess)\s+(fair\s+)?value|ignore\s+consumer\s+duty)`, _output_text) - msg := "FCA Consumer Duty (PRIN 2A.1): firms must ensure products and services provide fair value" + msg := "FCA Consumer Duty (PRIN 2A.4): firms must ensure products and services provide fair value" } # SM&CR: accountability delegation to AI diff --git a/examples/policies/uk-regulatory/rego/uk-gdpr-data-protection.rego b/examples/policies/uk-regulatory/rego/uk-gdpr-data-protection.rego index 72c7a7a72..df57bbb36 100644 --- a/examples/policies/uk-regulatory/rego/uk-gdpr-data-protection.rego +++ b/examples/policies/uk-regulatory/rego/uk-gdpr-data-protection.rego @@ -7,7 +7,7 @@ # "params": { "destination_country": "US", "adequacy_covered": false, # "safeguards_in_place": false, "record_count": 500 }, # "output": "agent output text", -# "context": { "lawful_basis_documented": false } } +# "context": { } } package agt_policies_uk.uk_gdpr @@ -40,13 +40,13 @@ pii_update_actions := { # UK adequacy-covered destinations (illustrative — verify against current gov.uk list) adequacy_countries := { - "GB", "EU", "EEA", "US", "JP", "KR", "CA", "NZ", "AU", "CH", "IL", "UY", + "GB", "EU", "EEA", "US", "JP", "KR", "CA", "NZ", "CH", "IL", "UY", } -# Art. 33 / DPA 2018 s.67: block breach suppression +# Art. 33: block breach suppression deny contains msg if { regex.match(`(?i)(don'?t\s+(report|notify|disclose)|hide\s+(the\s+)?(breach|incident)|suppress\s+(the\s+)?(breach|notification)|delay\s+(breach|incident)\s+(report|notification))`, _output_text) - msg := "UK GDPR Art. 33 / DPA 2018 s.67: where a breach is likely to result in a risk to rights and freedoms, notify the ICO without undue delay and, where feasible, within 72 hours — agent cannot suppress or delay notification" + msg := "UK GDPR Art. 33: where a breach is likely to result in a risk to rights and freedoms, notify the ICO without undue delay and, where feasible, within 72 hours — agent cannot suppress or delay notification" } # Art. 34: block suppression of individual notification diff --git a/examples/policies/uk-regulatory/uk-gdpr-data-protection.yaml b/examples/policies/uk-regulatory/uk-gdpr-data-protection.yaml index e44a85d34..72c91ba61 100644 --- a/examples/policies/uk-regulatory/uk-gdpr-data-protection.yaml +++ b/examples/policies/uk-regulatory/uk-gdpr-data-protection.yaml @@ -16,7 +16,6 @@ # UK GDPR Art. 9 Special category data # UK GDPR Art. 32 Security of processing # UK GDPR Art. 33–34 Breach notification (72 hours to ICO; individuals if high risk) -# DPA 2018 s.67 Statutory breach notification duty # UK GDPR Art. 44–49 Restricted international transfers (DUAA "not materially lower" test) # DPA 2018 s.164A Mandatory data protection complaints procedure (DUAA s.103) # @@ -30,14 +29,14 @@ description: > special-category handling, restricted-transfer review, and complaints-procedure awareness. metadata: - source_regulation: "UK GDPR Arts. 5, 9, 32, 33–34, 44–49; DPA 2018 ss. 67, 164A; DUAA 2025" + source_regulation: "UK GDPR Arts. 5, 9, 32, 33–34, 44–49; DPA 2018 s.164A; DUAA 2025" jurisdiction: "GB" enforcing_authority: "Information Commissioner's Office (ICO)" rules: # ========================================================================= - # UK GDPR Art. 33 / DPA 2018 s.67 — Breach Notification (72 hours to ICO) + # UK GDPR Art. 33 — Breach Notification (72 hours to ICO) # ========================================================================= - name: ukgdpr-breach-suppression-deny @@ -47,7 +46,7 @@ rules: value: "(?i)(don'?t\\s+(report|notify|disclose)|hide\\s+(the\\s+)?(breach|incident)|suppress\\s+(the\\s+)?(breach|notification)|delay\\s+(breach|incident)\\s+(report|notification)|wait\\s+before\\s+report(ing)?\\s+(to\\s+)?(the\\s+)?ico)" action: deny priority: 1 - message: "UK GDPR Art. 33 / DPA 2018 s.67: where a breach is likely to result in a risk to rights and freedoms, notify the ICO without undue delay and, where feasible, within 72 hours — agent cannot suppress or delay notification" + message: "UK GDPR Art. 33: where a breach is likely to result in a risk to rights and freedoms, notify the ICO without undue delay and, where feasible, within 72 hours — agent cannot suppress or delay notification" - name: ukgdpr-breach-individual-suppression-deny condition: @@ -75,12 +74,12 @@ rules: # UK GDPR Art. 5(1)(b) — Purpose Limitation # ========================================================================= - - name: ukgdpr-purpose-limitation-escalate + - name: ukgdpr-purpose-limitation-block condition: field: output operator: matches value: "(?i)(reuse|repurpose|secondary\\s+use|use\\s+for\\s+another\\s+purpose).{0,40}(personal\\s+data|pii)" - action: escalate + action: block priority: 2 message: "UK GDPR Art. 5(1)(b): personal data must not be further processed incompatibly — verify compatible purpose or DUAA recognised legitimate interests before repurposing" @@ -93,7 +92,7 @@ rules: field: output operator: matches value: "(?i)(medical\\s+record|health\\s+(condition|status|data)|nhs\\s+number|genetic\\s+(data|test)|mental\\s+health|disability|prescription)" - action: escalate + action: block priority: 1 message: "UK GDPR Art. 9: health data is special category personal data — requires Art. 9(2) condition and, typically, explicit consent or Schedule 1 DPA condition" @@ -102,7 +101,7 @@ rules: field: output operator: matches value: "(?i)(ethnic\\s+origin|race|religion|political\\s+opinion|sexual\\s+orientation|trade\\s+union|criminal\\s+conviction|biometric\\s+(template|data))" - action: escalate + action: block priority: 1 message: "UK GDPR Art. 9: special category personal data detected — requires explicit consent or a Schedule 1 DPA 2018 condition" @@ -110,12 +109,12 @@ rules: # UK GDPR Art. 5(1)(c) — Data Minimisation # ========================================================================= - - name: ukgdpr-bulk-export-escalate + - name: ukgdpr-bulk-export-block condition: field: action operator: matches value: "bulk_export|export_all|dump_database|download_all_records|full_table_export|batch_download_pii" - action: escalate + action: block priority: 2 message: "UK GDPR Art. 5(1)(c): bulk personal data export — data minimisation requires documented necessity and DPO review" @@ -123,21 +122,21 @@ rules: # UK GDPR Art. 44–49 — Restricted International Transfers (DUAA 2025) # ========================================================================= - - name: ukgdpr-cross-border-language-escalate + - name: ukgdpr-cross-border-language-block condition: field: output operator: matches value: "(?i)(send(ing)?|transfer(ring)?|export(ing)?).{0,60}(outside\\s+(the\\s+)?uk|cross.?border|international\\s+transfer|third\\s+country|offshore)" - action: escalate + action: block priority: 2 message: "UK GDPR Art. 44: restricted transfer language detected — verify UK adequacy, IDTA/UK Addendum safeguards, and data protection test (DUAA 'not materially lower' standard) before proceeding" - - name: ukgdpr-cross-border-action-escalate + - name: ukgdpr-cross-border-action-block condition: field: action operator: matches value: "send_to_external|export_data|upload_to_cloud|forward_to|relay_data|sync_to_remote|transfer_personal_data" - action: escalate + action: block priority: 2 message: "UK GDPR Art. 44–46: cross-border transfer action — confirm adequacy coverage or binding safeguards plus documented data protection test before export" From 8c8e5706f2d2c2183f30f6126a6a0b7630fc1cf7 Mon Sep 17 00:00:00 2001 From: Ayo Omotayo Date: Wed, 8 Jul 2026 08:56:03 +0100 Subject: [PATCH 8/8] chore(spell): add UK policy terms for cspell check Signed-off-by: Ayo Omotayo --- .cspell-repo-terms.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.cspell-repo-terms.txt b/.cspell-repo-terms.txt index 818409fc8..6a6e1061d 100644 --- a/.cspell-repo-terms.txt +++ b/.cspell-repo-terms.txt @@ -874,3 +874,19 @@ tcpdump isascii multisink writeln +DUAA +PRIN +PECR +DSPT +Caldicott +SYSC +Organisations +vulnerabilit +foreseeably +DPIA +dpia +minimisation +ukgdpr +organisational +Minimisation +IDTA