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
anddocument
have relation calledparent
,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.