Why do you need RBAC?
Most products need to have a way to restrict access to certain operations. A standard way to do this is to use Role-Based Access Control (RBAC). RBAC is a method of restricting resource access based on permissions assigned to specific persons.
In SlashID there are two ways to assign permissions to a person:
- assigning a permission directly to a person,
- assigning permission to a role and then assigning the role to a person.
How does RBAC work in SlashID
Our goal was to create state-of-the-art RBAC implementation in SlashID. We did it by giving you features not available in other RBAC implementations:
- Our RBAC implementation is globally replicated - roles, permissions, and assignments are available in all regions, you can check permissions in any geographical location with minimal latency,
- it’s compatible with our replication model, where you can control write consistency,
- it works with our suborganizations model, so you can share roles and permissions between organizations within the organization tree,
- all write operations emit events, to which you can subscribe with webhooks.
Let’s now dive into how to use RBAC in SlashID.
In this post, I will show you how to use RBAC in SlashID, and how to create permissions, and roles, and assign them to persons. I’ll use an example of a billing system where we have two roles:
<SLASHID_ORG_ID_VALUE>/accountant
with permissionsbilling.invoices.list
,billing.invoices.create
<SLASHID_ORG_ID_VALUE>/administrator
with permissionsbilling.invoices.list
,billing.invoices.create
,billing.invoices.void
where <SLASHID_ORG_ID_VALUE>
is the ID of the organization.
Note: Organization ID is part of the role name to support the multi-organization model for RBAC.
In this scenario, persons with the <SLASHID_ORG_ID_VALUE>/accountant
role will have access to read and create invoices,
while persons with the <SLASHID_ORG_ID_VALUE>/administrator
role can read, create, and void invoices.
Creating permissions
You can create permissions with the POST /rbac/permissions
endpoint.
curl -L -X POST 'https://api.slashid.com/rbac/permissions' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'SlashID-OrgID: <SLASHID_ORG_ID_VALUE>' \
-H 'SlashID-API-Key: <API_KEY_VALUE>' \
--data-raw '{
"name": "billing.invoices.list",
"description": "This role allows to list invoices"
}'
Each endpoint allows you to specify the required regional consistency of the request. By default, the request will update the region to which the request was sent. Other regions will be updated asynchronously to achieve eventual consistency through our replication model.
Note: If you want to learn more about our replication model, please visit our documentation.
Creating roles
After creating permissions, you can create roles with the POST /rbac/roles
endpoint.
curl -L -X POST 'https://api.slashid.com/rbac/roles' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'SlashID-OrgID: <SLASHID_ORG_ID_VALUE>' \
-H 'SlashID-API-Key: <API_KEY_VALUE>' \
--data-raw '{
"name": "<SLASHID_ORG_ID_VALUE>/accountant",
"description": "This role is assigned to accountants",
"permissions": [
"billing.invoices.list",
"billing.invoices.create"
]
}'
Assigning roles and permissions to a person
After creating roles and permissions, you can assign them to a person with the PUT /persons/:person_id/roles
endpoint.
curl -L -X PUT 'https://api.slashid.com/persons/:person_id/roles' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'SlashID-OrgID: <SLASHID_ORG_ID_VALUE>' \
-H 'SlashID-API-Key: <API_KEY_VALUE>' \
--data-raw '{
"roles": [
"<SLASHID_ORG_ID_VALUE>/accountant"
]
}'
You can also assign additional permissions with the PUT /persons/:person_id/additional-permissions
endpoint.
curl -L -X PUT 'https://api.slashid.com/persons/:person_id/additional-permissions' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'SlashID-OrgID: <SLASHID_ORG_ID_VALUE>' \
-H 'SlashID-API-Key: <API_KEY_VALUE>' \
--data-raw '{
"permissions": [
"billing.invoices.list"
]
}'
Verifying permissions
You can check if a person has specific permission with POST /rbac/check
endpoint:
curl -L -X POST 'https://api.slashid.com/rbac/check' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'SlashID-OrgID: <SLASHID_ORG_ID_VALUE>' \
-H 'SlashID-API-Key: <API_KEY_VALUE>' \
--data-raw '{
"person_id": "064b7b63-ea43-76e5-b208-1900795bc5b7",
"permission_name": "billing.invoices.list"
}'
Note:
/rbac/check
endpoint is transitive. It checks both permissions directly assigned to the user and permissions inherited through roles.
Finding all persons with a specific role
You can use GET /persons
endpoint to filter persons by role or permission with filters:
roles eq "<SLASHID_ORG_ID_VALUE>/accountant"
- find all persons with role<SLASHID_ORG_ID_VALUE>/accountant
,permissions eq "billing.invoices.list"
- find all persons with permissionbilling.invoices.list
.
For example:
curl -L -X GET 'https://api.slashid.com/persons?filter=roles%20eq%20%22a4ed1ac1-b89c-3b8e-4752-f121fed331a0%2Faccountant%22' \
-H 'Accept: application/json' \
-H 'SlashID-OrgID: <SLASHID_ORG_ID_VALUE>' \
-H 'SlashID-API-Key: <API_KEY_VALUE>'
Note: Please remember to URL encode the filter parameter.
For the entire GET /persons
specification, please visit our API documentation.
Multi-org support
By default, roles and permissions are isolated within the organization tree.
You can share roles and permissions between sub-organizations by enabling the inherit_rbac_pools
feature when creating a suborganization.
When you enable the inherit_rbac_pools
feature:
- Suborganizations can’t add new permissions - they can only use permissions from the first parent who has
inherit_rbac_pools
set tofalse
. - Suborganizations can add new roles and assign them to persons in the sub-organization. Roles created in the sub-organization can use permissions from the parent organization.
Adding permissions to a token
You can add permissions to a token by using token templating functionality.
curl -L -X PUT 'https://api.slashid.com/organizations/config/token-template' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'SlashID-OrgID: <SLASHID_ORG_ID_VALUE>' \
-H 'SlashID-API-Key: <API_KEY_VALUE>' \
--data-raw '{
"content": "{ \"permissions\": {{ person.permissions }} }"
}'
Conclusion
You can find specifications for our RBAC endpoints in our API documentation. You can also use our latest OpenAPI specification.
Don’t hesitate to reach out to us or sign up for free here!