Data Residency & Customer-Managed Keys
Two per-agent controls for teams with a regulatory constraint on where their prompts go and who can decrypt what the gateway keeps. Both fail closed. If the gateway cannot prove a destination is in your region, or cannot obtain your key, it refuses the request — it does not fall back to a global endpoint or to a KnoxCall-held key.Set both on the agent, not the gateway: a team usually has one gateway and
several agents, and residency is a property of the workload, not the container.
Data residency
Setdata_residency_region on an agent to one of us, eu, uk, ca, au,
jp, in.
/v1/ai data plane —
the primary route, every fallback route, the output-schema retry, the
semantic-cache embedder, and your PII analyzer sidecar if you have configured one
— must target an endpoint KnoxCall classifies as serving that region. Anything
else is refused with 403 residency_violation before that call is made.
The fallback path is the one that matters. An unpinned failover is exactly how a
Frankfurt workload ends up in us-east-1 at 3am: the primary 5xxs, the gateway
does what it was configured to do, and nothing in the request looks wrong
afterwards. A pinned agent skips an out-of-region fallback and surfaces the
primary’s error instead.
What KnoxCall classifies
What it refuses, deliberately
What this control is, precisely
It is an administrative control on destination selection. A pinned agent may only egress to endpoints KnoxCall has classified as serving the pinned region. It stops misconfiguration and silent drift, which is the failure mode that actually produces residency incidents. It is not a cryptographic or network guarantee: if you point your own route at a host you have classified in-region and it is not, you are exporting your own data and no gateway can stop that. Every vendor’s “data residency” feature is this control. Ours says so.Auditing it
Eachai_gateway_usage row records the region the agent was pinned to at the
time of that call, so a residency audit reads evidence rather than the agent’s
current configuration. It is returned by the usage export alongside cost and
attribution.
Customer-managed encryption keys (CMEK)
Setcmek_key_id on an agent to the id of one of your tenant master keys. That
agent’s PII token map — the reversible map behind streaming PII
redaction, which holds the original values — is then
encrypted under that key rather than the tenant’s current active key.
Prerequisite: BYOK
cmek_key_id must name a key whose wrap_method is customer_kms — a key your
own AWS/GCP/Azure KMS wraps. See Bring your own key.
A key KnoxCall wraps is refused, with 503 cmek_unavailable. This is the
load-bearing check: without it, “CMEK enabled” could resolve to a
platform-wrapped key and you would have a green checkbox and no custody.
What happens when the key is unavailable
Every one of these refuses the data-plane request with503 cmek_unavailable:
- the key does not exist, or is not this tenant’s;
- the key is not customer-managed;
- your tenant has no active master key;
- your tenant’s active key is no longer customer-managed (you rotated off BYOK);
- your KMS refuses to unwrap it (a revoked grant, a disabled key, an outage).
Reads are not gated. A KnoxCall envelope names its own key version, so rows
written before you attached a CMEK still decrypt. Refusing to read them would
destroy data you are entitled to see. Re-wrapping history under a new key is the
BYOK rewrap sweep’s job, not this setting’s.
Key rotation
cmek_key_id names your customer-managed key chain, not one frozen version.
Rotating your tenant master key the normal way keeps the agent working: writes
follow whatever version of that chain is currently active. What is refused is a
chain that stops being customer-managed — if you rotate back onto KnoxCall’s
platform wrap, the agent refuses rather than silently accepting a key we can
unwrap.
Scope today
CMEK covers the agent’s PII token map — the reversible(surrogate → original) store, which is the one place the gateway durably holds your original
values.
Two honest limitations:
- The response cache is not encrypted at all.
ai_gateway_cache_entriesstores response bodies as plain bytes, and the buffered path caches AFTER detokenization — so for an agent withpii_detokenize_responseon, the original values would sit in that table in the clear for the cache TTL. Rather than leave that beside a customer-managed key, an agent with acmek_key_iddoes not use the response cache at all. You lose the cache; you do not lose custody. - The MCP plane’s stored configuration (
ai_gateway_mcp_servers) is not covered. Its upstream credentials are envelope-encrypted through the normal tenant key — customer-managed too when BYOK is configured for the tenant — but they do not follow the per-agent pin.