对于金融、医疗和公共部门团队,“数据留在英国”往往还不够。更严格的控制要求是:Claude Code 的每一次模型推理都只能在指定的 AWS 区域内完成,例如伦敦区域 eu-west-2,不能由跨区域推理机制转发到其他区域。
在 Amazon Bedrock 上,可以采用两条路径实现这种约束:使用单区域应用推理配置文件,或者让 Claude Code 连接指定区域的 Mantle 端点。无论选择哪一种,都应再用 IAM 的区域条件建立强制边界,并通过 AWS CloudTrail 验证实际调用发生在哪里。
“客户端设置了伦敦”为什么还不够
只设置下面的环境变量,只能表达客户端的区域选择:
export CLAUDE_CODE_USE_BEDROCK=1
export AWS_REGION=eu-west-2
export AWS_DEFAULT_REGION=eu-west-2
它不能单独构成完整的合规控制。模型标识可能指向跨区域推理配置文件,开发者也可能覆盖环境变量,CI 任务还可能使用另一套 AWS 配置。
因此,单区域方案至少要覆盖三层:
- 路由层:使用单区域应用推理配置文件,或伦敦区域的 Mantle 端点。
- 授权层:IAM 仅允许请求发送到
eu-west-2。 - 审计层:在 CloudTrail 中持续检查 Bedrock 调用的
awsRegion。
这里需要区分两个概念:in-geography 表示请求仍在某个地理范围内,但可能在该范围的多个区域之间路由;single-Region 则把处理范围缩小到一个明确区域。受监管工作负载通常需要后者。
路径一:使用单区域应用推理配置文件
应用推理配置文件可以作为 Claude Code 使用的模型入口,同时提供独立的调用归属和成本追踪能力。关键不在于“创建了配置文件”,而在于它复制或引用的模型源必须是伦敦区域支持的单区域模型,而不是跨区域推理配置文件。
可以这样实践。运行前,将 MODEL_ID 替换为当前账户在 eu-west-2 可用的 Claude 模型 ID;模型是否支持伦敦区域应以 Bedrock 控制台或 list-foundation-models 的结果为准。
#!/usr/bin/env bash
set -euo pipefail
REGION="eu-west-2"
MODEL_ID="anthropic.claude-REPLACE_WITH_SUPPORTED_MODEL"
PROFILE_NAME="claude-code-london-only"
MODEL_ARN="arn:aws:bedrock:${REGION}::foundation-model/${MODEL_ID}"
aws bedrock create-inference-profile \
--region "$REGION" \
--inference-profile-name "$PROFILE_NAME" \
--description "Claude Code inference restricted to London" \
--model-source "copyFrom=${MODEL_ARN}"
aws bedrock list-inference-profiles \
--region "$REGION" \
--type-equals APPLICATION \
--query "inferenceProfileSummaries[?inferenceProfileName=='${PROFILE_NAME}'].[inferenceProfileArn,status]" \
--output table
创建完成后,把返回的应用推理配置文件 ARN 配置为 Claude Code 的 Bedrock 模型标识:
export CLAUDE_CODE_USE_BEDROCK=1
export AWS_REGION=eu-west-2
export AWS_DEFAULT_REGION=eu-west-2
export ANTHROPIC_MODEL="arn:aws:bedrock:eu-west-2:123456789012:application-inference-profile/REPLACE_ME"
claude
不要把类似 eu.*、us.* 或其他跨区域推理配置文件 ID 当成单区域模型。前缀本身不能替代检查,部署前应查看配置文件的模型来源和组织内允许的区域清单。
路径二:连接伦敦区域的 Mantle 端点
另一种做法是让 Claude Code 连接 Mantle 的区域端点,以端点本身明确请求入口。适合希望保留 Claude Code 使用体验、同时把 Bedrock 接入固定到伦敦区域的团队。
端点地址和 Claude Code 使用的配置项可能随客户端版本及 AWS 提供方式变化,因此应从当前 AWS 环境或官方配置中取得伦敦 Mantle 端点,不要从其他区域复制地址。可以这样组织启动脚本:
#!/usr/bin/env bash
set -euo pipefail
: "${LONDON_MANTLE_ENDPOINT:?Set LONDON_MANTLE_ENDPOINT to the eu-west-2 Mantle endpoint}"
: "${BEDROCK_MODEL_ID:?Set BEDROCK_MODEL_ID to a Claude model available in eu-west-2}"
export CLAUDE_CODE_USE_BEDROCK=1
export AWS_REGION="eu-west-2"
export AWS_DEFAULT_REGION="eu-west-2"
export ANTHROPIC_MODEL="$BEDROCK_MODEL_ID"
export ANTHROPIC_BEDROCK_BASE_URL="$LONDON_MANTLE_ENDPOINT"
exec claude "$@"
运行方式如下:
export LONDON_MANTLE_ENDPOINT="REPLACE_WITH_THE_EU_WEST_2_MANTLE_ENDPOINT"
export BEDROCK_MODEL_ID="anthropic.claude-REPLACE_WITH_SUPPORTED_MODEL"
./run-claude-london.sh
这条路径仍然需要 IAM 约束。区域端点是路由配置,不应被当作不可绕过的安全边界。
用 IAM 把区域限制变成强制规则
最小权限策略可以只允许调用一个应用推理配置文件,并增加 aws:RequestedRegion 条件。将账户 ID和配置文件 ID 替换为实际值:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "InvokeApprovedLondonProfile",
"Effect": "Allow",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream"
],
"Resource": "arn:aws:bedrock:eu-west-2:123456789012:application-inference-profile/REPLACE_ME",
"Condition": {
"StringEquals": {
"aws:RequestedRegion": "eu-west-2"
}
}
},
{
"Sid": "DenyBedrockInferenceOutsideLondon",
"Effect": "Deny",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream"
],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:RequestedRegion": "eu-west-2"
}
}
}
]
}
显式 Deny 很重要:即使身份通过其他用户策略、角色策略或组策略获得了更宽的 Bedrock 权限,区域外调用仍会被拒绝。大型组织还可以把同类条件放进 AWS Organizations 的服务控制策略,但部署前要评估它对其他 Bedrock 工作负载的影响。
还要检查 IAM 边界之外的授权来源,包括权限边界、会话策略、资源策略和组织级 SCP。合规评审不应只查看 Claude Code 使用的那一份角色策略。
在 CloudTrail 中验证,而不是只检查配置
控制上线后,应发起一次真实的 Claude Code 请求,然后在 CloudTrail 中检查 Bedrock 运行时事件。CloudTrail Lake 适合按区域持续查询。将 EVENT_DATA_STORE_ID 替换为启用了相关 Bedrock 事件记录的数据存储 ID:
EVENT_DATA_STORE_ID="REPLACE_ME"
QUERY_ID=$(aws cloudtrail start-query \
--query-statement "
SELECT eventTime, eventName, awsRegion, userIdentity.arn, requestParameters
FROM ${EVENT_DATA_STORE_ID}
WHERE eventSource = 'bedrock-runtime.amazonaws.com'
AND eventName IN ('InvokeModel', 'InvokeModelWithResponseStream')
AND eventTime > date_add('hour', -24, current_timestamp)
ORDER BY eventTime DESC
" \
--query QueryId \
--output text)
while true; do
STATUS=$(aws cloudtrail get-query-results \
--query-id "$QUERY_ID" \
--query QueryStatus \
--output text)
case "$STATUS" in
FINISHED) break ;;
FAILED|CANCELLED|TIMED_OUT) echo "CloudTrail query failed: $STATUS" >&2; exit 1 ;;
*) sleep 3 ;;
esac
done
aws cloudtrail get-query-results --query-id "$QUERY_ID" --output json
审计时至少确认以下字段:
eventSource是 Bedrock 运行时服务。eventName与实际调用方式一致,例如流式调用通常对应InvokeModelWithResponseStream。awsRegion始终为eu-west-2。userIdentity对应批准的 Claude Code 角色或联合身份。- 请求中的模型资源是批准的应用推理配置文件或伦敦区域模型。
还应建立反向检测,主动搜索任何区域外事件:
SELECT eventTime, eventName, awsRegion, userIdentity.arn, requestParameters
FROM REPLACE_WITH_EVENT_DATA_STORE_ID
WHERE eventSource = 'bedrock-runtime.amazonaws.com'
AND eventName IN ('InvokeModel', 'InvokeModelWithResponseStream')
AND awsRegion <> 'eu-west-2'
ORDER BY eventTime DESC;
需要注意,CloudTrail 的事件覆盖范围取决于组织的 trail、event data store 和事件选择器配置。查询不到记录并不能自动证明没有调用;它也可能表示相应事件没有被采集。上线前应先制造一条已知调用,确认事件能够进入审计存储。
上线前检查清单
单区域数据驻留不是一个环境变量,而是一组互相校验的控制:
- Claude Code 和 AWS SDK 的默认区域均为
eu-west-2。 - 使用单区域应用推理配置文件或伦敦 Mantle 端点。
- 应用推理配置文件没有引用跨区域推理来源。
- IAM 同时包含精确资源授权和区域外显式拒绝。
- CloudTrail 已采集 Bedrock 运行时事件,并能查到测试调用。
- 自动审计会对任何
awsRegion <> 'eu-west-2'的事件告警。 - 模型升级前重新确认新模型在伦敦区域的可用性和路由方式。
这种设计的代价是灵活性和可用区间收窄:单区域容量不足或区域故障时,系统不能自动借用其他区域。对于受监管的开发环境,这是明确的合规取舍。团队应把降级策略、区域故障处理和模型版本变更纳入变更管理,而不是临时解除 IAM 限制。