opa-golib-python-bindings
Python bindings for the OPA Rego engine, embedding
github.com/open-policy-agent/opa/v1/rego via a Go c-shared library and a stdlib-only
ctypes wrapper.
Build
Requires Go >= 1.26 and Python >= 3.14.
make build # builds src/opa_bindings/libopabridge.so
make test # builds + runs pytest
Usage
from opa_bindings import OpaEngine
users = {"alice": {"role": "admin"}}
with OpaEngine() as engine:
engine.add_policy("authz.rego", """
package authz
allow if lookup_user(input.user).role == "admin"
""")
engine.add_data({"admin": ["alice"]}, path="roles") # deep-merged; conflicts raise
engine.register_function("lookup_user", lambda name: users.get(name))
engine.eval_document("authz.allow", {"user": "alice"}) # -> True
engine.eval_query("x = data.roles.admin[_]") # -> [{"x": "alice"}]
Notes:
-
add_datadeep-merges objects; identical values coexist, conflicting values raiseOpaError(code="merge_conflict")naming the conflicting path. -
A Go-side panic in any bridge call surfaces as
OpaError(code="panic")instead of killing the process; the engine stays usable afterwards. (The bridge also validatescompile_filters(mappings=...)values are strings and rejects malformed shapes withOpaError(code="invalid_json").) -
register_functioninfers arity from the callable's signature. A*argsfunction is variadic and is called from Rego with a single array argument:many(["a", "b"])(OPA does not support variadic builtins with return values). -
Builtin arguments and return values are JSON-compatible objects. A callback exception becomes an evaluation error; returning is fine.
-
An undefined document raises
OpaUndefinedError. -
Pass
coverage=Truetoeval_document/eval_queryto capture a coverage report (OPA'scovertracer) inengine.last_coverage: per-filecovered/not_coveredline ranges plus line counts and a coverage percentage over all added policies. Evaluating withoutcoverage=Trueresets it toNone. -
Pass
trace=Trueto capture the full evaluation trace inengine.last_trace: a list of event dicts (op,location,node,locals, ...) in evaluation order.localsholds the plugged variable bindings live at each step, so the value a statement produced is visible (e.g.{"x": 6}afterx := input.n * 2); a false condition appears as aFailevent at its location. An undefined document still carries its trace — the main way to see which condition failed. Note thatnodeshows the compiler-rewritten expression (temporaries like__local0__), a statement may appear multiple times (Redoon backtracking), and tracing slows evaluation, so keep it opt-in per call. Coverage only records which statements were evaluated; traces are how to see their results. -
compile_filterspartially evaluates a query and translates the residual policy into a data filter (OPA's Compile-API / data-filter machinery):engine.add_policy("filters.rego", """ package filters include if input.fruits.colour == "green" include if { input.fruits.name == "banana" input.user == "admin" } """) engine.compile_filters( "data.filters.include", {"user": "admin"}, # known input unknowns=["input.fruits"], # left symbolic target="sql", dialect="postgresql", ) # -> {"query": "WHERE (fruits.colour = E'green' OR fruits.name = E'banana')", # "masks": None}
target="sql"(dialectspostgresql,mysql,sqlserver,sqlite) yields a WHERE clause string;target="ucast"(dialectsall,prisma,linq, or"") yields a UCAST condition dict (theucast.jsonwire format).queryisNonewhen the policy can never match and""/{}when it always matches.mappingsrenames tables/columns (e.g.{"fruits": {"$self": "fruit_table", "colour": "col"}}), andmask_rulenames a rule evaluated to produce column masks (returned under"masks"). Residual conditions that cannot be expressed for the chosen target raiseOpaError(code="compile_error").Unknown refs must have the shape
input.<table>.<column>— exactly two segments afterinput, whatever the declared unknown boundary is, and for every target/dialect (ucast/allincluded;mappingscannot deepen it). Sounknowns=["input.item"]permits onlyinput.item.<column>, while the bareunknowns=["input"]permitsinput.<table>.<column>. Deeper refs likeinput.item.attrs.price.valuefail withpe_fragment_error: invalid ref operand, so nested documents (e.g. an EAV entity with per-attribute type/value objects, or per-locale value objects) must be flattened into columns (input.attr.value_number,input.attr.value_de, ...). Dynamic column choice is fine as long as the key is known at compile time:input.attr[sprintf("value_%s", [input.locale])]resolves to a single column during partial evaluation. -
Rego
print(...)output is captured per evaluation: setengine.print_handlerto acallable(message, location)to receive it (default: written to stderr);engine.last_printsholds the(message, location)pairs of the last eval. -
Concurrency: an engine may be shared across threads — evals are serialized by an internal re-entrant lock (builtins may evaluate on their own engine). Per-eval state (
last_trace,last_coverage,last_prints) reflects the most recently completed eval, so with a shared engine prefer return values overlast_*attributes, or use one engine per thread. -
Resource limits / DoS: there are no built-in caps. Policy/data sizes, the number of engines (call
close();__del__is best-effort under GC), and the set of distinct query strings (each is cached as a prepared query on the engine, invalidated by any config change) are bounded only by the process. If queries are dynamic or attacker-shaped, cap and canonicalize them in the application; treatquery,policy source, anddataas privileged inputs on a multi-tenant host. Rego itself can loop/compute without limits, so the caller should apply timeouts/load controls at the application layer if policies are untrusted. -
Confidentiality: traces (
trace=True) capture the plugged values of local variables, and Regoprint()calls see their arguments; both can contain secrets frominputordata. Keep them off shared logs, or scrub them, when evaluating sensitive inputs. (The default print handler writes to stderr.)
Metadata
Release files for opa-golib-python-bindings 0.4.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| opa_golib_python_bindings-0.4.2.tar.gz | 26.1 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| opa_golib_python_bindings-0.4.2-py3-none-manylinux_2_34_x86_64.whl | Python 3 | none | Linux glibc 2.34+ x86-64 | Details |
| opa_golib_python_bindings-0.4.2-py3-none-manylinux_2_34_aarch64.whl | Python 3 | none | Linux glibc 2.34+ ARM64 | Details |
| opa_golib_python_bindings-0.4.2-py3-none-macosx_11_0_x86_64.whl | Python 3 | none | macOS 11.0+ x86-64 | Details |
| opa_golib_python_bindings-0.4.2-py3-none-macosx_11_0_arm64.whl | Python 3 | none | macOS 11.0+ ARM64 | Details |
Total release size: 40.0 MB
Release files / opa_golib_python_bindings-0.4.2.tar.gz
| Download URL | opa_golib_python_bindings-0.4.2.tar.gz |
|---|---|
| Size | 26.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
aeb87d3e8e7d7e308ae6c1238b5b126f761b0e214f623617e056a25b4cdb1500
|
|
BLAKE2b-256 checksum How to use checksums |
997c6fd87d962592e06011d3f5c0f8723e046ac0bd9f10bc3943e05307a19ca3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.
Transparency logRelease files / opa_golib_python_bindings-0.4.2-py3-none-manylinux_2_34_x86_64.whl
| Download URL | opa_golib_python_bindings-0.4.2-py3-none-manylinux_2_34_x86_64.whl |
|---|---|
| Size | 13.4 MB |
| Tags | Linux glibc 2.34+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
c2dafc8418d5be1b4ad2d148246d94f6121e75faffa20ff4191ba1a4b70753e8
|
|
BLAKE2b-256 checksum How to use checksums |
9964f5be9046ab68eb3ac42b61e5e0d2c284859d03d7dbf1ea09a7d9a8c56fe2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.
Transparency logRelease files / opa_golib_python_bindings-0.4.2-py3-none-manylinux_2_34_aarch64.whl
| Download URL | opa_golib_python_bindings-0.4.2-py3-none-manylinux_2_34_aarch64.whl |
|---|---|
| Size | 12.1 MB |
| Tags | Linux glibc 2.34+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
51964e8ad00fcd16bd7848cb6d705d7798e38c028f977a3a42cf72beb988f996
|
|
BLAKE2b-256 checksum How to use checksums |
7e542996d8774b63dfbc0eb4b68199a8cf7164fd439e36cea56d942a24cfdf90
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.
Transparency logRelease files / opa_golib_python_bindings-0.4.2-py3-none-macosx_11_0_x86_64.whl
| Download URL | opa_golib_python_bindings-0.4.2-py3-none-macosx_11_0_x86_64.whl |
|---|---|
| Size | 7.5 MB |
| Tags | Python 3 macOS 11.0+ x86-64 |
|
SHA-256 checksum How to use checksums |
a9805c5a7ed458b50d0d8d314c8d14bf6d9137477a3aaa28db3cbb82a7e951c8
|
|
BLAKE2b-256 checksum How to use checksums |
cad590e8ec886cb7b98f3e220f45c7a789b756b253b5f16318f22beeb6ff6cc4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.
Transparency logRelease files / opa_golib_python_bindings-0.4.2-py3-none-macosx_11_0_arm64.whl
| Download URL | opa_golib_python_bindings-0.4.2-py3-none-macosx_11_0_arm64.whl |
|---|---|
| Size | 6.9 MB |
| Tags | Python 3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
64e745fda1585d96931be5aadf81226099818eccb61e5aa0953309a4ca037861
|
|
BLAKE2b-256 checksum How to use checksums |
9e2514def5dc0c39c7add38a11d503e5f9a0b86017ae95fcbad48eb579cdaab3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.
Transparency log