Skip to main content

SpiceDB

SpiceDB schema

A SpiceDB schema defines the objects that are required for the authorization model. Each object has a set of relations and permissions derived from the relations. Relations in SpiceDB consist of a Subject, a Resource and a relation type. Both the subject and the resource of a relation must be defined as objects in the schema.

The ODJ schema contains the following objects and their relations:

definition user {}

definition global {
relation admin: user
relation all: user
relation supporter: user
relation am_admin: user
relation am_reader: user
relation um_admin: user
relation um_reader: user
relation billing_element_admin: user
relation billing_element_reader: user
relation notification_admin: user
relation feed_writer: user
}

definition team {
relation root: global

relation owner: user
relation lead_engineer: user
relation engineer: user
relation contributor: user
relation reader: user
relation stakeholder: user
}

definition application {
relation team: team

relation deployment_worker: user
}

User

A user represents both human users and service accounts. The identifier for users has the form aad:81c6f688-518d-41e4-b47c-3e934f5a3ac8 or myapi:O1FK2nXU16VNron8Hf2BIPfFkIM5ySPP where the first part is the source for the user account and the second part the identifier in that external system. For Azure AD, the identifier is the Azure ID, for MyAPI the client ID of the corresponding Consumer App.

User identifiers

We do not use the identifiers of our own User Management! Instead, we always use the external identifier for the user. The reason for this is that tokens are generated by MyAPI where we do not have access to our User Management. However, the combination of the source IDP and the external identifier is still unique in our User Management. This means every token can still be mapped to exactly one user.

Global

The global namespace only contains one object with the identifier root. This object represents the ODJ platform itself. On this level, we define a collection of all valid ODJ users with the all relation and global roles like admin.

Team

Teams are linked to the ODJ platform via the root relation. When creating a team in the ODJ, we also write this relation to allow the propagation of global permissions to individual teams. For instance, the read permission of a team is only expressed through the root->all relation.

Application

Applictions are linked to their parent team through their team relation. When creating an application in the ODJ, we also write this relation in SpiceDB. Our SpiceDB schema also allows members to be added to applications directly. This is used for our workers which are often scoped to individual applications and should only have permissions there.

Base64-encoded Identifiers

Identifiers are encoded in Base64 when relations are written to and read from SpiceDB. This is necessary to get around limitations for identifiers in SpiceDB. Base64 encoding is the recommended approach to solve this problem.

Permissions

While it is posssible to provide the name of a relation when performing a CHECK operation in SpiceDB, it is recommended to define permissions for all actions that should be governed by the access management. Permissions are defined based on the relations of an object. Using the -> operator, it is possible to traverse the object tree upwards to check relations/permissions on a higher level.

Permissions

Permisisons can be redefined later without touching the relations that they are based on. Therefore, it is always recommended to create distinct permisisons for different actions. This allows us to change the access model later without touching anything else.