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.
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.
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.