Claude Codeでスイッチロールができない場合の対応方法

Claude Codeでスイッチロールができない場合の対応方法

Clock Icon2025.06.12

こんにちは。たかやまです。

最近Claude Codeに入門して触っています。

Claude Codeではコーディングのほか、AWS環境の操作も依頼しています。

複数のAWS環境を扱う際に、Claude Code内でスイッチロールを行って異なるアカウントにアクセスしたい場面があります。

普段 awsume を使っているのですが、awsume でスイッチロールを実行したつもりが、実際には元のアカウントのままでアクセス拒否エラーが発生してしまいました。

> awsume classmethodを実行した後 aws s3 lsを実行してください。

⏺ Bash(awsume classmethod)
  ⎿  Session token will expire at 2025-06-12 21:06:18
     [classmethod] Role credentials will expire 2025-06-12 10:18:28

⏺ Bash(aws s3 ls)
  ⎿  Error: An error occurred (AccessDenied) when calling the ListBuckets operation: User: arn:aws:iam::<スイッチ前のアカウントID>:user/cm-takayama.kotaro is 
     not authorized to perform: s3:ListAllMyBuckets with an explicit deny in an identity-based policy

⏺ AWS role switched to classmethod but S3 access is denied due to an explicit deny policy.

そこで今回はClaude CodeでAWS環境の切り替えを正しく動作させる方法をご紹介します。

さきにまとめ

  • Claude Codeは独立したセッションでコマンドを実行するため、Claude Code内で設定した環境変数は後続のコマンドに引き継がれない
  • 対応方法として以下のアプローチがある
    • AND演算子を使用した同一セッション内での環境変数の引き継ぎ

      サンプルプロンプト
      awsコマンドを実行する前には `awsume <your-profile> &&`して実行してください。
      
      サンプルコマンド
      awsume <your-profile> && aws s3 ls
      
    • Claude Codeの環境設定(.claude/settings.local.json)にAWS環境変数を設定する

      awsume <your-profile> >/dev/null 2>&1 && \
      jq --arg ak "$AWS_ACCESS_KEY_ID" \
         --arg sk "$AWS_SECRET_ACCESS_KEY" \
         --arg st "$AWS_SESSION_TOKEN" \
         '.env={AWS_ACCESS_KEY_ID:$ak,AWS_SECRET_ACCESS_KEY:$sk,AWS_SESSION_TOKEN:$st}' \
         .claude/settings.local.json > .claude/settings.local.json.tmp && \
      mv .claude/settings.local.json.tmp .claude/settings.local.json && \
      echo "✅ Claude AWS認証情報を更新しました"
      

原因調査

発生したエラー

冒頭記載したように以下のようなエラーが発生しました。

awsume classmethodで認証は成功したように見えますが、実際のS3操作でアクセス拒否エラーが発生しています。

> awsume classmethodを実行した後 aws s3 lsを実行してください。

⏺ Bash(awsume classmethod)
  ⎿  Session token will expire at 2025-06-12 21:06:18
     [classmethod] Role credentials will expire 2025-06-12 10:18:28

⏺ Bash(aws s3 ls)
  ⎿  Error: An error occurred (AccessDenied) when calling the ListBuckets operation: User: arn:aws:iam::<スイッチ前のアカウントID>:user/cm-takayama.kotaro is 
     not authorized to perform: s3:ListAllMyBuckets with an explicit deny in an identity-based policy

⏺ AWS role switched to classmethod but S3 access is denied due to an explicit deny policy.

原因調査

awsume のコマンドを実行した後、envコマンドを実行してみるとAWS関連の環境変数が設定されていないことがわかります。

> envコマンドを実行してください。

⏺ Bash(env)
  ⎿  MallocNanoZone=0
     USER=takayama.kotaro
     COMMAND_MODE=unix2003
     __CFBundleIdentifier=com.todesktop.230313mzl4w4u92
     … +52 lines (ctrl+r to expand)

⏺ Environment variables displayed. No AWS-related environment variables are currently set, which confirms the role
  switch from awsume affected the current session but didn't persist to environment variables in this shell
  context.

> `awsume classmethod` を実行した後 `env | grep AWS_` コマンドを実行してください。

⏺ Bash(awsume classmethod)
  ⎿  Session token will expire at 2025-06-12 21:06:18
     [classmethod] Role credentials will expire 2025-06-12 10:29:36

⏺ Bash(env | grep AWS_)  # ここではAWS関連の環境変数が設定されていないことがわかる
  ⎿  No matches found

⏺ No AWS environment variables are set after awsume execution. This suggests awsume may be running in a subshell or
   the credentials aren't being exported to the current environment.

awsume classmethod && aws s3 ls のように&&(AND演算子)であればawsume のコマンドを実行した後、aws s3 lsを実行しても正しくスイッチロールが実行されていることがわかります。

> `awsume classmethod && aws s3 ls`を実行してください。

⏺ Bash(awsume classmethod && aws s3 ls)
  ⎿  2025-04-04 09:19:19 bucket1
     2025-05-05 12:02:21 bucket2
     2024-11-09 12:46:44 bucket3
     2024-11-12 17:06:31 bucket4
     … +23 lines (ctrl+r to expand)

⏺ Successfully switched to classmethod role and listed S3 buckets. The command worked when run together with &&.

この辺りから環境変数がセッション上で引き継がれていなそうな雰囲気を感じますね

Claude Codeに何度かbashセッションを確認させるコマンドを実行させてみます。

> bashセッションを確認するコマンドを何回か実行してください。

⏺ Bash(echo "Session 1: $$ - $(date)")
  ⎿  Session 1: 92199 - 2025年 6月11日 水曜日 16時39分17秒 JST

⏺ Bash(echo "Session 2: $$ - $(date)")
  ⎿  Session 2: 92223 - 2025年 6月11日 水曜日 16時39分24秒 JST

⏺ Bash(echo "Session 3: $$ - $(date)" && export TEST_VAR="session3" && echo "TEST_VAR set to: $TEST_VAR")
  ⎿  Session 3: 92255 - 2025年 6月11日 水曜日 16時39分36秒 JST
     TEST_VAR set to: session3

⏺ Bash(echo "Session 4: $$ - $(date)" && echo "TEST_VAR from previous session: $TEST_VAR")
  ⎿  Session 4: 92319 - 2025年 6月11日 水曜日 16時39分58秒 JST
     TEST_VAR from previous session:

⏺ Bash(ps -p $$ -o pid,ppid,command)
  ⎿    PID  PPID COMMAND
     92347 86671 /bin/zsh -c -l source /var/folders/tz/53916r9s20144g8273g3d9580000gp/T/claude-shell-snapshot-ba04 && eval 'ps -p $$ -o
     pid,ppid,command' \< /dev/null && pwd -P >| /var/folders/tz/53916r9s20144g8273g3d9580000gp/T/claude-bd8a-cwd

⏺ 結果から分かること:

  1. 各Bashツール呼び出しは独立したプロセス
    - Session 1: PID 92199
    - Session 2: PID 92223
    - Session 3: PID 92255
    - Session 4: PID 92319
    - Session 5: PID 92347
  2. 環境変数は引き継がれない
    - Session 3で設定したTEST_VARがSession 4では空
  3. プロセス構造
    - 各セッションは親プロセス86671から独立して起動
    - /bin/zsh -c -lで実行される一時的なシェル

  この証明により、Claude CodeのBashツールでawsumeセッションが永続化されない理由が明確になりました。各コマンド実行時にeval $(awsume classmethod -o env)を併用する必要があります。

この結果から、Claude Codeでは都度コマンドごとに独立したBashセッションが起動されるため、環境変数が引き継がれないことがわかります。

対応方法

解決方法1: AND演算子を使用したコマンド連結

すでに原因調査内でもやっていますが、&&(AND演算子)を使用して同一セッション内でコマンドを実行し環境変数を引き継ぐ方法です。

サンプルコマンド
awsume <your-profile> && aws s3 ls

以下のようなプロンプトや CLAUDE.md に記載することでClaude Codeがawsコマンドを実行する前にスイッチロールするようにできます。

サンプルプロンプト
awsコマンドを実行する前には `awsume <your-profile> &&`して実行してください。

解決方法2: Claude Codeの環境設定

もう一つの解決方法はClaude Codeの環境設定を行う方法です。

https://docs.anthropic.com/ja/docs/claude-code/overview

Claude Codeではsettings.jsonで環境設定を行うことができ、envキーで環境変数を設定することができます。

Example settings.json
{
  "permissions": {
    "allow": [
      "Bash(npm run lint)",
      "Bash(npm run test:*)",
      "Read(~/.zshrc)"
    ],
    "deny": [
      "Bash(curl:*)"
    ]
  },
  "env": {
    "CLAUDE_CODE_ENABLE_TELEMETRY": "1",
    "OTEL_METRICS_EXPORTER": "otlp"
  }
}

環境設定は各種で設定可能で、以下の優先順位で環境設定が適用されます。

  1. エンタープライズポリシー(macos: ~/Library/Application Support/ClaudeCode/policies.json,Linux: /etc/claude-code/policies.json)
  2. コマンドライン引数
  3. ローカルプロジェクト設定(.claude/settings.local.json)
  4. 共有プロジェクト設定(.claude/settings.json)
  5. ユーザー設定(~/.claude/settings.json)

Claude Codeの設定の優先順位 - Anthropic

プロジェクトフォルダには.claude/settings.json.claude/settings.local.json があります。
Claude Codeでは.claude/settings.local.jsonをgitで無視するように設定されているので、機密情報はこちらに記載していきます。

AWSの環境変数を.claude/settings.local.jsonに設定する場合には以下のようになります。

{
  "permissions": {
    "allow": [],
    "deny": []
  },
   "env": {
+    "AWS_ACCESS_KEY_ID": "xxxxxxxxxxxxxxxxxxxx",
+    "AWS_SECRET_ACCESS_KEY": "xxxxxxxxxxxxxxxxxxxx",
+    "AWS_SESSION_TOKEN": "xxxxxxxxxxxxxxxxxxxx"
  }
}

以下のコマンドを実行することで、 settings.local.json にAWSの認証情報を設定することができます。

awsume classmethod >/dev/null 2>&1 && \
jq --arg ak "$AWS_ACCESS_KEY_ID" \
   --arg sk "$AWS_SECRET_ACCESS_KEY" \
   --arg st "$AWS_SESSION_TOKEN" \
   '.env={AWS_ACCESS_KEY_ID:$ak,AWS_SECRET_ACCESS_KEY:$sk,AWS_SESSION_TOKEN:$st}' \
   .claude/settings.local.json > .claude/settings.local.json.tmp && \
mv .claude/settings.local.json.tmp .claude/settings.local.json && \
echo "✅ Claude AWS認証情報を更新しました"

この状態でClaude Codeでenv | grep AWS_コマンドを実行すると、settings.local.jsonに設定したAWSの認証情報が正しく設定されていることが確認できます。

> `env | grep AWS_`コマンドを実行してください

⏺ Bash(env | grep AWS_)
  ⎿ AWS_ACCESS_KEY_ID=xxxxxxxxxxxxxxxxxxxx
    AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxxxxxx
    AWS_SESSION_TOKEN=xxxxxxxxxxxxxxxxxxxx

最後に

今回はClaude CodeでAWSスイッチロールを正しく動作させる方法を紹介しました。

Claude Codeでは各コマンドが独立したセッションで実行されるため、通常のawsumeコマンドでは環境変数が引き継がれません。

Claude Code内で環境変数を設定したい場合には今回はご紹介した対処方法を参考いただければと思います。

個人的な使い分けとしては、以下のような感じです。

  • ワンショットで別アカウントにコマンドを実行したい時は AND演算子を使用したコマンド連結を利用
  • Claude codeセッション内で特定のAWSアカウント作業を継続する場合には環境設定を利用する

このブログがどなたかの参考になれば幸いです。

以上、たかやま(@nyan_kotaroo)でした。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.