Data Residency Policy
The data-residency policy category restricts agent execution to one or more approved regions for data-sovereignty compliance. Runs that report an execution_region outside the allowlist are blocked.
This is observe-side enforcement (post-hoc audit) by nature -- the actual pinning of execution to a region happens at the infrastructure layer (ECS task placement, region-locked endpoints). The policy fires when a run reports an execution region outside the allowed set, surfacing the violation in audit + alerting.
Aligned to ISO 42001 A.8.4 (data residency control), GDPR (cross-border transfer restrictions), and EU AI Act (regional deployment obligations).
Rules
| Rule | Type | Default | Description |
|---|---|---|---|
allowed_regions | string[] | [] | Region identifiers (case-insensitive) where execution is permitted |
require_region_declaration | boolean | true | Block runs that lack an execution_region declaration |
action_on_violation | string | "block" | Action on violation: "block" or "warn" |
How It Works
The data-residency handler runs at before_workflow, mid_execution, and after_workflow. It compares context.execution_region (case-insensitive) against the allowed_regions list.
Decision Flow
- No
execution_regiondeclared +require_region_declaration = true→BLOCK(signal:no_region_declared) - No
execution_regiondeclared +require_region_declaration = false→ALLOW - Empty
allowed_regions+require_region_declaration = true→BLOCK(signal:no_allowed_regions, acts as a kill-switch) - Empty
allowed_regions+require_region_declaration = false→ALLOW - Region not in allowlist →
BLOCK(signal:region_not_allowed) - Region in allowlist →
ALLOW
Context Attributes Read
| Attribute | Phase | Purpose |
|---|---|---|
context.execution_region | all | Region identifier reported by the runtime (e.g., "eu-west-1") |
Example Policy
EU-Only Residency
{
"allowed_regions": ["eu-west-1", "eu-central-1", "eu-north-1"],
"require_region_declaration": true,
"action_on_violation": "block"
}
Kill-Switch Mode
Empty allowlist + required declaration blocks all runs. Useful as a regional kill-switch during incident response:
{
"allowed_regions": [],
"require_region_declaration": true,
"action_on_violation": "block"
}
SDK Integration
import waxell_observe as waxell
waxell.init()
@waxell.observe(agent_name="eu-claims-agent", enforce_policy=True)
async def process_eu_claim(claim: dict) -> dict:
return await adjudicate(claim)
The runtime is responsible for setting context.execution_region. For ECS deployments this typically comes from the AWS metadata service; for k8s it comes from the node label.
Observability
| Field | Example |
|---|---|
| Category | data-residency |
| Action | block |
| Reason | "Execution region 'us-east-1' not in approved list ['eu-central-1', 'eu-west-1']." |
| Metadata | {"signal": "region_not_allowed", "execution_region": "us-east-1", "allowed_regions": ["eu-central-1", "eu-west-1"], "iso_42001": "A.8.4"} |
Common Gotchas
-
Region comparison is case-insensitive.
"EU-West-1","eu-west-1", and"Eu-West-1"all match["eu-west-1"]. The handler lowercases both sides. -
Post-hoc enforcement only. This policy detects runs in the wrong region; it does not prevent them from starting. Actual pinning requires infrastructure controls (ECS region constraints, region-locked endpoints, VPC peering rules). Pair this policy with infra-level region pins.
-
Empty allowlist + required declaration = kill switch. This is intentional -- it lets you flip residency off globally with a single config change. Don't accidentally ship an empty allowlist in production unless you mean it.
-
context.execution_regionmust be populated by the runtime. Custom runtimes that omit this attribute will trigger theno_region_declaredblock whenrequire_region_declaration = true. Wire your runtime to set it from the AWS/k8s metadata. -
Same policy fires three times per run. The handler runs at
before_workflow,mid_execution, andafter_workflow. Audit will show three entries for blocked runs -- this is intentional (detects mid-flight region migrations) but can be noisy. -
Cross-region telemetry shipping is NOT covered. This policy only governs agent execution. If your telemetry pipeline ships logs from
eu-west-1to a US-hosted Tempo, that data movement is outside this policy's scope -- govern it withdata-accessand infra controls.
Next Steps
- Privacy Policy -- PII detection (foundational to GDPR compliance)
- Compliance Policy -- Meta-validator for ISO 42001 / GDPR / EU AI Act
- Data Access Policy -- Source allowlists (often paired with regional restrictions)
- Kill Switch Policy -- Emergency stop independent of region
- Policy Categories -- All categories