Github ActionsからOIDCでIAM Roleを使用する場合では、セッションにタグは付与されない理由

# 今回の内容

以下の記事について、さらに調べてなぜそうなるかの内部的な仕組みについて把握したのでまとめます

https://qiita.com/willco21/items/fba62a87742daa4dfa75

# いきなりまとめ

- OIDCの場合、内部ではAWSのAssumeRoleWithWebIdentity APIを使用しており、このAPIでは認証に使うTokenのClaimにタグ情報を記載することで使用する認証内にタグ情報を持つことができる。
  - `https://aws.amazon.com/tags`のKey内に記載する

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_adding-assume-role-idp

- しかし、github側ではclaimに上記情報を付与していない。そのためセッションタグを付与することができない
  - subを変更できる機能はあるが、claimにKey自体を追加する機能はない。

https://docs.github.com/en/actions/security-for-github-actions/security-hardening-your-deployments/about-security-hardening-with-openid-connect#understanding-the-oidc-token


# AssumeRoleWithWebIdentityのAPIにおけるタグ付与の方法

API ドキュメントを見るにAssumeRoleWithWebIdentityでもタグ情報は持つことができるように見えます

https://docs.aws.amazon.com/ja_jp/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html#API_AssumeRoleWithWebIdentity_RequestParameters

以下のように書かれており、web identity tokenの中で渡すことで付与できるとのことです

>Tags
>(Optional) You can configure your IdP to pass attributes into your web identity token as session tags. Each session tag consists of a key name and an associated value. For more information about session tags, see [Passing Session Tags in AWS STS in the IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html) User Guide.

一方で、AssumeRoleWithWebIdentityのAPI引数にはtagはありません。

リンク先を見るとセッションタグを渡す方法としてPrincipalTag OIDC トークンと記載されています

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372042/b652f4ef-be79-416b-83b2-6944810fb694.png)

つまりリクエストパラメータの以下の部分に含める必要があるということになります

>WebIdentityToken
>The OAuth 2.0 access token or OpenID Connect ID token that is provided by the identity provider. Your application must get this token by authenticating the user who is using your application with a web identity provider before the application makes an AssumeRoleWithWebIdentity call. Timestamps in the token must be formatted as either an integer or a long integer. Tokens must be signed using either RSA keys (RS256, RS384, or RS512) or ECDSA keys (ES256, ES384, or ES512).

WebIdentityTokenに渡す値（JWT）ついては、以下の記事をとかが参考になるかなと思います

https://it-biz.online/it-skills/jwt/

要するにJson情報を署名してToken化をしているものです。これも用いることで安全に認証を行っています

なので、このToken内にtagの情報を入れておけばセッションタグを付与可能です
そして、AWS側もどのような情報を入れれば良いかをドキュメントに記載しています

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_adding-assume-role-idp

以下は引用ですが、`"https://aws.amazon.com/tags"`の要素を含めればOKだとわかります

>```json
>{
>    "sub": "johndoe",
>    "aud": "ac_oic_client",
>    "jti": "ZYUCeRMQVtqHypVPWAN3VB",
>    "iss": "https://xyz.com",
>    "iat": 1566583294,
>    "exp": 1566583354,
>    "auth_time": 1566583292,
>    "https://aws.amazon.com/tags": {
>        "principal_tags": {
>            "Project": ["Automation"],
>            "CostCenter": ["987654"],
>            "Department": ["Engineering"]
>        },
>        "transitive_tag_keys": [
>            "Project",
>            "CostCenter"
>        ]
>    }
>}
>```

# githubが発行するJWTについて

では、githubが提供するJWTはどのようなものかというと、以下のドキュメントに記載されています

https://docs.github.com/en/actions/security-for-github-actions/security-hardening-your-deployments/about-security-hardening-with-openid-connect#understanding-the-oidc-token

この中には`"https://aws.amazon.com/tags"`は含まれていません。
たしかに、awsのためだけに共通でこのKey情報を含めるのは現実的ではなさそうです

では、claimの要素を足して`"https://aws.amazon.com/tags"`を含めることは可能なのでしょうか

## claimのカスタマイズについて

claimのカスタマイズについては、以下の部分で様々な方法を触れています。

https://docs.github.com/ja/actions/security-for-github-actions/security-hardening-your-deployments/about-security-hardening-with-openid-connect#customizing-the-token-claims

一方で、`aud` と `sub`の要素のカスタマイズしか記載されておらず、Keyを追加することはできません

## 独自Tokenの発行について

ここで結論としても良いのですが、JWTの仕組みを使用している以上、独自にToken発行をするアプローチも検討できます。

これについては、以下のページにて案内されています

https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-cloud-providers

ここでは2つの方法を提示しています

1. actions/core のgetIDToken()を使用してTokenを取得
1. curlを使用してTokenを取得

一方でいずれにしても署名済みのTokenの取得になるので、こちら側で追加するのは難しそうです

なので結局Token発行の処理で、`"https://aws.amazon.com/tags"`を追加する必要があります

# 今後実現するには

actions/core のgetIDTokenは 以下のリポジトリで管理されています。

https://github.com/actions/toolkit

なのでこの部分にて、`"https://aws.amazon.com/tags"`の対応、あるいはユーザー側からのclaim Keyの追加などがサポートされる などが必要と思われます。