306 lines
6.4 KiB
JSON
306 lines
6.4 KiB
JSON
{
|
|
"$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"
|
|
]
|
|
]
|
|
]
|
|
]
|
|
}
|
|
}
|
|
}
|