{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://ucan.xyz/schemas/policy.json", "title": "UCAN Policy Language", "description": "Policy statements and selectors for constraining invocation arguments", "$defs": { "Selector": { "title": "Policy Selector", "description": "jq-inspired selector for navigating IPLD data structures", "type": "string", "pattern": "^\\.(([a-zA-Z_][a-zA-Z0-9_]*)|(\\[[^\\]]+\\])|(\\[\\])|(\\[-?\\d+\\])|(\\[\\d*:\\d*\\]))?((\\.[a-zA-Z_][a-zA-Z0-9_]*)|(\\[[^\\]]+\\])|(\\[\\])|(\\[-?\\d+\\])|(\\[\\d*:\\d*\\]))*\\??$", "examples": [ ".", ".foo", ".bar[0]", ".items[-1]", ".data[2:5]", ".optional?" ] }, "GlobPattern": { "title": "Glob Pattern", "description": "Pattern for 'like' operator. * = wildcard, \\* = literal", "type": "string", "examples": [ "*@example.com", "prefix*suffix" ] }, "EqualityOperator": { "title": "Equality Operator", "type": "string", "enum": [ "==", "!=" ] }, "InequalityOperator": { "title": "Inequality Operator", "type": "string", "enum": [ ">", ">=", "<", "<=" ] }, "EqualityStatement": { "title": "Equality Statement", "description": "Deep comparison: [operator, selector, value]", "type": "array", "prefixItems": [ { "$ref": "#/$defs/EqualityOperator" }, { "$ref": "#/$defs/Selector" }, {} ], "minItems": 3, "maxItems": 3, "examples": [ [ "==", ".status", "draft" ], [ "!=", ".deleted", true ] ] }, "InequalityStatement": { "title": "Inequality Statement", "description": "Numeric comparison: [operator, selector, number]", "type": "array", "prefixItems": [ { "$ref": "#/$defs/InequalityOperator" }, { "$ref": "#/$defs/Selector" }, { "type": "number" } ], "minItems": 3, "maxItems": 3, "examples": [ [ ">", ".age", 18 ], [ "<=", ".price", 100.50 ] ] }, "LikeStatement": { "title": "Like Statement", "description": "Glob pattern matching: ['like', selector, pattern]", "type": "array", "prefixItems": [ { "const": "like" }, { "$ref": "#/$defs/Selector" }, { "$ref": "#/$defs/GlobPattern" } ], "minItems": 3, "maxItems": 3, "examples": [ [ "like", ".email", "*@example.com" ] ] }, "NotStatement": { "title": "Not Statement", "description": "Logical negation: ['not', statement]", "type": "array", "prefixItems": [ { "const": "not" }, { "$ref": "#/$defs/PolicyStatement" } ], "minItems": 2, "maxItems": 2 }, "AndStatement": { "title": "And Statement", "description": "Logical AND: ['and', [statements...]]. Empty array = true", "type": "array", "prefixItems": [ { "const": "and" }, { "type": "array", "items": { "$ref": "#/$defs/PolicyStatement" } } ], "minItems": 2, "maxItems": 2 }, "OrStatement": { "title": "Or Statement", "description": "Logical OR: ['or', [statements...]]. Empty array = true", "type": "array", "prefixItems": [ { "const": "or" }, { "type": "array", "items": { "$ref": "#/$defs/PolicyStatement" } } ], "minItems": 2, "maxItems": 2 }, "AllStatement": { "title": "All Statement", "description": "Universal quantifier: ['all', selector, statement]", "type": "array", "prefixItems": [ { "const": "all" }, { "$ref": "#/$defs/Selector" }, { "$ref": "#/$defs/PolicyStatement" } ], "minItems": 3, "maxItems": 3, "examples": [ [ "all", ".reviewers", [ "like", ".email", "*@example.com" ] ] ] }, "AnyStatement": { "title": "Any Statement", "description": "Existential quantifier: ['any', selector, statement]", "type": "array", "prefixItems": [ { "const": "any" }, { "$ref": "#/$defs/Selector" }, { "$ref": "#/$defs/PolicyStatement" } ], "minItems": 3, "maxItems": 3, "examples": [ [ "any", ".tags", [ "==", ".", "urgent" ] ] ] }, "PolicyStatement": { "title": "Policy Statement", "description": "A single policy predicate expression", "oneOf": [ { "$ref": "#/$defs/EqualityStatement" }, { "$ref": "#/$defs/InequalityStatement" }, { "$ref": "#/$defs/LikeStatement" }, { "$ref": "#/$defs/NotStatement" }, { "$ref": "#/$defs/AndStatement" }, { "$ref": "#/$defs/OrStatement" }, { "$ref": "#/$defs/AllStatement" }, { "$ref": "#/$defs/AnyStatement" } ] }, "Policy": { "title": "UCAN Policy", "description": "Array of statements forming implicit AND. Constrains invocation args.", "type": "array", "items": { "$ref": "#/$defs/PolicyStatement" }, "examples": [ [], [ [ "==", ".from", "alice@example.com" ] ], [ [ "==", ".status", "draft" ], [ "all", ".reviewer", [ "like", ".email", "*@example.com" ] ] ] ] } } }