Summary
Add support for loading protobuf-format plan bundles produced by OPA's new opa build --format=proto flag (open-policy-agent/opa#8825, merged).
Background
OPA now emits IR plan bundles in two wire formats:
--format |
Plan file |
Manifest file |
json (default) |
/plan.json |
/.manifest |
proto (new) |
/plan.pb |
/.manifest.pb |
The protobuf encoding is defined by the schemas added in open-policy-agent/opa#8775:
v1/ir/plan.proto — the IR plan
v1/bundle/manifest.proto — the bundle manifest
The proto form is significantly smaller on the wire (per the PR, a minimal policy produces plan.pb 469 bytes vs plan.json 2098 bytes; .manifest.pb 21 bytes vs .manifest 59 bytes). OPA's own bundle reader auto-detects either form and rejects mixed-format bundles.
Current state in this package
The package today only understands the JSON forms:
BundleLoader switches on the hard-coded filenames plan.json, .manifest, and data.json, and DirectoryLoader.keepFiles is Set(["data.json", "plan.json", ".manifest"]).
Policy.init(jsonData:) (Sources/IR/IR+Decode.swift) decodes the IR plan with JSONDecoder.
OPA.Manifest(from:) (Sources/Rego/Manifest+Codable.swift) decodes the manifest from JSON.
There is no path to load a bundle built with --format=proto.
Proposed work
- Bundle detection — teach
BundleLoader / DirectoryLoader to recognize plan.pb and .manifest.pb alongside plan.json / .manifest, matching OPA's auto-detection and mixed-format rejection semantics (don't allow a bundle to mix .json and .pb plan/manifest forms).
- Proto plan decoding — add a
Policy.init(protobufData:) (or similar) that decodes plan.pb per v1/ir/plan.proto into the existing IR Policy model, then runs the same prepareForExecution() static-analysis passes as the JSON path.
- Proto manifest decoding — add an
OPA.Manifest initializer that decodes .manifest.pb per v1/bundle/manifest.proto.
- Schema source & codegen — decide how to generate the Swift bindings from the
.proto schemas (likely swift-protobuf via protoc-gen-swift), pinning the schemas to a specific OPA release for reproducible output. Consider whether the generated code / SwiftProtobuf dependency should be isolated behind a product/target so consumers who only need JSON aren't forced to pull in protobuf.
- Tests — round-trip fixtures built with both
--format=json and --format=proto from the same policy, asserting identical evaluation results; plus a mixed-format-bundle rejection test. The ComplianceSuite could exercise both formats.
Open questions
- Should proto support be a separate target/product or folded into
Rego/IR?
- Which OPA release should we pin the
.proto schemas to?
- Do we need write support (emitting
.pb bundles), or is read-only sufficient for this package's use cases?
References
Summary
Add support for loading protobuf-format plan bundles produced by OPA's new
opa build --format=protoflag (open-policy-agent/opa#8825, merged).Background
OPA now emits IR plan bundles in two wire formats:
--formatjson(default)/plan.json/.manifestproto(new)/plan.pb/.manifest.pbThe protobuf encoding is defined by the schemas added in open-policy-agent/opa#8775:
v1/ir/plan.proto— the IR planv1/bundle/manifest.proto— the bundle manifestThe proto form is significantly smaller on the wire (per the PR, a minimal policy produces
plan.pb469 bytes vsplan.json2098 bytes;.manifest.pb21 bytes vs.manifest59 bytes). OPA's own bundle reader auto-detects either form and rejects mixed-format bundles.Current state in this package
The package today only understands the JSON forms:
BundleLoaderswitches on the hard-coded filenamesplan.json,.manifest, anddata.json, andDirectoryLoader.keepFilesisSet(["data.json", "plan.json", ".manifest"]).Policy.init(jsonData:)(Sources/IR/IR+Decode.swift) decodes the IR plan withJSONDecoder.OPA.Manifest(from:)(Sources/Rego/Manifest+Codable.swift) decodes the manifest from JSON.There is no path to load a bundle built with
--format=proto.Proposed work
BundleLoader/DirectoryLoaderto recognizeplan.pband.manifest.pbalongsideplan.json/.manifest, matching OPA's auto-detection and mixed-format rejection semantics (don't allow a bundle to mix.jsonand.pbplan/manifest forms).Policy.init(protobufData:)(or similar) that decodesplan.pbperv1/ir/plan.protointo the existing IRPolicymodel, then runs the sameprepareForExecution()static-analysis passes as the JSON path.OPA.Manifestinitializer that decodes.manifest.pbperv1/bundle/manifest.proto..protoschemas (likelyswift-protobufviaprotoc-gen-swift), pinning the schemas to a specific OPA release for reproducible output. Consider whether the generated code / SwiftProtobuf dependency should be isolated behind a product/target so consumers who only need JSON aren't forced to pull in protobuf.--format=jsonand--format=protofrom the same policy, asserting identical evaluation results; plus a mixed-format-bundle rejection test. The ComplianceSuite could exercise both formats.Open questions
Rego/IR?.protoschemas to?.pbbundles), or is read-only sufficient for this package's use cases?References