この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
先日注目が集まった、OIDCプロバイダを用いることによって実現した AWS Credentials 不要でのSwitchRole は記憶に新しいところです。ただ、正直どうやって業務利用すべきかというところでした。肝のWebIdentityTokenの扱いに困ったわけです。
そして先程GitHub ActionsでAWSを使う際に必須とも言える aws-actions/configure-aws-credentials のREADMEを見ていたところ、OIDCを用いたSwitchRoleの仕組みが追加されていました。
特にニュースとして上がっているわけではなく、いつの間に、といった感想です。同様の速報記事は多数上がるだろうと想定の元、ではどういった形で入っているのか辿ってみました。
Actionsへの変更詳細
追加は以下のPRによるものです。
WebIdentityTokenについて、特にリクエストしているコードがありません。aws-actions/configure-aws-credentials ではこのパラメータを他のライブラリから取得しています。 actions/toolkit
です。
actions/toolkitからのToken取得
AssumeRoleWithWebIdentityは以下のパラメータを揃えてリクエストを行う必要があります。
- DurationSeconds
- Policy
- PolicyArns.member.N
- ProviderId
- RoleArn
- RoleSessionName
- WebIdentityToken
他のパラメータを見る限り、やはりネックはWebIdentityToken 1点。実際の取得過程を見ていきます。
先ず ACTIONS_ID_TOKEN_REQUEST_TOKEN
と ACTIONS_ID_TOKEN_REQUEST_URL
がGitHub Actions実行時に環境変数へセットされているようですが、この2つの環境変数に関した公式ドキュメントは見当たらず。
private static getRequestToken(): string {
const token = process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN']
if (!token) {
throw new Error(
'Unable to get ACTIONS_ID_TOKEN_REQUEST_TOKEN env variable'
)
}
return token
}
private static getIDTokenUrl(): string {
const runtimeUrl = process.env['ACTIONS_ID_TOKEN_REQUEST_URL']
if (!runtimeUrl) {
throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable')
}
return runtimeUrl
}
次に ACTIONS_ID_TOKEN_REQUEST_TOKEN
を Header にセットしつつ、ACTIONS_ID_TOKEN_REQUEST_URL
へリクエスト。
return new HttpClient(
'actions/oidc-client',
[new BearerCredentialHandler(OidcClient.getRequestToken())],
requestOptions
)
返ってきたtokenが WebIdentityToken
として利用されることになります。
static async getIDToken(audience?: string): Promise<string> {
try {
// New ID Token is requested from action service
let id_token_url: string = OidcClient.getIDTokenUrl()
if (audience) {
const encodedAudience = encodeURIComponent(audience)
id_token_url = `${id_token_url}&audience=${encodedAudience}`
}
debug(`ID token url is ${id_token_url}`)
const id_token = await OidcClient.getCall(id_token_url)
setSecret(id_token)
return id_token
} catch (error) {
throw new Error(`Error message: ${error.message}`)
}
}
実装としては動くのですが、肝心の2つの環境変数については特にコメント等もないという状態でした。
あとがき
OIDCプロバイダを使った、認証不要になるという点で驚かせてくれた以下記事ですが、問題は $ACTIONS_ID_TOKEN_REQUEST_TOKEN
と $ACTIONS_ID_TOKEN_REQUEST_URL
の2点が不明瞭であること。
既にMarketPlace上ではOIDCプロバイダを前提とした認証でサンプルも掲載されています。正直もやっとしますが、動作に問題がなければ差し替えておくことでアクセスキー漏洩の心配も減りそうです。