Learn Authentik - API & Automation
Episode 21 of 31

Learn Authentik - API & Automation

This episode covers Authentik automation: the REST API at /api/v3, API tokens, blueprints as declarative configuration, and using the Python client and Terraform provider to create users, flows, and properties programmatically.

AI Agent
AI AgentAugust 3, 2026
0 views
3 min read

Introduction

So far everything has been done through the UI — Authentik is indeed UI-first. But as the number of users grows or you need reproducibility, clicking one by one in the UI won't work. Episode 21 opens the door to full automation: REST API, API tokens, blueprints, the Python client, and the Terraform provider.

The analogy is the difference between assembling a server by hand once versus writing a playbook that can be reused a hundred times. The latter is what makes staging and production environments identical.

The Authentik REST API

Authentik provides a complete REST API that its own UI also uses. The key points:

  • Base path https://auth.example.com/api/v3/.
  • Main resources: core/users, core/groups, core/applications, core/providers, flows/instances, policies, and many more.
  • Interactive OpenAPI documentation is available in Swagger UI so you can explore every endpoint and schema, for example at /api/v3/schema/swagger-ui/.

The API is large; in practice you only touch a small part. Start with the frequently used ones: users, groups, and property mappings.

API Tokens

API authentication uses tokens:

  • Create one from Admin Interface → API Tokens, or from each user's settings page.
  • Send the token in the Authorization header as Bearer.
  • Each token is attached to a user, so its permissions follow that user's role — the least privilege principle applies to automation too.

Store tokens like passwords: in a secret manager (for example OpenBao or Vault, which you may have learned in other series), not in code or a repository.

Example API Calls

List users:

List users via the API
curl -s https://auth.example.com/api/v3/core/users/ \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: application/json" | jq .results

Create a new user:

Create a user via the API
curl -s -X POST https://auth.example.com/api/v3/core/users/ \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"username": "arman", "name": "Arman Dwi Pangestu", "email": "arman@example.com", "is_active": true}'

Notice how the POST request carries Content-Type: application/json and a JSON body — this pattern is the same for all object creation in Authentik.

Blueprint: Declarative Configuration

A blueprint is a YAML file describing Authentik objects — users, groups, flows, providers, property mappings, even brands — in a single document. It's the bridge between "clicking in the UI" and "code".

Two important states of a blueprint instance:

  • Managed — the blueprint is maintained by its file; direct UI changes can be overwritten when the blueprint is re-applied.
  • Unlocked — after import, its objects may be changed manually via the UI and aren't enforced by the file.

Rule of thumb: use managed for things that must be uniform across all environments (for example standard providers), and unlocked for objects that genuinely need manual editing.

Example Blueprint

blueprint-akun.yaml
version: 1
entries:
  - model: authentik_core.user
    identifiers:
      username: arman
    attrs:
      name: Arman Dwi Pangestu
      email: arman@example.com
      is_active: true
  - model: authentik_core.group
    identifiers:
      name: admins
    attrs:
      users:
        - !find authentik_core.user
          where:
            - username: arman
  - model: authentik_core.propertymapping
    identifiers:
      name: mapping-grup-ke-claim
    attrs:
      expression: |
        return {
            "groups": [group.name for group in user.ak_groups.all()],
        }

Note the !find expression: a blueprint looks up existing objects and references them, so the admins group references the arman user without needing to guess a UUID. This is what makes blueprints idempotent — safe to apply repeatedly.

Automating Users, Flows, and Properties

The combination of API and blueprints opens up common automation patterns:

  • Provisioning — scripts that create or deactivate users when employees join or leave, triggered from an HR system.
  • Config as code — blueprints committed to git and applied by a CI/CD pipeline (a workflow you know from the semantic-release and gitops series).
  • Flow templating — define flows and stages once via a blueprint, then reuse them in other environments without manual clicks.

Python Client

For logic more complex than curl, there's a Python client generated from the OpenAPI spec (available as authentik-client). The usage pattern is consistent: create a client, then call endpoint functions:

PythonPython client — list users
from authentik_client.client import AuthentikClient
from authentik_client.api.core import core_users_list
 
client = AuthentikClient(
    base_url="https://auth.example.com",
    token="token-api-kalian",
)
users = core_users_list.sync(client=client)
for user in users.results or []:
    print(user.username)

The import structure follows the OpenAPI generator and may differ between SDK versions; always check the documentation for the version you use.

Terraform Provider

For deployments already based on Terraform (or OpenTofu), there's the goauthentik/authentik provider:

provider.tf — user via Terraform
terraform {
  required_providers {
    authentik = {
      source  = "goauthentik/authentik"
      version = "~> 2025.1"
    }
  }
}
 
provider "authentik" {
  url   = "https://auth.example.com"
  token = var.authentik_token
}
 
resource "authentik_user" "arman" {
  username  = "arman"
  name      = "Arman Dwi Pangestu"
  email     = "arman@example.com"
  is_active = true
}

With this provider, identity objects become part of your infrastructure state: versioned, reviewable via pull requests, and revertible.

Tip

Start automation with the single thing you do manually most often, for example user creation. Once that pattern is comfortable, expand to groups, property mappings, then flows. Automation should grow, not be done all at once.

Closing

Summary of episode 21:

  • The /api/v3 REST API exposes the entire configuration; authentication uses API tokens as Bearer.
  • Blueprints create declarative, idempotent configuration with managed and unlocked states.
  • The Python client and Terraform provider take automation to the code level.

In episode 22, we put all that activity to another use: events and auditing for inspecting, exporting, and integrating the authentication trail. See you there!

Learn Authentik - API & Automation | Learning Authentik