DEV Community

Cover image for Setting Up AWS Bedrock with Claude Code via IAM — No Hardcoded Keys, Ever
Karan Vaghela
Karan Vaghela

Posted on

Setting Up AWS Bedrock with Claude Code via IAM — No Hardcoded Keys, Ever

Posted by Karan Vaghela | Leader, AWS Student Builder Groups at P P Savani University | Cybersecurity & Cloud


The fastest way to get your AWS project hacked is to hardcode your credentials somewhere. An AWS_ACCESS_KEY_ID sitting in a .env file that accidentally gets pushed to GitHub is a classic mistake, and it happens to experienced engineers too, not just beginners.

When I was setting up Claude on Amazon Bedrock for a project, I made sure the entire flow used IAM roles and profiles — zero hardcoded keys anywhere. This post walks through exactly how to do that, why it matters, and the specific gotchas I ran into along the way.


Why IAM Roles Over Access Keys

Access keys are long-lived credentials. If they leak, an attacker has persistent access until you manually rotate or revoke them. IAM roles, on the other hand, issue temporary credentials that expire automatically. They are the AWS-recommended approach for any application running on AWS infrastructure, and they are what you should be using even for local development once you understand the pattern.

The security principle here is simple: credentials should be as short-lived and as scoped as possible. IAM makes this the default if you set it up right.


The Setup: Claude Code CLI on Bedrock via IAM

Here is the exact configuration I used. The goal was to run Claude Code CLI backed by Bedrock, authenticated entirely through IAM with no keys in any config file.

Step 1: Create a Named AWS Profile

Instead of using the default profile, create a named one so you can switch contexts cleanly.

Edit ~/.aws/credentials:

[bedrock-dev]
aws_access_key_id = YOUR_ACCESS_KEY
aws_secret_access_key = YOUR_SECRET_KEY
Enter fullscreen mode Exit fullscreen mode

And ~/.aws/config:

[profile bedrock-dev]
region = us-east-1
output = json
Enter fullscreen mode Exit fullscreen mode

This is still using access keys locally, but they are scoped to a named profile and never leave your machine. The key move is what happens next.

Step 2: Scope the IAM Policy

Create an IAM policy that grants only what Bedrock needs. Nothing more.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "bedrock:InvokeModel",
        "bedrock:InvokeModelWithResponseStream"
      ],
      "Resource": [
        "arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-*"
      ]
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Attach this policy to an IAM user or role. Do not use AdministratorAccess or any wildcard resource. Least privilege is the rule.

Step 3: Configure Claude Code to Use Bedrock

In ~/.claude/settings.json:

{
  "env": {
    "CLAUDE_CODE_USE_BEDROCK": "1",
    "AWS_PROFILE": "bedrock-dev",
    "AWS_REGION": "us-east-1",
    "ANTHROPIC_MODEL": "anthropic.claude-sonnet-4-20250514",
    "ANTHROPIC_SMALL_FAST_MODEL": "anthropic.claude-haiku-4-5-20251001"
  }
}
Enter fullscreen mode Exit fullscreen mode

Three things to note here:

AWS_REGION must be explicit. Do not assume it will be picked up from your AWS config. If this is missing, Claude Code will fail silently or fall back to a default region where your model may not be available. Always set it.

AWS_PROFILE must match exactly. The string here must match the profile name in your ~/.aws/config exactly, including case.

/login and /logout do not work in Bedrock mode. These commands are only for Anthropic's direct API with an API key. In Bedrock mode, authentication is entirely handled by your AWS credentials. Do not look for them.

Step 4: Verify the Connection

Run a quick test:

aws bedrock list-foundation-models --profile bedrock-dev --region us-east-1 | grep claude
Enter fullscreen mode Exit fullscreen mode

If you see Claude models listed, your IAM setup is correct and Bedrock is reachable. If you get an AccessDeniedException, check your policy. If you get an error about the region, check that your selected region actually has Bedrock available — not all regions do.


The Production Pattern: No Keys at All

If you are running this on an EC2 instance, Lambda, or any AWS compute, you should not have any access keys anywhere. Instead, attach an IAM role to the compute resource directly.

For EC2:

  1. Create an IAM role with the Bedrock policy above attached.
  2. Attach the role to your EC2 instance under Actions > Security > Modify IAM Role.
  3. Remove any aws_access_key_id and aws_secret_access_key from your credentials file on that machine.

The AWS SDK will automatically pick up credentials from the instance metadata service. Your application code does not change. Your ~/.aws/config just needs the region:

[default]
region = us-east-1
Enter fullscreen mode Exit fullscreen mode

No keys. No secrets. The role does everything.


What Not to Do

A few patterns I see people use that you should avoid:

Do not put credentials in your .env file and add .env to .gitignore. This is better than nothing but still risky. .gitignore rules have edge cases, and if you ever run git add -f or misconfigure something, those keys are in your history forever. Use IAM profiles.

Do not use your root account credentials for anything. Ever. Create an IAM user with only the permissions you need. The root account should have MFA enabled and nothing else touching it.

Do not share credentials across environments. Your dev IAM user and your production IAM role should be completely separate identities with separate policies. If your dev credentials leak, your production environment should be unaffected.


Why This Matters Beyond Security

There is a practical ops benefit too. When you use IAM profiles and roles properly, rotating credentials becomes a non-event. You update the IAM user's keys in one place, update your ~/.aws/credentials, and everything downstream picks it up. No hunting through .env files across multiple projects.

For a student or someone early in their career, building this habit now means you will never be the engineer who accidentally commits an API key. That matters more than it sounds.


Quick Reference

Situation Approach
Local dev machine Named IAM profile in ~/.aws/credentials
EC2 / Lambda / ECS IAM role attached to compute, no keys
CI/CD pipeline OIDC identity provider or short-lived role assumption
Never Hardcoded keys in code or .env files

Bedrock is a powerful way to run foundation models without managing your own infrastructure. Setting it up with IAM properly from the start means you get all that power without the security debt that trips up so many early projects.

If you run into specific errors while setting this up, drop them in the comments. Happy to help debug.


Tags: #aws #bedrock #iam #security #cloud #beginners

Top comments (0)