ワークフローの実行権限が思っている以上に重要である理由
自動化されたワークフロー (CI/CD パイプライン、データ処理ジョブ、インフラストラクチャ プロビジョニング) は、許可に応じてどのアクションが許可されるかを決定します。しかし、アクセス許可は後付けとして扱われることが多く、一度設定したら忘れてしまいます。これは、パイプラインが途中で失敗するか、さらに悪いことに、悪意のある攻撃者が過剰な特権トークンを悪用するまで機能します。
典型的なシナリオを考えてみましょう。開発者がコードをリポジトリにプッシュし、Docker イメージを構築してレジストリにプッシュする CI パイプラインをトリガーし、ステージング サーバーにデプロイします。各ステップには、リポジトリへの読み取りアクセス、レジストリへの書き込み、ステージング サーバーへの SSH アクセスなど、異なる権限が必要です。これらのアクセス許可のいずれかが正しく構成されていない場合、パイプラインは通知なく失敗するか、シークレットが公開されます。
ワークフローの実行権限は、単に「誰がワークフローを実行できるか」ということだけではありません。それらには以下が含まれます:
- どの ID (ユーザー、サービス アカウント、システム) が実行を開始できるか。
- ワークフローが実行中にアクセスできるリソース。
- ワークフローがそれらのリソースに対して実行できるアクション。
課題は、これらのアクセス許可がソース管理、アーティファクト リポジトリ、コンピューティング環境、シークレット管理などの複数のシステムにわたってカスケードされることです。トークンの構成が 1 つ間違っていると、展開全体が停止する可能性があります。
具体的なシナリオ: 金曜日に中断されたステージング展開
実際の例を見てみましょう。 Sarah は、フィンテックのスタートアップ企業の DevOps エンジニアです。彼女は、次のような GitHub Actions ワークフローを設定します。
mainにプッシュすると、Node.js アプリが構築されます。- 単体テストを実行します。
- Docker イメージを AWS ECR にプッシュします。
kubectl経由で Kubernetes ステージング クラスターにデプロイします。
ワークフローを実行するために、ECR にプッシュして Kubernetes デプロイメントを更新する権限を持つ IAM ユーザーを使用して、GitHub Actions シークレット AWS_ACCESS_KEY_ID および AWS_SECRET_ACCESS_KEY を作成します。
すべては数週間は機能します。その後、ある金曜日、チームメイトがマイナーな変更をプッシュすると、ワークフローはステップ 3 で「AccessDenied」エラーで失敗します。サラは IAM ユーザーを確認しますが、何も変化はありませんでした。 AWS の秘密はまだ存在します。どうしたの?
問題: IAM ユーザーのキーは、定期的なコンプライアンス スイープの一環としてセキュリティ チームによってローテーションされましたが、GitHub シークレットは更新されませんでした。ワークフローは無効なキーを使用しようとしましたが、失敗しました。
これは典型的な障害モードです。外部の変更によって引き起こされる 権限のドリフト です。ワークフロー自体は変更されませんでしたが、基礎となる認証情報は変更されました。誰も回転に気付かなかったため、パイプラインは何時間も壊れた。

ワークフローの実行権限が失敗する理由
資格情報のドリフト以外にも、次のような一般的な障害モードがあります。
- 広すぎる権限: 無制限のアクセスを許可する管理者レベルのサービス アカウントを使用します。これにより、ワークフローが侵害された場合の影響範囲が拡大します。
- スコープの欠如: 必要なリポジトリが 1 つだけである場合に、すべてのリポジトリへの書き込みアクセスを許可します。
- ハードコードされたシークレット: ログに公開されるコードまたはワークフロー ファイルに API キーを埋め込む。
- OIDC またはトークン交換が欠落している: 動的に発行できる有効期間の短いトークンではなく、有効期間の長い認証情報に依存しています。
私たちのシナリオでは、AWS の OIDC プロバイダーと GitHub Actions を使用することで修正できた可能性があります。これにより、ジョブごとに有効期間の短いトークンが発行され、静的キーが不要になります。ただし、ターゲット プラットフォームが OIDC をサポートしていない場合は、常にそれが可能であるとは限りません。

実用的な方法: 最小権限のワークフロー権限の実装
金曜日の夜の停止を回避するには、次の手順に従います。
-
すべてのリソース アクセスをマップする: ワークフロー ステップごとに、正確な API 呼び出しとリソースをリストします。この例の場合:
repoのecr:PutImage、クラスター上のeks:UpdateClusterConfig、さらにリポジトリへの読み取りアクセス。 -
可能な場合は OIDC を使用します: GitHub Actions、GitLab CI、およびその他の多くが OIDC をサポートしています。これにより、ワークフロー ID がリポジトリとブランチに関連付けられ、アクションにスコープされた短期間のトークンが発行されます。
-
スコープ指定されたサービス アカウント: OIDC が利用できない場合は、ワークフローごとまたは環境ごとに専用のサービス アカウントを作成します。単一の管理者アカウントを再利用することは避けてください。
-
認証情報のローテーションを自動化: キーを自動ローテーションし、API 経由でワークフロープロバイダーに更新をプッシュするシークレットマネージャー (AWS Secrets Manager、HashiCorp Vault) を使用します。
-
権限パイプラインをテストします: 各ステップが必要なリソースにアクセスできることを確認する統合テストを作成します。これにより、展開前にドリフトが検出されます。
サラの場合、OIDC に切り替えると、ハードコードされた AWS キーが削除されます。ワークフローが失敗するのは、OIDC プロバイダー自体がダウンした場合 (まれなイベント) のみであり、資格情報は 1 時間ごとに自動的にローテーションされます。
権限が壊れるとどうなりますか?結果と回復
ワークフローの実行権限が失敗すると、即座にパイプラインの障害が発生します。しかし、実際のコストは時間です。開発者は修正を待ち、展開期間は閉まり、関係者は自信を失います。
復旧計画:
- ロールバック戦略を立てます。ワークフローを既知の良好なバージョンに戻すか、手動展開に切り替えます。
- フォールバック ID を使用する: プライマリ サービス アカウントに障害が発生した場合、アラートをトリガーし、同じスコープを持つセカンダリ アカウントにフォールバックします (緊急時のみ)。
- 事後検証を実行します。権限ドキュメントを更新し、認証情報をローテーションし、権限の有効期限の監視を追加します。
複雑な環境に対する代替アプローチ
組織に複数のチームがある場合、または複雑なコンプライアンス要件がある場合は、次のことを考慮してください。
- ワークフロー レベルの RBAC: 一部のワークフロー エンジン (Apache Airflow など) は、ワークフローをトリガーまたは変更できるユーザーを制限するロールベースのアクセス制御を提供します。
- コードとしてのポリシー: OPA (Open Policy Agent) などのツールは、実行時にアクセス許可を強制し、未承認のアクションを動的にブロックできます。
- 個別のワークフロー環境: 開発、ステージング、運用環境に異なる認証情報を使用します。すべてのチェックに合格しない限り、
mainから実行されているワークフローが本番環境にアクセスすることを決して許可しないでください。
各アプローチにはトレードオフがあります。 RBAC により構成のオーバーヘッドが追加されます。 Policy-as Code では、新しい DSL を学習する必要があります。環境が別々になると、管理する秘密が増えることになります。チームの規模とコンプライアンスのニーズに基づいて選択してください。
最終的な考え
ワークフローの実行権限は、信頼性の高い自動化の要です。これらはセキュリティに関するものだけではなく、稼働時間に直接影響します。適切に設計されたアクセス許可モデルにより、障害が減少し、デバッグが簡素化され、回復時間が短縮されます。
CI/CD パイプライン、データ ワークフロー、または自動システムを構築している場合は、事前に時間を投資して各実行コンテキストの権限を設計してください。 OIDC または有効期限の短いトークンを使用し、ローテーションを自動化し、定期的にテストします。金曜の夜はきっと感謝されるでしょう。

コメントはまだありません