Skip to main content

A dead-simple version manager for Open Policy Agent (OPA).

Project description

opavm

A dead-simple version manager for Open Policy Agent (OPA).

opavm lets you install, pin, and switch OPA versions locally and per-project so your policies run against the same OPA version in dev, CI, and production. No Docker. No magic. Just predictable binaries.

Why opavm exists

OPA is "just a single binary" until it isn't. Teams regularly run into:

  • different OPA versions in CI vs local
  • silent upgrades via package managers
  • subtle behavior changes across releases
  • ad-hoc scripts and manual downloads

opavm solves this by making OPA versioning explicit, reproducible, and boring.

Features (v0.1)

  • Install specific OPA versions (or latest)
  • Install Regal (Rego linter/LSP) versions
  • Set a global default OPA version
  • Pin OPA per project with .opa-version
  • Automatically switch versions by directory
  • CI-safe execution without PATH hacks
  • Rich progress bar UI for installs
  • Show recent OPA/Regal releases in a Rich table (opavm releases)
  • Zero runtime services, zero configuration files

Installation

v0.1 supports:

  • macOS (amd64, arm64)
  • Linux (amd64, arm64)
  • Windows (amd64)

Install as a Python package (recommended with pipx):

pipx install opavm

Or with pip:

pip install opavm

Then add the shim directory to your shell.

macOS/Linux:

export PATH="$HOME/.opavm/shims:$PATH"

Windows PowerShell:

$env:Path = "$HOME\.opavm\shims;$env:Path"

GitHub repo override

By default, opavm uses:

  • open-policy-agent/opa for OPA release lookup
  • StyraInc/regal for Regal release lookup

You can override with:

  • OPAVM_GITHUB_REPO for OPA
  • OPAVM_REGAL_GITHUB_REPO for Regal
  • OPAVM_GITHUB_TOKEN to increase GitHub API rate limits and support private repo access

Current shell (macOS/Linux):

export OPAVM_GITHUB_REPO="open-policy-agent/opa"
export OPAVM_REGAL_GITHUB_REPO="StyraInc/regal"

Persist on Ubuntu:

echo 'export OPAVM_GITHUB_REPO="open-policy-agent/opa"' >> ~/.bashrc
echo 'export OPAVM_REGAL_GITHUB_REPO="StyraInc/regal"' >> ~/.bashrc
source ~/.bashrc

Current PowerShell session:

$env:OPAVM_GITHUB_REPO = "open-policy-agent/opa"
$env:OPAVM_REGAL_GITHUB_REPO = "StyraInc/regal"

Persist in PowerShell profile:

Add-Content -Path $PROFILE -Value '$env:OPAVM_GITHUB_REPO = "open-policy-agent/opa"'
Add-Content -Path $PROFILE -Value '$env:OPAVM_REGAL_GITHUB_REPO = "StyraInc/regal"'
. $PROFILE

Quick start

Install OPA:

opavm install 0.62.1

Set a global default:

opavm use 0.62.1

Now:

opa version

uses OPA 0.62.1.

Per-project pinning

Inside a repo that requires a specific version:

opavm pin 0.61.0

If that version is not installed, opavm prompts to install it.

This creates a .opa-version file:

0.61.0

Anywhere inside that repo:

opa version

automatically resolves to 0.61.0. Outside the repo, your global version is used again.

Common commands

Install versions:

opavm install 0.62.1
opavm install latest
opavm install regal 0.38.1
opavm install regal latest

List installed versions:

opavm list
opavm list --tool regal

Switch global version:

opavm use 0.63.0

See what's active (and why):

opavm current

Get the actual binary path:

opavm which

opavm which prints the resolved OPA binary as an absolute path.

Show recent OPA releases:

opavm releases --limit 10
opavm releases --tool regal --limit 10

Run OPA without relying on PATH (CI-safe):

opavm exec -- test -v ./policy

Remove a version:

opavm uninstall 0.59.0
opavm uninstall 0.38.1 --tool regal

How version resolution works

When you run opa (via the shim):

  1. Look for .opa-version in the current directory or parents
  2. If found, use that version
  3. Otherwise, use the global default
  4. If neither exists, error with guidance

This behavior is deterministic and transparent.

File layout

~/.opavm/
|- versions/
|  |- 0.62.1/opa
|  `- 0.63.0/opa
|- tools/
|  `- regal/
|     `- versions/
|        `- 0.38.1/regal
|- shims/
|  `- opa (or opa.cmd on Windows)
`- state.json

.opa-version files live in your project repos and should usually be committed.

CI usage

You don't need shell shims in CI:

opavm install 0.62.1
opavm exec -- test ./policy

This guarantees the correct OPA version regardless of environment.

Integrity and Reliability

  • opavm verifies downloaded binaries by executing <tool> version after install.
  • For releases that provide *.sha256 assets (for example OPA), opavm validates SHA256 before completing install.
  • GitHub error handling includes actionable messages for:
    • proxy misconfiguration (HTTP_PROXY / HTTPS_PROXY)
    • rate limit exhaustion
    • network connectivity failures
    • auth/permission failures

Testing and Quality Gates

  • Lint: ruff check .
  • Tests: pytest -q
  • Coverage gate: enforced with pytest-cov and --cov-fail-under=70
  • Coverage report artifact: coverage.xml (uploaded by CircleCI)

The coverage threshold is intentionally a floor and should be raised as test depth increases.

CircleCI

This repo uses CircleCI for CI and release.

Validate CircleCI config locally:

circleci config validate .circleci/config.yml

Run CI job locally (Docker executor):

circleci local execute lint-test

Release flow:

  • Tag push vX.Y.Z triggers the release workflow.
  • publish-pypi requires CircleCI context pypi with env var PYPI_API_TOKEN.

What opavm is not

  • Not a container runtime
  • Not a policy runner
  • Not a plugin manager

It does one thing: manage OPA binaries predictably.

License

Apache 2.0. See LICENSE and license.md.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

opavm-0.1.0.tar.gz (20.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

opavm-0.1.0-py3-none-any.whl (17.7 kB view details)

Uploaded Python 3

File details

Details for the file opavm-0.1.0.tar.gz.

File metadata

  • Download URL: opavm-0.1.0.tar.gz
  • Upload date:
  • Size: 20.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for opavm-0.1.0.tar.gz
Algorithm Hash digest
SHA256 4059209250ca0d8fa1fda84a58d06dbf6619edb065b7cae9578753ab9fd409be
MD5 bcb97b079dbcd6fbd6d04c08d490da0e
BLAKE2b-256 bc692aab3c59c362da6d5b3e878aba34fb7d4cc262e952b0705f22efa9403651

See more details on using hashes here.

File details

Details for the file opavm-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: opavm-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 17.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for opavm-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 de374a58e9b424162c8a967488ca6afc4e0d74d4954e1c31da04372814c3abd5
MD5 b5c3ec87d3fccba73254f42f59c62699
BLAKE2b-256 fd8e0e3e8fb7c8d18fc3d9c52567ddef8022c106a45995ac67cd12a03e827ae0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page