OIDC と bot ユーザー + アクセスキー
OIDC と bot ユーザー + アクセスキー
OIDC の利点は長期認証情報の排除です(デフォルトで一時認証情報の有効期限は 1 時間です)。
さらに使用元も制限できます(例えば CircleCI の特定プロジェクトのブランチ etc )。
bot ユーザー + アクセスキーの問題点
| 問題 | 内容 |
|---|---|
| 長期認証情報 | アクセスキーは手動で削除するまで有効。漏洩しても気づきにくい |
| 漏洩リスク | CircleCI の環境変数に保存 → CircleCI が侵害されたら即アウト |
| ローテーション負担 | 定期的に手動で交換 + CircleCI の環境変数も更新が必要 |
| 使用元の無制限 | 漏洩したキーは世界中どこからでも使える |
OIDC が解決する点
OIDC では CircleCI がジョブ実行ごとに JWT トークン(一時的な身元証明書) を発行し、AWS STS ( AWS Security Token Service )がそれと引き換えに 有効期限付きの一時認証情報 を返します。
CircleCI Job
|
| (1) JWT トークン発行( CircleCI が署名)
|
▼
AWS STS ( AssumeRoleWithWebIdentity )
|
| (2) JWT を検証 → 一時認証情報を発行(有効期限: 1 時間等)
▼
AWS リソース操作
|
| (3) 有効期限切れで自動失効
|
▼
(終了)
| 比較 | bot ユーザー + アクセスキー | OIDC |
|---|---|---|
| 認証情報の寿命 | 永続(手動削除まで) | 短期(自動失効) |
| CircleCI に保存するシークレット | あり(アクセスキー) | なし |
| 漏洩時の影響 | 失効させるまで悪用され続ける | すぐ期限切れ |
| 使用元の制限 | 不可 | 可(特定の org/project/branch のみ許可) |
| ローテーション | 手動で必要 | 不要 |
条件の絞り込み例(trust policy の Condition):
"Condition": {
"StringLike": {
"oidc.circleci.com/org/xxx:sub": "org/xxx/project/yyy/user/*"
}
}
Appendix: JWT トークン
JWT とは
JWT(JSON Web Token)は、2者間で情報を安全にやり取りするための 署名付き JSON です。OIDC では「私は CircleCI の特定のジョブです」という身元を証明するために使います。
構造
JWT は . で区切られた 3 つの部分から構成されます。
eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczovL29pZGMuY2lyY2xlY2kuY29tL29yZy94eHgifQ.signature
▲ ▲ ▲
Header Payload Signature
| 部分 | 内容 |
|---|---|
| Header | 署名アルゴリズム(例:RS256)とトークン種別 |
| Payload | クレーム(誰が・どこから・いつまで有効か) |
| Signature | Header + Payload を秘密鍵で署名したもの |
各部分は Base64URL エンコードされているだけなので、デコードすれば中身を読めます(ただし改ざんは署名で検出できます)。
Payload のクレーム例(CircleCI)
{
"iss": "https://oidc.circleci.com/org/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"sub": "org/xxxxxxxx/project/yyyyyyyy/user/zzzzzzzz",
"aud": "sts.amazonaws.com",
"exp": 1713800000,
"iat": 1713796400
}
| クレーム | 意味 |
|---|---|
iss(Issuer) |
トークンの発行者(CircleCI の OIDC エンドポイント) |
sub(Subject) |
トークンの主体(どの org/project/user か) |
aud(Audience) |
トークンの受取先(AWS STS) |
exp(Expiration) |
有効期限(Unix タイムスタンプ) |
iat(Issued At) |
発行日時 |
AWS が JWT を信頼できる理由
AWS は事前に登録された CircleCI の OIDC プロバイダー公開鍵 で Signature を検証します。秘密鍵は CircleCI だけが持っているため、署名が正しければ「本物の CircleCI が発行したトークン」と確認できます。
CircleCI(秘密鍵で署名)→ JWT → AWS STS(公開鍵で検証)→ OK → 一時認証情報を発行
trust policy の Condition は、この Payload のクレーム値を使って「どの CircleCI プロジェクトからの実行か」を絞り込んでいます。