opa icon indicating copy to clipboard operation
opa copied to clipboard

Add metadata annotation for reusable schema references

Open tsandall opened this issue 6 months ago • 2 comments

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 (👎 ).

tsandall avatar Aug 13 '24 23:08 tsandall