Policy Expression Language

Declarative expression language for policy.where clauses

Purpose

The policy expression language provides a simple, safe, and deterministic way to define access control and behavior constraints in policy.where clauses.

Design Philosophy

Simple

Minimal syntax for common use cases

Safe

No code execution or side effects

Deterministic

Same input always produces same result

JSONPath-like

Familiar to developers using JSON query languages

Grammar

expression     = comparison | logical_expr | literal

comparison     = accessor operator value
logical_expr   = expression logical_op expression
               | "(" expression ")"
               | "not" expression

accessor       = identifier *("." identifier | "[" index "]")
identifier     = ALPHA *(ALPHA | DIGIT | "_")
index          = DIGIT+ | STRING

operator       = "==" | "!=" | ">" | "<" | ">=" | "<="
               | "~" | "!~" | "in" | "not in"
               | "contains" | "starts_with" | "ends_with"

logical_op     = "&&" | "||" | "and" | "or"

value          = STRING | NUMBER | BOOLEAN | NULL | array
array          = "[" [value *("," value)] "]"

STRING         = "'" *CHAR "'"
NUMBER         = ["-"] DIGIT+ ["." DIGIT+]
BOOLEAN        = "true" | "false"
NULL           = "null"

Operators

Comparison Operators

OperatorDescriptionExample
==Equalitytool.type == 'http'
!=Inequalitytool.type != 'system'
>Greater thanmessage.priority > 5
<Less thancontext.window < 8192
>=Greater or equalruntime.memory_mb_min >= 512
<=Less or equalruntime.cpu_cores_min <= 4

String Operators

OperatorDescriptionExample
~Regex matchtool.endpoint ~ '^https://internal\\.corp'
!~Regex non-matchtool.endpoint !~ 'external'
containsSubstring testmessage.payload contains 'urgent'
starts_withPrefix testagent.id starts_with 'ajson://internal'
ends_withSuffix testtool.endpoint ends_with '.internal.corp'

Collection Operators

OperatorDescriptionExample
inMembership testtool.type in ['http', 'function']
not inNon-membershiptool.type not in ['system', 'plugin']

Logical Operators

OperatorDescriptionExample
&& / andLogical ANDtool.type == 'http' && tool.auth.method == 'none'
|| / orLogical ORmessage.priority > 8 || message.urgent == true
notLogical NOTnot (tool.type in ['system', 'plugin'])

Operator Precedence

From highest to lowest:

  1. 1. Parentheses: ( )
  2. 2. Unary: not
  3. 3. Comparison: ==, !=, >, <, >=, <=
  4. 4. String/Collection: ~, !~, in, not in, contains, starts_with, ends_with
  5. 5. Logical AND: &&, and
  6. 6. Logical OR: ||, or

Context Variables

Expressions evaluate against a context object containing:

{
  "tool": {          // Current tool being invoked
    "id": "...",
    "type": "...",
    "endpoint": "...",
    ...
  },
  "message": {       // Current message envelope
    "from": "...",
    "to": "...",
    "payload": {...},
    "intent": "...",
    ...
  },
  "agent": {         // Current agent manifest
    "id": "...",
    "name": "...",
    ...
  },
  "runtime": {       // Runtime context
    "environment": "production",
    "timestamp": "2025-11-10T00:00:00Z",
    ...
  }
}

Examples

Simple Comparison

{
  "id": "deny-http-no-auth",
  "effect": "deny",
  "action": "tool.call",
  "where": "tool.type == 'http' && tool.auth.method == 'none'"
}

Denies calls to HTTP tools that don't have authentication configured.

Regex Pattern Matching

{
  "id": "deny-external-endpoints",
  "effect": "deny",
  "action": "tool.call",
  "where": "tool.endpoint !~ '^https://.*\\.internal\\.corp'"
}

Blocks access to any endpoints outside the internal corporate domain.

Complex Logic

{
  "id": "audit-sensitive-messages",
  "effect": "audit",
  "action": "message.send",
  "where": "(message.payload contains 'password' || message.payload contains 'api_key') && not (message.to starts_with 'ajson://internal')"
}

Audits messages containing sensitive keywords being sent to external agents.

Collection Membership

{
  "id": "allow-safe-tools",
  "effect": "allow",
  "action": "tool.call",
  "where": "tool.type in ['function', 'http'] && tool.id in ['tool://safe/search', 'tool://safe/summarize']"
}

Allows only specific whitelisted tools of approved types.

Evaluation Semantics

Type Coercion

  • Comparisons between incompatible types evaluate to false
  • String comparisons are case-sensitive
  • Numbers are compared numerically
  • Booleans compare by value (true > false)

Missing Fields

  • Accessing non-existent fields returns null
  • null == null evaluates to true
  • null compared to any non-null value evaluates to false

Short-Circuit Evaluation

  • &&: If left operand is false, right operand is not evaluated
  • ||: If left operand is true, right operand is not evaluated

Implementation Guidance

Security

  • MUST NOT execute arbitrary code
  • MUST limit recursion depth (recommended: 10 levels)
  • MUST prevent regex denial-of-service (ReDoS)
  • SHOULD implement expression complexity limits

Performance

  • Evaluate in constant or linear time when possible
  • Cache compiled expressions
  • Optimize common patterns (e.g., simple equality)

Error Handling

  • Syntax errors SHOULD fail policy evaluation (fail-closed)
  • Runtime errors MAY log warnings
  • Invalid regex patterns MUST fail at compile time

Future Extensions

  • Functions: length(), upper(), lower()
  • Array operations: map(), filter()
  • Temporal operators: before, after
  • Quantifiers: exists, forall

Learn More

Read the complete policy expression language specification in Appendix B

View Full Specification

Related Resources

Continue exploring JSON AGENTS