[BUG] Claude Code does not handle expiry of short term IAM credentials (security tokens)

Status Fixed / completed
Maintainer reply ✓ Yes — ant-kurt
Activity 13 comments · opened Jun 19, 2025 · closed Jul 15, 2025
💡 Likely answer: A maintainer (ant-kurt, collaborator) responded on this thread — see the highlighted reply below.

Environment

  • Platform (select one):
  • [ ] Anthropic API
  • [x] AWS Bedrock
  • [ ] Google Vertex AI
  • [ ] Other: <!-- specify -->
  • Claude CLI version: 1.0.29 (Claude Code)
  • Operating System: Windows 11
  • Terminal: cmd

Bug Description

When using CLAUDE_CODE_USE_BEDROCK=1, if your IAM credentials expire, Claude Code does not pick up new credentials if they are refreshed.

Steps to Reproduce

  1. log into AWS via CLI and export AWS_PROFILE of relevant profile (using short-term STS token)
  2. start Claude Code
  3. wait for credentials to expire
  4. refresh AWS credentials (in another window)
  5. it will no longer be possible to run any commands in Claude Code

Expected Behaviour

I expect Claude Code to check for refreshed credentials when receiving 403s (API Error: 403 The security token included in the request is expired) from AWS API calls.

Actual Behaviour

API Error: 403 The security token included in the request is expired is returned continually.
To work around you can quit and restart with claude --continue but if using many Claude Code sessions this is problematic.

Additional Context

It is common for enterprises to not use long lived IAM access keys but rather short lived STS tokens, for example via saml2aws/oktacli if using Okta. These credentials typically only last for hours or a day.
If you have many different Claude Code sessions open all sharing the same base IAM profile you will need to re-open all of them to pick up new credentials.

View original on GitHub ↗

13 Comments

ant-kurt collaborator · 1 year ago

Hmm - this works for me when using a stable profile (e.g. CLAUDE_CODE_USE_BEDROCK=1 AWS_PROFILE=<stable-profile-id> and aws sso login --profile=<stable-profile-id>).

Are your profile IDs dynamic? Are you also setting other vars like AWS_ACCESS_KEY_ID for the Claude process?

Yukitada-Ri · 1 year ago

Hi team, I totally faced the same issue.
My situation is using Azure SSO to get and update AWS credentials.
My campany allows only 1 hour expiration.
After the credentails expire, claude code sends ``API Error: 403 The security token included in the request
is expired
`` error.
I open the new terminal and refresh the credentails, but sill show the same error.

ant-kurt collaborator · 1 year ago

@Yukitada-Ri can you share how you're specifying the credentials to Claude Code - are you passing AWS_PROFILE, or AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKEN?

We're working on a long-term solution to this, and want to make sure it covers a breadth of auth approaches.

Yukitada-Ri · 1 year ago

@ant-kurt
Thank you for your replay.
I use aws-azure-login.
This refreshs and creates new aws_access_key_id, aws_secret_access_key and aws_session_token.
I believe I use AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKEN instead of AWS_PROFILE.

# old
$ cat ~/.aws/credentials
[default]
aws_access_key_id=A*********************A
aws_secret_access_key=L***************************************K
aws_session_token="F*******************************************g="
aws_expiration=2025-06-27T09:18:52.000Z
# Run aws azure login
$ aws-azure-login --no-prompt
(node:72175) NOTE: We are formalizing our plans to enter AWS SDK for JavaScript (v2) into maintenance mode in 2023.

Please migrate your code to use AWS SDK for JavaScript (v3).
For more information, check the migration guide at https://a.co/7PzMCcy
(Use `node --trace-warnings ...` to show where the warning was created)
Logging in with profile 'default'...
Using AWS SAML endpoint https://signin.aws.amazon.com/saml
Assuming role arn:aws:iam::<ACCOUNT_ID>:role/<ROLE_NAME>

# After run aws azure login, new aws_access_key_id, aws_secret_access_key, aws_session_token are created.
$ cat ~/.aws/credentials
[default]
aws_access_key_id=A*********************D
aws_secret_access_key=x***************************************a
aws_session_token="F*******************************************k="
aws_expiration=2025-06-28T02:28:40.000Z

You can see the profile is the same.
It is still [default].
But the aws_access_key_id, aws_secret_access_key and aws_session_token are updated with the new expiration.

ant-kurt collaborator · 1 year ago

Hmm - as a workaround, Claude Code should auto-detect those values if you perform your command (writing to ~/.aws/credentials) in another tab.

We're also looking into options on allowing a "hook" to auto-refresh these values - I'll have an update on this in a week or so.

ant-kurt collaborator · 1 year ago

Update: right now we're tentatively looking to add an AWS-specific setting similar to apiKeyHelper, which will run a command when Bedrock indicates credentials are expired. This will likely surface stdout directly to the user, since some configurations require user-facing verification codes.

We're also open to offering a setting to return AWS_ACCESS_KEY_ID etc, if that's a configuration that folks need (can't modify .aws for some reason?)

zaripych · 1 year ago

Was researching and just bumped into this myself.

can't modify .aws for some reason

👍 Many people have .aws configs on their machines managed by their employer. So might not be always editable (or hassle to maintain if updated). Sometimes those have multiple aws-profiles and bedrock might work only on one of them. (ie have to pass AWS_PROFILE to Claude for it to work)

We have a wrapper around Claude Code that passes in bedrock related environment variables.

This wrapper however, doesn't affect Claude Code controlled by the IDE's (VSCode).

So, if you ask VSCode to fix a problem for you - it starts Claude which is unable to authenticate. It can be closed and restarted via wrapper with --continue but still a bit annoying.

So, some sort of awsAuthHelper that allows:

  • Not having to export AWS_PROFILE globally (to not affect other tools)
  • Automatically refreshes the key (to solve the key expiry)
  • Make sure these keys are not passed on to Bash tool and other tools started via REPL (security)

Would be great.

Thank you.

ant-kurt collaborator · 1 year ago
jonmabe · 1 year ago

Running on macos v1.0.52, I'm getting an "Found invalid settings files" message on launch and "Unrecognized field" response in /doctor when trying to use this setting.

jonm@local bar % cat ~/.claude/settings.json 
{
  "permissions": {
    "allow": [],
    "deny": []
  },
  "awsAuthRefresh": "aws sso login --profile myprofile"
}
jonm@local bar % claude update
Current version: 1.0.52
Checking for updates...
Claude Code is up to date (1.0.52)
jonm@local bar % claude                     
╭───────────────────────────────────────────────────────────╮
│ ✻ Welcome to Claude Code!                                 │
│                                                           │
│   /help for help, /status for your current setup          │
│                                                           │
│   cwd: /Users/jonm/foo/bar  │
╰───────────────────────────────────────────────────────────╯


 ⚠ Found invalid settings files. They will be ignored. Run /doctor for details.

 Claude CLI Diagnostic
 Currently running: npm-global (1.0.52)
 Path: /opt/homebrew/Cellar/node/23.7.0/bin/node
 Invoked: /opt/homebrew/bin/claude
 Config install method: global
 Auto-updates enabled: true
 Update permissions: Yes

 Invalid Settings
 /Users/jonm/.claude/settings.json
  └ Unrecognized field: awsAuthRefresh
ant-kurt collaborator · 1 year ago

Sorry about that, this is actually in 1.0.53!

leotac · 1 year ago

Opened an issue about the new feature. Not working well for me, for whatever reason #3823

Yukitada-Ri · 1 year ago

@ant-kurt
Hi, I set awsAuthRefresh but it still can not use the updated aws credentials...

I setup awsAuthRefresh to ./claude/settings.local.json like the below.
I added the command(aws-azure-login --no-prompt) which refresh and create a new aws_access_key_id, aws_secret_access_key and aws_session_token with 1 hour expiration.

{
  "awsAuthRefresh": "aws-azure-login --no-prompt",
  "env": {
    "CLAUDE_CODE_USE_BEDROCK": "1",
    "AWS_PROFILE": "default",
    "AWS_REGION": "us-east-1",
    "ANTHROPIC_MODEL": "arn:aws:bedrock:us-east-1:670*********:application-inference-profile/lf1*******",
    "ANTHROPIC_SMALL_FAST_MODEL": "arn:aws:bedrock:us-east-1:670*********:application-inference-profile/lf1*******"
  }
}

In claude code, when the session expire, it run the command (aws-azure-login --no-prompt).
I checked ~/.aws/credentials and can see the new aws_access_key_id, aws_secret_access_key and aws_session_token are created.
But the claude code does not use the new created aws_access_key_id, aws_secret_access_key and aws_session_token and shows the error like this.

> hi
(node:36932) NOTE: We are formalizing our plans to enter AWS SDK for JavaScript (v2) into maintenance mode in 2023.

Please migrate your code to use AWS SDK for JavaScript (v3).
For more information, check the migration guide at https://a.co/7PzMCcy
(Use `node --trace-warnings ...` to show where the warning was created)

Logging in with profile 'default'...

Using AWS SAML endpoint https://signin.aws.amazon.com/saml

Assuming role arn:aws:iam::670*********:role/aws-************-****-admin

  ⎿  API Error (403 The security token included in the request is expired) · Retrying in 1 seconds… (attempt 1/10)
  ⎿  API Error (403 The security token included in the request is expired) · Retrying in 1 seconds… (attempt 2/10)
  ⎿  API Error (403 The security token included in the request is expired) · Retrying in 2 seconds… (attempt 3/10)
  ⎿  API Error (403 The security token included in the request is expired) · Retrying in 4 seconds… (attempt 4/10)
  ⎿  API Error (403 The security token included in the request is expired) · Retrying in 10 seconds… (attempt 5/10)
  ⎿  API Error (403 The security token included in the request is expired) · Retrying in 18 seconds… (attempt 6/10)
  ⎿  API Error (403 The security token included in the request is expired) · Retrying in 34 seconds… (attempt 7/10)
  ⎿  API Error (403 The security token included in the request is expired) · Retrying in 38 seconds… (attempt 8/10)
  ⎿  API Error (403 The security token included in the request is expired) · Retrying in 37 seconds… (attempt 9/10)
github-actions[bot] · 1 year ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.