GitHub Actions から AWS:「Could not load credentials from any providers」
aws-actions/configure-aws-credentials が、サインインに使える認証情報を見つけられませんでした。OIDC で引き受けられるロールもアクセスキーも渡されないと、アクションはマシン自身の認証情報を探しますが、GitHub のホストランナーにはありません。多いのは、ロールの ARN かキーはワークフローに書いてあるのに、アクションには空の文字列で届いたケースです。GitHub は、その実行に渡さないシークレットを "" にし、エラーも出しません。
見え方
Retry validateCredentials: reached max retries (12); giving up. Error: Credentials could not be loaded, please check your action inputs: Could not load credentials from any providers
アクションは待ち時間を延ばしながら12回試してからあきらめるので(helpers.ts)、ステップが失敗するまで少し時間がかかります。原因を探すあいだは retry-max-attempts: 1 にすると、すぐに失敗します。
2つのどちらか
ログでステップを開き、やり直しの行より上を見ます。
- 「It looks like you might be trying to authenticate with OIDC. Did you mean to set the
id-tokenpermission?」の行がある:アクションがこれを記録するのは、role-to-assumeに値があり、ジョブに OIDC のトークンが無いときだけです(index.ts)。ロールは届いていて、権限が足りません(6)。 - その行が無く、ログのステップの
with:の一覧にrole-to-assume(またはaws-access-key-id)が無い:値が空でした。aws-durable-execution-docs(#301)・konica/agent-tutor(#278)・saayam-for-all/ai(#215)では、失敗したステップの入力の一覧にその行がまったくありませんでした。よくある理由は1から4です。
1. フォークからのプルリクエスト
GitHub のドキュメント:「With the exception of GITHUB_TOKEN, secrets are not passed to the runner when a workflow is triggered from a forked repository.」(GITHUB_TOKEN を除き、フォークしたリポジトリから起動されたワークフローでは、シークレットはランナーに渡されません)。closed のイベントも同じです:saayam-for-all/ai では、フォークのプルリクエストがマージされたときに動くデプロイのジョブがこれで失敗しました。マージでできるブランチへのプッシュの実行にはシークレットがあるので、デプロイはプッシュの側に置きます(#215)。rotel-lambda-extension は、フォークのプルリクエストでは AWS のステップを飛ばします(#99):
- uses: aws-actions/configure-aws-credentials@v6
if: ${{ github.event.pull_request.head.repo.fork != true }}
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: us-east-1
2. Dependabot
GitHub のドキュメント:「When a Dependabot event triggers a workflow, the only secrets available to the workflow are Dependabot secrets. GitHub Actions secrets are not available.」(Dependabot のイベントでワークフローが動くとき、使えるシークレットは Dependabot のシークレットだけで、GitHub Actions のシークレットは使えません)。NASA-IMPACT/veda-backend(#682)と shiptrack-modern(#61)では、Dependabot のプルリクエストがこれで失敗しました。同じ名前で Dependabot のシークレットにも値を入れるか(両方から動くワークフローには、ドキュメントがこれを勧めています)、github.actor != 'dependabot[bot]' で AWS のステップを飛ばします。shiptrack-modern は、Dependabot に AWS を触らせないために後者を選びました。
3. 式が見ている場所にシークレットが無い
- environment のシークレットは、その environment を使うジョブにしか届きません。ドキュメント:「These secrets are only available to workflow jobs that use the environment.」(これらのシークレットは、その environment を使うジョブでしか使えません)。ジョブに
environment: production(自分の environment の名前)を足します。 - その名前のシークレットが無い。aws-durable-execution-docs では、シークレットの名前を確かめると、リポジトリのシークレットに
BEDROCK_ROLE_ARNは無く、ジョブの environment にはシークレットが1つもありませんでした(#301)。名前は Settings > Secrets and variables > Actions か、gh secret listとgh secret list --env NAMEで見られます。 - ARN をシークレットではなく変数に入れている。値が
vars.AWS_DEPLOY_ROLE_ARNにあると、secrets.AWS_DEPLOY_ROLE_ARNは空です。verifypass はどちらからでも読むようにしました:${{ secrets.AWS_DEPLOY_ROLE_ARN || vars.AWS_DEPLOY_ROLE_ARN }}(#4)。
4. シークレットを渡していない再利用ワークフロー
呼び出されたワークフローに届くのは、呼び出し側が渡したシークレットだけです。自分のジョブがそのシークレットのある environment を使っていても同じです。ドキュメント:「The caller workflow must still pass the secret」(それでも呼び出し側がシークレットを渡す必要があります)、「If the caller workflow doesn't pass an environment secret, the secret resolves to an empty string in the reusable workflow. The workflow run doesn't show an error.」(呼び出し側が environment のシークレットを渡さないと、再利用ワークフローではそのシークレットは空の文字列になり、実行にエラーは出ません)。konica/agent-tutor の最初のデプロイはここで止まり、呼び出す6つのジョブに secrets: inherit を足しました(#278)。
# 呼び出し側
jobs:
deploy:
uses: ./.github/workflows/deploy.yml
secrets: inherit
# deploy.yml
on:
workflow_call:
secrets:
AWS_ROLE_ARN:
required: true
required: true にすると、呼び出し側がシークレットを渡さないときに実行が失敗します。シークレットに値があるかまでは確かめません。
5. 空なら、その場で止める
シークレットは if: で直接使えないので、ドキュメントはジョブの環境変数にすることを勧めています。アクションの前のステップで何が悪いかを1行で出すか、if: env.AWS_ROLE_ARN != '' で AWS のステップを飛ばします:
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
env:
AWS_ROLE_ARN: ${{ secrets.AWS_ROLE_ARN }}
steps:
- if: env.AWS_ROLE_ARN == ''
run: |
echo "::error::AWS_ROLE_ARN is empty in this run (fork, Dependabot, environment or caller)"
exit 1
- uses: aws-actions/configure-aws-credentials@v6
with:
role-to-assume: ${{ env.AWS_ROLE_ARN }}
aws-region: us-east-1
6. ロールはあるのに、ジョブに id-token: write が無い
権限が無いとジョブに OIDC のトークンが無いので、アクションは OIDC を試さず、同じメッセージで終わります。id-token: write を足します。ジョブに permissions: を書くとワークフローの分が置き換わるので、自分の分を書いたジョブにも要ります。再利用ワークフローのつながりでは権限は「can only be maintained or reduced」(保つか減らすことしかできない、とドキュメント)ので、呼び出す側のジョブにも要ります。トークンが届いて AWS がそれを断ると、エラーは「Not authorized to perform sts:AssumeRoleWithWebIdentity」に変わります:GitHub Actions の OIDC で AWS に入れない。
7. セルフホストランナー
ロールもキーも無いと、アクションは AWS SDK の既定のチェーンを通して、マシンが持っている認証情報を使います:環境変数、~/.aws のファイル、コンテナの認証情報(ECS・EKS・CodeBuild)、インスタンスのメタデータ(CredentialsClient.ts)。セルフホストランナーでこのメッセージが出るのは、ランナーのプロセスにそのどれも答えなかったということです。アクションの README には CodeBuild と EKS のランナーのことと、マシン自身のロールから別のロールを引き受ける role-chaining: true が書いてあります。
見分け方
- 「Credentials could not be loaded, please check your action inputs:」のあとに「The security token included in the request is invalid」のような AWS 自身の理由が続く:キーはアクションに届いていて、AWS が断りました。アクションは
GetCallerIdentityでキーを確かめ、AWS のメッセージを同じ書き出しのあとにつけます。 - 「'aws-secret-access-key' must be provided if 'aws-access-key-id' is provided」:2つのキーのシークレットのうち、片方だけが空でした。
- 「Could not assume role with OIDC: Not authorized to perform sts:AssumeRoleWithWebIdentity」:トークンは届き、ロールの信頼ポリシーが合いませんでした(OIDC のページ)。
失敗したジョブを IntelliJ IDEA から見るなら
Pipeline Inbox for GitHub Actions Workflows は、Lesstep が作っている JetBrains IDE(2024.1 以降)のプラグインです。すべてのリポジトリの実行を、ジョブ・ステップと一緒に IDE のツールウィンドウに並べ、いまのブランチの実行はステータスバーに出ます。読むのは無料、失敗したジョブの再実行・キャンセル・ワークフローの実行・デプロイのレビューは Pro(月 US$1.50・30日の無料試用つき)です。
GitHub と GitHub Actions は GitHub, Inc. の商標、AWS は Amazon.com, Inc. またはその関連会社の商標、IntelliJ IDEA は JetBrains s.r.o. の商標です。このページは GitHub, Inc.・Amazon・JetBrains のいずれとも提携しておらず、承認も受けていません。
ほかに:「Not authorized to perform sts:AssumeRoleWithWebIdentity」 · npm publish の「ENEEDAUTH」 · 「Resource not accessible by integration」 · IntelliJ IDEA で使える GitHub Actions のプラグインの比較 · English