Skip to main content

Manifest language reference

The annotated manifest below describes an authorization model for an application that allows users to manage folders and documents. It demonstrates the building blocks of the modeling language and how they can be put together to provide a complete authorization solution. The annotated manifest is followd by more detailed discussion of its various parts.

Annotated reference

# yaml-language-server: $schema=https://www.topaz.sh/schema/manifest.json
---

# Declares the version of the model
# Supported value: 3
model:
version: 3

## Declare object types
types:

# Define the "user" object type
# The annotation "display_name" acts as a hint to the Topaz UI for a display name for this type

### display_name: User ###
user:

# Define relations that can have a user as their object.
relations:

# Define a "manager" relation that can only have a "user" as its subject.
# The object of the relation is also a user because it is defined within the "user:" block.
# That means that the "manager" relation can only occur between two users.
manager: user


# Define the "group" object type

### display_name: Group ###
group:

# Define relations that can have a group as their object.

relations:
# Define a "member" relation that can take as its subject one of:
# * an individual user
# * the members of a group
member: user | group#member


# Define the "folder" object type

### display_name: Folder ###
folder:

# Define relations that can have a folder as their object.
relations:

# A folder can have another folder as its parent.
parent: folder

# A folder may have individual users or groups as its owners and editors.
owner: user | group#member
editor: user | group#member

# The subjects of a the "viewer" relation can be:
# 1. An individual "user".
# 2. All users (the wildcard id "*").
# 3. All members of a given group.
viewer: user | user:* | group#member

# Define permissions on folder objects.
permissions:

# The "can_delete_folder" permission is granted to:
# * Anyone who is an owner of the folder (subject of the "owner" relation)
# * Anyone with the "can_delete_folder" permission on the folder's parent.
# This is a recursive definition that can be resolved anywhere up the folder's "parent" chain.
can_delete_folder: owner | parent->can_delete_folder

# The "can_write_folder" permission is granted to:
# * Anyone with the "can_delete_folder" permission.
# * Anyone with the "can_write_folder" permission on the folder's parent.
# * Anyone who has the "editor" relation with the folder.
can_write_folder: can_delete_folder | parent->can_write_folder | editor

can_read_folder: can_write_folder | parent->can_read_folder | viewer


# Define the "document" object type

### display_name: Document ###
document:
relations:
parent: folder
owner: user | group#member
editor: user | group#member
viewer: user | group#member

permissions:

# The "can_delete_document" permission only granted if BOTH conditions are met.
can_delete_document: owner & parent->can_write_folder

can_write_document: can_delete_document | parent->can_write_document | editor
can_read_document: can_write_document | parent->can_read_document | viewer

Identifiers

Object, relation, and permission names are treated as identifiers and must satisfy the conditions below.

  • Be all lowercase.
  • Start with a letter.
  • Can contain letters, digits, dots (.), underscores (_), and dashes (-).
  • Must end with a letter or digit.
  • No longer than 64 characters.

Uniqueness

  • Object names must be unique. It is not possible to have two distinct object types with the same name.
  • Relation and permission names must be unique within an object type but relations or permissions with the same name can be defined on different object types. In the example above, both folder and document have relation called parent, owner, etc

Relation definitions

A relation definition specifies the set of valid assignments for the relation. Relation names must be unique within an object type. The object of the relation must be of the type in which the relation is defined and the subject must match one of the assignment terms in the relation definition.

There are three kinds of assignment specifiers:

Direct assignment

Direct assignment specifies an object type that can be used as the subject of the relation. For example, the manager relation below can be directly assigned to an object of type user:

user:
relations:
manager: user # direct assignment

That means that a manager relation can be created with a user object and a user subject.

Wildcard assignment

In addition to a direct relation between two object, it is also possible to allow wildcard relations where the subject is the set of all objects of the given type. For example, the viewer relation below can be created between a document and a specific user (direct assignment) or between a document and all users.

document:
relations:
viewer: user | user:*

This definition allows the viewer relation to be created between a document and the user with ID *, which represents all users.

Subject Relations

In addition to direct and wildcard assignments, it is also possible to create relations to dynamically computed sets of subjects. For example, the editor relation defined below on the document type can be directly assigned to a user OR to everyone with the member relation to a specified group.

group:
relations:
member: user

document:
relations:
editor: user | group#member

Unlike direct assignments, we not only specify the type of subject (group) but also a relation on that type (member). In other words, we create an editor relation between a document and all users that have a member relation with a given group.

Subject relations can also be used to defined nested sets. For example, we can modify the definition of group to be:

group:
relations:
member: user | group#member

This allows us to create member relations between groups to indicate that all members of one group are also members of another.

Permission definitions

Permissions are similar to relations but instead of assigning them explicitly, they are defined by combining relations or other permissions using operators. They can be thought of as implicitly-assigneed relations.

Topaz supports four operators for defining how permissions are granted through relations and/or other permissions.

Union

The union operator (|) indicates that a permission is granted through ANY of the listed relations or permissions.

Example:

  can_read: can_write | viewer

This means that the can_read permission is granted to anyone who has the can_write permission OR is the subject of the viewer relation.

Intersection

The intersection operator (&) indicates that a permission is granted only if the target is part of ALL the listed relations/permissions.

Example:

  can_comment: can_view & commenter

This means that the can_comment permission is granted only if the user has the can_view permission AND is also the subject of the commenter relation.

Exclusion

The exclusion operator (-) indicates that a permission is granted only if the target is NOT part of the specified relation/permission.

Example:

  can_comment: commenter - guest

This means that the can_comment permission is granted to subjects that are commenters and are NOT guests.

Arrow

The arrow operator (->) allows a permission to be granted to subjects who have a specified relation or permission with another object that is related to the object on which the permission is defined.

Example:

  types:
folder:
relations:
parent: folder
owner: user | group#member
permissions:
can_delete_folder: owner | parent->can_delete_folder

document:
relations:
parent: folder
owner: user | group#member
permissions:
can_delete_document: owner | parent->can_delete_folder

In the above example, document and folder types both have a parent relation to a folder.

The can_delete_folder permission can be granted by assigning a subject directly as the owner of a folder, OR if that subject has the can_delete_folder permission on any folder in the parent relation chain.

Likewise, the can_delete_document permission can be granted by assigning a subject directly as the owner of a document, OR if that subject has a can_delete_folder permission on a folder in the parent relation chain.

Arrow operators are integral to defining hierarchical permissions.