Authentik Open Source Docs
Last reviewed: 2026-03-08 CET
Overview
Use this skill for self-hosted Authentik based on the upstream community documentation at docs.goauthentik.io.
Treat this as a documentation-grounded skill, not a general IAM improvisation skill. Prefer the official docs, use Tavily tools to fetch the relevant pages, and keep Enterprise guidance out of scope unless the user explicitly asks for it.
This skill is the documentation-and-schema companion to ../authentik-management/SKILL.md. Use this one to interpret upstream Authentik OSS docs correctly. Use authentik-management when the task becomes concrete server automation, deployment, or production operations.
For configuration management, prefer this order unless the user explicitly asks otherwise:
- File-backed blueprints managed by Ansible
- Authentik configuration via
.envand container mounts managed by Ansible - Manual outpost deployment managed by Ansible
- Database-backed blueprints or blueprint API only when filesystem-based control is not practical
- Admin UI only for discovery, export, or one-off bootstrap
When to Use This Skill
- The user asks about Authentik installation, configuration, applications, providers, bindings, outposts, upgrades, or logs.
- The user wants Authentik managed as code through blueprints, YAML, or Ansible.
- The user wants community/open source Authentik guidance and does not want Enterprise-specific instructions.
- The user references
docs.goauthentik.io,compose.yml,akadmin,AUTHENTIK_SECRET_KEY,Create with Provider,ak export_blueprint,managed/blueprints, or Authentik outposts. - The user wants answers grounded in current Authentik documentation rather than memory or generic SSO advice.
Do not use this skill for:
- Enterprise-only Authentik features or pages under
/enterprise/. - Authentik Cloud or commercial packaging questions.
- Generic OAuth, SAML, LDAP, or reverse proxy questions that do not require Authentik-specific behavior.
Scope Guardrails
- Prefer
docs.goauthentik.iopages outside/enterprise/. - If the site navigation or search results include Enterprise material, ignore it unless the user explicitly asks for Enterprise.
- Prefer blueprints over repetitive click-path instructions when the user is managing Authentik declaratively.
- Prefer file-backed blueprints for steady-state management with Ansible.
- Treat Admin UI instructions as secondary when the request is about repeatable operations or infrastructure as code.
- Do not invent deployment shortcuts that contradict the docs.
- Do not recommend the deprecated
:latestcontainer tag. - For upgrades, assume downgrades are unsupported.
Primary Workflow
1. Discover the right documentation pages
Use Tavily against docs.goauthentik.io before answering non-trivial questions.
- Use
mcp_tavily-search_tavily_mapto understand the section layout. - Use
mcp_tavily-search_tavily_crawlto gather a focused slice of the OSS docs. - Use
mcp_tavily-search_tavily_extractfor the exact pages you plan to rely on.
Recommended crawl focus:
/install-config/.*/add-secure-apps/.*/customize/blueprints/.*/core/architecture.*/security/.*/troubleshooting/.*
Exclude:
/enterprise/.*- pricing or support pages
- unrelated integration marketing pages unless the user asked for one specific integration
2. Choose the control plane
When the user wants Ansible or infrastructure as code, choose one of these models explicitly:
File-backed blueprints:
- Blueprint YAML lives in git.
- Ansible templates or copies files into a mounted blueprint directory.
- Authentik worker auto-discovers new files and reapplies changed files.
- Best default for Git-managed Authentik state.
Database-backed blueprints:
- Blueprint content is stored in Authentik's database.
- Suitable when the control plane must work through API-driven tooling.
- Useful when direct filesystem mounts are not available.
Imported flows:
- Good for one-time bootstrap or experimentation.
- Not the preferred steady-state configuration-as-code model.
Docker outpost integration:
- Lets Authentik manage outpost containers through the Docker API.
- Useful when Authentik is allowed to control runtime infrastructure.
Manual outposts:
- Better fit when Ansible is the source of truth for containers and networks.
3. Anchor the answer in Authentik's model
Keep these distinctions explicit:
- Applications control visibility and access on the
My applicationspage. - Providers define the authentication protocol or mechanism.
- Bindings are how access is restricted or hidden.
- Outposts are separate components used for proxy, LDAP, RAC, RADIUS, and related deployment patterns.
- Blueprints are the native Authentik configuration-as-code mechanism.
4. Answer with the smallest correct workflow
Prefer a minimal path that matches the docs:
- the Ansible-managed files or variables involved
- the required
.envvariables or blueprint fields - the exact Authentik object model involved
- the one or two checks that confirm success
If the user needs depth, then expand into provider-specific, blueprint-schema, or outpost-specific detail.
Quick Reference
Blueprint-first configuration as code
Blueprints are Authentik's native configuration-as-code system. For Ansible-managed environments, prefer file-backed blueprints mounted into the worker container over repeated UI configuration.
Key facts from the docs:
- Blueprint files are YAML.
- File-based blueprints are discovered under
/blueprintsin the worker container. - New files trigger discovery automatically.
- Modified files trigger apply automatically.
- Blueprint instances are also re-read regularly, approximately every 60 minutes.
- Blueprint execution is atomic: if one entry fails, the entire blueprint is rolled back.
Blueprint schema essentials
Use the official schema header in blueprint files:
# yaml-language-server: $schema=https://goauthentik.io/blueprints/schema.json
version: 1
metadata:
name: example-blueprint
entries: []
Important fields to explain correctly:
versionmetadata.labelscontextentriesmodelidentifiersattrsstate
Important state values:
present: create or update selected fieldscreated: create once, preserve later manual changesmust_created: fail if the object already existsabsent: delete the object if it exists
Important caveats:
- Blueprint discovery order is not guaranteed.
- If one blueprint depends on another, use blueprint meta models to control ordering.
- Exported blueprints usually need cleanup because they contain hardcoded primary keys and are not automatically templated.
Docker Compose install
Use the upstream compose.yml, not a hand-written stack, for first-time community installs.
Key steps from the docs:
- Download
compose.ymlfromhttps://docs.goauthentik.io/compose.yml. - Add at minimum:
PG_PASSAUTHENTIK_SECRET_KEY
- Optionally add:
AUTHENTIK_ERROR_REPORTING__ENABLED=trueCOMPOSE_PORT_HTTPCOMPOSE_PORT_HTTPS
- Start with:
docker compose pull
docker compose up -d
- Open the initial setup flow with a trailing slash:
http://<host>:9000/if/flow/initial-setup/
Important warnings from the docs:
- Do not mount
/etc/timezoneor/etc/localtimeinto Authentik containers. - The initial setup URL must end with
/or you can getNot Found.
Configuration via environment variables
- Authentik configuration keys use double underscores, for example
AUTHENTIK_POSTGRESQL__HOST. - With Docker Compose, append keys to
.envand re-apply withdocker compose up -d. - These
.envvalues are a good fit for Ansible templating. - The docs also support
env://...andfile://...sources, which are useful when secrets are injected by deployment tooling. - Verify the active config with:
docker compose run --rm worker ak dump_config
Applications, providers, and bindings
- Use
Applications -> Applications -> Create with Providerfor the simplest first setup. - Explain that every application needs a provider.
- If no bindings are defined, all users can access the application.
- Use bindings when the user wants application visibility or access limited by group or user.
- When the request is IaC-focused, translate UI objects into blueprint-managed objects instead of stopping at click instructions.
Provider selection
Use the provider that matches the application protocol instead of forcing one pattern everywhere.
| Need | Typical provider |
|---|---|
| Modern web app SSO | OAuth2/OIDC |
| Existing enterprise app or SP metadata | SAML |
| Directory access | LDAP |
| Forward auth or protected app proxying | Proxy |
| Network auth edge case | RADIUS |
| Provisioning users/groups into downstream apps | SCIM |
Outposts
- The default community Docker Compose install mounts the Docker socket into the worker for automatic outpost management.
- Treat that as a security decision, not a default you must preserve.
- If Authentik manages outposts through Docker integration, the worker needs Docker API permissions and can auto-upgrade outposts when Authentik upgrades.
- If Ansible is the source of truth for containers, prefer manual outpost deployment and manage the outpost Compose definitions yourself.
- Safer documented alternatives are:
- use a Docker Socket Proxy
- remove the socket mount and deploy outposts manually
- For manual Compose deployments, use the documented container image and environment pattern for the specific outpost type.
Export and migration to blueprints
Use export when the current state lives in the UI and needs to be moved into git-managed configuration.
Global export command:
docker compose run --rm worker ak export_blueprint
Key export caveats from the docs:
- Exports contain raw object lists and usually need cleanup.
- Write-only fields, such as some secret values, are not exported.
- Default values may be omitted.
- Expect manual refactoring before treating an export as a reusable blueprint.
Ansible-managed Authentik pattern
Prefer this model for repeatable infrastructure:
- Template
compose.ymland.envwith Ansible. - Mount a dedicated blueprint directory into the Authentik worker.
- Manage blueprint YAML files in git.
- Use handlers to restart or reconcile only when Compose or environment changes require it.
- Rely on blueprint file creation and modification events for blueprint discovery and apply.
For steady state, avoid editing the same objects manually in the UI without reconciling those changes back into blueprints.
Upgrades
- Authentik does not support downgrading.
- Back up PostgreSQL before upgrading.
- Read the release notes for the target version.
- Follow major releases sequentially and do not skip directly across them.
- Upgrade outposts at the same time and keep versions matched.
- Refresh
compose.yml, then run:
docker compose pull
docker compose up -d
Logs and troubleshooting
- Default log level is
info. - Raise to
debugfirst; usetraceonly when necessary because it can expose sensitive data. - Recreate containers after changing log level.
- For recent logs:
docker logs <container> --since 5m
docker logs <container> -f
Hardening for IaC-controlled environments
If Authentik must only be changed from files managed by Ansible, the hardening docs note that you can block API access to:
/api/v3/managed/blueprints
With that restriction in place, blueprints can only be edited through the filesystem. This is a strong fit when file-backed blueprints in git are the intended source of truth.
Response Pattern
For non-trivial requests, structure the answer in this order:
- What part of Authentik the request touches.
- Which community docs pages you relied on.
- Which control plane is appropriate: file blueprint, database blueprint, manual outpost, or runtime config.
- The shortest correct workflow.
- The main gotcha or risk.
- One verification step.
Keep answers specific. If the docs distinguish between Docker Compose, Kubernetes, and AWS CloudFormation, only describe the one the user is actually using.
When the user mentions Ansible, always prefer a repo-managed file path and reconciliation workflow over click-by-click instructions unless they explicitly ask for UI steps.
Common Mistakes
- Mixing Enterprise pages into community guidance.
- Treating the Admin UI as the primary source of truth in an Ansible-managed deployment.
- Telling users to write a custom Compose stack before they have a working baseline unless that is explicitly the target state.
- Forgetting the trailing slash on the initial setup URL.
- Recommending
:latestinstead of a real release tag. - Changing log level to
tracewithout warning about sensitive data exposure. - Upgrading core Authentik without upgrading outposts.
- Treating applications and providers as interchangeable.
- Forgetting that bindings control access and visibility behavior.
- Assuming blueprint apply order is deterministic.
- Treating exported blueprints as production-ready without cleanup.
- Letting Authentik auto-manage outposts via Docker when Ansible is supposed to own container lifecycle.
- Using Jinja2 filter syntax in email templates — Authentik email templates use Django template language, not Jinja2.
{{ var | default(fallback) }}crashes withTemplateSyntaxError: default requires 2 arguments. Use{% firstof var fallback %}instead. - Nesting
{% raw %}blocks in.j2email templates — Ansible.j2files for email content must wrap the entire body in a single outer{% raw %}…{% endraw %}. Never place an inner{% raw %}inside an already-open outer block; Django receives the literal tag text and re-crashes.
Email Template Patterns
Authentik email templates use Django template language, not Jinja2.
Correct Patterns
{# Fallback value — Django style #}
{% firstof user.name user.username %}
{# Conditional block #}
{% if action_url %}
<a href="{{ action_url }}">{{ action_label }}</a>
{% endif %}
{# Loop over key/value table #}
{% for key, value in key_value.items %}
<tr><td>{{ key }}</td><td>{{ value }}</td></tr>
{% endfor %}
Incorrect Patterns (Jinja2)
{{ user.name | default(user.username) }} ← TemplateSyntaxError: default requires 2 arguments
{{ value | upper }} ← not all Jinja filters exist in Django
Available Template Variables
| Variable | Notes |
|---|---|
user.name |
Display name |
user.username |
Username |
user.email |
Email address |
flow_info.title |
Flow display title |
site_name |
Authentik brand name |
url |
Recovery/confirmation link (EmailStage) |
title |
Subject or notification title |
body |
Main notification body |
action_url |
CTA link URL |
action_label |
CTA button label |
key_value |
Dict for table display |
Ansible .j2 Template Rule
When managing email templates as Ansible templates, the entire Django template body must lie inside ONE outer {% raw %}…{% endraw %} wrapper. Not nested — one wrapper, whole file:
{% raw %}
<!DOCTYPE html>
<html>
{% if user.name %}…{% endif %}
<p>{% firstof user.name user.username %}</p>
</html>
{% endraw %}
Authentication Flow Patterns
Single-Screen Login (Username + Password on one page)
Set password_stage on the IdentificationStage attrs to embed the password field on the same screen:
- model: authentik_stages_identification.identificationstage
id: stage-identification
attrs:
name: tangoatlas-auth-identification
user_fields:
- username
- email
password_stage: !KeyOf stage-password # ← embeds password on same screen
recovery_flow: !Find # ← adds "Forgot password?" link
- authentik_flows.flow
- [slug, tangoatlas-recovery-flow]
Add the PasswordStage as a normal entry — it will not be shown as a separate step:
- model: authentik_stages_password.passwordstage
id: stage-password
attrs:
name: tangoatlas-auth-password
backends:
- authentik.core.auth.InbuiltBackend
!KeyOf vs !Find
| Tag | Use when |
|---|---|
!KeyOf <id> |
Object is created in the same blueprint — references by the blueprint entry's id field |
!Find [model.class, [field, value]] |
Object exists outside the blueprint (created by another blueprint or the UI) — looks up by a known field value |
# Inside the same blueprint:
password_stage: !KeyOf stage-password
# Cross-blueprint reference (flow created by another blueprint):
recovery_flow: !Find
- authentik_flows.flow
- [slug, tangoatlas-recovery-flow]
Brand Wiring
To attach authentication and recovery flows to a brand (domain), include an authentik_brands.brand entry in the blueprint:
- model: authentik_brands.brand
id: brand-tangoatlas
identifiers:
domain: id.tangoatlas.org
attrs:
branding_title: TangoAtlas Passport
flow_authentication: !KeyOf flow-auth # ← auth flow
flow_recovery: !KeyOf flow-recovery # ← recovery flow (shows on login page)
flow_invalidation: null # optional
flow_recovery on the brand is what makes "Forgot password?" appear on the login page. Setting recovery_flow on the IdentificationStage is the companion setting that routes the stage's link to the correct flow.
References
Use the bundled source map in references/oss-doc-map.md to choose the right upstream page before answering.
Use references/ansible-iac-patterns.md when the user wants a practical Ansible management pattern for Authentik.