Skip to main content

ZITADEL with Django Python

This integration guide demonstrates the recommended way to incorporate ZITADEL into your Django Python application. It explains how to check the token validity in the API and how to check for permissions.

By the end of this guide, your application will have three different endpoint which are public, private(valid token) and private-scoped(valid token with specific role).


This documentation references our example on GitHub.

ZITADEL setup​

Before we can start building our application, we have to do a few configuration steps in ZITADEL Console.

Create application​

  1. Go to your Project and click on the New button as shown below.

Register the API

  1. Give a name to your application (Test API is the name given below) and select type API.

Register the API

  1. Select JWT as the authentication method and click Continue.

Register the API

  1. Now review your configuration and click Create.

Register the API

  1. You will now see the API’s Client ID. You will not see a Client Secret because we are using a private JWT key.

Register the API

  1. Next, we must create the key pairs. Click on New.

Register the API

  1. Select JSON as the type of key. You can also set an expiration time for the key or leave it empty. Click on Add.

Register the API

  1. Download the created key by clicking the Download button and then click Close.

Register the API

  1. The key will be downloaded.

Register the API

  1. When you click on URLs on the left, you will see the relevant OIDC URLs. Note down the issuer URL, token_endpoint and introspection_endpoint.

Register the API

  1. The key that you downloaded will be of the following format.
  1. Also note down the Resource ID of your project.

Register the API

Create Serviceuser​

  1. Go to the Users tab in your organization as shown below and click on the Service Users tab.

Register the API

  1. To add a service user, click on the New button.

Register the API

  1. Next, add the details of the service user and select either Bearer or JWT for Access Token Type and click on Create. For this example, we will select JWT.

Register the API

  1. Now you will see the saved details.

Register the API

  1. Next, we need to generate a private-public key pair in ZITADEL and you must get the private key to sign your JWT. Go to Keys and click on New.

Register the API

  1. Select type JSON and click Add.

Register the API

  1. Download the key by clicking Download. After the download, click Close.

Register the API

  1. You will see the following screen afterwards.

Register the API

  1. The downloaded key will be of the following format:
"key":"-----BEGIN RSA PRIVATE KEY-----\n<YOUR_KEY>\n-----END RSA PRIVATE KEY-----\n",

Give Serviceuser an authorization​

In order to access this route, you must create the role read:messages in your ZITADEL project and also create an authorization for the service user you created by adding the role to the user. Follow these steps to do so:

  1. Go to your project and select Roles. Click New.

Register the API

  1. Add the read:messages role as shown below and click Save.

Register the API

  1. You will see the created role listed.

Register the API

  1. To assign this role to a user, click on Authorizations.

Register the API

  1. Select the user you want to assign the role to.

Register the API

  1. Select the project where this authorization is applicable.

Register the API 7. Click Continue.

Register the API

  1. Select the role read:messages and click Save.

Register the API

  1. You will now see the your service user has been assigned the role read:messages.

Register the API


At the end you should have the following for the API:

  • Issuer, something like or http://localhost:8080
  • Introspection URL, something like
  • Token URL, something like
  • .json-key-file for the API, from the application
  • ID of the project

And the following from the Serviceuser:

  • .json-key-file from the serviceuser

Setup new Django application​

Setup Python​

You have to install Python as described in their documentation.

Install dependencies​

For this example we need the following dependencies:

  • django: to create an API with django
  • python-dotenv: to use environment variables in the configuration
  • authlib: client-side OAuth functionality
  • requests: HTTP requests for the introspection

For the dependencies we need a requirements.txt-file with the following content:


Then install all dependencies with:

python -m pip install -U requirements.txt

Then in your folder of choice, call the following command to create a Django base:

django-admin startproject myapi .

Define the Django API​

Add to the to include ZITADEL info​

There is info needed for the introspection calls, which we put into the


and create a ".env"-file in the root folder with the configuration as an example:

ZITADEL_INTROSPECTION_URL = 'URL to the introspection endpoint to verify the provided token'
ZITADEL_DOMAIN = 'Domain used as audience in the token verification'
API_PRIVATE_KEY_FILE_PATH = 'Path to the key.json created in ZITADEL'

I should look something like this:

API_PRIVATE_KEY_FILE_PATH = '/tmp/example/250719519163548112.json'

Validator definition​

To validate the tokens, we need a validator which can be called in the event of API-calls.


Requests and URLs​

We define 3 different endpoints which differ in terms of requirements.


To handle endpoints the urls have to be added to the



Create and run migrations:

python migrate


You can use a local Django server to test the application.

python runserver

Call the API​

To call the API you need an access token, which is then verified by ZITADEL. Please follow this guide here, ignoring the first step as we already have the .json-key-file from the serviceaccount.

Optionally set the token as an environment variable:

export TOKEN='MtjHodGy4zxKylDOhg6kW90WeEQs2q...'

With the access token, you can then do the following calls:

curl -H "Authorization: Bearer $TOKEN" -X GET http://localhost:8000/api/public
curl -H "Authorization: Bearer $TOKEN" -X GET http://localhost:8000/api/private
curl -H "Authorization: Bearer $TOKEN" -X GET http://localhost:8000/api/private-scoped


Congratulations! You have successfully integrated your Django API with ZITADEL!

If you get stuck, consider checking out our example application. This application includes all the functionalities mentioned in this quick-start. You can start by cloning the repository and defining the settings in the If you face issues, contact us or raise an issue on GitHub.