GitHub Actions の OIDC で Azure に入れない:「AADSTS700213: No matching federated identity record found」
GitHub はジョブにトークンを渡し、Microsoft Entra ID は、アプリの登録かマネージド ID のフェデレーション資格情報から、subject がトークンの sub とまったく同じものを探しました。見つかりませんでした。AWS と違って Entra は受け取った subject を表示するので、同じ文字列の資格情報を作れば直ります。
見え方
Federated token details: issuer - https://token.actions.githubusercontent.com subject claim - repo:octo-org@123456/octo-repo@456789:environment:dev audience - api://AzureADTokenExchange job_workflow_ref - octo-org/octo-repo/.github/workflows/deploy.yml@refs/heads/main ... AADSTS700213: No matching federated identity record found for presented assertion subject 'repo:octo-org@123456/octo-repo@456789:environment:dev'. Check your federated identity credential Subject, Audience and Issuer against the presented assertion. Error: Login failed with Error: The process '/usr/bin/az' failed with exit code 1. Double check if the 'auth-type' is correct. Refer to https://github.com/Azure/login#readme for more information.
最後の行は、az login の失敗を azure/login が伝えているものです。そこにある auth-type はここでは関係なく、問題は subject です。azure/login はログインの前にトークンの中身を表示するので、subject はログに2回出ます。
ID があるのはどちら側か
エラーの subject と、資格情報の subject を見比べます:
az ad app federated-credential list --id APP-OBJECT-ID --query "[].{name:name,subject:subject}"
ユーザー割り当てのマネージド ID なら az identity federated-credential list --identity-name NAME --resource-group GROUP です。そのうえで:
- エラーには
@と数字があり、資格情報には無い:リポジトリが GitHub の不変の subject を使っています。GitHub の2026年4月23日の変更履歴によると、2026年7月15日より後に作られたリポジトリは自動で新しい不変の形式になり、7月15日より後の名前の変更と移管も新しい形式に移ります。古いリポジトリは、誰かが有効にしたときにこの形式になります。10月の報告には、subject が:environment:devで終わる environment のデプロイ(Dorfplatz #78)と、名前だけの subject を書いて 0 で終わり、デプロイを失敗させたままにした準備用のスクリプト(TALXIS lab #98)があります。エラーの subject で資格情報を足します。 - 資格情報には ID があり、エラーには無い:逆の向きです。Azure ポータルの GitHub Actions 用の入力欄では、オーナーとリポジトリの ID の欄は任意で、そこを埋めると不変の形式が書かれます(azure/login のトラブルシューティング)。2026年7月15日より前に作られたリポジトリはまだ名前だけを送るので、どれにも一致しません(azure/login #617)。資格情報から ID を外すか、リポジトリの OIDC の設定で不変の subject を有効にします。Microsoft の移行ガイドが向かうのは後者です。
- 形は同じなのに文字列が違う:リポジトリのあとの部分(次の節)か、大文字と小文字です。Entra は subject の大文字と小文字を区別し、そこだけが違うときは別のコード
AADSTS7002138で「The subject matches with case-insensitive comparison, but not with case-sensitive comparison.」と答えます。
ジョブを走らせずに、自分のリポジトリの接頭辞を見るには:
gh api repos/OWNER/REPO/actions/oidc/customization/sub
答えには use_immutable_subject と sub_claim_prefix があり、たとえば repo:octo-org@123456/octo-repo@456789 です。
資格情報を足す
Microsoft のガイド「Migrate GitHub Actions federated credentials to immutable subjects」から、アプリの登録の場合です。中身を credential.json に書きます:
{
"name": "octo-repo-dev",
"issuer": "https://token.actions.githubusercontent.com",
"subject": "repo:octo-org@123456/octo-repo@456789:environment:dev",
"audiences": ["api://AzureADTokenExchange"]
}
az ad app federated-credential create --id APP-OBJECT-ID --parameters ./credential.json
ユーザー割り当てのマネージド ID なら:
az identity federated-credential create --name octo-repo-dev \ --identity-name NAME --resource-group GROUP \ --issuer https://token.actions.githubusercontent.com \ --subject 'repo:octo-org@123456/octo-repo@456789:environment:dev' \ --audiences api://AzureADTokenExchange
- 1つの資格情報が当たるのは1つの subject です。
mainから、そして2つの environment を通してデプロイするワークフローには3つ要ります。または柔軟なフェデレーション資格情報を1つ使います。ガイドの例はclaimsMatchingExpressionでrepo:octo-org@123456/octo-repo@456789:*に当て、repository_idも確かめています。 - 新しい資格情報で動くまで古いものは残し、動いてから消します。Microsoft のガイドもこの順です。
- 資格情報を足したり変えたりした直後は、変更が行き渡るまでの数分間、
AADSTS70021: No matching federated identity record found for presented assertion.でログインが失敗することがあります。Microsoft の考慮事項のページは、少し待ってやり直すよう書いています。 - subject を
repo:${owner}/${repo}から組み立てるスクリプトや Bicep・Terraform のファイルは、新しいリポジトリにはどれもこれまでの形を書きます。TALXIS lab #98 が勧める直し方は、上の API からsub_claim_prefixを読むことです。
リポジトリのあとの部分
environment:のあるジョブは、ref の代わりに…:environment:名前になります。pull_requestの実行は…:pull_requestですが、ジョブに environment が無いときだけです。- それ以外は ref です:
…:ref:refs/heads/main、タグなら…:ref:refs/tags/v1.2.0。 - 値の中のコロンは
%3Aになるので、Production:V1という environment はenvironment:Production%3AV1と出ます。 - リポジトリや組織で独自のテンプレート(
include_claim_keys)を使うと、sub全体が変わります。不変の形式では、そのときもオーナーとリポジトリの ID は残る、と GitHub のドキュメントにあります。
ジョブがトークンを頼んでいない
id-token: write が無いとトークンが無く、AADSTS のコードも出ません。azure/login は「Failed to fetch federated token from GitHub. Please make sure to give write permissions to id-token in the workflow.」と記録し、「Login failed with Error: Error message: Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable.」で失敗します。
permissions: id-token: write contents: read
ジョブに permissions: を書くと、そのジョブではワークフローの分が置き換わるので、そこにも id-token: write が要ります。フォークからのプルリクエストと再利用ワークフローには、別の制限があります:「Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable」。
見分け方
AADSTS7002138:大文字と小文字だけが違う同じ subject です。- 資格情報を変えた直後の
AADSTS70021:変更がまだ行き渡っていません。 AADSTS700016:Entra がテナントにアプリを見つけられませんでした。違うのは subject ではなくclient-idかtenant-idです。- Google Cloud では、名前の形の
subを見る条件が「The given credential is rejected by the attribute condition」で失敗します。 - AWS では、同じ食い違いのメッセージに subject が出ません:「Not authorized to perform sts:AssumeRoleWithWebIdentity」。
失敗したジョブを IntelliJ IDEA から見るなら
Pipeline Inbox for GitHub Actions Workflows は、Lesstep が作っている JetBrains IDE(2024.1 以降)のプラグインです。すべてのリポジトリの実行を、ジョブ・ステップと一緒に IDE のツールウィンドウに並べ、いまのブランチの実行はステータスバーに出ます。読むのは無料、失敗したジョブの再実行・キャンセル・ワークフローの実行・デプロイのレビューは Pro(月 US$1.50・30日の無料試用つき)です。
GitHub と GitHub Actions は GitHub, Inc. の商標、Microsoft Azure と Microsoft Entra は Microsoft Corporation の商標、IntelliJ IDEA は JetBrains s.r.o. の商標です。このページは GitHub, Inc.・Microsoft・JetBrains のいずれとも提携しておらず、承認も受けていません。
ほかに:GitHub Actions の OIDC で AWS に入れない · 「Waiting」でレビューを待つ実行の承認 · npm publish の「ENEEDAUTH」 · IntelliJ IDEA で使える GitHub Actions のプラグインの比較 · English