Skip to main content

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

Set data_residency_region on an agent to one of us, eu, uk, ca, au, jp, in.
From then on, every upstream call this agent makes on the /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 /v1/mcp plane is not covered yet. An MCP server’s upstream_url is dialled without a residency check, so tool-call arguments and results from an agent’s MCP tools can leave the region even when the agent is pinned. If you are pinning for a regulatory reason, do not attach MCP servers to that agent until this lands. Tracked as AIGW-77.
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

Unclassifiable means refused. The three global endpoints above are exactly the hosts most likely to be left in a route by accident, so “unknown = allow” would make the pin decorative. If you need an endpoint we do not classify, open a ticket — we would rather add a documented rule than have you turn the pin off.

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

Each ai_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)

Set cmek_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 with 503 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).
Nothing is written under a different key, and nothing is written in the clear. Revoking the grant in your KMS therefore stops the agent within the key-cache TTL — five minutes for BYOK keys — which is the same revocation contract the rest of BYOK carries.
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_entries stores response bodies as plain bytes, and the buffered path caches AFTER detokenization — so for an agent with pii_detokenize_response on, 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 a cmek_key_id does 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.