こんにちは!日々のCI/CDパイプラインの構築や、チームの開発効率化に奔走お疲れ様です。世界中の現場を見てきた私から一つ質問させてください。
「うちの組織では、誰も勝手に危ない権限を持つGitHub Actionsを使わないように!」
……なんて、口頭やドキュメントでルールを縛っていませんか?
残念ながら、人間を信じるだけのガバナンスは必ず破られます。深夜の急ぎのデプロイで、誰かが「一時的に動かすためだけに」危険な設定(例えば、すべてのブッシュを無条件で本番環境にデプロイするような設定)を書いてしまう。そして、それがそのままマージされて事故が起きる……。この悪夢、あなたも一度や二度、目撃したことがあるはずです。
これを根本から解決するのが、今回紹介する「Policy as Code(ポリシーのコード化)」というアプローチです。
今回は、数あるツールの中でも最強のポリシーエンジンである OPA (Open Policy Agent) とその専用言語 Rego を使って、GitHub Actionsのワークフロー自体を自動で検知・ブロックする「組織の守護神」の作り方を、優しく、そして徹底的に解説していきます。
これをマスターすれば、あなたの組織のセキュリティ統制は劇的に自動化され、夜も安心して眠れるようになりますよ。一緒に見ていきましょう!
—
1. OPA/Regoってなに? & なぜGitHub Actionsに必要なの?
まずは基本のキから。初めて聞く名前だらけで身構えてしまうかもしれませんが、怖がらなくて大丈夫です。
OPA(Open Policy Agent)とは?
一言で言うと、「あらゆるシステムの門番(ポリシーエンジン)」です。
KubernetesやTerraform、そして今回のGitHub Actionsなど、あらゆるツールの「設定ファイル」や「JSON/YAMLデータ」を入力として受け取り、「この設定はうちのセキュリティ基準に違反しているからダメ!」「こっちはOK!」と判定を下してくれるオープンソースのエンジンです。
Rego(レゴ)とは?
OPA専用のクエリ言語です。設定ファイルの中に、危険なキーワード(例えば `permissions: write-all` や `pull_request_target` の不適切な使用など)が含まれていないかを、まるでパズルを組み立てるようにエレガントに記述できます。
なぜGitHub Actionsにこれを適用するのか?
GitHub Actionsは非常に強力で便利ですが、設定の自由度が高すぎるゆえに、以下のような「セキュリティホール」を簡単に作れてしまいます。
- 過剰な権限(`permissions` の欠落や `write-all`)の付与
- 信頼できない外部フォークからの `pull_request_target` の悪用
- 社外秘のリポジトリへシークレットを漏らすようなスクリプトの混入
これらを人間の目(コードレビュー)だけでチェックするのは不可能に近いです。だからこそ、「マージする前に、機械が自動でポリシー違反を検知して門前払いする仕組み(ガードレール)」をCI/CDのパイプラインに組み込む必要があるのです。
—
2. 基礎セットアップ:ツールをインストールしよう
百聞は一見に如かず。実際に手を動かして環境を整えていきましょう。
今回はローカルマシンでOPAの動作確認ができるところまでをサクッと進めます。
ステップ1: OPAのインストール
MacならHomebrewで一発です。
Macの場合
brew install opa
インストール確認
opa version
WindowsやLinuxをお使いの方も、公式サイトからバイナリを1つダウンロードするだけなので非常に簡単です(`curl -L -o opa …`)。
これだけで、あなたのPCは強力なポリシー判定マシーンに変身しました。
—
3. HelloWorld:はじめてのポリシー(Rego)を書く
それでは、記念すべき最初のポリシーを作ってみましょう。
今回のターゲットは、「GitHub Actionsのワークフローファイルにおいて、すべての権限を与える危険な設定(`permissions: write-all`)が含まれていたらエラーにする」というルールです。
① ポリシーファイルを書く(`security_policy.rego`)
適当なディレクトリを作り、`security_policy.rego` というファイルを作成してください。
package github.actions.security
デフォルトでは「違反している(deny = true)」と仮定して安全側に倒します
default deny = false
ルール: ワークフロー内のどこかに “permissions: write-all” があれば違反とする
deny {
# YAMLが変換されたJSONデータから、ジョブやステップの権限設定をスキャン
# input は、検査対象のGitHub ActionsのワークフローYAML
# 全ジョブ(jobs)を走査
job := input.jobs[_]
# 権限(permissions)が文字列で “write-all” に設定されているかチェック
job.permissions == “write-all”
}
違反メッセージの定義
violation_msg = “【セキュリティ警告】ワークフローで ‘permissions: write-all’ を使用することは禁止されています。最小権限の原則に従い、必要な権限のみを個別に付与してください。” if {
deny
}
② テスト用の「悪い」GitHub Actionsファイルを用意する(`bad-workflow.yml`)
次に、わざとルールに違反したYAMLファイル(`bad-workflow.yml`)を用意します。
name: Unsafe Workflow
on: [push]
jobs:
build:
runs-on: ubuntu-latest
# ここが違反ポイント!すべての権限を与えてしまっている
permissions: write-all
steps:
- name: Checkout
uses: actions/checkout@v4
—
4. 精度高い動作確認:OPAで静的解析を実行する
さあ、役者は揃いました。OPAを使って、このワークフローファイルがポリシーに違反しているかテストしてみましょう。
ここで一つポイントがあります。OPAはJSONデータを好むため、YAMLをJSONに変換してOPAに読み込ませます(実務では `yq` などのツールや、後述する専用のGitHub Actionsアクションを使います)。
今回は手動でOPAの評価コマンドを実行してみましょう。YAMLをJSONに変換しつつOPAに渡します(※あらかじめ `yq` がインストールされている前提です)。
YAMLをJSONに変換してOPAでポリシーチェックを実行
opa eval –data security_policy.rego –input <(yq -o=json bad-workflow.yml) "data.github.actions.security.deny"
実行結果の出力(イメージ):
{
- “result”: [
{
- “expressions”: [
{
- “value”: true,
- “text”: “data.github.actions.security.deny”
}
]
}
]
}
見事に `value: true`(=ポリシー違反!)が返ってきました!
「危険な設定である」とプログラムが正確に検知できた瞬間です。
—
5. 実戦投入:GitHub ActionsのCIパイプラインに組み込む
ローカルで動くことが確認できたら、次はこれをGitHub Actionsのプルリクエスト時に自動実行するように組み込みます。
ここが今回のハイライトです。「ポリシーでGitHub Actionsを守るために、GitHub Actionsを使う」という美しい構造を作ります。
プロジェクトの `.github/workflows/policy-check.yml` として、以下のファイルを作成してください。
name: Policy as Code Guardrail
on:
pull_request:
paths:
- ‘.github/workflows/’ # ワークフローファイルが変更された時だけ発火
jobs:
opa-check:
name: OPA Policy Validation
runs-on: ubuntu-latest
steps:
# 1. リポジトリのコードをチェックアウト
- name: Checkout Code
uses: actions/checkout@v4
# 2. Open Policy Agent (OPA) のセットアップ
- name: Setup OPA
uses: open-policy-agent/setup-opa@v2
with:
opa_version: latest
# 3. yqのインストール(YAMLをJSONに変換するため)
- name: Install yq
run: |
sudo wget https://github.com/mikefarah/yq/releases/download/v4.40.1/yq_linux_amd64 -O /usr/bin/yq
sudo chmod +x /usr/bin/yq
# 4. すべてのワークフローファイルに対してOPAポリシーを適用してテスト
- name: Run OPA Policy Check
run: |
FAILED=0
# .github/workflows 内のすべてのYAMLファイルを走査
for file in .github/workflows/.yml; do
echo “Checking $file…”
# OPAで評価実行
RESULT=$(opa eval –data security_policy.rego –input <(yq -o=json "$file") "data.github.actions.security.deny" --format raw)
if [ "$RESULT" = "true" ]; then
echo "❌ Policy Violation detected in $file"
# 詳細なメッセージを表示
opa eval --data security_policy.rego --input <(yq -o=json "$file") "data.github.actions.security.violation_msg"
FAILED=1
else
echo "✅ $file passed."
fi
done
# 違反があった場合はCIを失敗(exit 1)させる
exit $FAILED
このワークフローをメインブランチにマージしておけば、今後は開発者が不適切な権限設定を含んだPRを作った瞬間、CIが自動で赤く染まり、マージボタンがロックされます。人間の目をすり抜けるミスを、コード化されたポリシーが完璧にブロックしてくれるのです。
---
おわりに:統制とは「開発者の自由を守るためのインフラ」である
お疲れ様でした!今回は OPA/Rego を用いて、GitHub Actionsの設定を自動でガードレール化する手法を解説しました。
「ガバナンス」や「ポリシー」という言葉を聞くと、なんだか窮屈で開発スピードが落ちるような印象を受けるかもしれません。しかし、本質は全く逆です。
危ない変更を人間がピリピリ監視するのではなく、コード(機械)が自動で弾いてくれるからこそ、開発者は安心して思い切りスピーディーにコードを書くことができるのです。
ルールを守らせるための面倒な作業から解放され、毎日の開発が劇的に楽で安全になる――これこそが、私たちが目指すべき最高のDevOps環境です。
まずは小さなルール1つから、あなたのチームにも「Policy as Code」を取り入れてみませんか?きっと思っている以上に世界が変わりますよ。それでは、次の現場でお会いしましょう!