An EU inference profile only keeps your data in the EU if nobody can
call anything else. If a developer swaps one model ID for a global.
profile, processing leaves the EU, and by default nothing in Bedrock
stops them.
The fix comes in two layers. IAM policies decide which profiles each role can call. Service control policies (SCPs) enforce the same rule across every account in your organisation. In this post I’ll walk through both, plus the mistake that most often breaks EU routing: blocking a Region the profile needs. It builds on Can You Use Claude Without Sending Prompts and Responses Outside the EU?
How Bedrock checks a cross-Region call
A single call to an EU profile gets authorised several times: once for the inference profile, once for the model in your source Region, and once for the model in each Region the request could be sent to (AWS: Geographic cross-Region inference). Every one of those checks has to pass, in IAM and in your SCPs.
Give each application role access to specific EU profiles and nothing more. The policy below follows AWS’s documented pattern for geographic profiles, but treat it as illustrative until you have tested it in your own sandbox. The exact resources and conditions depend on the model, source Region and profile you approve.
- Block one destination Region and the whole call fails. If an SCP denies Bedrock in any Region the profile can route to, the request fails, even if every other Region is allowed (AWS ML blog). In organisations with Region-deny SCPs, this is the most common reason people think EU routing “doesn’t work”.
- The
bedrock:InferenceProfileArncondition key is what makes this manageable. It’s set on the model checks, which carry the destination Regions, but not on the profile check. So you can allow model access only when it comes through an approved profile, and exempt that routing from a Region-deny SCP without opening those Regions to anything else (AWS: Geographic cross-Region inference).
Layer 1: IAM allows only the approved EU profile
Give each application role access to specific EU profiles and nothing more. The policy below lets a role call Claude Sonnet 5 through the EU profile from Frankfurt, and use the underlying model only when the request comes through that profile. It follows the pattern AWS documents for geographic profiles (AWS: Prerequisites for inference profiles).
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowApprovedEuProfile",
"Effect": "Allow",
"Action": ["bedrock:InvokeModel", "bedrock:InvokeModelWithResponseStream"],
"Resource": "arn:aws:bedrock:eu-central-1:111122223333:inference-profile/eu.anthropic.claude-sonnet-5"
},
{
"Sid": "AllowModelOnlyThroughEuProfile",
"Effect": "Allow",
"Action": ["bedrock:InvokeModel", "bedrock:InvokeModelWithResponseStream"],
"Resource": "arn:aws:bedrock:*::foundation-model/anthropic.claude-sonnet-5",
"Condition": {
"StringEquals": {
"bedrock:InferenceProfileArn": "arn:aws:bedrock:eu-central-1:111122223333:inference-profile/eu.anthropic.claude-sonnet-5"
}
}
}
]
}
A few notes on using it:
- Replace the account ID and source Region with your own. System-defined profile ARNs include your account ID.
- The wildcard Region on the model is safe here. The condition only
allows access through the EU profile, and that profile can only route
to its fixed list of destinations. If your auditors would rather see
explicit Regions, list the ones
get-inference-profilereturns. ConverseandConverseStreamare covered too, because Bedrock authorises them throughbedrock:InvokeModelandbedrock:InvokeModelWithResponseStream.
Repeat both statements for every model you approve, and keep that list short. Each approved model is one more thing to recheck when models change.
Layer 2: SCPs enforce it across the organisation
IAM protects the roles you write policies for. An SCP protects every role in every account under an organisational unit, including the ones someone creates next month. Two rules do the work.
Deny Global routing outright. AWS documents denying requests where
aws:RequestedRegion equals unspecified as the way to block Global
profiles (AWS: Prerequisites for inference
profiles).
I’d also deny the global. profile ARNs directly, so anyone reading the
policy can see what it’s for. Doing both costs nothing.
Deny unapproved Regions, but let EU routing through. Many
organisations allow only one or two EU Regions, while an EU profile
routes across six or more. Exempting calls that come through an approved
bedrock:InferenceProfileArn lets the profile reach its destinations
without opening those Regions for anything else. The exemption doesn’t
apply to the originating call, so requests still have to start in an
allowed Region (AWS: Geographic cross-Region
inference).
A useful side effect: nobody can call the EU profile from London or
Zurich.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyGlobalBedrockRouting",
"Effect": "Deny",
"Action": "bedrock:InvokeModel*",
"Resource": "*",
"Condition": {
"StringEquals": { "aws:RequestedRegion": "unspecified" }
}
},
{
"Sid": "DenyGlobalBedrockProfiles",
"Effect": "Deny",
"Action": "bedrock:InvokeModel*",
"Resource": "arn:aws:bedrock:*:*:inference-profile/global.*"
},
{
"Sid": "DenyOutsideApprovedRegionsExceptEuProfiles",
"Effect": "Deny",
"Action": "*",
"Resource": "*",
"Condition": {
"StringNotEquals": { "aws:RequestedRegion": ["eu-central-1", "eu-west-1"] },
"ArnNotLike": { "bedrock:InferenceProfileArn": "arn:aws:bedrock:*:*:inference-profile/eu.*" }
}
}
]
}
Please don’t paste the third statement in as it is. Real Region-deny
SCPs exempt global services such as IAM, Organizations and Support,
usually with NotAction. Merge the ArnNotLike condition into the
Region-deny SCP you already have, following AWS’s example (AWS ML
blog).
If you use AWS Control Tower, use its OU Region-deny control or
Customizations for Control Tower rather than editing its SCPs, so you
don’t cause drift.
Don’t forget the second endpoint
Everything above covers the bedrock-runtime endpoint. Newer Claude
models are also served through bedrock-mantle, which uses a different
IAM action: bedrock-mantle:CreateInference (Anthropic: Claude in
Amazon
Bedrock).
A role with that permission isn’t affected by any of your
bedrock:InvokeModel rules.
It’s also where single-Region inference lives for models like Claude
Sonnet 5. AWS says to use bedrock-mantle with the bare model ID when
you need single-Region processing, and for Sonnet 5 that’s available in
Stockholm and Ireland within the EU (AWS: Claude Sonnet 5 model
card).
If you use it, allow the action only in those Regions:
{
"Sid": "AllowMantleInRegionOnly",
"Effect": "Allow",
"Action": "bedrock-mantle:CreateInference",
"Resource": "*",
"Condition": {
"StringEquals": { "aws:RequestedRegion": ["eu-west-1", "eu-north-1"] }
}
}
Then narrow Resource down to your approved model ARNs. I haven’t
confirmed how aws:RequestedRegion behaves for Global calls on
bedrock-mantle, so test that a Global call fails before relying on
this. If you don’t use bedrock-mantle at all, deny bedrock-mantle:*
in your SCP and the question goes away.
Test it
A policy you haven’t tested is a guess. Run these calls with an application role and keep the results with the date. They’re your evidence that the controls work.
| Call | Expected result |
|---|---|
eu. profile from Frankfurt | Succeeds |
global. profile from Frankfurt | AccessDenied |
us. profile from Frankfurt | AccessDenied |
eu. profile from London (eu-west-2) | AccessDenied (Region not allowed) |
Bare model ID on bedrock-mantle in Ireland | Succeeds, if you approved it |
Global call on bedrock-mantle | AccessDenied |
Unapproved model through an eu. profile | AccessDenied |
For the calls that succeed, check the CloudTrail event as described in How to Verify Where Claude Processed Your Request with AWS CloudTrail. For the ones that fail, the error message says which type of policy blocked the call, so you can see the right layer is doing its job.
What these policies don’t cover
- Other services. Knowledge bases, agents, S3 and vector stores need their own Region controls.
- New models. Each approved model needs its own statements, so
recheck the profile’s destinations with
get-inference-profilebefore adding one. - What goes into the prompt. IAM controls where a request can be processed, not what’s in it. Your data classification rules still decide what can be sent at all.
Need a second pair of eyes on the controls?
Wolkn Minds can design the IAM and SCP layer, test the allowed and denied paths in a sandbox, and turn the results into evidence your security team can keep.

