EU data residency
Definition
EU data residency is the guarantee that a gateway processes model data only inside the European Union. A gateway that is put into EU-region routing mode serves a request only when the resolved provider and region are EU-hosted; any other route is refused.
Function
EU-region routing exists for deployments where model data must stay in the EU, such as regulated and public-sector tenants. When the residency floor is armed, the gateway fails closed: a request whose provider or region is not EU-hosted is rejected with HTTP 403 (data_residency_blocked) before any upstream call, so the request never reaches a non-EU endpoint.
The floor is off by default. It is armed per gateway (eu_region_routing), armed organisation-wide from Settings → Organisation → Routing (a floor no gateway can go below), or set deployment-wide on a sovereign stack.
Rules and facts
- Every dispatch path is covered. The check sits at the single upstream dispatch point, so the same refusal applies to the primary request, every failover attempt, each tool-loop leg, and the agentic-fetch call. The conversation-summary (compaction) call is the one exception to "single point": it dispatches on its own, and reaches the same verdict by calling the same shared gate rather than by passing through that point. One consequence is worth knowing: the observed-host re-check described below lives at the dispatch point, so it does not apply to the compaction call — a compaction routed to
myrais checked before dispatch but not re-checked against the host that actually served it. - The observed upstream host is re-checked, not just the picked provider. The self-hosted EU fleet (provider
myra) is fronted by a router that can transparently overflow a saturated in-house model group to a cloud fallback (for example a US endpoint). That overflow is invisible to the pre-dispatch provider check, which vouchesmyraas EU. After a successful response, the gateway therefore re-evaluates the host the request was actually served from (reported by the upstream): on an armed gateway a non-EU observed host is refused with the same403 data_residency_blockedbefore any answer bytes reach the client. Because this specific overflow is a TRANSIENT in-house capacity condition (not a static misconfiguration), the gateway retries the same route a bounded number of times (the gateway's normalretry_count, with backoff between attempts) before failing over to the next EU route or, absent one, surfacing the403— a static pre-dispatch refusal (a genuinely non-EU/non-allowlisted provider) is never retried, only this post-hoc overflow case. This retry never counts against the shared myra health/circuit-breaker signal: myra itself answered successfully, it only routed off-EU for this residency-armed gateway, so a saturation window on one such gateway cannot trip the (fleet-wide, cross-tenant) breaker for every other gateway on the myra fleet. The observed host is untrusted upstream data — a host that cannot be positively vouched as EU is treated as non-EU (fail closed). The positive-EU host set defaults to the Myra fleet domain and is configurable per deployment by your operator (a list of DNS suffixes; private/loopback IPs are always treated as EU). - Operational requirement (armed gateways). Because the observed-host check fails closed, an EU upstream node on an armed gateway MUST be reported by the router under a recognized EU DNS suffix (the default
.myra.eu, or a suffix your operator adds to the deployment's positive-EU host set). A legit EU node addressed by a bare public IP or an unlisted internal hostname classifies as unvouchable and is refused — your operator must add its suffix to that set. This trade-off is deliberate: an unrecognized host is never silently trusted. A refused observed host is logged ([residency_egress_block]) so a misconfiguration is distinguishable from a genuine overflow. - Web search is forced through the EU path. Under the floor, a non-EU search backend is blocked and provider-native search is routed through the gateway EU two-leg. An armed gateway can turn web search off, but never falls back to a non-EU search backend.
- Model-slug search is guaranteed off only under the armed floor. Web search that is intrinsic to a model name (for example OpenAI
gpt-*-search-preview, Groqcompound, Perplexitysonar) runs on the model's own server regardless of any request knob, so the gateway cannot strip it. Under the armed floor this is a non-issue — such a model is a non-EU provider and is dispatch-blocked before it runs. But a gateway that only configures an EU search provider (web_search.provider: "linkup") without armingeu_region_routingdoes not dispatch-block the model, so agpt-*-search-previewrequest still reaches its US backend for the whole request. Pair the EU search provider with the armed residency floor for full sovereignty; configuring linkup alone is not sufficient. See Web search — EU data residency. - Per-tenant region selection. A tenant carries a default EU region for AWS Bedrock and Google Vertex, inherited by every gateway under it that sets no region of its own. Regions are validated as EU-member regions at the trust boundary, independent of whether enforcement is on.
- Embeddings and image generation are served only by the on-premise Myra EU fleet.
Residency evidence (per-request jurisdiction)
Independently of whether the floor is armed, every model dispatch records the jurisdiction it actually ran in, as immutable evidence for data-localization reporting. Each request-log leg carries a residency zone, resolved and frozen at dispatch time:
eu— the model dispatch was positively EU-vouched (identical to the fail-closed dispatch guarantee: an EU provider, or an EU Bedrock/Vertex/Azure region, with a Bedrock model pinned to a single EU-27 region). When the upstream reports the host it actually served from, the recorded zone reflects that observed host — so a request the picked EU provider transparently overflowed to a non-EU cloud fallback is recorded asnon_eu(orunknown), never laundered toeu. This honesty applies on every gateway, including one that does not arm the residency floor, so the compliance export always reflects the real egress.non_eu— a positively known non-EU host (a US provider or SaaS, DeepSeek in China, a US Bedrock/Vertex region, or an Azure non-EU region).non_euspans the US and China; the per-provider breakdown remains available.unknown— the jurisdiction cannot be proven at dispatch: opaque or variable routing (OpenRouter), a Bedrock cross-region inference profile that cannot be proven to stay within the EU-27, a per-gateway base-URL override to an unvouchable host, an Azure route with no region asserted, or a region-configurable/self-hosted provider (Hugging Face, custom).unknownis counted as not EU-clean in the report, so it never under-states egress.- empty — the leg was not a residency-bearing leg (a guardrail or PII leg), or the request was residency-blocked before any dispatch. Such requests are neither EU-clean nor non-EU.
The zone is frozen at dispatch and never recomputed from the current gateway configuration — unlike the model hosting label, which is a mutable display value. It is server-authoritative: a client cannot influence the zone recorded for its own request.
Search-egress jurisdiction (second axis)
The model-generated web-search query egresses to a separate backend on its own jurisdiction axis. Every gateway-path web-search egress now records its own residency-zoned leg (kind = web_search_query), zoned by the search provider rather than the model:
eu— an EU-vouched search backend (linkup, France; SOC 2 II, Art. 28 DPA, zero-retention).non_eu— any other search backend, including the historical Brave (US) default and any unrecognized provider (fail-closed).
The zone is recorded on every egress attempt — a search whose queries all failed still egressed the query text to the backend, so it still leaves an evidence leg (only a fully withheld/residency-blocked search, where nothing left the gateway, records nothing). This is orthogonal to billing: Brave stays unmetered as before; the leg is evidence, not a charge.
Under the EU floor, web search is forced through the gateway EU two-leg (linkup), so on an armed gateway the search axis is always eu. On a non-enforced gateway a model may instead run its own provider-native web search — Anthropic web_search, Gemini/Vertex googleSearch grounding, the OpenRouter web plugin, or the Mistral Agents web_search tool. Each of these now records its own kind = web_search_query residency leg, zoned by the native backend, so that egress is no longer invisible:
non_eu— every provider-native backend today (none is EU-vouched: Anthropic and Gemini/Vertex search on US infrastructure, OpenRouter's plugin falls back to a US provider, and Mistral's Agentsweb_searchuses a non-EU search subprocessor).
The native-search leg is captured from the final outbound request, so it covers both search the gateway enabled from a request header/config and a native search directive a client supplied directly (a raw Anthropic web_search tool, an OpenRouter plugins:[{id:"web"}] or :online model slug, a Gemini web_search marker). It is evidence only — never billed and never counted in the model token totals.
Mistral is two axes at once, deliberately kept apart. A Mistral request that uses native web search records a model leg zoned eu (the model ran on Mistral's EU host) and a separate web_search_query leg zoned non_eu (its search subprocessor is not EU-vouched). The two are never merged: the model-host zone stays truthful, and the search-egress zone still marks the request as not EU-clean.
💡 Note: The full, current list of subprocessors — including the search and model backends named above and where they process data — is published in Myra's public Trust Center at
/trust, with a downloadable subprocessor register. See Subprocessors.
One documented residual remains: OpenAI model-slug search (web_search_options / gpt-*-search-preview), where the search is intrinsic to the model name and cannot be detected as a distinct request-side directive. It is guaranteed off only under the armed floor (the model is a non-EU provider and is dispatch-blocked); on a non-enforced gateway it is not captured as a distinct leg.
The per-request verdict folds a request's residency-bearing legs worst-case: any non_eu or unknown leg (model or search) makes the whole request not EU-clean.
Cross-links
- Configuration reference — Data residency — the full configuration, the EU-hosted allowlist, and the EU-27 model list.
- Tenants and gateways API — Per-tenant cloud region — setting the tenant Bedrock and Vertex regions.
- AWS Bedrock — the EU-region Bedrock routes.
- Web search — forced gateway search under the EU floor.