Skip to main content

Compliance Policy

The compliance policy category is a meta-validator -- it doesn't inspect agent behavior. Instead, it verifies that other required policy categories are active and properly configured before letting the agent run.

Use it when you need to enforce regulatory frameworks (HIPAA, SOC 2, PCI-DSS, GDPR) that require a constellation of policies to be in place.

Rules

RuleTypeDefaultDescription
profilestring"Custom"Label for the compliance framework: HIPAA, SOC 2, PCI-DSS, GDPR, or Custom. Used in reason strings only
required_categoriesstring[][]Policy categories that must be active (e.g. ["audit", "content", "privacy"])
required_rulesobject{}Per-category rule constraints (e.g. {"audit": {"retention_days": 2555}})
strictbooleantruetrue blocks on violation, false warns and lets the agent continue

How It Works

The compliance handler runs at before_workflow only. It reads active_policies -- a dict of {category: merged_rules} that the policy manager injects before evaluation. This dict contains all policies that apply to the current context (matching agent name, user, group, etc.).

Evaluation Steps

  1. If required_categories is empty, return ALLOW immediately (nothing to check)
  2. For each required category, check if it exists in active_policies
  3. For present categories, validate each entry in required_rules:
    • Nested dicts: recursive key equality check (e.g. pii_detection.enabled)
    • Numeric values: >= comparison (actual must be >= required)
    • All other types: exact != equality
  4. Missing categories or rule violations produce BLOCK (strict) or WARN (non-strict)

Rule Matching

Required RuleActive RuleMatch?Why
retention_days: 2555retention_days: 2555YesExact match
retention_days: 2555retention_days: 3650Yes3650 ≥ 2555 (numeric comparison)
retention_days: 2555retention_days: 90No90 < 2555
log_inputs: truelog_inputs: trueYesExact match
log_inputs: truelog_inputs: falseNofalse != true
pii_detection: {enabled: true}pii_detection: {enabled: true}YesNested key match
pii_detection: {enabled: true}pii_detection: {enabled: false}NoNested value mismatch
pii_detection: {enabled: true}pii_detection: "basic"NoExpected dict, got string
Numeric Rules Use >= Comparison

A retention_days of 3650 satisfies a requirement of 2555. The compliance handler checks that the actual value meets or exceeds the required minimum. This means stricter configurations always pass.

Profile Presets

The profile field is a label used in reason strings. Common profiles and their typical required categories:

ProfileTypical Required CategoriesKey Rules
HIPAAaudit, content, privacy, data-accessaudit.retention_days >= 2555, content.pii_detection.enabled: true
SOC 2audit, safety, kill, operationsaudit.log_inputs: true, safety.max_steps configured
PCI-DSSaudit, content, network, data-accessaudit.retention_days >= 365, network restrictions
GDPRprivacy, content, auditprivacy.require_consent: true, content.pii_detection.enabled: true
Custom(your choice)(your rules)

These are recommendations -- you configure the actual required_categories and required_rules to match your compliance needs.

Example Policies

HIPAA Compliance

Require audit, content, and privacy policies with specific settings:

{
"profile": "HIPAA",
"required_categories": ["audit", "content", "privacy"],
"required_rules": {
"audit": {
"log_inputs": true,
"retention_days": 2555
},
"content": {
"pii_detection": {
"enabled": true
}
}
},
"strict": true
}

SOC 2 Compliance

Require operational safety policies:

{
"profile": "SOC 2",
"required_categories": ["audit", "safety", "kill", "operations"],
"required_rules": {
"audit": {
"log_inputs": true
}
},
"strict": true
}

Custom Framework

Minimal compliance -- just ensure audit logging is active:

{
"profile": "Custom",
"required_categories": ["audit"],
"required_rules": {
"audit": {
"retention_days": 365
}
},
"strict": false
}

SDK Integration

Using the Context Manager

import waxell_observe as waxell
from waxell_observe.errors import PolicyViolationError

waxell.init()

try:
async with waxell.WaxellContext(
agent_name="auditor",
enforce_policy=True,
) as ctx:
# If compliance policy is active and required sibling
# policies are missing → PolicyViolationError raised here
# (before any agent work happens)

result = await analyze_data(query)
ctx.set_result(result)

except PolicyViolationError as e:
print(f"Compliance block: {e}")
# e.g. "Compliance profile 'HIPAA' not met: Missing categories: privacy"

Using the Decorator

@waxell.observe(
agent_name="auditor",
enforce_policy=True,
)
async def run_audit(query: str):
# Compliance check happens before this function body runs
return await analyze_data(query)

Enforcement Flow

Agent starts (WaxellContext.__aenter__ or decorator entry)

└── before_workflow governance runs

├── Compliance handler reads active_policies

├── required_categories empty? → ALLOW (nothing to check)

├── For each required category:
│ ├── Category missing from active_policies? → violation
│ └── Category present? → check required_rules
│ ├── Nested dict? → recursive key check
│ ├── Numeric? → actual >= required?
│ └── Other? → exact equality

├── Any violations?
│ ├── strict=true → BLOCK (PolicyViolationError)
│ └── strict=false → WARN (agent continues)

└── All checks pass → ALLOW

The compliance handler only runs at before_workflow. There is no mid-execution check. The after_workflow phase is a stub that always returns ALLOW with an attestation pass.

Creating via Dashboard

  1. Navigate to Governance > Policies
  2. Click New Policy
  3. Select category Compliance
  4. Set the profile (HIPAA, SOC 2, etc.)
  5. Configure required categories and required rules
  6. Set scope to target specific agents (e.g., compliance-agent)
  7. Enable

Then create the sibling policies that the compliance policy requires (audit, content, privacy, etc.) with the same agent scope.

Creating via API

# Create the compliance policy
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
https://acme.waxell.dev/waxell/v1/policies/ \
-d '{
"name": "HIPAA Compliance",
"category": "compliance",
"rules": {
"profile": "HIPAA",
"required_categories": ["audit", "content", "privacy"],
"required_rules": {
"audit": {"log_inputs": true, "retention_days": 2555},
"content": {"pii_detection": {"enabled": true}}
},
"strict": true
},
"scope": {
"agents": ["auditor"]
},
"enabled": true
}'

# Create the required sibling policies
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
https://acme.waxell.dev/waxell/v1/policies/ \
-d '{
"name": "Full Audit Logging",
"category": "audit",
"rules": {"log_inputs": true, "retention_days": 2555},
"scope": {"agents": ["auditor"]},
"enabled": true
}'

Observability

Governance Tab

Compliance evaluations appear with:

FieldExample
Policy nameHIPAA Compliance
Actionallow, warn, or block
Categorycompliance
Reason"Compliance profile 'HIPAA' requirements met"
Metadata{"profile": "HIPAA", "categories_verified": ["audit", "content", "privacy"]}

For violations:

FieldExample
Reason"Compliance profile 'HIPAA' not met: Missing categories: privacy | Rule violations: audit.retention_days: 90 below required 2555"
Metadata{"profile": "HIPAA", "missing_categories": ["privacy"], "rule_violations": ["audit.retention_days: 90 below required 2555"]}

After-Workflow Attestation

The after_workflow phase always returns ALLOW with {"attestation": "pass"}. This is a stub for future compliance attestation features.

Common Gotchas

  1. Compliance doesn't monitor agent behavior. It validates that the right policies exist. To govern what agents actually do, use the specific category policies (code-execution, communication, content, etc.).

  2. Empty required_categories means always ALLOW. A compliance policy with no required categories is a no-op. Always specify at least one category to check.

  3. strict: false means warn-only. The agent still runs even when required policies are missing. Use strict mode for production compliance enforcement.

  4. Numeric rules use >= comparison. A retention_days of 3650 satisfies a requirement of 2555. Stricter configurations always pass.

  5. Multiple policies of the same category merge via dict.update(). If two audit policies exist, their rules are merged and the last one wins for conflicting keys. Be careful with overlapping policies.

  6. after_workflow is a stub. It always returns ALLOW with an attestation pass. Don't rely on it for enforcement.

  7. Only runs at before_workflow. Compliance blocks happen before the agent does any work. There is no mid-execution compliance check.

  8. The profile field is just a label. Setting profile: "HIPAA" doesn't automatically enforce HIPAA rules -- you must configure required_categories and required_rules yourself.

Next Steps