Quickstart
In this tutorial, we will show you how to integrate Permit.io 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 Permit.io API key
Navigate to the Project Management page with the Permit.io web interface. Find the active environment that is marked with a green dot on the icon. Copy the Secret Key.
Alternatively, while anyhwere on the Permit.io web interface, click on your user icon in the top right of the screen, and "Copy SDK Secret Key" from there.
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.
Integrate SDK
- NodeJS
- Python (sync)
- Python (asyncio)
- Java
- .Net
Add the SDK to your JS code
Initialise the Node.js SDK and check for permissions.
- Install the Permit.io SDK
Please note, this is a temporary version for working with the new SDK.
npm install permitio@next
- Import the SDK into your code
const { Permit } = require("permitio");
- Create a new instance of the SDK.
You can find instructions on getting a secret API key in the previous section.
// This line initializes the SDK and connects your Node.js app
// to the Permit.io PDP container you've set up in the previous step.
const permit = new Permit({
// in production, you might need to change this url to fit your deployment
pdp: "http://localhost:7766",
// your API Key
token: "[YOUR_API_KEY]",
});
Check for permissions using the API
You can run a permission check with permit.check()
. You need to pass 3 arguments to the function:
user.id
: a unique user id or user email that identifies the user doing the action.action
: the action performed.resource
: the resource the action is performed on.
In the following example we are checking that a user with the unique id john@permit.io
can create
a document
resource.
const permitted = await permit.check("john@permit.io", "create", "document");
if (permitted) {
console.log("User is PERMITTED to create a document");
} else {
console.log("User is NOT PERMITTED to create a document");
}
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.
const permitted = await permit.check("userId", "action", {
type: "resource",
tenant: "tenant",
});
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 Node.js app made up of a single file, with the permitio
and express
modules installed.
const { Permit } = require("permitio");
const express = require("express");
const app = express();
const port = 4000;
// This line initializes the SDK and connects your Node.js app
// to the Permit.io PDP container you've set up in the previous step.
const permit = new Permit({
// in production, you might need to change this url to fit your deployment
pdp: "http://localhost:7766",
// your secret API Key
token: "[YOUR_API_KEY]",
});
// You can open http://localhost:4000 to invoke this http
// endpoint, and see the outcome of the permission check.
app.get("/", async (req, res) => {
// Example user object
// You would usually get the user from your authentication layer (e.g. Auth0, Cognito, etc) via a JWT token or a database.
const user = {
id: "[A_USER_ID]",
firstName: "John",
lastName: "Smith",
email: "john@permit.io",
};
// check for permissions to a resource and action (in this example, create a document)
const permitted = await permit.check(user.id, "create", "document");
if (permitted) {
res
.status(200)
.send(
`${user.firstName} ${user.lastName} is PERMITTED to create document!`
);
} else {
res
.status(403)
.send(
`${user.firstName} ${user.lastName} is NOT PERMITTED to create document!`
);
}
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
});
Add the SDK to your Python code
Initialise the Python SDK and check for permissions.
- Install the Permit.io SDK:
pip install permit
- Import the SDK into your code.
Notice that you need to import the classPermit
frompermit.sync
to get the sync-python SDK.
from permit.sync import Permit
- Create a new instance of the SDK.
You can find instructions on getting a secret API key in the previous section.
# This line initializes the SDK and connects your python app
# to the Permit.io PDP container you've set up.
permit = Permit(
# in production, you might need to change this url to fit your deployment
pdp="http://localhost:7766",
# your secret API KEY
token="<your-api-key>",
)
Check for permissions using the API
You can run a permission check with permit.check()
, passing in 3 arguments:
user_id
: a unique string id that identifies the user doing the action.action
: the action performed.resource
: the resource (object) the action is performed on.
In the following example we are checking that a user with the unique id john@smith.com
can create
a document
resource.
permitted = await permit.check("john@smith.com", "create", "document")
if permitted:
print("John is permitted to create a document")
else:
print("John is NOT PERMITTED to create document!")
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.
const permitted = await permit.check("userId", "action", { type: "resource", tenant: "tenant" });
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 Python app made up of a single file, with the permit
and FastAPI
modules installed.
Create a new directory for your new python project.
mkdir hello-permissions && cd hello-permissions
Optionally, create a new virtual environment for your project - you might need to install pyenv
and virtualenv
.
pyenv virtualenv permissions && pyenv activate permissions
Now install the Permit.io SDK. We will also install flask
package.
pip install permit==1.0.0rc1 flask
Create a file called test.py
.
touch test.py
Copy the following code inside test.py
and replace with your API KEY
and user-object
.
You can find instructions on getting a secret API Key in the previous section.
import json
from permit.sync import Permit
from flask import Flask, Response
app = Flask(__name__)
# This line initializes the SDK and connects your python app
# to the Permit.io PDP container you've set up in the previous step.
permit = Permit(
# in production, you might need to change this url to fit your deployment
pdp="http://localhost:7766",
# your API KEY
token="[YOUR_API_KEY]",
)
def sync_objects():
# first let's create a user:
user = {
"key": "john@smith.com",
"firstName": "John",
"lastName": "Smith",
"email": "john@smith.com",
"roles": [{"role":"admin", "tenant": "default"}]
}
permit.write(permit.api.sync_user(user))
tenant2 = {
"key": "tenant2",
"name": "Second Tenant"
}
# create tenant 2 and assign role viewer to user john
permit.write(
permit.api.create_tenant(tenant2),
permit.api.assign_role("john@smith.com", "viewer", "tenant2")
)
sync_objects()
@app.route("/")
def check_permissions():
# After we created this user in the previous step, we also synced the user's identifier
# to permit.io servers with permit.write(permit.api.syncUser(user)). The user identifier
# can be anything (email, db id, etc.) but must be unique for each user. Now that the
# user is synced, we can use its identifier to check permissions with `permit.check()`.
permitted = permit.check("john@smith.com", "retrieve", "task") # default tenant is used
if not permitted:
return Response(json.dumps({
"result": f"John Smith is NOT PERMITTED to retrieve task!"
}), status=403, mimetype='application/json')
return Response(json.dumps({
"result": f"John Smith is PERMITTED to retrieve task!"
}), status=200, mimetype='application/json')
@app.route("/tenant2")
def check_permissions_tenant2():
# After we created this user in the previous step, we also synced the user's identifier
# to permit.io servers with permit.write(permit.api.syncUser(user)). The user identifier
# can be anything (email, db id, etc.) but must be unique for each user. Now that the
# user is synced, we can use its identifier to check permissions with `permit.check()`.
permitted = permit.check("john@smith.com", "create", {"type": "task", "tenant": "tenant2"}) # tenant2 is used
if not permitted:
return Response(json.dumps({
"result": f"John Smith is NOT PERMITTED to create task (tenant 2)!"
}), status=403, mimetype='application/json')
return Response(json.dumps({
"result": f"John Smith is PERMITTED to create task (tenant 2)!"
}), status=200, mimetype='application/json')
Now that your application is ready, let's run it!
FLASK_APP=test flask run --host=0.0.0.0
Finally, go to your applications localhost live deployment to see the outcome of the permission check.
Add the SDK to your Python code
Initialise the Python SDK and check for permissions.
- Install the Permit.io SDK
pip install permit
- Import the SDK into your code
from permit import Permit
- Create a new instance of the SDK. You can find instructions on getting a secret API key in the previous section.
# This line initializes the SDK and connects your python app
# to the Permit.io PDP container you've set up.
permit = Permit(
# in production, you might need to change this url to fit your deployment
pdp="http://localhost:7766",
# your secret API KEY
token="<your-api-key>",
)
Check for permissions using the API
You can run a permission check with permit.check()
, passing in 3 arguments:
user_id
: a unique string id that identifies the user doing the action.action
: the action performed.resource
: the resource (object) the action is performed on.
In the following example we are checking that a user with the unique id john@smith.com
can create
a document
resource.
permitted = await permit.check("john@smith.com", "create", "document")
if permitted:
print("John is permitted to create a document")
else:
print("John is NOT PERMITTED to create document!")
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.
const permitted = await permit.check("userId", "action", { type: "resource", tenant: "tenant" });
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 Python app made up of a single file, with the permit
and FastAPI
modules installed.
Create a new directory for your new python project.
mkdir hello-permissions && cd hello-permissions
Optionally, create a new virtual environment for your project - you might need to install pyenv
and virtualenv
.
pyenv virtualenv permissions && pyenv activate permissions
Now install the Permit.io SDK. We will also install the FastAPI
and Uvicorn
packages in order to run an HTTP server in our example.
pip install permit==1.0.0rc1 fastapi "uvicorn[standard]"
Create a file called test.py
.
touch test.py
Copy the following code inside test.py
and replace with your API KEY
and user-object
.
You can find instructions on getting a secret API Key in the previous section.
import asyncio
from permit import Permit
from fastapi import FastAPI, status, HTTPException
from fastapi.responses import JSONResponse
app = FastAPI()
# This line initializes the SDK and connects your python app
# to the Permit.io PDP container you've set up in the previous step.
permit = Permit(
# in production, you might need to change this url to fit your deployment
pdp="http://localhost:7766",
# your API KEY
token="[YOUR_API_KEY]",
)
# This user was defined by you in the previous step and
# is already assigned with a role in the permission system.
user = {
"key": "john@smith.com",
"firstName": "John",
"lastName": "Smith",
"email": "john@smith.com",
} # in a real app, you would typically decode the user id from a JWT token
@app.get("/")
async def check_permissions():
permitted = await permit.check("john@smith.com", "read", "document")
if not permitted:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail={
"result": f"{user.get('firstName')} {user.get('lastName')} is NOT PERMITTED to create document!"
})
return JSONResponse(status_code=status.HTTP_200_OK, content={
"result": f"{user.get('firstName')} {user.get('lastName')} is PERMITTED to create document!"
})
Now that your application is ready, let's run it! Go to your applications localhost live deployment to see the outcome of the permission check.
uvicorn test:app --reload --port=<YOUR_LOCALHOST_PORT_NUMBER>
Add the SDK to your Java code
Initialise the Javs SDK and check for permissions.
- Install the Permit.io SDK with:
- Maven
- Gradle
For Maven projects, use:
<dependency>
<groupId>io.permit</groupId>
<artifactId>permit-sdk-java</artifactId>
<version>0.0.11</version>
</dependency>
For Gradle projects, configure permit-sdk-java
as a dependency in your build.gradle
.
dependencies {
// ...
implementation 'io.permit:permit-sdk-java:0.0.11'
}
- 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 Permit.io 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
.withPdpAddress("http://localhost:7766")
.build()
);
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.
// init your user (only needed ONCE, after the user first logins successfully)
User user = new User.Builder("[A_USER_ID]")
.withEmail("john@smith.com")
.withFirstName("John")
.withLastName("Smith")
// you can assign role to the user at login
.withRoles(new ArrayList<>(List.of(new AssignedRole[]{
new AssignedRole("roleId", "tenantId"),
// example assign the user (at login) to the default tenant with an admin role
new AssignedRole("admin", "default"),
})))
.build();
// You need to call sync user in order to create the user in the
// permission system and be able to ask permit.check() on that user
permit.api.syncUser(user);
Check for permissions using the API
import io.permit.sdk.enforcement.Resource;
import io.permit.sdk.enforcement.User;
boolean permitted = permit.check(
user,
"create",
Resource.fromString("document")
);
if (permitted) {
System.out.println("User is PERMITTED to create a document");
} else {
System.out.println("User is NOT PERMITTED to create a document");
}
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.PermitApiException;
import io.permit.sdk.enforcement.Resource;
import io.permit.sdk.enforcement.User;
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;
import java.io.IOException;
@RestController
@SpringBootApplication
public class DemoApplication {
// You can open http://localhost:4000 to invoke this http
// endpoint, and see the outcome of the permission check.
@GetMapping("/")
ResponseEntity<String> home() throws IOException, PermitApiException {
// init the permit SDK
Permit permit = new Permit(
new PermitConfig.Builder("[YOUR_API_KEY]")
// in production, you might need to change this url to fit your deployment
.withPdpAddress("http://localhost:7000")
.build()
);
// init your user (only needed ONCE, after the user first logins successfully)
User user = new User.Builder("[A_USER_ID]")
.withEmail("john@smith.com")
.withFirstName("John")
.withLastName("Smith")
.withRoles(new ArrayList<>(List.of(new AssignedRole[]{
new AssignedRole("roleId", "tenantId"),
// assign the user the admin role inside the default tenant
new AssignedRole("admin", "default"),
})))
.build();
// You need to call sync user in order to create the user in the
// permission system and be able to ask permit.check() on that user
permit.api.syncUser(user);
boolean permitted = permit.check(
user, // you may also call User.fromString("[A_USER_ID]"),
"create",
Resource.fromString("document")
);
if (permitted) {
return ResponseEntity.status(HttpStatus.OK).body(
"User is PERMITTED to create a document"
);
} else {
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(
"User is NOT PERMITTED to create a document"
);
}
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Add the SDK to your .NET code
We are now ready to init the .NET SDK and check for permissions.
- Create a new directory with an empty .NET project inside (we use HttpListener to demonstrate a REST API).
mkdir hello-permissions-dotnet && cd hello-permissions-dotnet && dotnet new console
- Install the Permit.io SDK
dotnet add package Permit --version 0.4.0-rc
- Import the SDK into your code
using PermitSDK;
using PermitSDK.Models;
- Create a new instance of the SDK.
You can find instructions on getting a secret API key in the previous section.
// This line initializes the SDK and connects your .NET app
// to the Permit.io PDP container you've set up in the previous step.
Permit permit = new Permit(
"[YOUR_API_KEY]",
"http://localhost:7766"
);
Check for permissions using the API
bool permitted = await permit.Check(user.key, "create", "document");
if (permitted)
{
Console.Write("User is PERMITTED to create a document");
}
else
{
Console.Write("User is NOT PERMITTED to create a document");
}
Full app example
Assuming a .NET app made up of a single file, with the Permit
modules installed.
using System;
using System.Text;
using System.Net;
using System.Threading.Tasks;
using PermitSDK;
using PermitSDK.Models;
namespace PermitOnboardingApp
{
class HttpServer
{
public static HttpListener listener;
public static string url = "http://localhost:4000/";
public static string pageData ="<p>User {0} is {1} to {2} {3}</p>";
public static async Task HandleIncomingConnections()
{
bool runServer = true;
while (runServer)
{
HttpListenerContext ctx = await listener.GetContextAsync();
HttpListenerResponse resp = ctx.Response;
// in a real app, you would typically decode the user id from a JWT token
UserKey user = new UserKey("userId", "John", "Smith", "john@permit.io");
// init Permit SDK
string clientToken = "[YOUR_API_KEY]";
Permit permit = new Permit(
clientToken,
"http://localhost:7766",
"default",
true
);
// After we created this user in the previous step, we also synced the user's identifier
// to permit.io servers with permit.write(permit.api.syncUser(user)). The user identifier
// can be anything (email, db id, etc) but must be unique for each user. Now that the
// user is synced, we can use its identifier to check permissions with `permit.check()`.
bool permitted = await permit.Check(user.key, "create", "task");
if (permitted)
{
await SendResponseAsync(resp, 200, String.Format(pageData, user.firstName + user.lastName, "Permitted", "create", "task"));
}
else
{
await SendResponseAsync(resp, 403, String.Format(pageData, user.firstName + user.lastName, "NOT Permitted", "create", "task"));
}
}
}
public static async Task SendResponseAsync(HttpListenerResponse resp, int returnCode, string responseContent)
{
byte[] data = Encoding.UTF8.GetBytes(responseContent);
resp.StatusCode = returnCode;
await resp.OutputStream.WriteAsync(data, 0, data.Length);
resp.Close();
}
public static void Main(string[] args)
{
// Create a Http server and start listening for incoming connections
listener = new HttpListener();
listener.Prefixes.Add(url);
listener.Start();
Console.WriteLine("Listening for connections on {0}", url);
Task listenTask = HandleIncomingConnections();
listenTask.GetAwaiter().GetResult();
listener.Close();
}
}
}
Now that your application is ready, let's run it:
dotnet run
Finally, go to http://localhost:4000 to see the outcome of the permission check.
Navigate to the audit log page to see your permissions request results.
Don't see logs? Use the troubleshooting page to find reasons why.
More SDK functionality coming soon.