Skip to content

Build & Package Policy

Preface

This guide will explain how to build and package a OPA Bundle from your policy. The bundle will be exported in OCI format, allowing publishing to an OCI registry.

Bundle Manifest

OPA OCI Bundles must contain a JSON formatted Manifest file (.manifest) which describes the bundle contents. This file must include the package roots - a list of package paths which the bundle provides.

Example

.manifest
{
    "roots": ["system", "my/helper"]
}

Building Policy

The OPA Bundle can be built using the opa build command. The policy bundle we are building is supplied using the --bundle option with the version given using the --revision option. If your policy package contains tests then you should ignore them using --ignore *_test.rego. This should produce a file of the form ``.

Example

opa build --bundle policy/ --revision v1.2.3 --ignore *_test.rego

Publishing Policy

The OCI image can be created an published using the oras push command. The first argument of the command is the registry which the image is to be pushed to whilst the second argument is the file to include in the image and the custom media type to use - this should be the file produced by opa build followed by :application/vnd.oci.image.layer.v1.tar+gzip.

Example

oras push localhost:5000/policy:v1.2.3 bundle.tar.gz:application/vnd.oci.image.layer.v1.tar+gzip

Continious Delivery

It is strongly recommended you implement policy packaging as part of your Continious Integration (CI) and Continious Delivey (CD) pipelines, an example for doing this in GitHub Actions is shown below.

Github action for building and releasing OPA policy as OCI bundle on GHCR

name: Policy Container

on:
  push:
  pull_request:

jobs:
  build_bundle:
    # Deduplicate jobs from pull requests and branch pushes within the same repo.
    if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.repository
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - name: Checkout source
        uses: actions/checkout@v4.2.1

      - name: Generate Image Name
        run: echo IMAGE_REPOSITORY=ghcr.io/$(echo "${{ github.repository }}-policy" | tr '[:upper:]' '[:lower:]' | tr '[_]' '[\-]') >> $GITHUB_ENV

      - name: Log in to GitHub Docker Registry
        uses: docker/login-action@v3.3.0
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Setup OPA
        uses: open-policy-agent/setup-opa@v2.2.0
        with:
          version: latest

      - name: Build OPA Policy
        run: >
          opa
          build
          --bundle policy
          --revision ${{ github.ref_name }}
          --ignore *_test.rego

      - name: Publish OPA Bundle
        if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags') }}
        run: >
          oras
          push
          ${{ env.IMAGE_REPOSITORY }}:${{ github.ref_name }}
          bundle.tar.gz:application/vnd.oci.image.layer.v1.tar+gzip