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.

This guide consist of 4 main sections:

  1. Set Up Your First Project & Integrate With Your App
  2. Model Authorization Policy
  3. Add Permissions & Store Authorization Data
  4. Perform Access Check

By the end of this guide, you’ll be able to:

  • Set up and configure Permify Cloud for your application.
  • Build and test a secure authorization flow to control access across different parts of your app.

Let’s get started!

Setting Up Your First Project

To get started with building your authorization system, the first step is to sign up for a Permify Cloud account.

  1. Navigate to the Permify Cloud.
  2. Enter your details and create your account.
  3. After signing up, it will redirect you to the Organization Creation step.
  4. After creating the organization, you can invite your organization members.

Once your organization is created, Permify will automatically spin up a Starter project to set up your first authorization system.

It can take a couple of minutes to boot up the Starter project. Sometimes, refreshing the page might be required to see the active state.

Click the starter project to see the dashboard. You’re now ready to start defining your authorization rules and policies!

Integrating With Your Application

Now that your project is set up, it’s time to integrate Permify Cloud with your application using the appropriate client library.

Setup your client

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.

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>");

Let’s try validating our connection by sending a List Tenants API request.

// Rest SDK for Java
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>");

TenancyApi tenancyApi = new TenancyApi(apiClient); // previously created apiClient
try {
  TenantListRequest req = new TenantListRequest();
  req.setPageSize((long) 20);
  tenancyApi.tenantsList(req);

} catch (Exception e) {
    System.out.println("Error occurred: " + e.getMessage());
}

Here is an example Python List Tenant request that shows a successful List Tenants response.

Lets move forward with defining our authorization model into Permify Cloud!

Model Authorization Policy

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.

What You Will Be Building

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:

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:

Entities

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.

entity user {}
entity organization {}
entity repository {}

Relations

Relations represent relationships between entities. Our application will have relations between users, organizations and repositories as follow:

  • The relationship between a user and an organization involves the user potentially being either a member or an admin of the organization.
entity organization {
    relation admin @user
    relation member @user
}
  • The relationship between a repository and an organization is such that a repository belongs to an organization.
entity repository {
    relation parent @organization
}
  • The relationship between a repository and an user is such that a repository is created by a user.
entity repository {
    relation owner @user
}

Permissions

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.
entity repository {
    permission edit = parent.admin or owner
    permission delete = owner
}

To see a live example and test of this example schema, visit the Permify Playground.

Apply Model via SDK

Let’s insert the example schema into Permify using the Write Schema API

// Rest SDK for Java
import org.permify.api.SchemaApi;
import org.permify.model.SchemasWriteRequest;
import org.permify.model.SchemaWriteResponse;

SchemaApi schemaApi = new SchemaApi(apiClient); // previously created apiClient
try {
    SchemasWriteRequest req = new SchemasWriteRequest();
    req.setSchema("entity user {}\n\nentity organization {\n    relation admin @user\n    relation member @user\n}\n\nentity repository {\n    relation parent @organization\n    relation owner @user\n    \n    permission edit = parent.admin or owner\n    permission delete = owner\n}");
    schemaApi.schemasWrite("t1", req);
} catch (Exception e) {
    System.out.println("Error occurred: " + e.getMessage());
}

Here you can observe your configured and deployed schema history in the Schema Section.

We defined our model to Permify Cloud, lets add some permissions and send example API check request in our application.

Add Permissions & Store Authorization Data

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.

Relationships

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

// Rest SDK for Java
import 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 apiClient
try {
    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());
}

On Data Section, you will see the data you have inserted to Permify:

Perform Access Check

Access Check

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.

// Rest SDK for Java
import 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());
    }
}

Below is an example of an implemented Python access check request and response