{"slug": "running-claude-code-on-aws-bedrock-iam-scps-and-the-governance-model-most-teams", "title": "Running Claude Code on AWS Bedrock: IAM, SCPs, and the Governance Model Most Teams Get Wrong", "summary": "A developer detailed the enterprise deployment of Claude Code on AWS Bedrock, emphasizing that the environment variable CLAUDE_CODE_USE_BEDROCK=1 is only the starting point. The guide covers critical IAM policies, SCPs, and governance models, including region strategy and model access provisioning, which are often overlooked by teams.", "body_md": "*Cross-posted with permission from iqraa.tech — the full guide has the complete IAM policy, SCP examples, and a 300-engineer rollout case study.*\n\nClaude Code has a Bedrock mode. Most people find out about it from a single environment variable — `CLAUDE_CODE_USE_BEDROCK=1`\n\n— and assume that's the whole story. It isn't. The env var is the on-switch; the IAM policy, region strategy, and governance layer around it are where almost every enterprise rollout actually gets stuck.\n\nI run through the deployment end to end below — the parts that matter for a platform team, not just \"here's a flag.\"\n\nThe models are identical either way. What changes is procurement, governance, and audit:\n\n```\nexport CLAUDE_CODE_USE_BEDROCK=1\nexport AWS_REGION=us-east-1\nexport ANTHROPIC_MODEL=us.anthropic.claude-sonnet-4-6-20250610-v1:0\nexport AWS_PROFILE=claude-code-prod\n```\n\nNote the model ID format difference — direct Anthropic uses `claude-sonnet-4-6`\n\n; Bedrock uses inference-profile IDs like `us.anthropic.claude-sonnet-4-6-20250610-v1:0`\n\n. The `us.`\n\nprefix means AWS load-balances the request across US regions for resilience. Drop the prefix and you're pinned to one region only. Mixing the two ID formats is the single most common \"model not found\" error teams hit on day one.\n\n`bedrock:*`\n\n)\n\n```\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Sid\": \"InvokeClaudeModels\",\n      \"Effect\": \"Allow\",\n      \"Action\": [\"bedrock:InvokeModel\", \"bedrock:InvokeModelWithResponseStream\"],\n      \"Resource\": [\n        \"arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-sonnet-*\",\n        \"arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-opus-*\",\n        \"arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-haiku-*\"\n      ]\n    },\n    {\n      \"Sid\": \"UseCrossRegionInferenceProfiles\",\n      \"Effect\": \"Allow\",\n      \"Action\": [\"bedrock:InvokeModel\", \"bedrock:InvokeModelWithResponseStream\"],\n      \"Resource\": [\"arn:aws:bedrock:us-east-1:*:inference-profile/us.anthropic.claude-*\"]\n    },\n    {\n      \"Sid\": \"ListFoundationModels\",\n      \"Effect\": \"Allow\",\n      \"Action\": \"bedrock:ListFoundationModels\",\n      \"Resource\": \"*\"\n    }\n  ]\n}\n```\n\nTwo details that trip people up:\n\n`InvokeModelWithResponseStream`\n\nis a `InvokeModel`\n\n. Miss it and Claude Code falls back to one-shot invocation — it still works, but feels sluggish and streaming sessions fail.`Resource: \"*\"`\n\non Bedrock invoke actions. Bedrock also hosts Llama, Mistral, Nova, and marketplace models with their own cost/security profile. Scope to `anthropic.claude-*`\n\nARNs only, so a leaked credential's blast radius stays limited to Anthropic models.New AWS accounts don't have Claude models enabled by default. You have to explicitly request access per model per region in the Bedrock console, and approval can take anywhere from minutes to several hours — not instant, despite what the console implies. Request access to Haiku, Sonnet, *and* Opus up front, even if you're only using Sonnet today, so a future model switch doesn't get blocked by a multi-hour provisioning delay mid-rollout.\n\nIAM controls what a role *can* do; SCPs control what an entire AWS account can do, org-wide:\n\n```\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Sid\": \"DenyBedrockOutsideApprovedRegions\",\n      \"Effect\": \"Deny\",\n      \"Action\": \"bedrock:*\",\n      \"Resource\": \"*\",\n      \"Condition\": {\n        \"StringNotEquals\": { \"aws:RequestedRegion\": [\"us-east-1\", \"eu-west-1\"] }\n      }\n    },\n    {\n      \"Sid\": \"DenyNonAnthropicBedrockModels\",\n      \"Effect\": \"Deny\",\n      \"Action\": [\"bedrock:InvokeModel\", \"bedrock:InvokeModelWithResponseStream\"],\n      \"Resource\": \"arn:aws:bedrock:*:*:foundation-model/*\",\n      \"Condition\": {\n        \"StringNotLike\": { \"bedrock:FoundationModelArn\": \"arn:aws:bedrock:*:*:foundation-model/anthropic.claude-*\" }\n      }\n    }\n  ]\n}\n```\n\nLayer this with an IAM permission boundary and the inline invoke policy above, and you get the same three-layer model mature shops already use for IAM and KMS: SCP governs the org, permission boundary governs what roles developers can create, inline policy governs what Claude Code itself can invoke.\n\nThe headline per-token rate is the ceiling, not what you'll actually pay:\n\n`CLAUDE.md`\n\n(no dynamic timestamps/build IDs) keeps cache hits high; that alone routinely cuts effective input cost 80-90% on long sessions.`CLAUDE.md`\n\nthat isn't giving Sonnet enough structure, or developers manually overriding the default.`--max-budget-usd`\n\nin CIClaude Code on Bedrock rides the standard AWS SDK credential chain — no custom auth to build. AWS SSO for developer workstations (`aws sso login`\n\n, short-lived creds, single point of revocation), OIDC federation for CI/CD (GitHub Actions/GitLab/Jenkins all support it — no static secrets), instance/task roles for EC2/ECS. If you're stuck on long-lived access keys, rotate quarterly via Secrets Manager + a rotator Lambda, not manually.\n\n`InvokeModelWithResponseStream`\n\nFull write-up (including a worked 300-engineer financial-services rollout, VPC endpoint config, and provisioned-throughput break-even math) is here: [Claude Code AWS Bedrock: Enterprise Setup Guide](https://iqraa.tech/ai-genai/claude/claude-code-aws-bedrock/)\n\nHappy to answer questions on IAM/SCP specifics in the comments — I set up a few of these rollouts and the model-access delay catches everyone the first time.", "url": "https://wpnews.pro/news/running-claude-code-on-aws-bedrock-iam-scps-and-the-governance-model-most-teams", "canonical_source": "https://dev.to/amartinawi/running-claude-code-on-aws-bedrock-iam-scps-and-the-governance-model-most-teams-get-wrong-3bg2", "published_at": "2026-07-13 20:09:02+00:00", "updated_at": "2026-07-13 20:46:17.351194+00:00", "lang": "en", "topics": ["artificial-intelligence", "large-language-models", "ai-infrastructure", "ai-safety", "developer-tools"], "entities": ["Claude Code", "AWS Bedrock", "Anthropic", "IAM", "SCP"], "alternates": {"html": "https://wpnews.pro/news/running-claude-code-on-aws-bedrock-iam-scps-and-the-governance-model-most-teams", "markdown": "https://wpnews.pro/news/running-claude-code-on-aws-bedrock-iam-scps-and-the-governance-model-most-teams.md", "text": "https://wpnews.pro/news/running-claude-code-on-aws-bedrock-iam-scps-and-the-governance-model-most-teams.txt", "jsonld": "https://wpnews.pro/news/running-claude-code-on-aws-bedrock-iam-scps-and-the-governance-model-most-teams.jsonld"}}