{"slug": "claude-code-authentication-subscription-api-key-amazon-bedrock-and-claude-on-aws", "title": "Claude Code Authentication: Subscription, API Key, Amazon Bedrock, and Claude Platform on AWS", "summary": "An engineer detailed the authentication options for Claude Code, including API keys, Amazon Bedrock, and the Claude Platform on AWS, highlighting use cases for each. The post includes a code example for building an agent with the Anthropic SDK and emphasizes Bedrock's advantages for organizations, such as IAM roles and CloudTrail audit trails.", "body_md": "I'm a big fan of using Claude and Claude Code for development. Many organizations are currently using these tools to improve developer productivity and ultimately build better products. Our role and our tools have changed — we went from powerful autocomplete to autonomous agents that can refactor, review, and implement features, most of the time better than we can on our own.\n\nThere are several authentication methods, each with different billing, cost tracking, and governance options. Depending on your organization, you will choose the one that fits best.\n\nI use this for experimenting with the Anthropic library for learning and prototyping. You set `ANTHROPIC_API_KEY`\n\nin your environment (or a `.env`\n\nfile), and the SDK picks it up automatically. Pay-as-you-go per token, no infrastructure needed.\n\n``` python\nfrom dotenv import load_dotenv\nload_dotenv()\nimport json\nimport anthropic\n\nclient = anthropic.Anthropic()\n\ntools = [\n    {\n        \"name\": \"get_weather\",\n        \"description\": (\n            \"Returns current weather for a city. Use ONLY for weather queries. \"\n            \"Input: city name (string). Output: temperature in Celsius and conditions.\"\n        ),\n        \"input_schema\": {\n            \"type\": \"object\",\n            \"properties\": {\"city\": {\"type\": \"string\"}},\n            \"required\": [\"city\"],\n        },\n    },\n    {\n        \"name\": \"get_time\",\n        \"description\": (\n            \"Returns the current local time for a city. Use ONLY for time/timezone queries. \"\n            \"Input: city name (string). Output: local time string.\"\n        ),\n        \"input_schema\": {\n            \"type\": \"object\",\n            \"properties\": {\"city\": {\"type\": \"string\"}},\n            \"required\": [\"city\"],\n        },\n    },\n]\n\ndef get_weather(city: str) -> dict:\n    return {\"city\": city, \"temp_c\": 22, \"conditions\": \"sunny\"}\n\ndef get_time(city: str) -> dict:\n    return {\"city\": city, \"local_time\": \"14:35\"}\n\nTOOL_FUNCTIONS = {\n    \"get_weather\": get_weather,\n    \"get_time\": get_time,\n}\n\ndef run_agent(user_message: str) -> str:\n    messages = [{\"role\": \"user\", \"content\": user_message}]\n    iteration = 0\n\n    print(f\"\\n[user] {user_message}\")\n\n    while True:\n        iteration += 1\n        print(f\"\\n--- iteration {iteration}: calling Claude ---\")\n\n        response = client.messages.create(\n            model=\"claude-sonnet-4-6\",\n            max_tokens=1024,\n            tools=tools,\n            messages=messages,\n        )\n\n        print(f\"[sdk] stop_reason = {response.stop_reason!r}\")\n        print(f\"[sdk] response.content blocks: {[b.type for b in response.content]}\")\n\n        if response.stop_reason == \"end_turn\":\n            final = next(b.text for b in response.content if b.type == \"text\")\n            print(f\"\\n[assistant] {final}\")\n            return final\n\n        messages.append({\"role\": \"assistant\", \"content\": response.content})\n\n        tool_results = []\n        for block in response.content:\n            if block.type == \"tool_use\":\n                print(f\"\\n[tool_use] Claude wants to call: {block.name!r}\")\n                print(f\"[tool_use] with input: {block.input}\")\n\n                fn = TOOL_FUNCTIONS[block.name]\n                result = fn(**block.input)\n                print(f\"[tool_result] returned: {result}\")\n\n                tool_results.append({\n                    \"type\": \"tool_result\",\n                    \"tool_use_id\": block.id,\n                    \"content\": json.dumps(result),\n                })\n\n        print(f\"\\n[loop] appending {len(tool_results)} tool result(s), looping back...\")\n        messages.append({\"role\": \"user\", \"content\": tool_results})\n\nif __name__ == \"__main__\":\n    run_agent(\"What's the weather and local time in Bogotá?\")\n```\n\nThis is my preferred option for organizations. With Bedrock you get inference profiles, IAM roles, and solid audit trails through CloudTrail — no floating API key to rotate or leak. The same credential chain you use for any other AWS SDK call works here.\n\nConfiguration is just a few lines in `~/.claude/settings.json`\n\n:\n\n```\n{\n  \"env\": {\n    \"CLAUDE_CODE_USE_BEDROCK\": \"1\",\n    \"AWS_REGION\": \"us-east-1\",\n    \"ANTHROPIC_DEFAULT_OPUS_MODEL\": \"us.anthropic.claude-opus-5\",\n    \"ANTHROPIC_DEFAULT_SONNET_MODEL\": \"global.anthropic.claude-sonnet-4-6\",\n    \"ANTHROPIC_DEFAULT_HAIKU_MODEL\": \"global.anthropic.claude-haiku-4-5-20251001-v1:0\",\n    \"CLAUDE_CODE_ENABLE_AUTO_MODE\": \"1\",\n    \"AWS_PROFILE\": \"aws-community-builders\"\n  }\n}\n```\n\nThe `global.`\n\nprefix on the model IDs uses cross-region inference profiles, which route to the lowest-latency region automatically and give higher throughput limits than a single-region endpoint.\n\nThis is the option for organizations that want AWS Marketplace billing combined with the full Anthropic API feature set. Unlike Bedrock (which routes requests through AWS's own inference infrastructure), Claude Platform on AWS sends requests directly to Anthropic's API — giving you the latest models on the same release schedule as the direct Claude API — while billing consolidates into your existing AWS spend through Marketplace.\n\nIt's a great fit when your organization has SSO set up through IAM Identity Center and wants a single sign-on experience without managing separate Anthropic credentials.\n\n**Step 1 — log in with SSO:**\n\n```\naws sso login --profile aws-community-sso\nexport AWS_PROFILE=aws-community-sso\n```\n\n**Step 2 — configure automatic credential refresh** so Claude Code re-authenticates when your SSO session expires, rather than dying mid-session. Add this to `~/.claude/settings.json`\n\n:\n\n```\n{\n  \"awsAuthRefresh\": \"aws sso login --profile aws-community-sso\"\n}\n```\n\n**Step 3 — point Claude Code at the platform:**\n\n```\nexport CLAUDE_CODE_USE_ANTHROPIC_AWS=1\nexport ANTHROPIC_AWS_WORKSPACE_ID=wrkspc_01ABCDEFGHIJKLMN\nexport AWS_REGION=us-east-1\n```\n\n`ANTHROPIC_AWS_WORKSPACE_ID`\n\nis required on every request — it identifies your organization's workspace and isn't inferred from your AWS credentials.\n\nRegardless of which auth method you use, always pin model versions before rolling out to a team. Without pinning, model aliases like `opus`\n\nand `sonnet`\n\nresolve to Claude Code's built-in defaults, which can change when Claude Code updates — and on Bedrock, that can silently move a Sonnet deployment to Opus pricing.\n\n```\nexport ANTHROPIC_DEFAULT_OPUS_MODEL='us.anthropic.claude-opus-4-8'\nexport ANTHROPIC_DEFAULT_SONNET_MODEL='us.anthropic.claude-sonnet-4-6'\nexport ANTHROPIC_DEFAULT_HAIKU_MODEL='us.anthropic.claude-haiku-4-5-20251001-v1:0'\n```\n\nRun `/status`\n\ninside Claude Code to confirm which provider and models are actually active.\n\nAmazon Bedrock Guardrails let you implement content filtering for Claude Code. Create a guardrail in the Amazon Bedrock console, publish a version, then add the guardrail headers to your settings file. Enable cross-region inference on your guardrail if you're using cross-region inference profiles.\n\n```\n{\n  \"env\": {\n    \"ANTHROPIC_CUSTOM_HEADERS\": \"X-Amzn-Bedrock-GuardrailIdentifier: your-guardrail-id\\nX-Amzn-Bedrock-GuardrailVersion: 1\"\n  }\n}\n```\n\nEach authentication method reflects a different stage of adoption and governance maturity:\n\nPick the option that matches your organization's current security and billing requirements — and remember that you can always migrate later. Start simple, and add governance as your usage grows.\n\n**There has never been a better time to be an engineer and create value in society through software.**\n\nIf you enjoyed the articles, visit my blog at [jorgetovar.dev](https://jorgetovar.dev).", "url": "https://wpnews.pro/news/claude-code-authentication-subscription-api-key-amazon-bedrock-and-claude-on-aws", "canonical_source": "https://dev.to/aws-builders/claude-code-authentication-subscription-api-key-amazon-bedrock-and-claude-platform-on-aws-436g", "published_at": "2026-08-05 18:23:32+00:00", "updated_at": "2026-08-05 18:57:58.280455+00:00", "lang": "en", "topics": ["developer-tools", "ai-tools", "artificial-intelligence", "large-language-models", "ai-agents"], "entities": ["Claude Code", "Anthropic", "Amazon Bedrock", "AWS", "CloudTrail", "IAM"], "alternates": {"html": "https://wpnews.pro/news/claude-code-authentication-subscription-api-key-amazon-bedrock-and-claude-on-aws", "markdown": "https://wpnews.pro/news/claude-code-authentication-subscription-api-key-amazon-bedrock-and-claude-on-aws.md", "text": "https://wpnews.pro/news/claude-code-authentication-subscription-api-key-amazon-bedrock-and-claude-on-aws.txt", "jsonld": "https://wpnews.pro/news/claude-code-authentication-subscription-api-key-amazon-bedrock-and-claude-on-aws.jsonld"}}