Amazon Bedrock in Practice

Cross-Account Bedrock Calls via IAM Role Assumption

Many enterprises route all Claude traffic through one central AWS account — one place for model access, quota, and governance. Role assumption is the mechanism that lets every other account's workloads use it.

Claude 3P 101 · Updated July 2026 · Unofficial guide

Because Claude's foundation models on Bedrock are AWS-owned resources — you can't attach a sharing policy to them the way you would to an S3 bucket — the standard way to let account B use account A's Bedrock setup is IAM role assumption. Account A (the "inference account") creates a role permitted to invoke Claude; account B's workload calls AWS STS (Security Token Service) to assume that role, receives temporary credentials, and makes Bedrock calls that execute, bill, and count against quota in account A. This article walks the pattern end to end.

The three moving parts

1. A role in the inference account. Its permissions policy grants the inference actions on approved models — bedrock:InvokeModel and bedrock:InvokeModelWithResponseStream on the foundation-model ARNs (arn:aws:bedrock:*::foundation-model/anthropic.claude-sonnet-5) plus any inference-profile ARNs, or bedrock-mantle:CreateInference on allowed model ARNs if workloads use the newer "Claude in Amazon Bedrock" surface. Anthropic's documentation describes exactly this assumed-role path as a supported authentication method for that surface, with a 12-hour maximum session duration.

2. A trust policy on that role. The trust policy names which principals — specific role ARNs from workload accounts, not whole accounts if you can avoid it — may assume the role. This is your cross-account contract; keep it explicit and short.

3. An sts:AssumeRole grant in the workload account. The calling compute's own role (its Lambda execution role, ECS task role, or EC2 instance profile — see service role patterns) must be allowed to assume the central role.

Wiring it up in Python

The Anthropic SDK resolves AWS credentials through the standard chain — constructor arguments, then environment variables, then the ambient credential providers, which include assumed roles. The simplest explicit version:

import boto3, os
from anthropic import AnthropicBedrockMantle

creds = boto3.client("sts").assume_role(
    RoleArn="arn:aws:iam::111122223333:role/central-claude-invoke",
    RoleSessionName="orders-service",
)["Credentials"]
os.environ["AWS_ACCESS_KEY_ID"] = creds["AccessKeyId"]
os.environ["AWS_SECRET_ACCESS_KEY"] = creds["SecretAccessKey"]
os.environ["AWS_SESSION_TOKEN"] = creds["SessionToken"]

client = AnthropicBedrockMantle(aws_region="us-east-1")

In long-running services, prefer your platform's refreshable-credentials machinery over one-shot environment variables, since STS sessions expire. Give each workload a distinct RoleSessionName: it appears in the central account's CloudTrail records, which is how you'll attribute traffic later.

What centralizing actually buys — and costs

DimensionEffect of the central-account pattern
Model accessMarketplace subscription and (legacy-surface) use-case form handled once, in one account
QuotaAll traffic draws one account's per-model, per-region, per-endpoint quotas — a shared pool that is simpler to raise but also a shared point of throttling
BillingConsolidated in the inference account; per-team attribution must come from CloudTrail identities, tags, or application inference profiles
GovernanceOne place for allowed-model policy, logging configuration, and guardrails
Blast radiusA noisy workload can exhaust quota for everyone; per-team roles and monitoring are essential
Rule of thumb: centralize when governance and quota management dominate; stay distributed (Bedrock access in each workload account) when teams need cost isolation and independent limits. Many organizations run both — central for shared services, direct for the biggest consumers. See multi-account setup.

Auditing the seam

Cross-account access deserves extra observability. CloudTrail in the inference account records each invocation with the assumed-role session identity, source IP, and timing; model invocation logging (CloudWatch Logs/S3, same account and region as the calls) can capture full request and response bodies on the legacy bedrock-runtime surface if your data policies allow. Review the trust policy on the central role as part of routine access reviews — it is effectively the door between your organization's accounts and your Claude spend.

Where to go next

Tighten what the central role may invoke with IAM condition keys, and read resource-based policies for why this pattern — rather than resource sharing — is the cross-account default on Bedrock.

Sources