
杉嵜です。肩甲骨のコリが最近の悩みです。
今回は、AWS の Lambda 関数から Google Cloud の Workload Identity Federation を使おうとした際に遭遇したエラーの話です。特に SAM や CloudFormation で AWS リソースを作成している場合に発生しやすいです。
The size of mapped attribute google.subject exceeds the 127 bytes limit. Either modify your attribute mapping or the incoming assertion to produce a mapped attribute that is less than 127 bytes.
自分は以下記事の実装をした際に遭遇したのですが、AWS と Google Cloud にまたがるためややこしい事象なのと、社内でも同じような事象に遭遇した人が出たので、小ネタとしてまとめておきます。
Workload Identity Federation(WIF)
Workload Identity Federation (Workload Identity連携、以下 WIF)は Google Cloud の外部からリソースにアクセスする際の認証方式です。ここでいう外部とは AWS や Azure、GitHub Actions などを指します。長期的な認証情報を使わなくて済むので、よりセキュアに認証できます。
どこでハマったか
AWS と連携する際の Workload Identity Pool (以下 WIP)の属性マッピングは、認証情報を借りようとしているユーザの識別子 google.subject として、デフォルトでは assumed-role の ARN がマッピングされます。この google.subject は127バイト以下にしないといけないですが、Lambda 関数から連携するケースでは基本的に assumed-role の ARN に IAM ロール名と Lambda 関数名が使われるので、これが長いと ARN が127バイトを超えてしまい、WIF 側でエラーになってしまいます。
対応方針としては以下のどちらかになります。
- Google Cloud の WIP の属性マッピングを変更し、
google.subjectを短くする - AWS のリソース名を短くし、生成される ARN を短くする
- IAM ロール名、Lambda 関数名など
Lambda 関数1つだけなら名前変更で対応できなくもないですが、可能なら属性マッピングを変更して127バイトを超えないようにしておきたいところです。
事象発生から原因判明まで

以前書いた記事で出したツールの構成図です。
この構成に至るまでの技術調査で、手動で Lambda 関数を作成して WIF と連携した際には起きませんでした。しかし AWS SAM テンプレートに書き起こして Lambda 関数などを生成し実行したところ、WIF との連携が上手くいかずに動作しませんでした。その後、ログ出力などを調整して確認できたエラーが、冒頭にも書いたこのようなエラーでした。
The size of mapped attribute google.subject exceeds the 127 bytes limit. Either modify your attribute mapping or the incoming assertion to produce a mapped attribute that is less than 127 bytes.
Google Cloud の WIP 側で google.subject にマッピングしようとした値が、上限である127バイトを超えてる旨のエラーです。ここで、AWS と連携する時に作成した WIP では、デフォルトで入っていた CEL 式 assertion.arn が入っていました( 参考 )。この値は最終的に AWS の Assumed Role の ARN が渡されるのですが、その ARN が127バイトを超えているためにエラーが出ているとわかりました。
AWS Assumed Role
デフォルトで google.subject に割り当てられる、Assumed Role の ARN を見てみましょう。このドキュメントによると、ARN はこのような形式の文字列になります。
arn:aws:sts::ACCOUNT:assumed-role/ROLE-NAME/ROLE-SESSION-NAME
ARN のうち固定の文字列とアカウント ID(12バイト)の合計は40バイトなので*1、全体で127バイトに収めるためにはロール名とセッション名で87バイトまでにしなければなりません。ここで、Lambda から使用する際のセッション名にはデフォルトで Lambda 関数名が使われるので、今回のケースでは IAM ロール名とLambda 関数名を合計87バイト以内に収める必要があります 。現状は半角文字だけなので、そのまま87文字ということになります。
AWS SAM などで生成したリソース名が、2つ合わせて87文字を超えるケースは珍しくありません。そのため、今回のように「手動で Lambda 関数を作って接続してみた時は問題なかったのに、SAM テンプレートにして生成した時は動かなくなった」という事象が起きたりします。
属性マッピングを編集して解消する
今回は ARN をそのままgoogle.subjectにマッピングせず、部分文字列をマッピングすることで解消させます。CEL 式のextract()関数を用いて部分文字列を抽出することで、文字数を削減します。色んな切り出し方が考えられますが、IAM ロール名だけなら上限64文字なので、Lambda 関数名の部分を切り落とすことで確実に127バイトに収められます。将来的に Assumed Role 以外のロールでアクセスされた場合も考慮すると、例えば以下のような式になります。
assertion.arn.contains('assumed-role') ? assertion.arn.extract('assumed-role/{role_name}/') : assertion.arn
マッピングを変更した場合、当然ながらgoogle.subjectが取りえる値は変わるので、後段の権限制御で値を使う場合は注意が必要です。
マッピングの妥当性
google.subjectの値に求められる要件として、Google Cloud のドキュメントにはこのように書かれています。
An external identity maps to exactly one google.subject value. A google.subject value maps to exactly one external identity. You can look up an external identity by its google.subject value.
要するに「external identity」と1対1で紐付け、google.subjectの値から逆引きできるようにするということです。
今回のケースでは IAM ロールが逆引きできます。従って、IAM ロールを使い回している場合は Lambda 関数名を特定することはできません。もっとも、複数の Lambda 関数で同じロールを使い回す構築は望ましくないので、多くのケースでは IAM ロールが特定できれば十分かと思います。
終わりに
以上、AWS から Google Cloud の Workload Identity Federation を利用する際にハマったエラーの話でした。普段の私の業務は AWS と Google Cloud を連携させるシステムを扱ってなかったので、Google Cloud 側の仕組みの理解に時間がかかり、解決までとても苦労しました。わかってしまえば単純ですが、本記事が同じような事象で困ってる人の助けになればと思います。
*1:arn:aws:sts::123456789012:assumed-role/ の39バイトと、ロール名の直後のスラッシュで合計40バイトとなる。