open-policy-agent / opa

Open Policy Agent (OPA) is an open source, general-purpose policy engine.
https://www.openpolicyagent.org
Apache License 2.0
9.59k stars 1.33k forks source link

Json Schema: `opa eval` throws cryptic error when a `$ref` tag is used inside `allOf` #6523

Open mosiac1 opened 8 months ago

mosiac1 commented 8 months ago

Short description

When attempting to use validation with a JSON Schema, if any document in the schema contains a $ref tag inside a allOf, opa eval ... will print a cryptic error (looking like a GO dump).

The $ref tag is used in JSON Schemas as a basic form of inheritance, including the contents of the referenced schema in the current one. It may be useful to use this together with allOf for multiple inheritance.

Steps To Reproduce

  1. Copy the json bellow to schema.json;

    {
    "$schema": "https://json-schema.org/draft-07/schema",
    "$id": "https://jsonschema.dev/schemas/opa-input",
    "$defs": {
    "mixins/action.schema.json": {
      "$schema": "https://json-schema.org/draft-07/schema",
      "$id": "mixins/action.schema.json",
      "type": "string"
    },
    "mixins/context.schema.json": {
      "$schema": "https://json-schema.org/draft-07/schema",
      "$id": "mixins/context.schema.json",
      "type": "object",
      "properties": {
        "user": {
          "type": "string"
        }
      },
      "required": ["user"]
    },
    "mixins/special-context.schema.json": {
      "$schema": "https://json-schema.org/draft-07/schema",
      "$id": "mixins/special-context.schema.json",
      "type": "object",
      "properties": {
        "groups": {
          "type": "string"
        }
      },
      "allOf": [
        { "$ref": "https://jsonschema.dev/schemas/mixins/context.schema.json" }
      ],
      "required": ["groups"]
    }
    },
    "type": "object",
    "properties": {
    "action": {
      "$ref": "https://jsonschema.dev/schemas/mixins/action.schema.json"
    },
    "context": {
      "$ref": "https://jsonschema.dev/schemas/mixins/special-context.schema.json"
    }
    },
    "required": ["action", "context"]
    }
  2. Create a basic Rego policy (what it does is not relevant, but the file needs to be a valid policy) named policy.rego;

  3. Create an empty file input.json;

  4. Run opa eval 'input' policy.rego -i input.json -s schema.json;

The output will be

{
  "errors": [
    {
      "message": "type checking: unexpected schema type \u0026{0xc000227dd0 https://jsonschema.dev/schemas/opa-input \u003cnil\u003e \u003cnil\u003e context \u003cnil\u003e {[]} https://jsonschema.dev/schemas/mixins/special-context.schema.json 0xc00020b000 0xc00020a400 [] false [] \u003cnil\u003e \u003cnil\u003e \u003cnil\u003e \u003cnil\u003e \u003cnil\u003e \u003cnil\u003e \u003cnil\u003e \u003cnil\u003e  \u003cnil\u003e \u003cnil\u003e [] map[] \u003cnil\u003e map[] \u003cnil\u003e \u003cnil\u003e \u003cnil\u003e false \u003cnil\u003e \u003cnil\u003e \u003cnil\u003e [] [] [] [] \u003cnil\u003e \u003cnil\u003e \u003cnil\u003e \u003cnil\u003e}: unable to merge these schemas",
      "code": "rego_type_error"
    }
  ]
}

Expected behavior

This is a valid JSON Schema (see https://www.jsonschemavalidator.net/s/a6r4YT0v) and OPA should use it to verify the Rego code.

Additional context

❯ opa version
Version: 0.60.0
Build Commit: a1a2ae3cbb5fdddf306b1ef67ca5a856fd94fa15
Build Timestamp: 2023-12-20T22:07:16Z
Build Hostname: 67c18570dbf9
Go Version: go1.21.5
Platform: linux/amd64
WebAssembly: unavailabl

Slack conversation: https://openpolicyagent.slack.com/archives/CBR63TK2A/p1704984957314319

anderseknert commented 8 months ago

Thanks @mosiac1 👍