title |
---|
Multi Tenancy |
Multi-tenancy in Permify refers to an authorization architecture where a single Permify authorization service serves multiple applications/organizations (tenants).
This allows customization of the authorization for each tenant's specific needs. With Multi-Tenancy support, you can create a custom authorization schema and authorization data for the different tenants and manage them in a single place.
For the users that don't have/need multi-tenancy in their authorization structure, we created a pre-inserted tenant (id: t1) that comes default when you serve a Permify service.
Almost all Permify API endpoints have a tenant_id
mandatory field. Let's examine a check request below,
cr, err: = client.Permission.Check(context.Background(), & v1.PermissionCheckRequest {
TenantId: "t1",
Metadata: & v1.PermissionCheckRequestMetadata {
SnapToken: ""
SchemaVersion: ""
Depth: 20,
},
Entity: & v1.Entity {
Type: "repository",
Id: "1",
},
Permission: "edit",
Subject: & v1.Subject {
Type: "user",
Id: "1",
},
if (cr.can === PermissionCheckResponse_Result.RESULT_ALLOWED) {
// RESULT_ALLOWED
} else {
// RESULT_DENIED
}
})
client.permission.check({
tenantId: "t1",
metadata: {
snapToken: "",
schemaVersion: "",
depth: 20
},
entity: {
type: "repository",
id: "1"
},
permission: "edit",
subject: {
type: "user",
id: "1"
}
}).then((response) => {
if (response.can === PermissionCheckResponse_Result.RESULT_ALLOWED) {
console.log("RESULT_ALLOWED")
} else {
console.log("RESULT_DENIED")
}
})
import permify
from permify.models.permission_check_request import PermissionCheckRequest
from permify.rest import ApiException
from pprint import pprint
configuration = permify.Configuration(host="http://localhost")
with permify.ApiClient(configuration) as api_client:
api_instance = permify.PermissionApi(api_client)
tenant_id = 't1'
body = PermissionCheckRequest(
tenant_id=tenant_id,
metadata={
"snapToken": "",
"schemaVersion": "",
"depth": 20
},
entity={
"type": "repository",
"id": "1",
},
permission="edit",
subject={
"type": "user",
"id": "1",
}
)
try:
api_response = api_instance.permissions_check(tenant_id, body)
if api_response.can == PermissionCheckResponse.Result.RESULT_ALLOWED:
print("RESULT_ALLOWED")
else:
print("RESULT_DENIED")
except ApiException as e:
print(f"Exception when calling PermissionApi->permissions_check: {e}")
curl --location --request POST 'localhost:3476/v1/tenants/{tenant_id}/permissions/check' \
--header 'Content-Type: application/json' \
--data-raw '{
"metadata":{
"snap_token": "",
"schema_version": "",
"depth": 20
},
"entity": {
"type": "repository",
"id": "1"
},
"permission": "edit",
"subject": {
"type": "user",
"id": "1",
"relation": ""
},
}'
Users that come from version 0.2.x and users that have a single tenant can enter t1 as tenant id. See changes on the other endpoints from API Overview Section.
To manage tenants we have added a Tenancy service; you can create, delete and list tenants. See the Tenancy Service in Using The API section.
A tenants table has been added to the Permissions database to store tenants' details.
tables
├── migrations
├── relation_tuples
├── schema_definitions
├── tenants
├── transactions
Authorization DATA and schema definition tables now have a tenant_id column, which stores the id of the tenant that the data belongs.
Let's take a look at a snapshot of the demo table on an example Permission Database.
Example Relation Tuples data table:
Example Schema Definitions data table
Our team is happy to help you get started with Permify. If you'd like to learn more about using Permify in your app or have any questions about this example, schedule a consultation call with one of our account executivess. Alternatively you can join our discord community to discuss.