Grammar specification for Cedar policy syntax

This topic describes the grammar specification for the Cedar Policy Language. This grammar uses the following symbols:

  • A vertical bar | designates alternatives. Only one alternative can be used.
  • Brackets [ ] designate an optional element.
  • Parentheses ( ) designate grouping
  • Braces { } designate repetition of an element zero or more times.

Capitalized words represent grammar constructs, and lexical tokens are displayed in all-caps.

Tokens are defined using regular expressions:

  • Brackets [ ] represent a range of characters.
  • A vertical bar | designates alternatives.
  • An asterisk * represents zero or more occurrences of an element.
  • A plus sign + represents one or more occurrences of an element.
  • A question mark ? represents exactly zero or one occurrences of an element.
  • A tilde ~ represents the complement of the following element.
  • A hyphen - represents difference.
  • Single quotation marks ' ' surround elements that must be entered literally as shown.

The grammar ignores whitespace and comments.

Policy

A policy consists of optional ‘Annotation’ entries, an Effect, a Scope in parentheses ( ), and an optional set of Conditions in braces { }.

A policy must always end with a semicolon ;.

Policy ::= {Annotation} Effect '(' Scope ')' {Conditions} ';'

Effect

The Effect element of a policy is either the word permit or forbid.

Effect ::= 'permit' | 'forbid'

Scope

The Scope element of a policy must include a Principal entity, an Action entity, and a Resource entity.

Scope ::= Principal ',' Action ',' Resource

Principal

The Principal element consists of the principal keyword. If specified by itself, the policy statement matches any principal.

Optionally, the keyword can be followed by either the in, ==, or is operator. An is operator may appear together with an in operators, but not an == operator. The in and == operators are followed by either an Entity, or the ?principal placeholder when used in a policy template.

Principal ::= 'principal' [(['is' PATH] ['in' (Entity | '?principal')]) | ('==' (Entity | '?principal'))]

Action

The Action element consists of the action keyword. If specified by itself, it matches any action. Optionally, it can be followed by either the == operator and an action entity, or in followed by an action entity or a set of action entities.

Action ::= 'action' [( '==' Entity | 'in' ('[' EntList ']' | Entity) )]

Resource

The Resource consists of the resource keyword. If specified by itself, it matches any resource. Optionally, it can be followed by either the in, ==, or is operator. An is operator may appear together with an in operators, but not an == operator. The in and == operators are followed by either an Entity, or the ?resource placeholder when used in a policy template.

Resource ::= 'resource' [(['is' PATH] ['in' (Entity | '?resource')]) | ('==' (Entity | '?resource'))]

Condition

A Condition consists of either the when or unless keyword followed by a Boolean expression surrounded by braces { }. A when clause matches the request when the expression evaluates to true. An unless clause matches the request when the expression (an Expr element) evaluates to false.

The parent Policy element can have zero or more when or unless clauses.

Condition ::= ('when' | 'unless') '{' Expr '}'

Expr

Expr ::= Or | 'if' Expr 'then' Expr 'else' Expr

Or

Or ::= And {'||' And}

For more details, see || (OR).

And

And ::= Relation {'&&' Relation}

For more details, see && (AND).

Relation

Relation ::= Add [RELOP Add] | Add 'has' (IDENT | STR) | Add 'like' PAT | Add 'is' Path ('in' Add)?

Add

Add ::= Mult {('+' | '-') Mult}

Mult

Mult ::= Unary { '*' Unary}

Unary

Unary ::= ['!' | '-']x4 Member

Member

Member ::= Primary {Access}

Annotation

Annotation ::= '@' ANYIDENT ( '('STR')' )?

Access

Access ::= '.' IDENT ['(' [ExprList] ')'] | '[' STR ']'

Primary

Primary ::= LITERAL 
           | VAR 
           | Entity 
           | ExtFun '(' [ExprList] ')' 
           | '(' Expr ')' 
           | '[' [ExprList] ']' 
           | '{' [RecInits] '}'

Path

Path ::= IDENT {'::' IDENT}

Entity

Entity ::= Path '::' STR

EntList

EntList ::= Entity {',' Entity}

ExprList

ExprList ::= Expr {',' Expr}

ExtFun

ExtFun ::= [Path '::'] IDENT

RecInits

RecInits ::= (IDENT | STR) ':' Expr {',' (IDENT | STR) ':' Expr}

RELOP

RELOP ::= '<' | '<=' | '>=' | '>' | '!=' | '==' | 'in'

ANYIDENT

ANYIDENT ::= ['_''a'-'z''A'-'Z']['_''a'-'z''A'-'Z''0'-'9']*

IDENT

IDENT ::= ANYIDENT - RESERVED

STR

STR ::= Fully-escaped Unicode surrounded by '"'s

PAT

PAT ::= STR with `\*` allowed as an escape

LITERAL

LITERAL ::= BOOL | INT | STR

BOOL

BOOL ::= 'true' | 'false'

INT

INT ::= '-'? ['0'-'9']+

RESERVED

RESERVED ::= BOOL | 'if' | 'then' | 'else' | 'in' | 'like' | 'has' | 'is' | '__cedar'

VAR

VAR ::= 'principal' | 'action' | 'resource' | 'context'

WHITESPC

WHITESPC ::= Unicode whitespace

COMMENT

COMMENT ::= '//' ~NEWLINE* NEWLINE