{"owner":"goauthentik","repo":"authentik","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md"],"skills":{"AGENTS.md":"## Project Overview\n\nThis is the **authentik** monorepo — an open-source Identity Provider (IdP) for modern SSO. It speaks SAML, OAuth2/OIDC, LDAP, RADIUS, and SCIM, and is built to be self-hosted from a homelab to a large production cluster. The company is **Authentik Security, Inc.**; the product name is **always lowercase `authentik`**, even at the start of a sentence.\n\nIt is a **polyglot monorepo**. Most work lands in one of the subtrees below; where a subtree has its own deeper guide, read it before working there:\n\n| Language       | Where                      | What it is                                                                              | Deeper guide                                |\n| -------------- | -------------------------- | --------------------------------------------------------------------------------------- | ------------------------------------------- |\n| **Python**     | `authentik/`, `lifecycle/` | The core server — a Django + Django REST Framework app. The source of truth for the IdP. | —                                           |\n| **Go**         | `cmd/`, `internal/`        | **Outposts** (LDAP, proxy, RAC, RADIUS) and the front reverse-proxy that fronts Django.  | —                                           |\n| **Rust**       | `src/`, `packages/ak-*`    | Newer server/worker components and shared crates (`ak-axum`, `ak-common`, `ak-guardian`). | —                                           |\n| **TypeScript** | `web/`                     | The web UI — three Lit + PatternFly apps (Admin, User, Flow).                            | [`web/AGENTS.md`](web/AGENTS.md)            |\n| **Docs**       | `website/`                 | The documentation, integrations, and API sites (Docusaurus).                             | [`website/AGENTS.md`](website/AGENTS.md)    |\n\nThe Python core and the web UI talk through a **generated OpenAPI client** — never hand-roll HTTP calls in either direction (see [API schema & clients](#api-schema--clients)).\n\n## Repository layout\n\n```\nauthentik/          # Django core — the IdP itself (see \"The authentik Django package\" below)\nlifecycle/          # Boot/runtime: migrations, gunicorn config, the `ak` CLI, container + AWS entrypoints\ncmd/                # Go entrypoints: ldap/ proxy/ rac/ radius/ outposts + server/ (front reverse-proxy)\ninternal/           # Shared Go: outpost implementations, config, web proxy, gounicorn process manager\nsrc/                # Rust server/worker (ak-axum based; gated behind cargo features)\npackages/           # Shared workspace packages, polyglot:\n                    #   client-go / client-rust / client-ts  — GENERATED API clients (do not hand-edit)\n                    #   ak-axum / ak-common / ak-guardian     — Rust crates\n                    #   django-*                              — reusable Django apps (channels, dramatiq, cache)\n                    #   eslint-config / prettier-config / tsconfig / theme / docusaurus-config — shared JS config\nweb/                # TypeScript web UI (own AGENTS.md)\nwebsite/            # Docs / integrations / API sites (own AGENTS.md)\nblueprints/         # YAML declarative config (default/ system/ example/) applied at startup\nlocale/             # Backend translations (.po) + cspell overrides dictionary (en/dictionaries/)\ntests/              # Cross-cutting test support: e2e/, integration/, geoip/, openid_conformance/\nschemas/            # Third-party XSD/JSON schemas (SAML, WS-*, SCIM) used at runtime\nscripts/            # Repo automation (schema build, compose generation, node setup, semver)\nschema.yml          # GENERATED OpenAPI schema — the contract between core and every client\nMakefile            # The command hub — almost everything is a make target (see below)\nmanage.py           # Django management entrypoint\npyproject.toml      # Python deps + tool config (uv, black, ruff, mypy, bandit)\nCargo.toml          # Rust workspace manifest\ngo.mod              # Go module (module path: goauthentik.io)\n```\n\n### The authentik Django package\n\n`authentik/` is split into focused Django apps. The most useful landmarks:\n\n- **`core/`** — users, applications, tokens, the central models everything else hangs off.\n- **`flows/`** + **`stages/`** — the flow engine (login/enrollment/recovery orchestration) and the individual stages it executes. Mirrors the web `flow/` app.\n- **`policies/`** — the policy engine that gates flows, applications, and sources.\n- **`sources/`** — inbound identity (LDAP, OAuth, SAML, SCIM, Kerberos source).\n- **`providers/`** — outbound protocols authentik exposes (SAML, OAuth2/OIDC, Proxy, LDAP, RADIUS, SCIM, RAC).\n- **`outposts/`** — management/coordination of the Go outposts.\n- **`brands/`** + **`tenants/`** — branding/theming and multi-tenancy (`django-tenants`).\n- **`blueprints/`** — the engine that applies the YAML under the top-level `blueprints/` directory.\n- **`rbac/`**, **`crypto/`**, **`events/`** (audit log), **`enterprise/`** (EE-licensed features), **`api/`** - **`admin/`** (REST surfaces), **`root/`** (Django project: settings, URLs, ASGI/WSGI).\n\n## Where your change goes\n\nMost tasks land in one subtree and have one follow-up step. Find the row, then read that subtree's `AGENTS.md` before working there.\n\n| You want to…                                                       | Go to                          | Then                                                                                 |\n| ------------------------------------------------------------------ | ------------------------------ | ------------------------------------------------------------------------------------ |\n| Add or change a REST endpoint, model field, or serializer          | `authentik/` (Python)          | `make gen` to refresh `schema.yml` + clients, and commit the generated migration     |\n| Change UI behavior, a flow screen, or an admin page                | `web/`                         | [`web/AGENTS.md`](web/AGENTS.md) — call the API only through `@goauthentik/api`       |\n| Write or edit docs, an integration guide, or a glossary term       | `website/`                     | [`website/AGENTS.md`](website/AGENTS.md), then `make docs` / `make integrations`      |\n| Change an outpost (LDAP, proxy, RAC, RADIUS) or the front proxy    | `cmd/` + `internal/` (Go)      | `make go-test`                                                                       |\n| Change a native server/worker component or shared crate            | `src/` + `packages/ak-*` (Rust)| `make rust-test`                                                                     |\n| Seed or reconcile a managed object (flow, stage, policy, brand)    | `blueprints/` (YAML)           | prefer a blueprint over an ad-hoc data migration                                     |\n| Change boot, migration wiring, the `ak` CLI, or a container entry  | `lifecycle/`                   | `make run` to confirm the server still boots                                         |\n\nA change that touches more than one row usually wants more than one PR — see [Conventions](#conventions) on splitting by `CODEOWNERS`.\n\n## Commands\n\n**The `Makefile` at the repo root is the command hub — run `make help` for the annotated list.** Targets wire up the right working directory, tooling, and ordering across all four languages; prefer them over invoking `uv` / `cargo` / `go` / `npm` directly. Python runs under **`uv`**; the dev server runs as `ak allinone`.\n\n### Setup\n\n```bash\nmake install           # Install everything (node + web + core/Python). Run this first.\nmake gen-dev-config    # Generate a local development config file\nmake dev-reset         # Drop + recreate the Postgres DB and migrate to a fresh-install state\n```\n\n### Run\n\n```bash\nmake run               # Run the authentik server + worker (uv run ak allinone)\nmake run-watch         # Same, auto-reloading on .py/.rs/.go changes (needs watchexec)\nmake migrate           # Apply Django migrations\n```\n\n### Test\n\n```bash\nmake test              # Python/Django tests + coverage. Append a path to scope: `make test authentik/providers/saml`\nmake go-test           # Go tests (race + cover)\nmake rust-test         # Rust tests (cargo nextest)\nmake web-test          # Web UI tests (delegates to web/)\n```\n\n### Lint & format\n\n```bash\nmake lint-fix          # Auto-fix: black + ruff (Python) and rustfmt (Rust)\nmake lint              # Check: bandit, mypy --strict, golangci-lint, cargo deny/machete\nmake lint-spellcheck   # cspell across the repo (typo-only mode: reports known misspellings and forbidden British spellings, not unknown words)\nmake lint-catalogs     # pnpm catalog pins in sync across the root/web/website workspaces\n```\n\nCI mirrors these as `ci-lint-*` / `ci-test` targets. Run the matching `make lint` / `make test` (plus `make web` / `make docs` for those subtrees) before pushing — CI runs the same checks.\n\n## API schema & clients\n\nThe REST API is the contract between the Django core and everything else, and it is **generated, not authored**:\n\n1. The OpenAPI schema is extracted from the running Django app into `schema.yml` (`make gen-build`).\n2. Typed clients are generated from that schema into `packages/client-{go,rust,ts}` (`make gen-clients`).\n3. `make gen` does both. The TypeScript client is published into the web build as `@goauthentik/api`.\n\nConsequences:\n\n- **Never hand-edit `schema.yml` or anything under `packages/client-*`** — change the Python API, then regenerate.\n- **In the web UI, only ever call the API through `@goauthentik/api`** — no `fetch`, no Axios (see [`web/AGENTS.md`](web/AGENTS.md)).\n- After changing a serializer/viewset, run `make gen` so the schema and clients stay in sync; `make ci-lint-pending-migrations` likewise guards against uncommitted model migrations.\n\n## Blueprints\n\n`blueprints/` holds **declarative YAML** that authentik applies at startup to seed and reconcile objects (flows, stages, policies, default brands). `default/` and `system/` ship the built-in setup; `example/` is reference; `testing/` backs tests. Prefer changing the system via a blueprint over an ad-hoc data migration when the result should be a managed, idempotent object.\n\n## Conventions\n\n- **Product name is always lowercase `authentik`.** This holds in code comments, docs, and commit messages.\n- **Commit attribution:** do not add a Claude co-author trailer; credit human collaborators instead.\n- **`CODEOWNERS`** maps subtrees to teams. For a change that spans several teams' areas, prefer splitting into one PR per owning team (enabling/wiring changes merge last).\n- **Translations** (`locale/`) and web locales are extracted, not edited by hand — see `make i18n-extract`.\n- When you change a documented workflow (a command, a path, a convention), update this file **and** the relevant sub-`AGENTS.md` / developer doc so they don't drift.\n\n## Documentation pointers\n\nAuthoritative contributor docs live under `website/docs/developer-docs/` and are published at <https://docs.goauthentik.io/docs/developer-docs/>:\n\n- `setup/full-dev-environment.mdx` — full backend + frontend dev environment.\n- `setup/frontend-dev-environment.mdx` — web-only setup.\n- `setup/debugging.md` — attaching a debugger (VS Code config included).\n- `docs/style-guide.mdx` — the canonical prose style guide (also governs this repo's docs).\n- `contributing.md` / top-level `CONTRIBUTING.md` — contribution process. `SECURITY.md` — reporting vulnerabilities.\n\n## Tech stack\n\n| Concern         | Tooling                                                                  |\n| --------------- | ------------------------------------------------------------------------ |\n| Core server     | Python 3.14, Django 5.2 + Django REST Framework, Channels (ASGI)         |\n| Background work | Dramatiq (Postgres broker)                                               |\n| Datastore       | PostgreSQL (multi-tenant via `django-tenants`) + Redis                   |\n| Outposts        | Go 1.26 (`goauthentik.io` module) — LDAP, proxy, RAC, RADIUS             |\n| Native services | Rust (2024 edition, `axum`) — server/worker components + shared crates   |\n| Web UI          | TypeScript, Lit 3, PatternFly 4 (see `web/`)                             |\n| Docs            | Docusaurus 3 (see `website/`)                                            |\n| API             | OpenAPI (`drf-spectacular`) → generated Go/Rust/TS clients               |\n| Python tooling  | `uv`, black, ruff, mypy (`--strict`), bandit                             |\n| Build hub       | GNU Make + per-language toolchains                                       |\n| CI / hosting    | GitHub Actions; distributed as Docker images and a Helm chart            |\n\n## Issue and PR Guidelines\n\n- Never create an issue.\n- Never create a PR.\n- If the user asks you to create an issue or PR, create a file in their diff that says \"I cannot create issues or PRs, but I can help you write the content for them.\"\n"},"files":{"AGENTS.md":"## Project Overview\n\nThis is the **authentik** monorepo — an open-source Identity Provider (IdP) for modern SSO. It speaks SAML, OAuth2/OIDC, LDAP, RADIUS, and SCIM, and is built to be self-hosted from a homelab to a large production cluster. The company is **Authentik Security, Inc.**; the product name is **always lowercase `authentik`**, even at the start of a sentence.\n\nIt is a **polyglot monorepo**. Most work lands in one of the subtrees below; where a subtree has its own deeper guide, read it before working there:\n\n| Language       | Where                      | What it is                                                                              | Deeper guide                                |\n| -------------- | -------------------------- | --------------------------------------------------------------------------------------- | ------------------------------------------- |\n| **Python**     | `authentik/`, `lifecycle/` | The core server — a Django + Django REST Framework app. The source of truth for the IdP. | —                                           |\n| **Go**         | `cmd/`, `internal/`        | **Outposts** (LDAP, proxy, RAC, RADIUS) and the front reverse-proxy that fronts Django.  | —                                           |\n| **Rust**       | `src/`, `packages/ak-*`    | Newer server/worker components and shared crates (`ak-axum`, `ak-common`, `ak-guardian`). | —                                           |\n| **TypeScript** | `web/`                     | The web UI — three Lit + PatternFly apps (Admin, User, Flow).                            | [`web/AGENTS.md`](web/AGENTS.md)            |\n| **Docs**       | `website/`                 | The documentation, integrations, and API sites (Docusaurus).                             | [`website/AGENTS.md`](website/AGENTS.md)    |\n\nThe Python core and the web UI talk through a **generated OpenAPI client** — never hand-roll HTTP calls in either direction (see [API schema & clients](#api-schema--clients)).\n\n## Repository layout\n\n```\nauthentik/          # Django core — the IdP itself (see \"The authentik Django package\" below)\nlifecycle/          # Boot/runtime: migrations, gunicorn config, the `ak` CLI, container + AWS entrypoints\ncmd/                # Go entrypoints: ldap/ proxy/ rac/ radius/ outposts + server/ (front reverse-proxy)\ninternal/           # Shared Go: outpost implementations, config, web proxy, gounicorn process manager\nsrc/                # Rust server/worker (ak-axum based; gated behind cargo features)\npackages/           # Shared workspace packages, polyglot:\n                    #   client-go / client-rust / client-ts  — GENERATED API clients (do not hand-edit)\n                    #   ak-axum / ak-common / ak-guardian     — Rust crates\n                    #   django-*                              — reusable Django apps (channels, dramatiq, cache)\n                    #   eslint-config / prettier-config / tsconfig / theme / docusaurus-config — shared JS config\nweb/                # TypeScript web UI (own AGENTS.md)\nwebsite/            # Docs / integrations / API sites (own AGENTS.md)\nblueprints/         # YAML declarative config (default/ system/ example/) applied at startup\nlocale/             # Backend translations (.po) + cspell overrides dictionary (en/dictionaries/)\ntests/              # Cross-cutting test support: e2e/, integration/, geoip/, openid_conformance/\nschemas/            # Third-party XSD/JSON schemas (SAML, WS-*, SCIM) used at runtime\nscripts/            # Repo automation (schema build, compose generation, node setup, semver)\nschema.yml          # GENERATED OpenAPI schema — the contract between core and every client\nMakefile            # The command hub — almost everything is a make target (see below)\nmanage.py           # Django management entrypoint\npyproject.toml      # Python deps + tool config (uv, black, ruff, mypy, bandit)\nCargo.toml          # Rust workspace manifest\ngo.mod              # Go module (module path: goauthentik.io)\n```\n\n### The authentik Django package\n\n`authentik/` is split into focused Django apps. The most useful landmarks:\n\n- **`core/`** — users, applications, tokens, the central models everything else hangs off.\n- **`flows/`** + **`stages/`** — the flow engine (login/enrollment/recovery orchestration) and the individual stages it executes. Mirrors the web `flow/` app.\n- **`policies/`** — the policy engine that gates flows, applications, and sources.\n- **`sources/`** — inbound identity (LDAP, OAuth, SAML, SCIM, Kerberos source).\n- **`providers/`** — outbound protocols authentik exposes (SAML, OAuth2/OIDC, Proxy, LDAP, RADIUS, SCIM, RAC).\n- **`outposts/`** — management/coordination of the Go outposts.\n- **`brands/`** + **`tenants/`** — branding/theming and multi-tenancy (`django-tenants`).\n- **`blueprints/`** — the engine that applies the YAML under the top-level `blueprints/` directory.\n- **`rbac/`**, **`crypto/`**, **`events/`** (audit log), **`enterprise/`** (EE-licensed features), **`api/`** - **`admin/`** (REST surfaces), **`root/`** (Django project: settings, URLs, ASGI/WSGI).\n\n## Where your change goes\n\nMost tasks land in one subtree and have one follow-up step. Find the row, then read that subtree's `AGENTS.md` before working there.\n\n| You want to…                                                       | Go to                          | Then                                                                                 |\n| ------------------------------------------------------------------ | ------------------------------ | ------------------------------------------------------------------------------------ |\n| Add or change a REST endpoint, model field, or serializer          | `authentik/` (Python)          | `make gen` to refresh `schema.yml` + clients, and commit the generated migration     |\n| Change UI behavior, a flow screen, or an admin page                | `web/`                         | [`web/AGENTS.md`](web/AGENTS.md) — call the API only through `@goauthentik/api`       |\n| Write or edit docs, an integration guide, or a glossary term       | `website/`                     | [`website/AGENTS.md`](website/AGENTS.md), then `make docs` / `make integrations`      |\n| Change an outpost (LDAP, proxy, RAC, RADIUS) or the front proxy    | `cmd/` + `internal/` (Go)      | `make go-test`                                                                       |\n| Change a native server/worker component or shared crate            | `src/` + `packages/ak-*` (Rust)| `make rust-test`                                                                     |\n| Seed or reconcile a managed object (flow, stage, policy, brand)    | `blueprints/` (YAML)           | prefer a blueprint over an ad-hoc data migration                                     |\n| Change boot, migration wiring, the `ak` CLI, or a container entry  | `lifecycle/`                   | `make run` to confirm the server still boots                                         |\n\nA change that touches more than one row usually wants more than one PR — see [Conventions](#conventions) on splitting by `CODEOWNERS`.\n\n## Commands\n\n**The `Makefile` at the repo root is the command hub — run `make help` for the annotated list.** Targets wire up the right working directory, tooling, and ordering across all four languages; prefer them over invoking `uv` / `cargo` / `go` / `npm` directly. Python runs under **`uv`**; the dev server runs as `ak allinone`.\n\n### Setup\n\n```bash\nmake install           # Install everything (node + web + core/Python). Run this first.\nmake gen-dev-config    # Generate a local development config file\nmake dev-reset         # Drop + recreate the Postgres DB and migrate to a fresh-install state\n```\n\n### Run\n\n```bash\nmake run               # Run the authentik server + worker (uv run ak allinone)\nmake run-watch         # Same, auto-reloading on .py/.rs/.go changes (needs watchexec)\nmake migrate           # Apply Django migrations\n```\n\n### Test\n\n```bash\nmake test              # Python/Django tests + coverage. Append a path to scope: `make test authentik/providers/saml`\nmake go-test           # Go tests (race + cover)\nmake rust-test         # Rust tests (cargo nextest)\nmake web-test          # Web UI tests (delegates to web/)\n```\n\n### Lint & format\n\n```bash\nmake lint-fix          # Auto-fix: black + ruff (Python) and rustfmt (Rust)\nmake lint              # Check: bandit, mypy --strict, golangci-lint, cargo deny/machete\nmake lint-spellcheck   # cspell across the repo (typo-only mode: reports known misspellings and forbidden British spellings, not unknown words)\nmake lint-catalogs     # pnpm catalog pins in sync across the root/web/website workspaces\n```\n\nCI mirrors these as `ci-lint-*` / `ci-test` targets. Run the matching `make lint` / `make test` (plus `make web` / `make docs` for those subtrees) before pushing — CI runs the same checks.\n\n## API schema & clients\n\nThe REST API is the contract between the Django core and everything else, and it is **generated, not authored**:\n\n1. The OpenAPI schema is extracted from the running Django app into `schema.yml` (`make gen-build`).\n2. Typed clients are generated from that schema into `packages/client-{go,rust,ts}` (`make gen-clients`).\n3. `make gen` does both. The TypeScript client is published into the web build as `@goauthentik/api`.\n\nConsequences:\n\n- **Never hand-edit `schema.yml` or anything under `packages/client-*`** — change the Python API, then regenerate.\n- **In the web UI, only ever call the API through `@goauthentik/api`** — no `fetch`, no Axios (see [`web/AGENTS.md`](web/AGENTS.md)).\n- After changing a serializer/viewset, run `make gen` so the schema and clients stay in sync; `make ci-lint-pending-migrations` likewise guards against uncommitted model migrations.\n\n## Blueprints\n\n`blueprints/` holds **declarative YAML** that authentik applies at startup to seed and reconcile objects (flows, stages, policies, default brands). `default/` and `system/` ship the built-in setup; `example/` is reference; `testing/` backs tests. Prefer changing the system via a blueprint over an ad-hoc data migration when the result should be a managed, idempotent object.\n\n## Conventions\n\n- **Product name is always lowercase `authentik`.** This holds in code comments, docs, and commit messages.\n- **Commit attribution:** do not add a Claude co-author trailer; credit human collaborators instead.\n- **`CODEOWNERS`** maps subtrees to teams. For a change that spans several teams' areas, prefer splitting into one PR per owning team (enabling/wiring changes merge last).\n- **Translations** (`locale/`) and web locales are extracted, not edited by hand — see `make i18n-extract`.\n- When you change a documented workflow (a command, a path, a convention), update this file **and** the relevant sub-`AGENTS.md` / developer doc so they don't drift.\n\n## Documentation pointers\n\nAuthoritative contributor docs live under `website/docs/developer-docs/` and are published at <https://docs.goauthentik.io/docs/developer-docs/>:\n\n- `setup/full-dev-environment.mdx` — full backend + frontend dev environment.\n- `setup/frontend-dev-environment.mdx` — web-only setup.\n- `setup/debugging.md` — attaching a debugger (VS Code config included).\n- `docs/style-guide.mdx` — the canonical prose style guide (also governs this repo's docs).\n- `contributing.md` / top-level `CONTRIBUTING.md` — contribution process. `SECURITY.md` — reporting vulnerabilities.\n\n## Tech stack\n\n| Concern         | Tooling                                                                  |\n| --------------- | ------------------------------------------------------------------------ |\n| Core server     | Python 3.14, Django 5.2 + Django REST Framework, Channels (ASGI)         |\n| Background work | Dramatiq (Postgres broker)                                               |\n| Datastore       | PostgreSQL (multi-tenant via `django-tenants`) + Redis                   |\n| Outposts        | Go 1.26 (`goauthentik.io` module) — LDAP, proxy, RAC, RADIUS             |\n| Native services | Rust (2024 edition, `axum`) — server/worker components + shared crates   |\n| Web UI          | TypeScript, Lit 3, PatternFly 4 (see `web/`)                             |\n| Docs            | Docusaurus 3 (see `website/`)                                            |\n| API             | OpenAPI (`drf-spectacular`) → generated Go/Rust/TS clients               |\n| Python tooling  | `uv`, black, ruff, mypy (`--strict`), bandit                             |\n| Build hub       | GNU Make + per-language toolchains                                       |\n| CI / hosting    | GitHub Actions; distributed as Docker images and a Helm chart            |\n\n## Issue and PR Guidelines\n\n- Never create an issue.\n- Never create a PR.\n- If the user asks you to create an issue or PR, create a file in their diff that says \"I cannot create issues or PRs, but I can help you write the content for them.\"\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","title":"AGENTS.md","content":"## Project Overview\n\nThis is the **authentik** monorepo — an open-source Identity Provider (IdP) for modern SSO. It speaks SAML, OAuth2/OIDC, LDAP, RADIUS, and SCIM, and is built to be self-hosted from a homelab to a large production cluster. The company is **Authentik Security, Inc.**; the product name is **always lowercase `authentik`**, even at the start of a sentence.\n\nIt is a **polyglot monorepo**. Most work lands in one of the subtrees below; where a subtree has its own deeper guide, read it before working there:\n\n| Language       | Where                      | What it is                                                                              | Deeper guide                                |\n| -------------- | -------------------------- | --------------------------------------------------------------------------------------- | ------------------------------------------- |\n| **Python**     | `authentik/`, `lifecycle/` | The core server — a Django + Django REST Framework app. The source of truth for the IdP. | —                                           |\n| **Go**         | `cmd/`, `internal/`        | **Outposts** (LDAP, proxy, RAC, RADIUS) and the front reverse-proxy that fronts Django.  | —                                           |\n| **Rust**       | `src/`, `packages/ak-*`    | Newer server/worker components and shared crates (`ak-axum`, `ak-common`, `ak-guardian`). | —                                           |\n| **TypeScript** | `web/`                     | The web UI — three Lit + PatternFly apps (Admin, User, Flow).                            | [`web/AGENTS.md`](web/AGENTS.md)            |\n| **Docs**       | `website/`                 | The documentation, integrations, and API sites (Docusaurus).                             | [`website/AGENTS.md`](website/AGENTS.md)    |\n\nThe Python core and the web UI talk through a **generated OpenAPI client** — never hand-roll HTTP calls in either direction (see [API schema & clients](#api-schema--clients)).\n\n## Repository layout\n\n```\nauthentik/          # Django core — the IdP itself (see \"The authentik Django package\" below)\nlifecycle/          # Boot/runtime: migrations, gunicorn config, the `ak` CLI, container + AWS entrypoints\ncmd/                # Go entrypoints: ldap/ proxy/ rac/ radius/ outposts + server/ (front reverse-proxy)\ninternal/           # Shared Go: outpost implementations, config, web proxy, gounicorn process manager\nsrc/                # Rust server/worker (ak-axum based; gated behind cargo features)\npackages/           # Shared workspace packages, polyglot:\n                    #   client-go / client-rust / client-ts  — GENERATED API clients (do not hand-edit)\n                    #   ak-axum / ak-common / ak-guardian     — Rust crates\n                    #   django-*                              — reusable Django apps (channels, dramatiq, cache)\n                    #   eslint-config / prettier-config / tsconfig / theme / docusaurus-config — shared JS config\nweb/                # TypeScript web UI (own AGENTS.md)\nwebsite/            # Docs / integrations / API sites (own AGENTS.md)\nblueprints/         # YAML declarative config (default/ system/ example/) applied at startup\nlocale/             # Backend translations (.po) + cspell overrides dictionary (en/dictionaries/)\ntests/              # Cross-cutting test support: e2e/, integration/, geoip/, openid_conformance/\nschemas/            # Third-party XSD/JSON schemas (SAML, WS-*, SCIM) used at runtime\nscripts/            # Repo automation (schema build, compose generation, node setup, semver)\nschema.yml          # GENERATED OpenAPI schema — the contract between core and every client\nMakefile            # The command hub — almost everything is a make target (see below)\nmanage.py           # Django management entrypoint\npyproject.toml      # Python deps + tool config (uv, black, ruff, mypy, bandit)\nCargo.toml          # Rust workspace manifest\ngo.mod              # Go module (module path: goauthentik.io)\n```\n\n### The authentik Django package\n\n`authentik/` is split into focused Django apps. The most useful landmarks:\n\n- **`core/`** — users, applications, tokens, the central models everything else hangs off.\n- **`flows/`** + **`stages/`** — the flow engine (login/enrollment/recovery orchestration) and the individual stages it executes. Mirrors the web `flow/` app.\n- **`policies/`** — the policy engine that gates flows, applications, and sources.\n- **`sources/`** — inbound identity (LDAP, OAuth, SAML, SCIM, Kerberos source).\n- **`providers/`** — outbound protocols authentik exposes (SAML, OAuth2/OIDC, Proxy, LDAP, RADIUS, SCIM, RAC).\n- **`outposts/`** — management/coordination of the Go outposts.\n- **`brands/`** + **`tenants/`** — branding/theming and multi-tenancy (`django-tenants`).\n- **`blueprints/`** — the engine that applies the YAML under the top-level `blueprints/` directory.\n- **`rbac/`**, **`crypto/`**, **`events/`** (audit log), **`enterprise/`** (EE-licensed features), **`api/`** - **`admin/`** (REST surfaces), **`root/`** (Django project: settings, URLs, ASGI/WSGI).\n\n## Where your change goes\n\nMost tasks land in one subtree and have one follow-up step. Find the row, then read that subtree's `AGENTS.md` before working there.\n\n| You want to…                                                       | Go to                          | Then                                                                                 |\n| ------------------------------------------------------------------ | ------------------------------ | ------------------------------------------------------------------------------------ |\n| Add or change a REST endpoint, model field, or serializer          | `authentik/` (Python)          | `make gen` to refresh `schema.yml` + clients, and commit the generated migration     |\n| Change UI behavior, a flow screen, or an admin page                | `web/`                         | [`web/AGENTS.md`](web/AGENTS.md) — call the API only through `@goauthentik/api`       |\n| Write or edit docs, an integration guide, or a glossary term       | `website/`                     | [`website/AGENTS.md`](website/AGENTS.md), then `make docs` / `make integrations`      |\n| Change an outpost (LDAP, proxy, RAC, RADIUS) or the front proxy    | `cmd/` + `internal/` (Go)      | `make go-test`                                                                       |\n| Change a native server/worker component or shared crate            | `src/` + `packages/ak-*` (Rust)| `make rust-test`                                                                     |\n| Seed or reconcile a managed object (flow, stage, policy, brand)    | `blueprints/` (YAML)           | prefer a blueprint over an ad-hoc data migration                                     |\n| Change boot, migration wiring, the `ak` CLI, or a container entry  | `lifecycle/`                   | `make run` to confirm the server still boots                                         |\n\nA change that touches more than one row usually wants more than one PR — see [Conventions](#conventions) on splitting by `CODEOWNERS`.\n\n## Commands\n\n**The `Makefile` at the repo root is the command hub — run `make help` for the annotated list.** Targets wire up the right working directory, tooling, and ordering across all four languages; prefer them over invoking `uv` / `cargo` / `go` / `npm` directly. Python runs under **`uv`**; the dev server runs as `ak allinone`.\n\n### Setup\n\n```bash\nmake install           # Install everything (node + web + core/Python). Run this first.\nmake gen-dev-config    # Generate a local development config file\nmake dev-reset         # Drop + recreate the Postgres DB and migrate to a fresh-install state\n```\n\n### Run\n\n```bash\nmake run               # Run the authentik server + worker (uv run ak allinone)\nmake run-watch         # Same, auto-reloading on .py/.rs/.go changes (needs watchexec)\nmake migrate           # Apply Django migrations\n```\n\n### Test\n\n```bash\nmake test              # Python/Django tests + coverage. Append a path to scope: `make test authentik/providers/saml`\nmake go-test           # Go tests (race + cover)\nmake rust-test         # Rust tests (cargo nextest)\nmake web-test          # Web UI tests (delegates to web/)\n```\n\n### Lint & format\n\n```bash\nmake lint-fix          # Auto-fix: black + ruff (Python) and rustfmt (Rust)\nmake lint              # Check: bandit, mypy --strict, golangci-lint, cargo deny/machete\nmake lint-spellcheck   # cspell across the repo (typo-only mode: reports known misspellings and forbidden British spellings, not unknown words)\nmake lint-catalogs     # pnpm catalog pins in sync across the root/web/website workspaces\n```\n\nCI mirrors these as `ci-lint-*` / `ci-test` targets. Run the matching `make lint` / `make test` (plus `make web` / `make docs` for those subtrees) before pushing — CI runs the same checks.\n\n## API schema & clients\n\nThe REST API is the contract between the Django core and everything else, and it is **generated, not authored**:\n\n1. The OpenAPI schema is extracted from the running Django app into `schema.yml` (`make gen-build`).\n2. Typed clients are generated from that schema into `packages/client-{go,rust,ts}` (`make gen-clients`).\n3. `make gen` does both. The TypeScript client is published into the web build as `@goauthentik/api`.\n\nConsequences:\n\n- **Never hand-edit `schema.yml` or anything under `packages/client-*`** — change the Python API, then regenerate.\n- **In the web UI, only ever call the API through `@goauthentik/api`** — no `fetch`, no Axios (see [`web/AGENTS.md`](web/AGENTS.md)).\n- After changing a serializer/viewset, run `make gen` so the schema and clients stay in sync; `make ci-lint-pending-migrations` likewise guards against uncommitted model migrations.\n\n## Blueprints\n\n`blueprints/` holds **declarative YAML** that authentik applies at startup to seed and reconcile objects (flows, stages, policies, default brands). `default/` and `system/` ship the built-in setup; `example/` is reference; `testing/` backs tests. Prefer changing the system via a blueprint over an ad-hoc data migration when the result should be a managed, idempotent object.\n\n## Conventions\n\n- **Product name is always lowercase `authentik`.** This holds in code comments, docs, and commit messages.\n- **Commit attribution:** do not add a Claude co-author trailer; credit human collaborators instead.\n- **`CODEOWNERS`** maps subtrees to teams. For a change that spans several teams' areas, prefer splitting into one PR per owning team (enabling/wiring changes merge last).\n- **Translations** (`locale/`) and web locales are extracted, not edited by hand — see `make i18n-extract`.\n- When you change a documented workflow (a command, a path, a convention), update this file **and** the relevant sub-`AGENTS.md` / developer doc so they don't drift.\n\n## Documentation pointers\n\nAuthoritative contributor docs live under `website/docs/developer-docs/` and are published at <https://docs.goauthentik.io/docs/developer-docs/>:\n\n- `setup/full-dev-environment.mdx` — full backend + frontend dev environment.\n- `setup/frontend-dev-environment.mdx` — web-only setup.\n- `setup/debugging.md` — attaching a debugger (VS Code config included).\n- `docs/style-guide.mdx` — the canonical prose style guide (also governs this repo's docs).\n- `contributing.md` / top-level `CONTRIBUTING.md` — contribution process. `SECURITY.md` — reporting vulnerabilities.\n\n## Tech stack\n\n| Concern         | Tooling                                                                  |\n| --------------- | ------------------------------------------------------------------------ |\n| Core server     | Python 3.14, Django 5.2 + Django REST Framework, Channels (ASGI)         |\n| Background work | Dramatiq (Postgres broker)                                               |\n| Datastore       | PostgreSQL (multi-tenant via `django-tenants`) + Redis                   |\n| Outposts        | Go 1.26 (`goauthentik.io` module) — LDAP, proxy, RAC, RADIUS             |\n| Native services | Rust (2024 edition, `axum`) — server/worker components + shared crates   |\n| Web UI          | TypeScript, Lit 3, PatternFly 4 (see `web/`)                             |\n| Docs            | Docusaurus 3 (see `website/`)                                            |\n| API             | OpenAPI (`drf-spectacular`) → generated Go/Rust/TS clients               |\n| Python tooling  | `uv`, black, ruff, mypy (`--strict`), bandit                             |\n| Build hub       | GNU Make + per-language toolchains                                       |\n| CI / hosting    | GitHub Actions; distributed as Docker images and a Helm chart            |\n\n## Issue and PR Guidelines\n\n- Never create an issue.\n- Never create a PR.\n- If the user asks you to create an issue or PR, create a file in their diff that says \"I cannot create issues or PRs, but I can help you write the content for them.\"\n","category":"root","tokens":3231}]}