Skip to content

Values and identities

Facts, rule conditions, and authorization checks use two kinds of concrete values:

  • Typed identities (User:alice, Document:123) reference domain entities.
  • Primitive constants ("read", 3, true) represent scalar values such as action names, counts, and flags.

A typed identity pairs an uppercase entity type (PascalCase) with an ID using TypeName:id syntax:

is_owner(User:sam, Document:sam);

Both the type and the ID must match. Even though User:sam and Document:sam share the ID "sam", they are distinct values and never match each other.

The ID after the colon is always treated as a string, even when written with digits (Document:123). If an ID contains characters outside standard letters, digits, and underscores (such as @, -, or spaces), wrap the ID in double quotes:

is_owner(User:"sam@example.com", Document:"q3-roadmap");

Use the exact same type and ID format when writing facts and enforcing decisions. See the Language Reference for character and escaping rules.

Use primitive literals for values that are not entity references:

TypeExamplesCommon uses
string"read", "published"Action names, roles, statuses, and labels
int3, 100Counts, versions, clearance levels, timestamps
booleantrue, falseExplicit two-state flags
allow(user: User, "read", document: Document) if
is_owner(user, document) and
publication_status(document, "published") and
clearance_level(user, 3);

Verdict never coerces values across types: the identity Document:3, the integer 3, and the string "3" are three distinct values.