Skip to main content
Version: 2.0.0

Python Quickstart Async


This tutorial is intended for users who have completed the basic setup of at least one policy in Permit. If you haven’t done that yet, check out this guide first.

1. Get your Permit Environment API Key

  • In the Permit Dashboard, navigate to the Projects screen.
  • Find the Project and Environment you wish to connect to.
  • Click the Dots icon on the top right of the environment card.
  • Click Copy API Key.
Copy secret key from user menu

You can also copy the Environment API Key of the active environment by clicking on the User Menu > Copy Environment Key

Copy secret key from Projects management

The API Key that you will copy from the user menu is linked to the active environment on the sidebar. Switching to another active environment and then clicking on the Copy Environment Key option will copy a different API Key - the API key of the newly activated environment.

2. Setup your PDP (Policy Decision Point) Container

Permit provides you with a Policy Decision Point, which functions as your microservice for authorization. The PDP is provided as a docker container ready for you to use, or as a cloud version for quick experimentation.

It is extremely simple to utilize the cloud PDP. As part of the initialization of the Permit instance, you need to pass the cloud PDP URL.


The cloud PDP is great for quick experimentation with Permit, to learn how the service works, and to quickly integrate the SDK.

In production deployments, it is best to deploy the Docker Container PDP for better latency and availability.

For time being, the cloud PDP is not compatible with Attribute-based Access Control policies (ABAC) and also Relationship-based Access Control policies (ReBAC).

// This line initializes the SDK and connects your app
// to the Cloud PDP.

const permit = new Permit({
pdp: "",
// your API Key
token: "[YOUR_API_KEY]",

Add the SDK to your Python code

Initialise the Python SDK and check for permissions.

  1. Install the SDK
pip install permit
  1. Import the SDK into your code
from permit import Permit
  1. 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 PDP container you've set up.
permit = Permit(
# your secret API KEY

# in production, you might need to change this url to fit your deployment
# this is the address where you can find the PDP container.

# optional, the timeout in seconds for the request to the PDP container (supported from version 2.5.0)
# optional, the timeout in seconds for the request to Permit cloud API (supported from version 2.5.0)

Check for permissions using the SDK

You can run a permission check with permit.check(), passing in 3 arguments:

  • user: a unique string id that identifies the user doing the action. This is typically the user key.
  • 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 can create a document resource.

permitted = await permit.check("", "create", "document")

if permitted:
print("John is permitted to create a document")
print("John is NOT PERMITTED to create document!")

Usually instead of an email 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.

For example, if we want to check if can read documents that belong to the awesome_inc tenant:

permitted = await permit.check(
# the key of the user
# the action
# the resource (all resources of type document under the awesome_inc tenant)
{ type: "document", tenant: "awesome_inc" }

Check permissions against ABAC policies

Above we have checked for permissions against an RBAC policy - but what if we have an ABAC policy we want to run a permission check for? An ABAC policy is made up of User Sets and Resource Sets, which you can read more about here.

With ABAC we define conditions based on pre-configured attributes.

If we are running a permit.check() for an ABAC policy, we can attach just-in-time attributes to the user and the resource. There attributes are merged (and override) user and resource attributes that were persisted to the permit API.

permitted = await permit.check(
# the user object
# the user key
"key": "",
# just-in-time attributes on the user
"attributes": {
"location": "England",
"department": "Engineering",
# the action the user is trying to do
# Resource
# the type of the resource (the resource key)
"type": "resource",
# just-in-time attributes on the resource
"attributes": {
"hasApproval": "true",
# the tenant the resource belong to
"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 SDK. We will also install the FastAPI and Uvicorn packages in order to run an HTTP server in our example.

pip install permit fastapi "uvicorn[standard]"

Create a file called


Copy the following code inside 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 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
# 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": "",
"first_name": "John",
"last_name": "Smith",
"email": "",
} # in a real app, you would typically decode the user id from a JWT token

async def check_permissions():
permitted = await permit.check("", "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>