Skip to main content
Version: 2.0.0

Java Quickstart

In this tutorial, we will show you how to integrate with your application in just a few simple steps.

Setup your PDP (Policy Decision Point) Container

We provide you with a Policy-Decision-Point - aka an authorization microservice, as a container for you to use. Please follow the steps below to install and run the container on your local machine.

1. Pull our PDP container from Docker Hub

If you do not have Docker installed as of yet, click here to install Docker.

docker pull permitio/pdp-v2:latest

2. Get the API key

Navigate to the Projects page with the web interface. Find the active environment that is marked with a green dot on the icon. Copy the Secret Key.

In the left navigation panel inside the app, click on your user icon and copy the SDK API Key.

Copy secret key from Projects management

Alternatively, you can navigate to the Projects panel, and underneath an existing project, for each environment, you will be able to access and copy an environment specific SDK API Key.


The SDK API KEY that is available for you to copy from your main user icon is the API Key that reflect the current project and the current environement you are in.

For each environment, you also have the option to Rotate the API Key, revoking access to the old API key and issuing a new one.


If there are any permission checks left in your code that are still using the old API key, they will immediately be denied. Your end users could potentially lose access.

Copy secret key from user menu

3. Run the container

Remember to replace <YOUR_API_KEY> with the Secret Key you have just obtained in the previous step.

docker run -p 7766:7000 --env PDP_API_KEY=<YOUR_API_KEY> permitio/pdp-v2:latest

Congratulations! You should now have a PDP container running. You can always check the status of the container by typing docker ps in your terminal.

Let's now add the Permit SDK to your app or use the following demo example below.

Add the SDK to your Java code

Initialise the Javs SDK and check for permissions.

  1. Install the SDK with:

For Maven projects, use:

  1. Create a new instance of the SDK.
    You can find instructions on getting a secret API key in the previous section.
import io.permit.sdk.Permit;
import io.permit.sdk.PermitConfig;

// This line initializes the SDK and connects your Java app
// to the PDP container you've set up in the previous step.
Permit permit = new Permit(
new PermitConfig.Builder("[YOUR_API_KEY]")
// in production, you might need to change this url to fit your deployment
// optionally, if you wish to get more debug messages to your log, set this to true
  1. Sync the user to the permissions system

    When the user first logins, and after you check if he authenticated successfully (i.e: by checking the JWT access token) - you need to declare the user in the permission system so you can run permit.check() on that user.

import io.permit.sdk.api.models.CreateOrUpdateResult;
import io.permit.sdk.openapi.models.UserRead;
import io.permit.sdk.enforcement.User;

// optional - save the user attributes in permit so that they are
// automatically available as ABAC attributes in permit.check()
HashMap<String, Object> userAttributes = new HashMap<>();
userAttributes.put("age", Integer.valueOf(20));
userAttributes.put("subscription", "pro");

// Syncing the user to the permission system
CreateOrUpdateResult<UserRead> response = permit.api.users.sync(
(new User.Builder("[A_UNIQUE_USER_ID]"))
.withEmail("") // optional
.withFirstName("John") // optional
.withLastName("Smith") // optional
.withAttributes(userAttributes) // optional, used for ABAC permission checks

// assign the `admin` role to the user in the `default` tenant
permit.api.users.assignRole(user.key, "admin", "default");

// the response object contains the user, and whether or not the user was create or updated
UserRead user = response.getResult();
boolean wasCreated = response.wasCreated();

Check for permissions using the SDK

import io.permit.sdk.enforcement.Resource;
import io.permit.sdk.enforcement.User;

// to run a permission check, use permit.check()
boolean permitted = permit.check(
// the user you check permission on
// the action (key) the user want to perform
// the resource the user is trying to access
new Resource.Builder("document").withTenant("default").build()

if (permitted) {
System.out.println("User is PERMITTED to create a document");
} else {
System.out.println("User is NOT PERMITTED to create a document");

Usually for the user ID you'd use the unique identifier provided by your chosen authentication solution. You can also pass the entire decoded JWT, to include attributes about the user.


In cases where you are dealing with more than one tenant in your application, permit.check() can pass the tenant as part of the resource.

The tenant passed in needs to be either the tenant id or the tenant key.

You can use the list_tenants API to get the ids and keys set for your tenants.

tenant: a unique tenant id or tenant key that you have defined within Permit.

// Tenants Example Coming Soon


Permission checks are being run against the PDP container that's running locally on your machine - offering minimal latency and without leaving your network.

This means that your user data never goes outside your system, keeping security high.

Full app example

Assuming a Spring Boot app made up of a single file, with the SDK installed.

package com.example.myproject;

import io.permit.sdk.Permit;
import io.permit.sdk.PermitConfig;
import io.permit.sdk.api.PermitApiError;
import io.permit.sdk.api.PermitContextError;
import io.permit.sdk.enforcement.Resource;
import io.permit.sdk.enforcement.User;
import io.permit.sdk.openapi.models.UserCreate;
import io.permit.sdk.openapi.models.UserRead;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;


public class DemoApplication {

final Permit permit;
final UserRead user;

public DemoApplication() {
// init the permit SDK
this.permit = new Permit(
new PermitConfig.Builder("[YOUR_API_KEY]")

try {
// typically you would sync a user to the permission system
// and assign an initial role when the user signs up to the system
this.user = permit.api.users.sync(
// the user "key" is any id that identifies the user uniquely
// but is typically taken straight from the user JWT `sub` claim
new UserCreate("[A_USER_ID]")

// assign the `admin` role to the user in the `default` tenant
permit.api.users.assignRole(user.key, "admin", "default");
} catch (IOException | PermitApiError | PermitContextError e) {
throw new RuntimeException(e);

ResponseEntity<String> home() throws IOException, PermitApiError, PermitContextError {
// is `user` allowed to do `action` on `resource`?
User user = User.fromString("[A_USER_ID]"); // pass the user key to init a user from string
String action = "create";
Resource resource = new Resource.Builder("document")

// to run a permission check, use permit.check()
boolean permitted = permit.check(user, action, resource);

if (permitted) {
return ResponseEntity.status(HttpStatus.OK).body(
"Joe Doe is PERMITTED to create document!"
} else {
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(
"Joe Doe is NOT PERMITTED to create document!"

public static void main(String[] args) {, args);