GitHub OIDCによる「脱・鍵管理」:CI/CDの聖域を守る最後の砦
長年、多くの企業で「漏洩したAWSシークレットキー」によるクラウド破産や、インフラ乗っ取りの悪夢を見てきた。GitHub Secretsに埋め込まれたIAMユーザーの長期キー。あれは、金庫の鍵を玄関マットの下に隠しているのと同じだ。
本稿では、レガシーなキー管理を過去の遺物とし、GitHub Actionsとクラウドプロバイダ(AWS)をOpenID Connect (OIDC) で直結させる。これは単なる「設定」ではない。「権限の最小化」と「認証の動的ライフサイクル管理」を極めるための、アーキテクトとしての必須教養だ。
—
1. なぜ「静的キー」は死刑宣告に等しいのか
静的なIAMアクセスキーは、以下の理由でCI/CDのセキュリティを根底から腐らせる。
- ローテーションの欠如: 一度漏洩すれば、検知して無効化するまで攻撃者は自由だ。
- 権限の肥大化: `secrets.AWS_ACCESS_KEY_ID`に紐づくIAMユーザーは、往々にして広すぎる権限を持つ。
- 監査の透明性欠如: CloudTrailには「IAMユーザー」として記録されるが、それが「どのリポジトリの」「どのコミットの」「どのワークフロー」から発行されたのか追跡は困難を極める。
OIDCはこれら全てを覆す。 GitHubはAWSに対して「私はこのリポジトリの、このブランチの実行環境です」というトークンを送り、AWSはそれを検証して、数分で期限が切れる一時的なセキュリティトークンを発行する。鍵など、最初から存在しないのだ。
—
2. アーキテクチャの核心:OIDCの魔法
GitHub Actionsは、実行時に`actions/setup-gcloud`や`aws-actions/configure-aws-credentials`を通じて、GitHubのOIDCプロバイダからJWT(JSON Web Token)を取得する。
このJWTには以下のクレームが含まれる。
- `sub`: `repo:org/repo:ref:refs/heads/main` (どのリポジトリの、どのブランチか)
- `aud`: `sts.amazonaws.com` (AWS STSへの要求であること)
この情報をAWS側で「信頼」することで、「特定のブランチの特定のアクション以外は絶対に通さない」という要塞が構築される。
—
3. 実装:AWS IAM OIDCプロバイダの自動構成
手作業でマネジメントコンソールをポチるなど、DevOpsエンジニアのやることではない。Terraformでインフラとしてコード化し、冪等性を担保する。
AWS側にGitHubのOIDCプロバイダを信頼させる(一度だけ設定)
resource “aws_iam_openid_connect_provider” “github” {
url = “https://token.actions.githubusercontent.com”
client_id_list = [“sts.amazonaws.com”]
# GitHubのサムプリントは常にこれ
thumbprint_list = [“6938fd4d98bab03faadb97b34396831e3780aea1”]
}
最小権限のロールを作成
resource “aws_iam_role” “github_actions_role” {
name = “github-actions-ci-cd-role”
assume_role_policy = jsonencode({
Version = “2012-10-17”
Statement = [{
Effect = “Allow”
Principal = { Federated = aws_iam_openid_connect_provider.github.arn }
Action = “sts:AssumeRoleWithWebIdentity”
Condition = {
StringLike = {
“token.actions.githubusercontent.com:sub”: “repo:your-org/your-repo:”
}
}
}]
})
}
—
4. GitHub Actions:究極のパイプライン設定
ここでのポイントは、`permissions`ブロックの定義だ。これがないパイプラインは、不必要なトークンをメモリ上に保持する脆弱な状態にある。
jobs:
deploy:
runs-on: ubuntu-latest
# 最小権限:id-tokenの取得のみを許可し、他は全て拒否
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v4
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/github-actions-ci-cd-role
aws-region: ap-northeast-1
# ここで発行されるトークンは、このjobが終わればゴミになる
- name: Deploy to Cloud
run: |
aws s3 sync ./dist s3://my-bucket/
—
5. エキスパートの視点:パフォーマンスと最適化
A. メモリ消費と認証のオーバーヘッド
OIDC認証はHTTPSリクエストを伴うため、極限までビルド時間を削りたい場合は、認証の頻度を設計せよ。複数のジョブで認証を繰り返すと、数秒のレイテンシが積み重なる。`workflow_call`による再利用可能なワークフローを使用し、認証済みセッションを適切に管理せよ。
B. 監査ログの極大化
CloudTrailで、`userIdentity.arn`に含まれるOIDCプロバイダの情報を解析し、「どのプルリクエストがデプロイをトリガーしたか」をメタデータとしてログに吐き出させる仕組みを構築せよ。これができるチームは、万が一のインシデント発生時に数秒で影響範囲を特定できる。
C. 「脱・鍵」のその先へ
IAMポリシーには `Condition` を使い倒せ。`aws:SourceIp` は使いにくいが、`aws:PrincipalTag` を利用して、GitHubから渡されるタグベースの属性制御を行えば、より柔軟なアクセス制御が可能だ。
—
結論:セキュリティは「設定」ではなく「規律」である
GitHub OIDCへの移行は、単なる認証方式の変更ではない。「認証情報を管理する」という、古臭くリスクの高い運用コストをゼロにするための意思決定だ。
この構成を導入した瞬間、あなたのパイプラインは「鍵」という爆弾を抱える必要がなくなる。後は、ポリシーをいかに洗練させ、最小権限の原則をどこまで突き詰められるか。それが、エンジニアとしての力量を試す最後のハードルだ。
さあ、今すぐSecretsからキーを削除し、IAMをクリーンアップせよ。それが、プロフェッショナルなDevOpsの第一歩である。