📡

GitHub Actionsから得られた結果をOPAサーバに問い合わせる

2021/12/21に公開

この記事はOPA/Regoアドベントカレンダーの21日目です。

GitHub Action で Trivy + OPA/Rego による脆弱性管理という記事では、Trivyの出力結果をOPAで検査してCIのPass/Failを判定するという事例を紹介しました。この例では判定用のポリシーを同じリポジトリで管理し、opa のコンテナイメージを使ってローカルで判定する、というアプローチを取っています。この方法は開発環境での再現も容易で、検査対象と一緒に確認しながらポリシーを記述できるというメリットがあります。

一方で、リポジトリ数が増えるとポリシーの管理が煩雑になってきてしまいます。特に1つのリポジトリに固有のポリシーであればそのリポジトリ内で管理する方が効率的ですが、複数リポジトリで共通するようなポリシーを運用する場合は都度ポリシーの内容を揃えるのにコストが掛かってしまいます。例として、セキュリティスキャンの結果に対するポリシーは組織横断で決まっていたり、Infrastructure as Codeのリポジトリが複数に分散している場合でもポリシーが部分的に共通である、というようなユースケースを想定しています。

OPAサーバに問い合わせる構成

やりたい構成は上記のようなイメージです。1つのサーバに複数のリポジトリからポリシーを参照することで、管理の手間が小さくなります。

クラウド上にOPAをデプロイする方法については以下を参照してください。

サーバへの問い合わせ

OPAサーバへの問い合わせも非常にシンプルです。詳しくは以下が参考になるかと思います。

基本的には出力された構造データをそのままOPAサーバへ送信するだけなのですが、その際ひと手間必要です。

  • 構造データそのままではなく {"input": ... } のフォーマットに変換する必要がある
  • ポリシーの判定が失敗しても、判定自体が正しく処理されればサーバは 200 (Status OK) を返す
  • 応答が {"result": ... } という形式なので取り出して中身を判定する必要がある

ということで問い合わせ自体をshell scriptで書くと、例えばこういう感じになります。

#!/bin/bash

echo '{}'| jq ".input += $(cat result.json)" > input.json
curl -L -o result.json https://opa-server-xxxxxxx.run.app/v1/data/somepolicy

RESULT=$(cat result.json | jq .result | jq length)

if [ "$RESULT" -ne "0" ]; then
        cat result.json | jq .result
        exit 1
fi

問い合わせたい結果が result.json に入っており、ルールのパッケージが package somepolicy 、応答に何かデータが入っていた場合にそれを表示し、失敗させるというスクリプトです。

Custom GitHub Actions

先のスクリプトを各リポジトリに配置してもいいですが、もう少しだけエレガントにやるためにCustom GitHub Actionsを使う方法も考えられます。もう少し汎用化したGitHub Actionsの例が以下になります。

https://github.com/m-mizutani/opa-inquiry

      - name: inquiry to OPA server
        uses: m-mizutani/opa-inquiry@main
        with:
          url: https://opa-server-xxxxxxxxxxxx.a.run.app
          input-file: results.json
          fail-defined: true

というように記述することでスクリプトを設置せずに問い合わせができるようになっています。 fail-defined で応答があった場合は失敗、fail-undefined で応答がなかった場合は失敗という選択も可能です。

代替案

今回はOPAサーバを用意しそこへ問い合わせるというアプローチにしましたが、GitHub Actionsで共通のポリシーを使う別の現実的な方法[1]として「ポリシーを含むCustom Actionsを作成する」が挙げられます。

OPAサーバを使う方法

  • Pros
    • ポリシー管理するリポジトリがpublicでなくてもOK
    • GitHub Actions以外からも容易に利用可能
  • Cons
    • サーバのデプロイが必要で手間がかかる
    • 認証認可をかけたい場合はさらに別途設定が必要

Custom Actionsを使う方法

  • Pros
    • GitHub Actionsから気軽に使うことができる
  • Cons
    • ポリシー管理するリポジトリがpublicでなければならない
    • GitHub Actions以外からも利用可能ではあるが、ひと手間必要
脚注
  1. 他にも別リポジトリにポリシーだけおいてチェックアウトしたり、S3/GCSにポリシーを配置してそれをダウンロードするなどのアプローチが考えられますが、今回挙げた2つの手法と似たような感じか、あるいはより複雑になるだけなのであまり推奨はできないと考えました。 ↩︎

Discussion