CI/CDセキュリティ:GitHub Actions OIDCで長期生存シークレットを排除する

Security tutorial - IT technology blog
Security tutorial - IT technology blog

CI/CDにおける「シークレットキー漏洩」という悪夢

多くのDevOpsエンジニアは、依然としてIAMユーザーを作成して管理者権限を付与し、AWS_ACCESS_KEY_IDのペアをGitHub Secretsに直接貼り付けるという習慣を持っています。この方法はワークフローをすぐに動かすには便利ですが、システムを極めて危険な状況にさらすことになります。わずかな不注意でログが漏洩したり、GitHubへのアクセス権を失ったりするだけで、クラウドインフラ全体が悪意のある者の手に渡ってしまうからです。

実際、一晩で数万ドルのAWS請求が届いた企業もあります。ハッカーは漏洩したキーを悪用し、仮想通貨マイニングのために大量のp3.16xlarge EC2インスタンスを作成することがよくあります。固定された「万能の鍵」を使用する代わりに、OIDC(OpenID Connect)を使用すれば、秘密のコードを保存することなく、信頼関係(trust relationship)に基づいてクラウドプロバイダーとの認証を行うことができます。

なぜOIDCは従来の方法よりも安全なのか?

従来の方法:静的認証情報(Static Credentials)

ユーザーを作成し、キーを取得してGitHubに保存します。この方法は単純ですが、非常にリスクが高いです。

  • リスク:キーは、明示的に削除するまで永久に有効です。
  • 管理:キーの手動ローテーションは非常に時間がかかり、システムのダウンタイムを引き起こす可能性があります。

モダンな方法:OIDC(OpenID Connect)

GitHub Actionsがアイデンティティプロバイダー(Identity Provider)として機能します。ワークフローが開始されると、GitHubはAWSやGCPに対して、数分間のみ有効な一時的なトークン(short-lived token)を発行します。クラウドプロバイダーはこのトークンを照合し、制限された範囲内でのみコマンドの実行を許可します。

  • メリット:トークンはワークフロー終了後に自動的に破棄されます。
  • 制御:どのリポジトリやブランチが権限を借用(Assume Role)できるかを正確に制限できます。

私があらゆる本番プロジェクトでOIDCを優先する理由

最大の価値は安心感です。シークレットが含まれるログを誤って出力したり、サービスアカウントのパスワードを定期的に変更し忘れたりする心配がなくなります。強力なパスワードが必要な手動管理タスクには、よくtoolcraft.appのパスワード生成ツールを使用しています。その後、CI/CDが完全に自動で動作するようにOIDCを設定し、キー管理プロセスから人的要因を完全に排除しています。

AWSとGitHub ActionsでOIDCを導入する3つのステップ

ステップ1:AWSでアイデンティティプロバイダーを設定する

まず、GitHubが信頼できる認証ソースであることをAWSに宣言する必要があります。**IAMコンソール -> アイデンティティプロバイダー -> プロバイダーを追加**にアクセスしてください。

  • プロバイダーのタイプ:OpenID Connect
  • プロバイダーのURL:https://token.actions.githubusercontent.com
  • 対象者(Audience):sts.amazonaws.com

ステップ2:IAMロールと信頼ポリシー(Trust Policy)の設定

これはリソースを保護するための重要なステップです。GitHub Actionsが「借用」するためのロールを作成します。以下の信頼ポリシーにより、指定したリポジトリのみがこのロールを使用できるようになります:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringLike": {
          "token.actions.githubusercontent.com:sub": "repo:my-org/my-repo:*"
        },
        "StringEquals": {
          "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
        }
      }
    }
  ]
}

123456789012を実際ののアカウントIDに、my-org/my-repoをご自身のリポジトリ情報に置き換えるのを忘れないでください。

ステップ3:Workflow YAMLの更新

ワークフローファイルには、id-token: write権限を必ず追加する必要があります。この行がないと、GitHubはAWSに送信するためのOIDCトークンを生成できません。

permissions:
  id-token: write
  contents: read

jobs:
  Deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v3
        with:
          role-to-assume: arn:aws:iam::123456789012:role/GitHubActionRole
          aws-region: ap-southeast-1
      - run: aws s3 ls

見逃せないセキュリティの原則

OIDCは非常に強力ですが、最小権限の原則(Least Privilege)に従う必要があります。CI/CDロールにAdministratorAccessを付与することは絶対に避けてください。S3へのアプリケーションデプロイのみであれば、s3:PutObjects3:ListBucketの権限のみを付与します。

信頼ポリシーの条件をブランチ指定で厳格化しましょう。例:repo:username/repo-name:ref:refs/heads/main。これにより、誰かがサブブランチを作成して不正なワークフローを実行し、クラウドの脆弱性を未然に防ぐことを防げます。安全なCI/CDシステムの構築を頑張ってください!

Share: