In this tutorial, we’ll walk you through how to build a comprehensive end-to-end authorization system using Permify Cloud. We’ll dive into example use cases, explore key concepts of Permify, and integrate sample codes from Permify’s SDKs to get you up and running quickly.
Permify Cloud currently gives you an Endpoint and an API Key to connect via gRPC or REST connection. Here is where ou can find your Permify Host and API Key from project page as in the figure below:
By using these configuration you can set up clients via our SDKs.
Copy
import org.permify.ApiClient;import org.permify.api.TenancyApi;import org.permify.model.TenantListRequest;ApiClient apiClient = new ApiClient();apiClient.setBasePath("<your-permify-endpoint:3476>");apiClient.addDefaultHeader("Authorization", "Bearer <your-permify-api-key>");
Copy
import org.permify.ApiClient;import org.permify.api.TenancyApi;import org.permify.model.TenantListRequest;ApiClient apiClient = new ApiClient();apiClient.setBasePath("<your-permify-endpoint:3476>");apiClient.addDefaultHeader("Authorization", "Bearer <your-permify-api-key>");
// Rest SDK for Javascriptconst permify = require('permify-javascript');const apiClient = new permify.ApiClient("<your-permify-endpoint>:3476");apiClient.defaultHeaders = {'Authorization': "Bearer <your-permify-api-key>"};
Copy
// Rest SDK for Typescriptimport * as permify from 'permify-typescript';const apiClient = new permify.ApiClient("<your-permify-endpoint:3476>");apiClient.defaultHeaders = {'Authorization': "Bearer <your-permify-api-key>"};
// Rest SDK for Javascriptconst permify = require('permify-javascript');const apiClient = new permify.ApiClient("<your-permify-endpoint>:3476");apiClient.defaultHeaders = {'Authorization': "Bearer <your-permify-api-key>"};const api = permify.TenancyApi(apiClient)const body = { pageSize: 20};try { api.tenantsList(body, (error, data, response) => { if (error) { // handle the error } // handle the response });} catch (error) { // This block will only handle synchronous errors, // so you generally wouldn't catch REST errors here.}
Copy
// Rest SDK for Typescriptimport * as permify from 'permify-typescript';const apiClient = new permify.ApiClient("<your-permify-endpoint:3476>");apiClient.defaultHeaders = {'Authorization': "Bearer <your-permify-api-key>"};apiClient.tenancy.list({ pageSize: 20}).then((response) => { console.log(response); // handle response})const api = permify.TenancyApi(apiClient)const body = { pageSize: 20};try { api.tenantsList(body, (error, data, response) => { if (error) { // handle the error } // handle the response });} catch (error) { // This block will only handle synchronous errors, // so you generally wouldn't catch REST errors here.}
In Permify, you can define that a user has certain permissions because of their relation to other entities.
An example of this would be granting a manager the same permissions as their subordinates, or giving a user access to a resource because they belong to a certain group.
This is facilitated by our relationship-based access control, which allows the definition of complex permission structures based on the relationships between users, roles, and resources.
In this tutorial, we will build a sample application using Permify’s default example. Here is the schema that defines the relationships and permissions for our application:
Copy
entity user {}entity organization { relation admin @user relation member @user}entity repository { relation parent @organization relation owner @user permission edit = parent.admin or owner permission delete = owner}
Let’s dive into more details to understand our model:
Entity is an object that defines your resources that held role in your permission system. Our application will manage three main entities: User, Organization, and Repository.
Copy
entity user {}entity organization {}entity repository {}
Permissions define what entities can perform within the system. Our application will manage permissions in relation to users, organizations, and repositories as follows:
If a user is an admin of an organization, that user can edit all repositories within that organization.
If a user is the owner of a repository, that user can edit the corresponding repository.
If a user is the owner of a repository, that user can delete the corresponding repository.
Permify unifies your authorization data and the authorization schemas you have in a database of your preference, which serves as the single source of truth for all authorization queries and requests via the Permify API.
In Permify, you can store authorization data in two different forms: as relationships and as attributes.
For the sake of simplicity, we will only add relationships in this tutorial. Hence, same write API also applies for inserting attributes too.
For more information about adding permissions and storing data refer to Storing Data section.
In Permify, relationship between your entities, objects, and users builds up a collection of access control lists (ACLs). Here is how we insert relationships into Permify via our SDKs using the Data Write API
We will assign admin role to the user:1 in organization:1 —> organization:1@admin#user:1
Copy
// Rest SDK for Javaimport org.permify.api.DataApi;import org.permify.model.Tuple;import org.permify.model.Entity;import org.permify.model.Subject;import org.permify.model.DataWriteRequest;import org.permify.model.DataWriteResponse;DataApi dataApi = new DataApi(apiClient); // previously created apiClienttry { DataWriteRequest req = new DataWriteRequest(); // Create a tuple for the relation Tuple tuple = new Tuple(); tuple.setRelation("admin"); // Create the entity for the organization Entity entity = new Entity(); entity.setId("organization1"); entity.setType("organization"); tuple.setEntity(entity); // Create the subject for the user Subject subject = new Subject(); subject.setId("user1"); subject.setType("user"); tuple.setSubject(subject); // Add the tuple to the DataWriteRequest req.addTuplesItem(tuple); dataApi.dataWrite("t1", req);} catch (Exception e) { System.out.println("Error occurred: " + e.getMessage());}
Copy
// Rest SDK for Javaimport org.permify.api.DataApi;import org.permify.model.Tuple;import org.permify.model.Entity;import org.permify.model.Subject;import org.permify.model.DataWriteRequest;import org.permify.model.DataWriteResponse;DataApi dataApi = new DataApi(apiClient); // previously created apiClienttry { DataWriteRequest req = new DataWriteRequest(); // Create a tuple for the relation Tuple tuple = new Tuple(); tuple.setRelation("admin"); // Create the entity for the organization Entity entity = new Entity(); entity.setId("organization1"); entity.setType("organization"); tuple.setEntity(entity); // Create the subject for the user Subject subject = new Subject(); subject.setId("user1"); subject.setType("user"); tuple.setSubject(subject); // Add the tuple to the DataWriteRequest req.addTuplesItem(tuple); dataApi.dataWrite("t1", req);} catch (Exception e) { System.out.println("Error occurred: " + e.getMessage());}
Verify whether a specific subject has access to a given entity. This allows you to determine permissions such as whether a user can view, edit, or delete a particular resource.
Copy
// Rest SDK for Javaimport org.permify.api.PermissionApi;import org.permify.model.*;public static void main(String[] args) { PermissionApi permissionApi = new PermissionApi(apiClient); try { PermissionsCheckRequest req = new PermissionsCheckRequest(); PermissionCheckRequestMetadata metadata = new PermissionCheckRequestMetadata(); metadata.setDepth(20); // Create the entity for the organization Entity entity = new Entity(); entity.setId("repository1"); entity.setType("repository"); // Create the subject for the user Subject subject = new Subject(); subject.setId("user1"); subject.setType("user"); req.setSubject(subject); req.setEntity(entity); req.setPermission("edit"); req.setMetadata(metadata); permissionApi.permissionsCheck("t1", req); } catch (Exception e) { System.out.println("Error occurred: " + e.getMessage()); }}
Copy
// Rest SDK for Javaimport org.permify.api.PermissionApi;import org.permify.model.*;public static void main(String[] args) { PermissionApi permissionApi = new PermissionApi(apiClient); try { PermissionsCheckRequest req = new PermissionsCheckRequest(); PermissionCheckRequestMetadata metadata = new PermissionCheckRequestMetadata(); metadata.setDepth(20); // Create the entity for the organization Entity entity = new Entity(); entity.setId("repository1"); entity.setType("repository"); // Create the subject for the user Subject subject = new Subject(); subject.setId("user1"); subject.setType("user"); req.setSubject(subject); req.setEntity(entity); req.setPermission("edit"); req.setMetadata(metadata); permissionApi.permissionsCheck("t1", req); } catch (Exception e) { System.out.println("Error occurred: " + e.getMessage()); }}