3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

語るも涙、聞くも涙。GitHub ActionsのAWS OIDC認証が新規リポジトリだけ失敗した2026年7月の思い出 (Not authorized to perform sts:AssumeRoleWithWebIdentity)

3
Last updated at Posted at 2026-08-03

image.png

TL;DR

  • aws-actions/configure-aws-credentials@v6 を使ったOIDC認証が、古いリポジトリでは通るのに新しいリポジトリでは通らないという謎に遭遇した
  • 原因は2026年7月15日にGitHubへ入った変更で、それ以降に作られたリポジトリは sub クレームの形式が変わっていた
  • 具体的には repo:OWNER/REPO:ref:refs/heads/main だった形式が repo:OWNER@OWNER_ID/REPO@REPO_ID:ref:refs/heads/main に変わっていた
  • IAMロールの信頼ポリシーをこの新形式に合わせて書き直したら、あっさり解決した

はじめに

だいぶ前に作ったリポジトリでは、IAMロールの信頼ポリシーをこう書けば何の問題もなくGitHub ActionsからAWSの認証が通っていました。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::<AWS_ACCOUNT_ID>:oidc-provider/token.actions.githubusercontent.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "token.actions.githubusercontent.com:sub": "repo:<octo-org>/<octo-repo>:ref:refs/heads/<branch>",
                    "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
                }
            }
        }
    ]
}

< > で囲った部分はすべてプレースホルダーです。実際にはご自身の値に読み替えてください。<branch>main固定ではなく、対象にしたい任意のブランチ名(あるいはタグなど)に置き換えてもらって構いません。

長年これでやってきて、なんの疑いも持っていませんでした。repo:<octo-org>/<octo-repo>:ref:refs/heads/<branch> という文字列さえsubの条件に書いておけば、OIDCは通る。そう信じて疑わなかったのです。

ところが2026年7月30日、新しく作ったリポジトリで同じようにGitHub Actionsのデプロイワークフローを組み、いつも通り信頼ポリシーに新しいリポジトリ名を追記しました。

認証されませんでした。

uses: aws-actions/configure-aws-credentials@v6 のステップが Could not assume role with OIDC: Not authorized to perform sts:AssumeRoleWithWebIdentity の一言を残して止まってしまいました。何年も同じやり方で通ってきたのに、なぜ今回だけ。最初は信頼ポリシーのタイプミスを疑い、リポジトリ名の大文字小文字を疑い、OIDCプロバイダーのARNを疑いました。原因はどれでもありませんでした。

語るも涙、聞くも涙の物語です。

原因:知らないうちにsubクレームの仕様が変わっていた

正体は、2026年7月15日にGitHub側にひっそりと入っていた変更でした。

GitHubのOIDCリファレンスには、この日以降に作成されたリポジトリでは、subクレームのデフォルト形式がオーナーIDとリポジトリIDを含む恒久的な形式に切り替わったと記載されています。

  • 旧形式(mutable): repo:<octo-org>/<octo-repo>:ref:refs/heads/<branch>
  • 新形式(immutable): repo:<octo-org>@<OWNER_ID>/<octo-repo>@<REPO_ID>:ref:refs/heads/<branch>

configure-aws-credentialsのREADMEにも同様の記述があり、2026年7月15日以降に作られたリポジトリ(および opt-in 済みの旧リポジトリ)は、組織とリポジトリそれぞれの永続的な数値IDを名前の後ろに@区切りで付与したsubクレームを発行するようになった、と説明されています。これは、リポジトリ名やOrg名が削除・再利用された際に、古い信頼ポリシーが新しい(しかし同名の)リポジトリに誤ってマッチしてしまう事故を防ぐための変更とのことです。

なぜこの変更が入ったかという「意図」自体はセキュリティ上まっとうです。ただ問題は、この変更が入ったことを知らずに、いつも通りのテンプレートで信頼ポリシーを書いてしまったことにあります。旧リポジトリのsubrepo:<octo-org>/<octo-repo>:ref:refs/heads/<branch>のままなので今まで通り動く一方、2026/7/15以降に新規作成したリポジトリの実際のsubrepo:<octo-org>@<OWNER_ID>/<octo-repo>@<REPO_ID>:ref:refs/heads/<branch>になっていて、両者はまったく別の文字列として扱われます。信頼ポリシー側は旧形式のままなので、当然マッチしません。

つまり、同じ書き方をしているつもりで、実は「別のフォーマットのIDカード」を求められていたというのが今回のオチでした。

対処:subクレームを新形式に書き換える

対処自体はシンプルです。信頼ポリシーのsubを新形式に合わせて書き直すだけです。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::<AWS_ACCOUNT_ID>:oidc-provider/token.actions.githubusercontent.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "token.actions.githubusercontent.com:sub": "repo:<octo-org>@<OWNER_ID>/<octo-repo>@<REPO_ID>:ref:refs/heads/<branch>",
                    "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
                }
            }
        }
    ]
}

ここでも< >部分はプレースホルダーです。<OWNER_ID><REPO_ID>だけ新たに埋める必要があり、それ以外(<AWS_ACCOUNT_ID><octo-org><octo-repo><branch>)は「はじめに」で使ったものと同じ考え方で読み替えてください。

ポイントは、旧リポジトリと新リポジトリでsubのフォーマットが違うまま共存するということです。7/15より前に作ったリポジトリは、こちらから明示的にオプトイン(=この場合、旧リポジトリ側で新形式を有効にする設定をオンにすること)しない限り旧形式のままなので、慌てて全部書き換える必要はありません。新規作成分だけ新形式で追記すればOKです。ただしセキュリティの観点では、余裕があれば旧リポジトリ側もオプトインして新形式に揃えておいた方が望ましいです。

OWNER_IDとREPO_IDの調べ方

肝心の<OWNER_ID><REPO_ID>は、対象リポジトリの Settings → Actions → OIDC ページをたどれば確認できます。そのリポジトリが実際に発行するsubクレームの形式(オーナーIDとリポジトリIDを含んだ文字列)がそのまま表示されています。ここに出ている値をコピーして、信頼ポリシーのsub条件にそのまま貼り付ければ間違いがありません。

スクリーンショット 2026-08-03 15.05.40.png

2026/7/15以降に作ったリポジトリは、デフォルトで、「Use immutable subject claim」に✅️があります。
2026/7/15より前に作ったリポジトリで、オプトインしたい場合は、この設定に✅️を入れます。

まとめ

  • 2026年7月15日を境に、新規作成されたGitHubリポジトリのOIDC subクレームはrepo:<octo-org>@<OWNER_ID>/<octo-repo>@<REPO_ID>:ref:refs/heads/<branch>という恒久的な形式に変わった
  • 旧リポジトリはそのままなので、同じ組織の中で新旧フォーマットが混在することがある
  • 信頼ポリシーのsub条件は、リポジトリの作成日に応じてどちらの形式で書くべきか確認が必要
  • リポジトリのSettings → Actions → Generalページを見れば、OWNER_ID/REPO_IDを含む実際のsubクレームがそのまま確認できる
  • 「いつも通りのコピペ」がある日突然通らなくなったら、GitHub側の仕様変更を疑うべし

知らないところで足元の仕様が変わっていた、地味だけどハマると小一時間溶かされる話でした。同じ轍を踏む人が一人でも減れば幸いです。

参考

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?