PATTERN Cited by 1 source
Align with upstream plugin input schema¶
Problem¶
When you build a variant integration of an OSS engine for your own ingress / proxy / mesh / framework, you face a schema-design question: what does the request object look like as passed into the policy engine? If you design your own schema, you force every internal developer to learn a Zalando-ism / Acme-ism that differs from the upstream example code, Stack Overflow answers, community tutorials, and Styra certification material.
Solution¶
Match the input schema of the canonical upstream plugin (for OPA: the OPA Envoy plugin). Every example, doc page, training, and Rego snippet written against the upstream plugin works against your integration. Developers who learn the upstream schema once can use it everywhere in your stack.
The explicit quote¶
From Zalando's post on embedding OPA in Skipper:
"Alignment with OPA Envoy Plugin's Input Structures: We chose to align closely with the OPA Envoy plugin's input structures to leverage existing documentation, examples, and training resources. This minimises the learning curve for our developers and keeps Zalando-isms at bay."
The OPA Envoy plugin is the most widely-deployed OPA-in-proxy
integration; its input.attributes.request.http.method,
input.attributes.request.http.path, input.parsed_path,
input.parsed_body, etc. are the community-canonical keys.
Skipper's embedded OPA integration matches this shape, so a Rego
snippet from the OPA docs works unchanged at Zalando.
Why this matters¶
- Documentation leverage. Every upstream doc, example, tutorial, and Stack Overflow answer is now free training material.
- Developer mobility. Engineers moving between companies / teams carry their Rego skill unchanged.
- Vendor ecosystem compatibility. Styra DAS tooling, third- party Rego linters, policy-libraries, IDE plugins all keep working because the schema matches.
- Keeps "Zalando-isms" out of the language. Internal deviations from a widely-used schema are a long-term technical-debt bill; aligning with upstream avoids opening the account.
When this pattern applies¶
This pattern generalises beyond OPA. Whenever you're building a variant of a well-known plugin / sidecar contract (ext-authz, OTel exporters, Prometheus exposition, Kafka Connect connectors), the default choice is to match the canonical contract, not invent your own. Deviations should be justified explicitly as "we had to", not implicit as "nobody pushed back".
Seen in¶
- sources/2024-12-05-zalando-open-policy-agent-in-skipper-ingress — Zalando's Skipper OPA integration explicitly adopts the OPA Envoy plugin's input schema despite Skipper being an architecturally different proxy from Envoy. The rationale is stated as a first-class technical-design decision, not an afterthought.
Related¶
- systems/envoy — the canonical plugin contract being aligned to
- systems/open-policy-agent
- systems/skipper-proxy
- concepts/backward-compatibility
- patterns/embedded-opa-in-proxy