Skip to main content

Warrants

Warrants are the access control policies used to enforce access within an application. You can think of them as the rules that specify which relationships (ex: [store:A] is [parent] of [item:123]) exist between objects in your system. Warrants must adhere to your system's object type definitions and are used at runtime to check user access.

Each warrant is composed of an object (identified by an objectType and an objectId), a relation (which must one of the relations defined on the object type) and a subject (which is another object or a set of objects for which the relation will apply).

For example, the following warrant specifies that [store:A] is [parent] of [item:123]:

{
"objectType": "item",
"objectId": "123",
"relation": "parent",
"subject": {
"objectType": "store",
"objectId": "A"
}
}

Direct Warrants

Direct warrants explicitly specify a relationship between two specific objects. They're especially useful for implementing fine grained access control where all relationships between objects must be specified explicitly. For example, we can define a warrant specifying that [user:1] is a [member] of [role:admin]:

{
"objectType": "role",
"objectId": "admin",
"relation": "member",
"subject": {
"objectType": "user",
"objectId": "1"
}
}

Indirect Warrants

There may be cases where we want to specify a relationship between an object and a subject without specifying exactly which subject the relation should apply to. This is especially useful for implementing less granular access control schemes like role based access control (RBAC), where users are grouped into roles, and permissions are assigned to roles instead of being directly assigned to users. Indirect Warrants include a relation attribute in their subject, allowing us to specify a set of subjects for which the warrant applies. For example, we can define an indirect warrant specifying that [a member of role:admin] can [edit] [report:1]:

{
"objectType": "report",
"objectId": "1",
"relation": "editor",
"subject": {
"objectType": "role",
"objectId": "admin",
"relation": "member"
}
}

Wildcards

In other cases, we might want to specify that a subject has a relation on all objects of a particular type without having to enumerate every object of that type. The objectId attribute on warrants supports the "wildcard" character *, meaning that the warrant applies to all objects of the given object type. For example, we can define a warrant specifying that [user:123] can [edit] [all reports]:

{
"objectType": "report",
"objectId": "*",
"relation": "editor",
"subject": {
"objectType": "user",
"objectId": "123"
}
}

Context

Some applications need to maintain different variations of the warrants for a particular subject or resource across one or more dimensions. For example, a user who is allowed to sign in to an application with one of many roles might have a different set of permissions depending on which role they sign in as, so their set of permissions is dependent on their current role.

Another common scenario at many B2B SaaS companies is the need for custom role/permission mappings per customer. For example, companyA might want their accountant role to include permissions A and B while companyB wants their accountant role to include permissions A, B, and C. If an admin user from companyA signs in, they should only have permissions A and B, but if an admin user from companyB signs in, they should have permissions A, B, and C. In this case, the set of permissions available is dependent on the company a user belongs to.

To solve these and other related authorization use cases, warrants can include an optional 'context' object that specifies the context in which the warrant should apply. For example, we can define a warrant specifying that [user:123] is a [member] of [role:admin] only in [tenant:wayne-enterprises]:

{
"objectType": "role",
"objectId": "admin",
"relation": "member",
"subject": {
"objectType": "user",
"objectId": "123"
},
"context": {
"tenant": "wayne-enterprises"
}
}

Since this warrant has a context, it will only match an access check query containing the exact same context object. An access check query containing no context or a different context object (for example [tenant:daily-planet]) will not match.

Creating and Managing Warrants

Warrants can be created directly in the Warrant dashboard or programmatically via API. Check out the API Reference for more details.