Defining a domain model
The authorization model needs to mirror the domain model used by the application. To populate the directory we need to define the domain model which is comprised of objects and relations. To define these objects and relations, we first need to declare object types, and their relations and permissions.
Object types
Object types define the entities in the system, such as user
, department
, document
, etc. Any declared object type can also be designated as a subject of a relationship, by specifying it as the target of a relation.
For example:
document
can be defined an object type.user
object type is typically used as a subject of a relation.group
can function as an object when defining a member relation to a user (subject), or it can function as a subject when defining an owner relation to a document (object).
Relations
Relations define the relationships between entities, such as member
, owner
, manager
, etc. Relations are defined on object types. In the context of authorization, we can think of relations as roles that can be assigned to subjects. For example, a user
can be assigned the owner
role for a document
. In our policy, we can check whether a relation exists for a subject
and an object
using the ds.check
built-in.
Permissions
While relations are helpful to model roles, we can associate many permissions to a single role. In the directory, permissions are associated with relations. For example, we can declare that the owner
relation confers the can_read
, can_write
, and can_delete
permissions. In our policy, we can check whether a permission exists between a subject
and an object
using the ds.check
built-in.
Defining the domain model
Create a manifest.yaml
to define object types, relations, and permission. For example:
# yaml-language-server: $schema=https://www.topaz.sh/schema/manifest.json
---
model:
version: 3
types:
### display_name: User ###
user:
relations:
manager: user
### display_name: Identity ###
identity:
relations:
identifier: user
### display_name: Group ###
group:
relations:
member: user | group#member
### display_name: Document ###
document:
relations:
owner: user | group#member
editor: user | group#member
viewer: user | group#member
permissions:
can_delete: owner
can_write: editor | can_delete
can_read: viewer | can_write
In this manifest, we define four object types: user
, identity
, group
, and document
.
- The
user
object type defines amanager
relation, whose target can only be another user. This makes it easy to model management hierarchies using Topaz. - The
identity
object type allows creating (or importing from an IDP) multiple identities associated with auser
object. - The
group
object type defines amember
relation, whose target can be auser
, or the set of users that have amember
relationship from anothergroup
object. This is designated by the notationgroup#member
. For example, if you define a group with an ID ofeditors
, you can add individual users to it, and you could also add themember
's of theviewers
group by adding that group object to theeditors
group. - The
document
object type defines theowner
,editor
, andviewer
relations, which can have subjects (targets) of either typeuser
orgroup
. In the case of a group, the set of instances in themember
relation of that group become part of the set referred to by the relation. - The
document
object type also defines thecan_read
,can_write
, andcan_delete
permissions. These permissions are granted through the relations we just defined. Note that permission definitions can use a few operators: union (|
), intersection (&
), exclusion (-
), and the arrow operator (->
).
More information on operators can be found in the Manifest Reference.
Loading the manifest
Load the manifest.yaml
file into Topaz by running:
topaz directory set manifest ./manifest.yaml -i
Manifest command reference
For a full list of commands for getting, setting, and deleting a manifest, refer to the manifest CLI docs.
Manifest language reference
A full annotated example of the manifest can be found here.