opa
opa copied to clipboard
Add metadata annotation for reusable schema references
OPA currently allows users to set the schema for input and data paths via the schemas annotation. This example says that input.foo
is an object with a property bar
that has type string
.
# METADATA
# schemas:
# - input.foo: {properties: {bar: {type: string}}}
package x
Schemas can be defined inline in .rego in annotations or loaded in from disk or via Go APIs and then referenced by path e.g., - input.foo: schema.path.to.schema
. This works well when ingesting preexisting schemas from the rest of the world. However, in some cases, it would be nice to be able to define reusable schemas and load them into OPA without having to integrate with the ast.SchemaSet
API.
To do this we could add a new annotation, e.g., schema_defs
, that would allow users to define arbitrary JSON schemas inline in .rego files. Then they could refer to these definitions in the existing schemas
annotation via URL. For example:
schema.rego:
# METADATA
# description: This package contains schema definitions that can be referenced in other policies
# schema_defs:
# foo: {$id: https://example.com/foo, properties: {type: {bar: string}}}
package schemas
x.rego
# METADATA
# schemas:
# - input.foo: {$ref: https://example.com/foo}
package x
There's an open question around scoping. Specifically, should the schema_defs annotation be supported anywhere or only at the global scope? If we allow schemas to be defined anywhere then we need to deal with conflicts, e.g., suppose two files declare schemas with the same URL. Is this an error? On the other hand, we could implement the feature such that schema_defs are only visible within the scope of the annotations (e.g., package/subpackage) but then that would force users to invent an artificial root for global schemas (👎 ).