Compare commits

..

49 Commits

Author SHA1 Message Date
c3789f583c web: Fix issue where linters collide. Update ignore file.
- Remove unused sort override for polyfills.
2025-05-02 15:28:28 +02:00
621b0e642c web: Use monorepo utilities when building. 2025-05-02 15:27:21 +02:00
39f68b9c3f web: WIP Add monorepo dependency. 2025-05-02 15:26:50 +02:00
9382fdf8cd web: Update build paths. Fix types. 2025-05-02 15:26:48 +02:00
01b9369afb web: WIP Prepare monorepo package for use. 2025-05-02 15:26:44 +02:00
be2cb10f40 web: Build entrypoints with a single ESBuild context. Clean up entrypoints. 2025-05-02 15:26:41 +02:00
af72a23d7c web: Revise globals. 2025-05-02 15:26:39 +02:00
aefe2d6eaf web: Format package.json. 2025-05-02 15:26:27 +02:00
c69d35b9f7 web: Format live reload package. 2025-05-02 15:26:19 +02:00
5c9e97e11c web: bump vite from 5.4.16 to 5.4.19 in /web (#14324)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.4.16 to 5.4.19.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v5.4.19/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.4.19/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 5.4.19
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-01 22:34:28 +02:00
2e7c620c9c core: bump setuptools from 78.1.0 to v79.0.0 (#14173) 2025-05-01 22:29:49 +02:00
30a2770781 core: bump ruff from 0.11.5 to v0.11.6 (#14171) 2025-05-01 22:29:36 +02:00
ef49fa0e79 core: bump s3transfer from 0.11.4 to v0.11.5 (#14172) 2025-05-01 22:29:03 +02:00
ac524ef425 core: bump packaging from 24.2 to v25.0 (#14169) 2025-05-01 22:28:44 +02:00
6f3c1c4537 core: bump aiohttp from 3.11.16 to v3.11.18 (#14166) 2025-05-01 22:28:35 +02:00
87886ca1b6 core: bump boto3 from 1.37.35 to v1.37.38 (#14167) 2025-05-01 22:28:11 +02:00
7ff96e30f9 core: bump frozenlist from 1.5.0 to v1.6.0 (#14168) 2025-05-01 22:28:02 +02:00
b26271557a core: bump pdoc from 15.0.1 to v15.0.3 (#14170) 2025-05-01 22:27:51 +02:00
15c99ff129 core: bump trio from 0.29.0 to v0.30.0 (#14174) 2025-05-01 22:27:32 +02:00
2a38e08e31 translate: Updates for file locale/en/LC_MESSAGES/django.po in it (#14271)
Translate locale/en/LC_MESSAGES/django.po in it

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'it'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-05-01 22:25:59 +02:00
3696706466 website: bump the build group across 1 directory with 9 updates (#14293)
Bumps the build group with 9 updates in the /website directory:

| Package | From | To |
| --- | --- | --- |
| [@rspack/binding-darwin-arm64](https://github.com/web-infra-dev/rspack/tree/HEAD/packages/rspack) | `1.3.6` | `1.3.8` |
| [@rspack/binding-linux-arm64-gnu](https://github.com/web-infra-dev/rspack/tree/HEAD/packages/rspack) | `1.3.6` | `1.3.8` |
| [@rspack/binding-linux-x64-gnu](https://github.com/web-infra-dev/rspack/tree/HEAD/packages/rspack) | `1.3.6` | `1.3.8` |
| [@swc/core-darwin-arm64](https://github.com/swc-project/swc) | `1.11.22` | `1.11.24` |
| [@swc/core-linux-arm64-gnu](https://github.com/swc-project/swc) | `1.11.22` | `1.11.24` |
| [@swc/core-linux-x64-gnu](https://github.com/swc-project/swc) | `1.11.22` | `1.11.24` |
| [@swc/html-darwin-arm64](https://github.com/swc-project/swc) | `1.11.22` | `1.11.24` |
| [@swc/html-linux-arm64-gnu](https://github.com/swc-project/swc) | `1.11.22` | `1.11.24` |
| [@swc/html-linux-x64-gnu](https://github.com/swc-project/swc) | `1.11.22` | `1.11.24` |



Updates `@rspack/binding-darwin-arm64` from 1.3.6 to 1.3.8
- [Release notes](https://github.com/web-infra-dev/rspack/releases)
- [Commits](https://github.com/web-infra-dev/rspack/commits/v1.3.8/packages/rspack)

Updates `@rspack/binding-linux-arm64-gnu` from 1.3.6 to 1.3.8
- [Release notes](https://github.com/web-infra-dev/rspack/releases)
- [Commits](https://github.com/web-infra-dev/rspack/commits/v1.3.8/packages/rspack)

Updates `@rspack/binding-linux-x64-gnu` from 1.3.6 to 1.3.8
- [Release notes](https://github.com/web-infra-dev/rspack/releases)
- [Commits](https://github.com/web-infra-dev/rspack/commits/v1.3.8/packages/rspack)

Updates `@swc/core-darwin-arm64` from 1.11.22 to 1.11.24
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.11.22...v1.11.24)

Updates `@swc/core-linux-arm64-gnu` from 1.11.22 to 1.11.24
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.11.22...v1.11.24)

Updates `@swc/core-linux-x64-gnu` from 1.11.22 to 1.11.24
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.11.22...v1.11.24)

Updates `@swc/html-darwin-arm64` from 1.11.22 to 1.11.24
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.11.22...v1.11.24)

Updates `@swc/html-linux-arm64-gnu` from 1.11.22 to 1.11.24
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.11.22...v1.11.24)

Updates `@swc/html-linux-x64-gnu` from 1.11.22 to 1.11.24
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.11.22...v1.11.24)

---
updated-dependencies:
- dependency-name: "@rspack/binding-darwin-arm64"
  dependency-version: 1.3.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@rspack/binding-linux-arm64-gnu"
  dependency-version: 1.3.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@rspack/binding-linux-x64-gnu"
  dependency-version: 1.3.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/core-darwin-arm64"
  dependency-version: 1.11.24
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/core-linux-arm64-gnu"
  dependency-version: 1.11.24
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/core-linux-x64-gnu"
  dependency-version: 1.11.24
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/html-darwin-arm64"
  dependency-version: 1.11.24
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/html-linux-arm64-gnu"
  dependency-version: 1.11.24
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/html-linux-x64-gnu"
  dependency-version: 1.11.24
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-01 22:20:34 +02:00
d0c9635033 core, web: update translations (#14309)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: rissson <18313093+rissson@users.noreply.github.com>
2025-05-01 22:20:27 +02:00
7731014e1c stages/authenticator_webauthn: Update FIDO MDS3 & Passkey aaguid blobs (#14311)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-05-01 22:20:08 +02:00
d478582a5c core: bump astral-sh/uv from 0.7.0 to 0.7.2 (#14315)
Bumps [astral-sh/uv](https://github.com/astral-sh/uv) from 0.7.0 to 0.7.2.
- [Release notes](https://github.com/astral-sh/uv/releases)
- [Changelog](https://github.com/astral-sh/uv/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/uv/compare/0.7.0...0.7.2)

---
updated-dependencies:
- dependency-name: astral-sh/uv
  dependency-version: 0.7.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-01 22:19:55 +02:00
6255f380aa core: bump goauthentik.io/api/v3 from 3.2025024.9 to 3.2025040.1 (#14316)
Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2025024.9 to 3.2025040.1.
- [Release notes](https://github.com/goauthentik/client-go/releases)
- [Changelog](https://github.com/goauthentik/client-go/blob/main/model_version_history.go)
- [Commits](https://github.com/goauthentik/client-go/compare/v3.2025024.9...v3.2025040.1)

---
updated-dependencies:
- dependency-name: goauthentik.io/api/v3
  dependency-version: 3.2025040.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-01 22:19:48 +02:00
1f02e67c5c core: bump github.com/redis/go-redis/v9 from 9.7.3 to 9.8.0 (#14317)
Bumps [github.com/redis/go-redis/v9](https://github.com/redis/go-redis) from 9.7.3 to 9.8.0.
- [Release notes](https://github.com/redis/go-redis/releases)
- [Changelog](https://github.com/redis/go-redis/blob/master/CHANGELOG.md)
- [Commits](https://github.com/redis/go-redis/compare/v9.7.3...v9.8.0)

---
updated-dependencies:
- dependency-name: github.com/redis/go-redis/v9
  dependency-version: 9.8.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-01 22:19:41 +02:00
d0bfb894b4 lifecycle/aws: bump aws-cdk from 2.1012.0 to 2.1013.0 in /lifecycle/aws (#14318)
Bumps [aws-cdk](https://github.com/aws/aws-cdk-cli/tree/HEAD/packages/aws-cdk) from 2.1012.0 to 2.1013.0.
- [Release notes](https://github.com/aws/aws-cdk-cli/releases)
- [Commits](https://github.com/aws/aws-cdk-cli/commits/aws-cdk@v2.1013.0/packages/aws-cdk)

---
updated-dependencies:
- dependency-name: aws-cdk
  dependency-version: 2.1013.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-01 22:19:31 +02:00
c5dfdc6deb website/integrations: youtrack document (#14264)
* add to sidebar

Signed-off-by: Dominic R <dominic@sdko.org>

* start ak config

Signed-off-by: Dominic R <dominic@sdko.org>

* init

* lint

* spelling 

Signed-off-by: Dominic R <dominic@sdko.org>

* Update website/integrations/services/youtrack/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dominic R <dominic@sdko.org>

* Update website/integrations/services/youtrack/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dominic R <dominic@sdko.org>

* Update website/integrations/services/youtrack/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dominic R <dominic@sdko.org>

---------

Signed-off-by: Dominic R <dominic@sdko.org>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
2025-05-01 11:13:21 -05:00
d04a66ad9a website/integrations: improve Gitea doc (#14194)
* Updating to new formatting rules, added note based on GH issue, wording improvements.

* Updated formatting, added testing configuration step, numbered steps, imrpoved wording

* Added numbered steps to the Gitea instructions and changed the navigation steps.

* Changed indenting on codeblocks

* Alterations based on feedback

* Altered icon urls and italicization

* changed line 52 to use png instead of svg

* Update website/integrations/services/gitea/index.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/gitea/index.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/gitea/index.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* changed <application lsug> to <slug>

* Update website/integrations/services/gitea/index.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/gitea/index.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Minor changes to wording/formatting and added a resources section

* Update website/integrations/services/gitea/index.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/gitea/index.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/gitea/index.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/gitea/index.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Added missing punctuation

* a few tweaks, and bumb to rebuild

---------

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>
Co-authored-by: Dominic R <dominic@sdko.org>
Co-authored-by: Tana M Berry <tana@goauthentik.io>
2025-05-01 09:54:52 -05:00
a5edaabec0 website/docs: "Device code flow" documentation improvements (#14257)
* Improved RFC reference

Replaced "abilities" with "capabilities" to better reflect RFC wording, added extended summary from RFC to ensure complete and clear understanding.

Signed-off-by: Dametto Luca <45915503+LucaTheHacker@users.noreply.github.com>

* Improved documentation

Added link for brand keyword, removed repetition

Signed-off-by: Dametto Luca <45915503+LucaTheHacker@users.noreply.github.com>

* Improved UX

Marked keywords with Capital letters and proper formatting to clarify those are references to actual values/labels

Signed-off-by: Dametto Luca <45915503+LucaTheHacker@users.noreply.github.com>

* SEO Optimization

Added alternative name to "also known" section to improve searchability

Signed-off-by: Dametto Luca <45915503+LucaTheHacker@users.noreply.github.com>

* Added step-by-step tutorial for setup

Signed-off-by: Dametto Luca <45915503+LucaTheHacker@users.noreply.github.com>

* "Relative vs. absolute paths" rule

Removed full link in favor of relative path

Signed-off-by: Dametto Luca <45915503+LucaTheHacker@users.noreply.github.com>

* Fixed formatting according to style guide

Signed-off-by: Dametto Luca <45915503+LucaTheHacker@users.noreply.github.com>

* Fixed relative path

Signed-off-by: Dametto Luca <45915503+LucaTheHacker@users.noreply.github.com>

* Update website/docs/add-secure-apps/providers/oauth2/device_code.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dametto Luca <45915503+LucaTheHacker@users.noreply.github.com>

* Update website/docs/add-secure-apps/providers/oauth2/device_code.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dametto Luca <45915503+LucaTheHacker@users.noreply.github.com>

* Update website/docs/add-secure-apps/providers/oauth2/device_code.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dametto Luca <45915503+LucaTheHacker@users.noreply.github.com>

* Update website/docs/add-secure-apps/providers/oauth2/device_code.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dametto Luca <45915503+LucaTheHacker@users.noreply.github.com>

* Update website/docs/add-secure-apps/providers/oauth2/device_code.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dametto Luca <45915503+LucaTheHacker@users.noreply.github.com>

* Update website/docs/add-secure-apps/providers/oauth2/device_code.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dametto Luca <45915503+LucaTheHacker@users.noreply.github.com>

* Update device_code.md

removed newline as per "prettier --write"

Signed-off-by: Dametto Luca <45915503+LucaTheHacker@users.noreply.github.com>

* Update website/docs/add-secure-apps/providers/oauth2/device_code.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dametto Luca <45915503+LucaTheHacker@users.noreply.github.com>

* Update website/docs/add-secure-apps/providers/oauth2/device_code.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update device_code.md

brute forced it here...

Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

---------

Signed-off-by: Dametto Luca <45915503+LucaTheHacker@users.noreply.github.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>
Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: Dominic R <dominic@sdko.org>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
2025-05-01 08:43:59 -05:00
daa367bc62 website/docs: adds webfinger doc under oauth provider (#14247)
* Added document and modified sidebar

* Update website/docs/add-secure-apps/providers/oauth2/webfinger_support.mdx

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

---------

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
2025-05-01 08:30:05 -05:00
78345853c2 website/docs: clean up oauth redirect paragraph (#14291)
* website/docs: clean up oauth redirect paragraph

Signed-off-by: Fletcher Heisler <fheisler@users.noreply.github.com>

* Dominic's edit, and yet another typo

---------

Signed-off-by: Fletcher Heisler <fheisler@users.noreply.github.com>
Co-authored-by: Tana M Berry <tana@goauthentik.io>
2025-04-30 16:11:16 -05:00
f0fa8a3226 brands: fix CSS Migration not updating brands (#14306)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-04-30 22:39:23 +02:00
3335fdc6ad website/docs: clarify 2025.4 breaking Reputation changes (#14284)
* website/docs: clarify `2025.4` breaking Reputation changes

* Update website/docs/releases/2025/v2025.4.md

Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

* change to bump build checks

* another tweak to bounce after rebase

---------

Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: Tana M Berry <tana@goauthentik.io>
2025-04-30 15:39:16 -05:00
29c2c0f7dc website/docs: clarify some points (i.e. around capitalization after colons) (#14290)
* a few new items

* more on capitalization

* Update website/docs/developer-docs/docs/style-guide.mdx

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* tweak to bump build

* typo thx fletcher

* remove mention of BR

* final edits in

---------

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>
Co-authored-by: Tana M Berry <tana@goauthentik.io>
Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
Co-authored-by: Dominic R <dominic@sdko.org>
2025-04-30 14:28:08 -05:00
ada4254f52 web: bump API Client version (#14301)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-04-30 13:43:37 +00:00
39035de552 website/docs: initial permissions: fix usage of term admin (#14300)
* website/docs: initial permissions: fix usage of term admin

Should be lowercase and use full word as it refers to an administrator. See pending PR for style guide 

Signed-off-by: Dominic R <dominic@sdko.org>

* fix2

Signed-off-by: Dominic R <dominic@sdko.org>

---------

Signed-off-by: Dominic R <dominic@sdko.org>
2025-04-30 13:19:43 +00:00
e76d388ce4 release: 2025.4.0 (#14299)
Co-authored-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-30 13:15:38 +00:00
a52f887692 core, web: update translations (#14273)
Co-authored-by: rissson <18313093+rissson@users.noreply.github.com>
2025-04-30 13:00:04 +00:00
d8b12a9a07 core: bump astral-sh/uv from 0.6.17 to 0.7.0 (#14294)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-30 12:59:49 +00:00
ec01f16e99 ci: cleanup post uv migration (#13538) 2025-04-30 12:43:14 +00:00
9e3aaefc20 website/docs: add gateway API to release notes and documentation (#14278) 2025-04-30 14:36:42 +02:00
4454592442 website/docs: Release notes 2025.4.0 (#14281)
* remove rc notice and enterprise tag for the span

* Edit sidebar and security.md

* Add api changes and minor fixes

* Fix linting

* fix netlify linter

* Update website/docs/releases/2025/v2025.4.md

Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

* Update website/docs/releases/2025/v2025.4.md

Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

* remove changelog entries that shouldn't be there

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* Update v2025.4.md

Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

* Update v2025.4.md

Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

* fix linting

---------

Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-29 20:48:49 +02:00
593c953ecc website/docs: sessions in database (#13507)
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-29 20:33:48 +02:00
bcefe7123c website/docs: add LDAP 'Lookup using user attribute' docs (#13966)
* website/docs: add LDAP 'Lookup using user attribute' docs

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* Updated the doc to new template, removed incorrect screenshot, clarified instructions

* Change in group field explanation as per Marc's comment

* Added examples for filters and changed some language.

* Removed additional info link

* fixup

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* Minor formatting changes

* Update website/docs/users-sources/sources/protocols/ldap/index.md

Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

* Update website/docs/users-sources/sources/directory-sync/active-directory/index.md

Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

* Update website/docs/users-sources/sources/directory-sync/active-directory/index.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Added more information to service account creation and LDAPS testing

* Added examples for fields based on issue #3801

---------

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>
Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: Dominic R <dominic@sdko.org>
2025-04-29 20:32:59 +02:00
812cf6c4f2 website/docs: add postgres pool configuration (#14060)
* website/docs: add postgres pool configuration

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* Update website/docs/install-config/configuration/configuration.mdx

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

---------

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-29 20:32:37 +02:00
73b6ef6a73 website/docs: docs about initial perms (#14263)
* basic procedural steps

* more questions, more typos

* more typos

* tweaks

* more content, new links

* fixed link

* tweak

* fix things

* more fixes

* yet more fixes

* Apply suggestions from code review

Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

* Update website/docs/users-sources/access-control/initial_permissions.mdx

Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

* dewi's edits

* dominic's edits

* gergo edits and more dominic edits

* one more

* yet one more fix

* final gergo observation

* tweak

---------

Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: Tana M Berry <tana@goauthentik.io>
Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
2025-04-29 20:31:01 +02:00
b58ebcddbf website/docs: Revert "website/docs: revert token_expiry format in example blueprint… (#14280)
Revert "website/docs: revert token_expiry format in example blueprint (#13582)"

This reverts commit 9538cf4690.
2025-04-29 20:30:13 +02:00
8b6ac3c806 website/docs: Password Uniqueness Policy (#13686)
* First draft docs for policies/unique_password

* simplify documentation

* fix styling

* Add clarification about when this policy takes effect

* change wording in how it works

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Marcelo Elizeche Landó <marce@melizeche.com>

* Take the user by the hand and tell them where to go

* Improve wording in Configuration options

* add suggestion from PR

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Marcelo Elizeche Landó <marce@melizeche.com>

* Update website/docs/customize/policies/unique_password.md

Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

* Apply suggestions from code review

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Marcelo Elizeche Landó <marce@melizeche.com>

* fix linting and wording

* Add instructions for binding

* Remove conf options section, add to sidebar

* Update website/docs/customize/policies/unique_password.md

Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

---------

Signed-off-by: Marcelo Elizeche Landó <marce@melizeche.com>
Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: Dominic R <dominic@sdko.org>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
2025-04-29 20:29:41 +02:00
107 changed files with 4765 additions and 1361 deletions

View File

@ -1,5 +1,5 @@
[bumpversion]
current_version = 2025.2.4
current_version = 2025.4.0
tag = True
commit = True
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(?:-(?P<rc_t>[a-zA-Z-]+)(?P<rc_n>[1-9]\\d*))?

View File

@ -1,5 +1,6 @@
---
name: "Prepare docker environment variables"
description: "Prepare docker environment variables"
inputs:
image-name:

View File

@ -1,4 +1,4 @@
name: Setup authentik testing environment
name: "Setup authentik testing environment"
description: "Setup authentik testing environment"
inputs:

View File

@ -42,7 +42,7 @@ jobs:
- uses: actions/checkout@v4
- uses: docker/setup-qemu-action@v3.6.0
- uses: docker/setup-buildx-action@v3
- name: Prepare variables
- name: prepare variables
uses: ./.github/actions/docker-push-variables
id: ev
env:
@ -64,12 +64,12 @@ jobs:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Make empty clients
- name: make empty clients
if: ${{ inputs.release }}
run: |
mkdir -p ./gen-ts-api
mkdir -p ./gen-go-api
- name: Generate TypeScript API Client
- name: generate ts client
if: ${{ !inputs.release }}
run: make gen-client-ts
- name: Build Docker Image

View File

@ -49,7 +49,7 @@ jobs:
shouldPush: ${{ steps.ev.outputs.shouldPush }}
steps:
- uses: actions/checkout@v4
- name: Prepare variables
- name: prepare variables
uses: ./.github/actions/docker-push-variables
id: ev
env:
@ -69,7 +69,7 @@ jobs:
tag: ${{ fromJson(needs.get-tags.outputs.tags) }}
steps:
- uses: actions/checkout@v4
- name: Prepare variables
- name: prepare variables
uses: ./.github/actions/docker-push-variables
id: ev
env:

View File

@ -7,7 +7,6 @@ on:
workflow_dispatch:
jobs:
build:
name: Build and Publish
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
runs-on: ubuntu-latest
permissions:
@ -15,7 +14,6 @@ jobs:
steps:
- id: generate_token
uses: tibdex/github-app-token@v2
name: Generate token
with:
app_id: ${{ secrets.GH_APP_ID }}
private_key: ${{ secrets.GH_APP_PRIVATE_KEY }}
@ -32,7 +30,7 @@ jobs:
uses: actions/setup-python@v5
with:
python-version-file: "pyproject.toml"
- name: Generate Python API Client
- name: Generate API Client
run: make gen-client-py
- name: Publish package
working-directory: gen-py-api/

View File

@ -7,7 +7,6 @@ on:
workflow_dispatch:
jobs:
build:
name: Build and Publish
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
runs-on: ubuntu-latest
steps:
@ -23,7 +22,7 @@ jobs:
with:
node-version-file: web/package.json
registry-url: "https://registry.npmjs.org"
- name: Generate TypeScript API Client
- name: Generate API Client
run: make gen-client-ts
- name: Publish package
working-directory: gen-ts-api/

View File

@ -18,7 +18,6 @@ env:
jobs:
check-changes-applied:
name: Check changes applied
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@ -37,7 +36,6 @@ jobs:
uv run make aws-cfn
git diff --exit-code
ci-aws-cfn-mark:
name: CI AWS CloudFormation Mark
if: always()
needs:
- check-changes-applied

View File

@ -9,7 +9,6 @@ on:
jobs:
test-container:
name: Test Container ${{ matrix.version }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
@ -20,7 +19,6 @@ jobs:
- version-2024-12
steps:
- uses: actions/checkout@v4
name: ${{ matrix.version }} Setup
- run: |
current="$(pwd)"
dir="/tmp/authentik/${{ matrix.version }}"

View File

@ -19,7 +19,6 @@ env:
jobs:
lint:
name: Lint
strategy:
fail-fast: false
matrix:
@ -34,10 +33,9 @@ jobs:
- uses: actions/checkout@v4
- name: Setup authentik env
uses: ./.github/actions/setup
- name: Run job ${{ matrix.job }}
- name: run job
run: uv run make ci-${{ matrix.job }}
test-migrations:
name: Test Migrations
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@ -46,7 +44,6 @@ jobs:
- name: run migrations
run: uv run python -m lifecycle.migrate
test-make-seed:
name: Test Make Seed
runs-on: ubuntu-latest
steps:
- id: seed
@ -55,7 +52,7 @@ jobs:
outputs:
seed: ${{ steps.seed.outputs.seed }}
test-migrations-from-stable:
name: Test Migrations From Stable - PostgreSQL ${{ matrix.psql }} - Run ${{ matrix.run_id }}/5
name: test-migrations-from-stable - PostgreSQL ${{ matrix.psql }} - Run ${{ matrix.run_id }}/5
runs-on: ubuntu-latest
timeout-minutes: 20
needs: test-make-seed
@ -70,26 +67,22 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Checkout Stable
- name: checkout stable
run: |
# Copy current, latest config to local
# Temporarly comment the .github backup while migrating to uv
cp authentik/lib/default.yml local.env.yml
# cp -R .github ..
cp -R .github ..
cp -R scripts ..
git checkout $(git tag --sort=version:refname | grep '^version/' | grep -vE -- '-rc[0-9]+$' | tail -n1)
# rm -rf .github/ scripts/
# mv ../.github ../scripts .
rm -rf scripts/
mv ../scripts .
rm -rf .github/ scripts/
mv ../.github ../scripts .
- name: Setup authentik env (stable)
uses: ./.github/actions/setup
with:
postgresql_version: ${{ matrix.psql }}
continue-on-error: true
- name: Run migrations to stable
run: poetry run python -m lifecycle.migrate
- name: Checkout current code
- name: run migrations to stable
run: uv run python -m lifecycle.migrate
- name: checkout current code
run: |
set -x
git fetch
@ -100,10 +93,10 @@ jobs:
uses: ./.github/actions/setup
with:
postgresql_version: ${{ matrix.psql }}
- name: Migrate to latest
- name: migrate to latest
run: |
uv run python -m lifecycle.migrate
- name: Run tests
- name: run tests
env:
# Test in the main database that we just migrated from the previous stable version
AUTHENTIK_POSTGRESQL__TEST__NAME: authentik
@ -113,7 +106,7 @@ jobs:
run: |
uv run make ci-test
test-unittest:
name: Unit tests - PostgreSQL ${{ matrix.psql }} - Run ${{ matrix.run_id }}/5
name: test-unittest - PostgreSQL ${{ matrix.psql }} - Run ${{ matrix.run_id }}/5
runs-on: ubuntu-latest
timeout-minutes: 20
needs: test-make-seed
@ -126,7 +119,7 @@ jobs:
run_id: [1, 2, 3, 4, 5]
steps:
- uses: actions/checkout@v4
- name: Setup authentik env (${{ matrix.psql }})
- name: Setup authentik env
uses: ./.github/actions/setup
with:
postgresql_version: ${{ matrix.psql }}
@ -149,7 +142,6 @@ jobs:
file: unittest.xml
token: ${{ secrets.CODECOV_TOKEN }}
test-integration:
name: Integration tests
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
@ -158,7 +150,7 @@ jobs:
uses: ./.github/actions/setup
- name: Create k8s Kind Cluster
uses: helm/kind-action@v1.12.0
- name: Run integration
- name: run integration
run: |
uv run coverage run manage.py test tests/integration
uv run coverage xml
@ -174,34 +166,34 @@ jobs:
file: unittest.xml
token: ${{ secrets.CODECOV_TOKEN }}
test-e2e:
name: Test E2E (${{ matrix.job.name }})
name: test-e2e (${{ matrix.job.name }})
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
job:
- name: Proxy Provider
- name: proxy
glob: tests/e2e/test_provider_proxy*
- name: OAuth2 Provider
- name: oauth
glob: tests/e2e/test_provider_oauth2* tests/e2e/test_source_oauth*
- name: OIDC Provider
- name: oauth-oidc
glob: tests/e2e/test_provider_oidc*
- name: SAML Provider
- name: saml
glob: tests/e2e/test_provider_saml* tests/e2e/test_source_saml*
- name: LDAP Provider
- name: ldap
glob: tests/e2e/test_provider_ldap* tests/e2e/test_source_ldap*
- name: RADIUS Provider
- name: radius
glob: tests/e2e/test_provider_radius*
- name: SCIM Source
- name: scim
glob: tests/e2e/test_source_scim*
- name: Flows
- name: flows
glob: tests/e2e/test_flows*
steps:
- uses: actions/checkout@v4
- name: Setup authentik env
uses: ./.github/actions/setup
- name: Setup E2E env (chrome, etc)
- name: Setup e2e env (chrome, etc)
run: |
docker compose -f tests/e2e/docker-compose.yml up -d --quiet-pull
- id: cache-web
@ -209,14 +201,14 @@ jobs:
with:
path: web/dist
key: ${{ runner.os }}-web-${{ hashFiles('web/package-lock.json', 'web/src/**') }}
- name: Prepare Web UI
- name: prepare web ui
if: steps.cache-web.outputs.cache-hit != 'true'
working-directory: web
run: |
npm ci
make -C .. gen-client-ts
npm run build
- name: Run E2E tests
- name: run e2e
run: |
uv run coverage run manage.py test ${{ matrix.job.glob }}
uv run coverage xml
@ -232,7 +224,6 @@ jobs:
file: unittest.xml
token: ${{ secrets.CODECOV_TOKEN }}
ci-core-mark:
name: CI Core Mark
if: always()
needs:
- lint
@ -247,7 +238,6 @@ jobs:
with:
jobs: ${{ toJSON(needs) }}
build:
name: Build
permissions:
# Needed to upload container images to ghcr.io
packages: write
@ -261,7 +251,6 @@ jobs:
image_name: ghcr.io/goauthentik/dev-server
release: false
pr-comment:
name: PR Comment
needs:
- build
runs-on: ubuntu-latest
@ -274,7 +263,7 @@ jobs:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Prepare variables
- name: prepare variables
uses: ./.github/actions/docker-push-variables
id: ev
env:

View File

@ -14,7 +14,6 @@ on:
jobs:
lint-golint:
name: Lint Go
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@ -27,7 +26,7 @@ jobs:
mkdir -p web/dist
mkdir -p website/help
touch web/dist/test website/help/test
- name: Generate Go API Client
- name: Generate API
run: make gen-client-go
- name: golangci-lint
uses: golangci/golangci-lint-action@v7
@ -36,7 +35,6 @@ jobs:
args: --timeout 5000s --verbose
skip-cache: true
test-unittest:
name: Unit Test Go
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@ -45,13 +43,12 @@ jobs:
go-version-file: "go.mod"
- name: Setup authentik env
uses: ./.github/actions/setup
- name: Generate Go API Client
- name: Generate API
run: make gen-client-go
- name: Go unittests
run: |
go test -timeout 0 -v -race -coverprofile=coverage.out -covermode=atomic -cover ./...
ci-outpost-mark:
name: CI Outpost Mark
if: always()
needs:
- lint-golint
@ -62,7 +59,6 @@ jobs:
with:
jobs: ${{ toJSON(needs) }}
build-container:
name: Build Container
timeout-minutes: 120
needs:
- ci-outpost-mark
@ -89,7 +85,7 @@ jobs:
uses: docker/setup-qemu-action@v3.6.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Prepare variables
- name: prepare variables
uses: ./.github/actions/docker-push-variables
id: ev
env:
@ -103,7 +99,7 @@ jobs:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Generate Go API Client
- name: Generate API
run: make gen-client-go
- name: Build Docker Image
id: push
@ -126,7 +122,6 @@ jobs:
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true
build-binary:
name: Build Binary
timeout-minutes: 120
needs:
- ci-outpost-mark
@ -145,6 +140,7 @@ jobs:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/setup-go@v5
with:
go-version-file: "go.mod"
- uses: actions/setup-node@v4
@ -152,7 +148,7 @@ jobs:
node-version-file: web/package.json
cache: "npm"
cache-dependency-path: web/package-lock.json
- name: Generate Go API Client
- name: Generate API
run: make gen-client-go
- name: Build web
working-directory: web/

View File

@ -13,7 +13,6 @@ on:
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
strategy:
fail-fast: false
@ -40,13 +39,12 @@ jobs:
- working-directory: ${{ matrix.project }}/
run: |
npm ci
- name: Generate TypeScript API
- name: Generate API
run: make gen-client-ts
- name: Lint
working-directory: ${{ matrix.project }}/
run: npm run ${{ matrix.command }}
build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@ -63,7 +61,6 @@ jobs:
working-directory: web/
run: npm run build
ci-web-mark:
name: CI Web Mark
if: always()
needs:
- build

View File

@ -13,7 +13,6 @@ on:
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
strategy:
fail-fast: false
@ -25,11 +24,10 @@ jobs:
- uses: actions/checkout@v4
- working-directory: website/
run: npm ci
- name: Lint ${{ matrix.command }}
- name: Lint
working-directory: website/
run: npm run ${{ matrix.command }}
test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@ -39,14 +37,18 @@ jobs:
cache: "npm"
cache-dependency-path: website/package-lock.json
- working-directory: website/
name: Install dependencies
run: npm ci
- name: Documentation test
- name: test
working-directory: website/
run: npm test
build:
name: Build Docs
runs-on: ubuntu-latest
name: ${{ matrix.job }}
strategy:
fail-fast: false
matrix:
job:
- build
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
@ -56,11 +58,10 @@ jobs:
cache-dependency-path: website/package-lock.json
- working-directory: website/
run: npm ci
- name: Build Docusaurus
- name: build
working-directory: website/
run: npm run build
run: npm run ${{ matrix.job }}
ci-website-mark:
name: Mark CI Website
if: always()
needs:
- lint

View File

@ -1,4 +1,4 @@
name: CodeQL
name: "CodeQL"
on:
push:

View File

@ -11,7 +11,6 @@ env:
jobs:
build:
name: Update WebAuthn MDS
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
runs-on: ubuntu-latest
steps:

View File

@ -12,7 +12,6 @@ permissions:
jobs:
cleanup:
name: Cleanup Cache
runs-on: ubuntu-latest
steps:
- name: Check out code

View File

@ -20,7 +20,7 @@ on:
jobs:
compress:
name: Compress Docker images
name: compress
runs-on: ubuntu-latest
# Don't run on forks. Token will not be available. Will run on main and open a PR anyway
if: |

View File

@ -25,17 +25,16 @@ jobs:
with:
fetch-depth: 2
- uses: actions/setup-node@v4
name: Setup Node.js
with:
node-version-file: packages/${{ matrix.package }}/package.json
registry-url: "https://registry.npmjs.org"
- name: Changed files (${{ matrix.package }})
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c
with:
files: |
packages/${{ matrix.package }}/package.json
- name: Publish package (${{ matrix.package }})
- name: Publish package
if: steps.changed-files.outputs.any_changed == 'true'
working-directory: packages/${{ matrix.package}}
run: |

View File

@ -12,7 +12,6 @@ env:
jobs:
publish-source-docs:
name: Publish
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
runs-on: ubuntu-latest
timeout-minutes: 120
@ -20,11 +19,11 @@ jobs:
- uses: actions/checkout@v4
- name: Setup authentik env
uses: ./.github/actions/setup
- name: Generate docs
- name: generate docs
run: |
uv run make migrate
uv run ak build_source_docs
- name: Deploy to Netlify
- name: Publish
uses: netlify/actions/cli@master
with:
args: deploy --dir=source_docs --prod

View File

@ -11,7 +11,6 @@ permissions:
jobs:
update-next:
name: Update Next Branch
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
runs-on: ubuntu-latest
environment: internal-production

View File

@ -7,7 +7,6 @@ on:
jobs:
build-server:
name: Build server
uses: ./.github/workflows/_reusable-docker-build.yaml
secrets: inherit
permissions:
@ -22,7 +21,6 @@ jobs:
registry_dockerhub: true
registry_ghcr: true
build-outpost:
name: Build outpost
runs-on: ubuntu-latest
permissions:
# Needed to upload container images to ghcr.io
@ -47,14 +45,14 @@ jobs:
uses: docker/setup-qemu-action@v3.6.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Prepare variables
- name: prepare variables
uses: ./.github/actions/docker-push-variables
id: ev
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
with:
image-name: ghcr.io/goauthentik/${{ matrix.type }},beryju/authentik-${{ matrix.type }}
- name: Make empty clients
- name: make empty clients
run: |
mkdir -p ./gen-ts-api
mkdir -p ./gen-go-api
@ -87,7 +85,6 @@ jobs:
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true
build-outpost-binary:
name: Build outpost binary
timeout-minutes: 120
runs-on: ubuntu-latest
permissions:
@ -132,7 +129,6 @@ jobs:
asset_name: authentik-outpost-${{ matrix.type }}_${{ matrix.goos }}_${{ matrix.goarch }}
tag: ${{ github.ref }}
upload-aws-cfn-template:
name: Upload AWS CloudFormation template
permissions:
# Needed for AWS login
id-token: write
@ -154,7 +150,6 @@ jobs:
aws s3 cp --acl=public-read lifecycle/aws/template.yaml s3://authentik-cloudformation-templates/authentik.ecs.${{ github.ref }}.yaml
aws s3 cp --acl=public-read lifecycle/aws/template.yaml s3://authentik-cloudformation-templates/authentik.ecs.latest.yaml
test-release:
name: Test release
needs:
- build-server
- build-outpost
@ -171,7 +166,6 @@ jobs:
docker compose start postgresql redis
docker compose run -u root server test-all
sentry-release:
name: Sentry release
needs:
- build-server
- build-outpost
@ -179,7 +173,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Prepare variables
- name: prepare variables
uses: ./.github/actions/docker-push-variables
id: ev
env:

View File

@ -20,7 +20,7 @@ jobs:
with:
app_id: ${{ secrets.GH_APP_ID }}
private_key: ${{ secrets.GH_APP_PRIVATE_KEY }}
- name: Prepare variables
- name: prepare variables
uses: ./.github/actions/docker-push-variables
id: ev
env:

View File

@ -4,7 +4,6 @@ on: [push, delete]
jobs:
to_internal:
name: Mirror to internal repository
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
runs-on: ubuntu-latest
steps:

View File

@ -11,7 +11,6 @@ permissions:
jobs:
stale:
name: Stale Issues
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
runs-on: ubuntu-latest
steps:

View File

@ -16,7 +16,6 @@ permissions:
jobs:
post-comment:
name: Post Comment
runs-on: ubuntu-latest
steps:
- name: Find Comment

View File

@ -16,7 +16,6 @@ env:
jobs:
compile:
name: Compile Translations
runs-on: ubuntu-latest
steps:
- id: generate_token
@ -33,12 +32,12 @@ jobs:
if: ${{ github.event_name == 'pull_request' }}
- name: Setup authentik env
uses: ./.github/actions/setup
- name: Generate TypeScript API
- name: Generate API
run: make gen-client-ts
- name: Extract Translations
- name: run extract
run: |
uv run make i18n-extract
- name: Compile Messages
- name: run compile
run: |
uv run ak compilemessages
make web-check-compile

View File

@ -12,7 +12,6 @@ permissions:
jobs:
rename_pr:
name: Rename PR
runs-on: ubuntu-latest
if: ${{ github.event.pull_request.user.login == 'transifex-integration[bot]'}}
steps:

View File

@ -94,7 +94,7 @@ RUN --mount=type=secret,id=GEOIPUPDATE_ACCOUNT_ID \
/bin/sh -c "/usr/bin/entry.sh || echo 'Failed to get GeoIP database, disabling'; exit 0"
# Stage 5: Download uv
FROM ghcr.io/astral-sh/uv:0.6.17 AS uv
FROM ghcr.io/astral-sh/uv:0.7.2 AS uv
# Stage 6: Base python image
FROM ghcr.io/goauthentik/fips-python:3.12.10-slim-bookworm-fips AS python-base

View File

@ -20,8 +20,8 @@ Even if the issue is not a CVE, we still greatly appreciate your help in hardeni
| Version | Supported |
| --------- | --------- |
| 2024.12.x | ✅ |
| 2025.2.x | ✅ |
| 2025.4.x | ✅ |
## Reporting a Vulnerability

View File

@ -2,7 +2,7 @@
from os import environ
__version__ = "2025.2.4"
__version__ = "2025.4.0"
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"

View File

@ -16,7 +16,7 @@ def migrate_custom_css(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
if not path.exists():
return
css = path.read_text()
Brand.objects.using(db_alias).update(branding_custom_css=css)
Brand.objects.using(db_alias).all().update(branding_custom_css=css)
class Migration(migrations.Migration):

File diff suppressed because one or more lines are too long

View File

@ -2,7 +2,7 @@
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "https://goauthentik.io/blueprints/schema.json",
"type": "object",
"title": "authentik 2025.2.4 Blueprint schema",
"title": "authentik 2025.4.0 Blueprint schema",
"required": [
"version",
"entries"

View File

@ -31,7 +31,7 @@ services:
volumes:
- redis:/data
server:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.2.4}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.4.0}
restart: unless-stopped
command: server
environment:
@ -55,7 +55,7 @@ services:
redis:
condition: service_healthy
worker:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.2.4}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.4.0}
restart: unless-stopped
command: worker
environment:

4
go.mod
View File

@ -21,13 +21,13 @@ require (
github.com/nmcclain/asn1-ber v0.0.0-20170104154839-2661553a0484
github.com/pires/go-proxyproto v0.8.0
github.com/prometheus/client_golang v1.22.0
github.com/redis/go-redis/v9 v9.7.3
github.com/redis/go-redis/v9 v9.8.0
github.com/sethvargo/go-envconfig v1.2.0
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.9.1
github.com/stretchr/testify v1.10.0
github.com/wwt/guac v1.3.2
goauthentik.io/api/v3 v3.2025024.9
goauthentik.io/api/v3 v3.2025040.1
golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab
golang.org/x/oauth2 v0.29.0
golang.org/x/sync v0.13.0

8
go.sum
View File

@ -245,8 +245,8 @@ github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0wM=
github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA=
github.com/redis/go-redis/v9 v9.8.0 h1:q3nRvjrlge/6UD7eTu/DSg2uYiU2mCL0G/uzBWqhicI=
github.com/redis/go-redis/v9 v9.8.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
@ -290,8 +290,8 @@ go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
goauthentik.io/api/v3 v3.2025024.9 h1:i3tbkyotE32ZpJ729BsPWTuLQUdtZ54Li4aP1amZzsM=
goauthentik.io/api/v3 v3.2025024.9/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw=
goauthentik.io/api/v3 v3.2025040.1 h1:rQEcMNpz84/LPX8LVFteOJuserrd4PnU4k1Iu/wWqhs=
goauthentik.io/api/v3 v3.2025040.1/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=

View File

@ -29,4 +29,4 @@ func UserAgent() string {
return fmt.Sprintf("authentik@%s", FullVersion())
}
const VERSION = "2025.2.4"
const VERSION = "2025.4.0"

View File

@ -9,7 +9,7 @@
"version": "0.0.0",
"license": "MIT",
"devDependencies": {
"aws-cdk": "^2.1012.0",
"aws-cdk": "^2.1013.0",
"cross-env": "^7.0.3"
},
"engines": {
@ -17,9 +17,9 @@
}
},
"node_modules/aws-cdk": {
"version": "2.1012.0",
"resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1012.0.tgz",
"integrity": "sha512-C6jSWkqP0hkY2Cs300VJHjspmTXDTMfB813kwZvRbd/OsKBfTBJBbYU16VoLAp1LVEOnQMf8otSlaSgzVF0X9A==",
"version": "2.1013.0",
"resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1013.0.tgz",
"integrity": "sha512-cbq4cOoEIZueMWenGgfI4RujS+AQ9GaMCTlW/3CnvEIhMD8j/tgZx7PTtgMuvwYrRoEeb/wTxgLPgUd5FhsoHA==",
"dev": true,
"license": "Apache-2.0",
"bin": {

View File

@ -10,7 +10,7 @@
"node": ">=20"
},
"devDependencies": {
"aws-cdk": "^2.1012.0",
"aws-cdk": "^2.1013.0",
"cross-env": "^7.0.3"
}
}

View File

@ -26,7 +26,7 @@ Parameters:
Description: authentik Docker image
AuthentikVersion:
Type: String
Default: 2025.2.4
Default: 2025.4.0
Description: authentik Docker image tag
AuthentikServerCPU:
Type: Number

Binary file not shown.

View File

@ -12,8 +12,8 @@
# tmassimi, 2024
# Marc Schmitt, 2024
# albanobattistella <albanobattistella@gmail.com>, 2024
# Kowalski Dragon (kowalski7cc) <kowalski.7cc@gmail.com>, 2025
# Matteo Piccina <altermatte@gmail.com>, 2025
# Kowalski Dragon (kowalski7cc) <kowalski.7cc@gmail.com>, 2025
#
#, fuzzy
msgid ""
@ -22,7 +22,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-23 09:00+0000\n"
"PO-Revision-Date: 2022-09-26 16:47+0000\n"
"Last-Translator: Matteo Piccina <altermatte@gmail.com>, 2025\n"
"Last-Translator: Kowalski Dragon (kowalski7cc) <kowalski.7cc@gmail.com>, 2025\n"
"Language-Team: Italian (https://app.transifex.com/authentik/teams/119923/it/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -383,7 +383,7 @@ msgstr "Mappatura delle proprietà"
#: authentik/core/models.py
msgid "session data"
msgstr ""
msgstr "dati sessione"
#: authentik/core/models.py
msgid "Session"
@ -509,7 +509,7 @@ msgstr ""
#: authentik/enterprise/policies/unique_password/models.py
msgid "Number of passwords to check against."
msgstr ""
msgstr "Numero di password da verificare."
#: authentik/enterprise/policies/unique_password/models.py
#: authentik/policies/password/models.py
@ -519,18 +519,19 @@ msgstr "Password non impostata nel contesto"
#: authentik/enterprise/policies/unique_password/models.py
msgid "This password has been used previously. Please choose a different one."
msgstr ""
"Questa password è già stata utilizzata in precedenza. Scegline una diversa."
#: authentik/enterprise/policies/unique_password/models.py
msgid "Password Uniqueness Policy"
msgstr ""
msgstr "Politica di unicità della password"
#: authentik/enterprise/policies/unique_password/models.py
msgid "Password Uniqueness Policies"
msgstr ""
msgstr "Criteri di unicità delle password"
#: authentik/enterprise/policies/unique_password/models.py
msgid "User Password History"
msgstr ""
msgstr "Cronologia password utente"
#: authentik/enterprise/policy.py
msgid "Enterprise required to access this feature."
@ -2203,7 +2204,7 @@ msgstr "Ruoli"
#: authentik/rbac/models.py
msgid "Initial Permissions"
msgstr ""
msgstr "Permessi Iniziali"
#: authentik/rbac/models.py
msgid "System permission"
@ -2458,6 +2459,9 @@ msgid ""
"attribute. This allows nested group resolution on systems like FreeIPA and "
"Active Directory"
msgstr ""
"Cerca l'appartenenza al gruppo in base a un attributo utente anziché a un "
"attributo di gruppo. Questo consente la risoluzione di gruppi nidificati su "
"sistemi come FreeIPA e Active Directory."
#: authentik/sources/ldap/models.py
msgid "LDAP Source"
@ -2477,19 +2481,19 @@ msgstr "Mappature delle proprietà della sorgente LDAP"
#: authentik/sources/ldap/models.py
msgid "User LDAP Source Connection"
msgstr ""
msgstr "Connessione Sorgente LDAP Utente"
#: authentik/sources/ldap/models.py
msgid "User LDAP Source Connections"
msgstr ""
msgstr "Connessioni Sorgente LDAP Utente"
#: authentik/sources/ldap/models.py
msgid "Group LDAP Source Connection"
msgstr ""
msgstr "Connessione Sorgente LDAP Gruppo"
#: authentik/sources/ldap/models.py
msgid "Group LDAP Source Connections"
msgstr ""
msgstr "Connessioni Sorgente LDAP Gruppo"
#: authentik/sources/ldap/signals.py
msgid "Password does not match Active Directory Complexity."
@ -2501,11 +2505,11 @@ msgstr "Nessun token ricevuto."
#: authentik/sources/oauth/models.py
msgid "HTTP Basic Authentication"
msgstr ""
msgstr "HTTP Basic Authentication"
#: authentik/sources/oauth/models.py
msgid "Include the client ID and secret as request parameters"
msgstr ""
msgstr "Includi il client ID e il segreto come parametri di richiesta"
#: authentik/sources/oauth/models.py
msgid "Request Token URL"
@ -2552,6 +2556,8 @@ msgid ""
"How to perform authentication during an authorization_code token request "
"flow"
msgstr ""
"Come eseguire l'autenticazione durante un flusso di richiesta del token "
"authorization_code"
#: authentik/sources/oauth/models.py
msgid "OAuth Source"
@ -3484,6 +3490,9 @@ msgid ""
"Show the user the 'Remember me on this device' toggle, allowing repeat users"
" to skip straight to entering their password."
msgstr ""
"Mostra all'utente il pulsante \"Ricordami su questo dispositivo\", "
"consentendo agli utenti abituali di passare direttamente all'inserimento "
"della password."
#: authentik/stages/identification/models.py
msgid "Optional enrollment flow, which is linked at the bottom of the page."
@ -3873,11 +3882,11 @@ msgstr ""
#: authentik/tenants/models.py
msgid "Reputation cannot decrease lower than this value. Zero or negative."
msgstr ""
msgstr "La reputazione non può scendere sotto questo valore. Zero o negativo."
#: authentik/tenants/models.py
msgid "Reputation cannot increase higher than this value. Zero or positive."
msgstr ""
msgstr "La reputazione non può superare questo valore. Zero o positivo."
#: authentik/tenants/models.py
msgid "The option configures the footer links on the flow executor pages."

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,5 +1,5 @@
{
"name": "@goauthentik/authentik",
"version": "2025.2.4",
"version": "2025.4.0",
"private": true
}

View File

@ -1,19 +0,0 @@
{
"name": "@goauthentik/monorepo",
"version": "1.0.0",
"description": "Utilities for the authentik monorepo.",
"private": true,
"license": "MIT",
"type": "module",
"exports": {
"./package.json": "./package.json",
".": {
"import": "./index.js",
"types": "./out/index.d.ts"
}
},
"types": "./out/index.d.ts",
"engines": {
"node": ">=20.11"
}
}

View File

@ -1,30 +0,0 @@
import { createRequire } from "node:module";
import { dirname, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";
const __dirname = dirname(fileURLToPath(import.meta.url));
/**
* @typedef {'~authentik'} MonoRepoRoot
*/
/**
* The root of the authentik monorepo.
*/
export const MonoRepoRoot = /** @type {MonoRepoRoot} */ (resolve(__dirname, "..", ".."));
const require = createRequire(import.meta.url);
/**
* Resolve a package name to its location in the monorepo to the single node_modules directory.
* @param {string} packageName
* @returns {string} The resolved path to the package.
* @throws {Error} If the package cannot be resolved.
*/
export function resolvePackage(packageName) {
const packageJSONPath = require.resolve(join(packageName, "package.json"), {
paths: [MonoRepoRoot],
});
return dirname(packageJSONPath);
}

View File

@ -1,6 +1,6 @@
[project]
name = "authentik"
version = "2025.2.4"
version = "2025.4.0"
description = ""
authors = [{ name = "authentik Team", email = "hello@goauthentik.io" }]
requires-python = "==3.12.*"

View File

@ -1,7 +1,7 @@
openapi: 3.0.3
info:
title: authentik
version: 2025.2.4
version: 2025.4.0
description: Making authentication simple.
contact:
email: hello@goauthentik.io

156
uv.lock generated
View File

@ -13,7 +13,7 @@ wheels = [
[[package]]
name = "aiohttp"
version = "3.11.16"
version = "3.11.18"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "aiohappyeyeballs" },
@ -24,24 +24,24 @@ dependencies = [
{ name = "propcache" },
{ name = "yarl" },
]
sdist = { url = "https://files.pythonhosted.org/packages/f1/d9/1c4721d143e14af753f2bf5e3b681883e1f24b592c0482df6fa6e33597fa/aiohttp-3.11.16.tar.gz", hash = "sha256:16f8a2c9538c14a557b4d309ed4d0a7c60f0253e8ed7b6c9a2859a7582f8b1b8", size = 7676826 }
sdist = { url = "https://files.pythonhosted.org/packages/63/e7/fa1a8c00e2c54b05dc8cb5d1439f627f7c267874e3f7bb047146116020f9/aiohttp-3.11.18.tar.gz", hash = "sha256:ae856e1138612b7e412db63b7708735cff4d38d0399f6a5435d3dac2669f558a", size = 7678653 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/db/38/100d01cbc60553743baf0fba658cb125f8ad674a8a771f765cdc155a890d/aiohttp-3.11.16-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:911a6e91d08bb2c72938bc17f0a2d97864c531536b7832abee6429d5296e5b27", size = 704881 },
{ url = "https://files.pythonhosted.org/packages/21/ed/b4102bb6245e36591209e29f03fe87e7956e54cb604ee12e20f7eb47f994/aiohttp-3.11.16-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6ac13b71761e49d5f9e4d05d33683bbafef753e876e8e5a7ef26e937dd766713", size = 464564 },
{ url = "https://files.pythonhosted.org/packages/3b/e1/a9ab6c47b62ecee080eeb33acd5352b40ecad08fb2d0779bcc6739271745/aiohttp-3.11.16-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fd36c119c5d6551bce374fcb5c19269638f8d09862445f85a5a48596fd59f4bb", size = 456548 },
{ url = "https://files.pythonhosted.org/packages/80/ad/216c6f71bdff2becce6c8776f0aa32cb0fa5d83008d13b49c3208d2e4016/aiohttp-3.11.16-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d489d9778522fbd0f8d6a5c6e48e3514f11be81cb0a5954bdda06f7e1594b321", size = 1691749 },
{ url = "https://files.pythonhosted.org/packages/bd/ea/7df7bcd3f4e734301605f686ffc87993f2d51b7acb6bcc9b980af223f297/aiohttp-3.11.16-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:69a2cbd61788d26f8f1e626e188044834f37f6ae3f937bd9f08b65fc9d7e514e", size = 1736874 },
{ url = "https://files.pythonhosted.org/packages/51/41/c7724b9c87a29b7cfd1202ec6446bae8524a751473d25e2ff438bc9a02bf/aiohttp-3.11.16-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd464ba806e27ee24a91362ba3621bfc39dbbb8b79f2e1340201615197370f7c", size = 1786885 },
{ url = "https://files.pythonhosted.org/packages/86/b3/f61f8492fa6569fa87927ad35a40c159408862f7e8e70deaaead349e2fba/aiohttp-3.11.16-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ce63ae04719513dd2651202352a2beb9f67f55cb8490c40f056cea3c5c355ce", size = 1698059 },
{ url = "https://files.pythonhosted.org/packages/ce/be/7097cf860a9ce8bbb0e8960704e12869e111abcd3fbd245153373079ccec/aiohttp-3.11.16-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09b00dd520d88eac9d1768439a59ab3d145065c91a8fab97f900d1b5f802895e", size = 1626527 },
{ url = "https://files.pythonhosted.org/packages/1d/1d/aaa841c340e8c143a8d53a1f644c2a2961c58cfa26e7b398d6bf75cf5d23/aiohttp-3.11.16-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7f6428fee52d2bcf96a8aa7b62095b190ee341ab0e6b1bcf50c615d7966fd45b", size = 1644036 },
{ url = "https://files.pythonhosted.org/packages/2c/88/59d870f76e9345e2b149f158074e78db457985c2b4da713038d9da3020a8/aiohttp-3.11.16-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:13ceac2c5cdcc3f64b9015710221ddf81c900c5febc505dbd8f810e770011540", size = 1685270 },
{ url = "https://files.pythonhosted.org/packages/2b/b1/c6686948d4c79c3745595efc469a9f8a43cab3c7efc0b5991be65d9e8cb8/aiohttp-3.11.16-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:fadbb8f1d4140825069db3fedbbb843290fd5f5bc0a5dbd7eaf81d91bf1b003b", size = 1650852 },
{ url = "https://files.pythonhosted.org/packages/fe/94/3e42a6916fd3441721941e0f1b8438e1ce2a4c49af0e28e0d3c950c9b3c9/aiohttp-3.11.16-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:6a792ce34b999fbe04a7a71a90c74f10c57ae4c51f65461a411faa70e154154e", size = 1704481 },
{ url = "https://files.pythonhosted.org/packages/b1/6d/6ab5854ff59b27075c7a8c610597d2b6c38945f9a1284ee8758bc3720ff6/aiohttp-3.11.16-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:f4065145bf69de124accdd17ea5f4dc770da0a6a6e440c53f6e0a8c27b3e635c", size = 1735370 },
{ url = "https://files.pythonhosted.org/packages/73/2a/08a68eec3c99a6659067d271d7553e4d490a0828d588e1daa3970dc2b771/aiohttp-3.11.16-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fa73e8c2656a3653ae6c307b3f4e878a21f87859a9afab228280ddccd7369d71", size = 1697619 },
{ url = "https://files.pythonhosted.org/packages/61/d5/fea8dbbfb0cd68fbb56f0ae913270a79422d9a41da442a624febf72d2aaf/aiohttp-3.11.16-cp312-cp312-win32.whl", hash = "sha256:f244b8e541f414664889e2c87cac11a07b918cb4b540c36f7ada7bfa76571ea2", size = 411710 },
{ url = "https://files.pythonhosted.org/packages/33/fb/41cde15fbe51365024550bf77b95a4fc84ef41365705c946da0421f0e1e0/aiohttp-3.11.16-cp312-cp312-win_amd64.whl", hash = "sha256:23a15727fbfccab973343b6d1b7181bfb0b4aa7ae280f36fd2f90f5476805682", size = 438012 },
{ url = "https://files.pythonhosted.org/packages/b5/d2/5bc436f42bf4745c55f33e1e6a2d69e77075d3e768e3d1a34f96ee5298aa/aiohttp-3.11.18-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:63d71eceb9cad35d47d71f78edac41fcd01ff10cacaa64e473d1aec13fa02df2", size = 706671 },
{ url = "https://files.pythonhosted.org/packages/fe/d0/2dbabecc4e078c0474abb40536bbde717fb2e39962f41c5fc7a216b18ea7/aiohttp-3.11.18-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d1929da615840969929e8878d7951b31afe0bac883d84418f92e5755d7b49508", size = 466169 },
{ url = "https://files.pythonhosted.org/packages/70/84/19edcf0b22933932faa6e0be0d933a27bd173da02dc125b7354dff4d8da4/aiohttp-3.11.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7d0aebeb2392f19b184e3fdd9e651b0e39cd0f195cdb93328bd124a1d455cd0e", size = 457554 },
{ url = "https://files.pythonhosted.org/packages/32/d0/e8d1f034ae5624a0f21e4fb3feff79342ce631f3a4d26bd3e58b31ef033b/aiohttp-3.11.18-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3849ead845e8444f7331c284132ab314b4dac43bfae1e3cf350906d4fff4620f", size = 1690154 },
{ url = "https://files.pythonhosted.org/packages/16/de/2f9dbe2ac6f38f8495562077131888e0d2897e3798a0ff3adda766b04a34/aiohttp-3.11.18-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5e8452ad6b2863709f8b3d615955aa0807bc093c34b8e25b3b52097fe421cb7f", size = 1733402 },
{ url = "https://files.pythonhosted.org/packages/e0/04/bd2870e1e9aef990d14b6df2a695f17807baf5c85a4c187a492bda569571/aiohttp-3.11.18-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b8d2b42073611c860a37f718b3d61ae8b4c2b124b2e776e2c10619d920350ec", size = 1783958 },
{ url = "https://files.pythonhosted.org/packages/23/06/4203ffa2beb5bedb07f0da0f79b7d9039d1c33f522e0d1a2d5b6218e6f2e/aiohttp-3.11.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40fbf91f6a0ac317c0a07eb328a1384941872f6761f2e6f7208b63c4cc0a7ff6", size = 1695288 },
{ url = "https://files.pythonhosted.org/packages/30/b2/e2285dda065d9f29ab4b23d8bcc81eb881db512afb38a3f5247b191be36c/aiohttp-3.11.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ff5625413fec55216da5eaa011cf6b0a2ed67a565914a212a51aa3755b0009", size = 1618871 },
{ url = "https://files.pythonhosted.org/packages/57/e0/88f2987885d4b646de2036f7296ebea9268fdbf27476da551c1a7c158bc0/aiohttp-3.11.18-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7f33a92a2fde08e8c6b0c61815521324fc1612f397abf96eed86b8e31618fdb4", size = 1646262 },
{ url = "https://files.pythonhosted.org/packages/e0/19/4d2da508b4c587e7472a032290b2981f7caeca82b4354e19ab3df2f51d56/aiohttp-3.11.18-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:11d5391946605f445ddafda5eab11caf310f90cdda1fd99865564e3164f5cff9", size = 1677431 },
{ url = "https://files.pythonhosted.org/packages/eb/ae/047473ea50150a41440f3265f53db1738870b5a1e5406ece561ca61a3bf4/aiohttp-3.11.18-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3cc314245deb311364884e44242e00c18b5896e4fe6d5f942e7ad7e4cb640adb", size = 1637430 },
{ url = "https://files.pythonhosted.org/packages/11/32/c6d1e3748077ce7ee13745fae33e5cb1dac3e3b8f8787bf738a93c94a7d2/aiohttp-3.11.18-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0f421843b0f70740772228b9e8093289924359d306530bcd3926f39acbe1adda", size = 1703342 },
{ url = "https://files.pythonhosted.org/packages/c5/1d/a3b57bfdbe285f0d45572d6d8f534fd58761da3e9cbc3098372565005606/aiohttp-3.11.18-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e220e7562467dc8d589e31c1acd13438d82c03d7f385c9cd41a3f6d1d15807c1", size = 1740600 },
{ url = "https://files.pythonhosted.org/packages/a5/71/f9cd2fed33fa2b7ce4d412fb7876547abb821d5b5520787d159d0748321d/aiohttp-3.11.18-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ab2ef72f8605046115bc9aa8e9d14fd49086d405855f40b79ed9e5c1f9f4faea", size = 1695131 },
{ url = "https://files.pythonhosted.org/packages/97/97/d1248cd6d02b9de6aa514793d0dcb20099f0ec47ae71a933290116c070c5/aiohttp-3.11.18-cp312-cp312-win32.whl", hash = "sha256:12a62691eb5aac58d65200c7ae94d73e8a65c331c3a86a2e9670927e94339ee8", size = 412442 },
{ url = "https://files.pythonhosted.org/packages/33/9a/e34e65506e06427b111e19218a99abf627638a9703f4b8bcc3e3021277ed/aiohttp-3.11.18-cp312-cp312-win_amd64.whl", hash = "sha256:364329f319c499128fd5cd2d1c31c44f234c58f9b96cc57f743d16ec4f3238c8", size = 439444 },
]
[[package]]
@ -165,7 +165,7 @@ wheels = [
[[package]]
name = "authentik"
version = "2025.2.4"
version = "2025.4.0"
source = { editable = "." }
dependencies = [
{ name = "argon2-cffi" },
@ -558,30 +558,30 @@ wheels = [
[[package]]
name = "boto3"
version = "1.37.35"
version = "1.37.38"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "botocore" },
{ name = "jmespath" },
{ name = "s3transfer" },
]
sdist = { url = "https://files.pythonhosted.org/packages/48/5f/e356ecd2f236e6ddc7711eaf3f075c15b13e2d044cfdb47719d49c4ae7dd/boto3-1.37.35.tar.gz", hash = "sha256:751ed599c8fd9ca24896edcd6620e8a32b3db1b68efea3a90126312240e668a2", size = 111640 }
sdist = { url = "https://files.pythonhosted.org/packages/0d/b5/d1c2e8c484cea43891629bbab6ca90ce9ca932586750bc0e786c8f096ccf/boto3-1.37.38.tar.gz", hash = "sha256:88c02910933ab7777597d1ca7c62375f52822e0aa1a8e0c51b2598a547af42b2", size = 111623 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/f6/e4/00958f65ac74ab0a76af33f16c8fdf5726a5c6f0d3c0d0c058ff0dd00fd7/boto3-1.37.35-py3-none-any.whl", hash = "sha256:5a90d674830adbaf86456d6b27a18f5f11378277da5286511fa860d2e7b14261", size = 139922 },
{ url = "https://files.pythonhosted.org/packages/d3/87/8189f22ee798177bc7b40afd13f046442c5f91b699e70a950b42ff447e80/boto3-1.37.38-py3-none-any.whl", hash = "sha256:b6d42803607148804dff82389757827a24ce9271f0583748853934c86310999f", size = 139922 },
]
[[package]]
name = "botocore"
version = "1.37.35"
version = "1.37.38"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "jmespath" },
{ name = "python-dateutil" },
{ name = "urllib3" },
]
sdist = { url = "https://files.pythonhosted.org/packages/64/0b/d281d74d53f7d4733402aed7a536275084fa344a2672f7ea4dbc8ebe1f1b/botocore-1.37.35.tar.gz", hash = "sha256:197a9bf8251c45b9d882c405ec0d0ab40c10e2d2a55ee66960185daec4beb6ec", size = 13821053 }
sdist = { url = "https://files.pythonhosted.org/packages/34/79/4e072e614339727f79afef704e5993b5b4d2667c1671c757cc4deb954744/botocore-1.37.38.tar.gz", hash = "sha256:c3ea386177171f2259b284db6afc971c959ec103fa2115911c4368bea7cbbc5d", size = 13832365 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/22/00/bf9c894f5af8e35b06ecf757d4a95883408e71c48642dc7f8760580584fd/botocore-1.37.35-py3-none-any.whl", hash = "sha256:50839212e90650d0b0fa6b8f7514876bf802f6164f2775f3abcd4d53c98bb73c", size = 13485892 },
{ url = "https://files.pythonhosted.org/packages/55/1b/93f3504afc7c523dcaa8a8147cfc75421983e30b08d9f93a533929589630/botocore-1.37.38-py3-none-any.whl", hash = "sha256:23b4097780e156a4dcaadfc1ed156ce25cb95b6087d010c4bb7f7f5d9bc9d219", size = 13499391 },
]
[[package]]
@ -1279,26 +1279,28 @@ wheels = [
[[package]]
name = "frozenlist"
version = "1.5.0"
version = "1.6.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/8f/ed/0f4cec13a93c02c47ec32d81d11c0c1efbadf4a471e3f3ce7cad366cbbd3/frozenlist-1.5.0.tar.gz", hash = "sha256:81d5af29e61b9c8348e876d442253723928dce6433e0e76cd925cd83f1b4b817", size = 39930 }
sdist = { url = "https://files.pythonhosted.org/packages/ee/f4/d744cba2da59b5c1d88823cf9e8a6c74e4659e2b27604ed973be2a0bf5ab/frozenlist-1.6.0.tar.gz", hash = "sha256:b99655c32c1c8e06d111e7f41c06c29a5318cb1835df23a45518e02a47c63b68", size = 42831 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/79/73/fa6d1a96ab7fd6e6d1c3500700963eab46813847f01ef0ccbaa726181dd5/frozenlist-1.5.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:31115ba75889723431aa9a4e77d5f398f5cf976eea3bdf61749731f62d4a4a21", size = 94026 },
{ url = "https://files.pythonhosted.org/packages/ab/04/ea8bf62c8868b8eada363f20ff1b647cf2e93377a7b284d36062d21d81d1/frozenlist-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7437601c4d89d070eac8323f121fcf25f88674627505334654fd027b091db09d", size = 54150 },
{ url = "https://files.pythonhosted.org/packages/d0/9a/8e479b482a6f2070b26bda572c5e6889bb3ba48977e81beea35b5ae13ece/frozenlist-1.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7948140d9f8ece1745be806f2bfdf390127cf1a763b925c4a805c603df5e697e", size = 51927 },
{ url = "https://files.pythonhosted.org/packages/e3/12/2aad87deb08a4e7ccfb33600871bbe8f0e08cb6d8224371387f3303654d7/frozenlist-1.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:feeb64bc9bcc6b45c6311c9e9b99406660a9c05ca8a5b30d14a78555088b0b3a", size = 282647 },
{ url = "https://files.pythonhosted.org/packages/77/f2/07f06b05d8a427ea0060a9cef6e63405ea9e0d761846b95ef3fb3be57111/frozenlist-1.5.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:683173d371daad49cffb8309779e886e59c2f369430ad28fe715f66d08d4ab1a", size = 289052 },
{ url = "https://files.pythonhosted.org/packages/bd/9f/8bf45a2f1cd4aa401acd271b077989c9267ae8463e7c8b1eb0d3f561b65e/frozenlist-1.5.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7d57d8f702221405a9d9b40f9da8ac2e4a1a8b5285aac6100f3393675f0a85ee", size = 291719 },
{ url = "https://files.pythonhosted.org/packages/41/d1/1f20fd05a6c42d3868709b7604c9f15538a29e4f734c694c6bcfc3d3b935/frozenlist-1.5.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30c72000fbcc35b129cb09956836c7d7abf78ab5416595e4857d1cae8d6251a6", size = 267433 },
{ url = "https://files.pythonhosted.org/packages/af/f2/64b73a9bb86f5a89fb55450e97cd5c1f84a862d4ff90d9fd1a73ab0f64a5/frozenlist-1.5.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:000a77d6034fbad9b6bb880f7ec073027908f1b40254b5d6f26210d2dab1240e", size = 283591 },
{ url = "https://files.pythonhosted.org/packages/29/e2/ffbb1fae55a791fd6c2938dd9ea779509c977435ba3940b9f2e8dc9d5316/frozenlist-1.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5d7f5a50342475962eb18b740f3beecc685a15b52c91f7d975257e13e029eca9", size = 273249 },
{ url = "https://files.pythonhosted.org/packages/2e/6e/008136a30798bb63618a114b9321b5971172a5abddff44a100c7edc5ad4f/frozenlist-1.5.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:87f724d055eb4785d9be84e9ebf0f24e392ddfad00b3fe036e43f489fafc9039", size = 271075 },
{ url = "https://files.pythonhosted.org/packages/ae/f0/4e71e54a026b06724cec9b6c54f0b13a4e9e298cc8db0f82ec70e151f5ce/frozenlist-1.5.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:6e9080bb2fb195a046e5177f10d9d82b8a204c0736a97a153c2466127de87784", size = 285398 },
{ url = "https://files.pythonhosted.org/packages/4d/36/70ec246851478b1c0b59f11ef8ade9c482ff447c1363c2bd5fad45098b12/frozenlist-1.5.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9b93d7aaa36c966fa42efcaf716e6b3900438632a626fb09c049f6a2f09fc631", size = 294445 },
{ url = "https://files.pythonhosted.org/packages/37/e0/47f87544055b3349b633a03c4d94b405956cf2437f4ab46d0928b74b7526/frozenlist-1.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:52ef692a4bc60a6dd57f507429636c2af8b6046db8b31b18dac02cbc8f507f7f", size = 280569 },
{ url = "https://files.pythonhosted.org/packages/f9/7c/490133c160fb6b84ed374c266f42800e33b50c3bbab1652764e6e1fc498a/frozenlist-1.5.0-cp312-cp312-win32.whl", hash = "sha256:29d94c256679247b33a3dc96cce0f93cbc69c23bf75ff715919332fdbb6a32b8", size = 44721 },
{ url = "https://files.pythonhosted.org/packages/b1/56/4e45136ffc6bdbfa68c29ca56ef53783ef4c2fd395f7cbf99a2624aa9aaa/frozenlist-1.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:8969190d709e7c48ea386db202d708eb94bdb29207a1f269bab1196ce0dcca1f", size = 51329 },
{ url = "https://files.pythonhosted.org/packages/c6/c8/a5be5b7550c10858fcf9b0ea054baccab474da77d37f1e828ce043a3a5d4/frozenlist-1.5.0-py3-none-any.whl", hash = "sha256:d994863bba198a4a518b467bb971c56e1db3f180a25c6cf7bb1949c267f748c3", size = 11901 },
{ url = "https://files.pythonhosted.org/packages/9c/8a/289b7d0de2fbac832ea80944d809759976f661557a38bb8e77db5d9f79b7/frozenlist-1.6.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:c5b9e42ace7d95bf41e19b87cec8f262c41d3510d8ad7514ab3862ea2197bfb1", size = 160193 },
{ url = "https://files.pythonhosted.org/packages/19/80/2fd17d322aec7f430549f0669f599997174f93ee17929ea5b92781ec902c/frozenlist-1.6.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ca9973735ce9f770d24d5484dcb42f68f135351c2fc81a7a9369e48cf2998a29", size = 123831 },
{ url = "https://files.pythonhosted.org/packages/99/06/f5812da431273f78c6543e0b2f7de67dfd65eb0a433978b2c9c63d2205e4/frozenlist-1.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6ac40ec76041c67b928ca8aaffba15c2b2ee3f5ae8d0cb0617b5e63ec119ca25", size = 121862 },
{ url = "https://files.pythonhosted.org/packages/d0/31/9e61c6b5fc493cf24d54881731204d27105234d09878be1a5983182cc4a5/frozenlist-1.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95b7a8a3180dfb280eb044fdec562f9b461614c0ef21669aea6f1d3dac6ee576", size = 316361 },
{ url = "https://files.pythonhosted.org/packages/9d/55/22ca9362d4f0222324981470fd50192be200154d51509ee6eb9baa148e96/frozenlist-1.6.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c444d824e22da6c9291886d80c7d00c444981a72686e2b59d38b285617cb52c8", size = 307115 },
{ url = "https://files.pythonhosted.org/packages/ae/39/4fff42920a57794881e7bb3898dc7f5f539261711ea411b43bba3cde8b79/frozenlist-1.6.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb52c8166499a8150bfd38478248572c924c003cbb45fe3bcd348e5ac7c000f9", size = 322505 },
{ url = "https://files.pythonhosted.org/packages/55/f2/88c41f374c1e4cf0092a5459e5f3d6a1e17ed274c98087a76487783df90c/frozenlist-1.6.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b35298b2db9c2468106278537ee529719228950a5fdda686582f68f247d1dc6e", size = 322666 },
{ url = "https://files.pythonhosted.org/packages/75/51/034eeb75afdf3fd03997856195b500722c0b1a50716664cde64e28299c4b/frozenlist-1.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d108e2d070034f9d57210f22fefd22ea0d04609fc97c5f7f5a686b3471028590", size = 302119 },
{ url = "https://files.pythonhosted.org/packages/2b/a6/564ecde55ee633270a793999ef4fd1d2c2b32b5a7eec903b1012cb7c5143/frozenlist-1.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e1be9111cb6756868ac242b3c2bd1f09d9aea09846e4f5c23715e7afb647103", size = 316226 },
{ url = "https://files.pythonhosted.org/packages/f1/c8/6c0682c32377f402b8a6174fb16378b683cf6379ab4d2827c580892ab3c7/frozenlist-1.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:94bb451c664415f02f07eef4ece976a2c65dcbab9c2f1705b7031a3a75349d8c", size = 312788 },
{ url = "https://files.pythonhosted.org/packages/b6/b8/10fbec38f82c5d163ca1750bfff4ede69713badf236a016781cf1f10a0f0/frozenlist-1.6.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d1a686d0b0949182b8faddea596f3fc11f44768d1f74d4cad70213b2e139d821", size = 325914 },
{ url = "https://files.pythonhosted.org/packages/62/ca/2bf4f3a1bd40cdedd301e6ecfdbb291080d5afc5f9ce350c0739f773d6b9/frozenlist-1.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ea8e59105d802c5a38bdbe7362822c522230b3faba2aa35c0fa1765239b7dd70", size = 305283 },
{ url = "https://files.pythonhosted.org/packages/09/64/20cc13ccf94abc2a1f482f74ad210703dc78a590d0b805af1c9aa67f76f9/frozenlist-1.6.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:abc4e880a9b920bc5020bf6a431a6bb40589d9bca3975c980495f63632e8382f", size = 319264 },
{ url = "https://files.pythonhosted.org/packages/20/ff/86c6a2bbe98cfc231519f5e6d712a0898488ceac804a917ce014f32e68f6/frozenlist-1.6.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9a79713adfe28830f27a3c62f6b5406c37376c892b05ae070906f07ae4487046", size = 326482 },
{ url = "https://files.pythonhosted.org/packages/2f/da/8e381f66367d79adca245d1d71527aac774e30e291d41ef161ce2d80c38e/frozenlist-1.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9a0318c2068e217a8f5e3b85e35899f5a19e97141a45bb925bb357cfe1daf770", size = 318248 },
{ url = "https://files.pythonhosted.org/packages/39/24/1a1976563fb476ab6f0fa9fefaac7616a4361dbe0461324f9fd7bf425dbe/frozenlist-1.6.0-cp312-cp312-win32.whl", hash = "sha256:853ac025092a24bb3bf09ae87f9127de9fe6e0c345614ac92536577cf956dfcc", size = 115161 },
{ url = "https://files.pythonhosted.org/packages/80/2e/fb4ed62a65f8cd66044706b1013f0010930d8cbb0729a2219561ea075434/frozenlist-1.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:2bdfe2d7e6c9281c6e55523acd6c2bf77963cb422fdc7d142fb0cb6621b66878", size = 120548 },
{ url = "https://files.pythonhosted.org/packages/71/3e/b04a0adda73bd52b390d730071c0d577073d3d26740ee1bad25c3ad0f37b/frozenlist-1.6.0-py3-none-any.whl", hash = "sha256:535eec9987adb04701266b92745d6cdcef2e77669299359c3009c3404dd5d191", size = 12404 },
]
[[package]]
@ -2158,11 +2160,11 @@ wheels = [
[[package]]
name = "packaging"
version = "24.2"
version = "25.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 }
sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 },
{ url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469 },
]
[[package]]
@ -2202,16 +2204,16 @@ wheels = [
[[package]]
name = "pdoc"
version = "15.0.1"
version = "15.0.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "jinja2" },
{ name = "markupsafe" },
{ name = "pygments" },
]
sdist = { url = "https://files.pythonhosted.org/packages/bf/16/1b542af6f18a27de059f722c487a596681127897b6d31f78e46d6e5bf2fe/pdoc-15.0.1.tar.gz", hash = "sha256:3b08382c9d312243ee6c2a1813d0ff517a6ab84d596fa2c6c6b5255b17c3d666", size = 154174 }
sdist = { url = "https://files.pythonhosted.org/packages/9f/e9/66ab0fc39276a1818dea6302858ec9558964d8d9f1c90dd1facfe395d216/pdoc-15.0.3.tar.gz", hash = "sha256:6482d8ebbd40185fea5e6aec2f1592f4be92e93cf6bf70b9e2a00378bbaf3252", size = 155384 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/2f/4d/60d856a1b12fbf6ac1539efccfa138e57c6b88675c9867d84bbb46455cc1/pdoc-15.0.1-py3-none-any.whl", hash = "sha256:fd437ab8eb55f9b942226af7865a3801e2fb731665199b74fd9a44737dbe20f9", size = 144186 },
{ url = "https://files.pythonhosted.org/packages/dc/37/bc3189471c63c84e15f7dc42d4b712747e9662ffbcfacfc4b6a93e6c3bc6/pdoc-15.0.3-py3-none-any.whl", hash = "sha256:686c921ef2622f166de5f73b7241935a4ddac79c8d10dbfa43def8c1fca86550", size = 145950 },
]
[[package]]
@ -2771,39 +2773,39 @@ wheels = [
[[package]]
name = "ruff"
version = "0.11.5"
version = "0.11.6"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/45/71/5759b2a6b2279bb77fe15b1435b89473631c2cd6374d45ccdb6b785810be/ruff-0.11.5.tar.gz", hash = "sha256:cae2e2439cb88853e421901ec040a758960b576126dab520fa08e9de431d1bef", size = 3976488 }
sdist = { url = "https://files.pythonhosted.org/packages/d9/11/bcef6784c7e5d200b8a1f5c2ddf53e5da0efec37e6e5a44d163fb97e04ba/ruff-0.11.6.tar.gz", hash = "sha256:bec8bcc3ac228a45ccc811e45f7eb61b950dbf4cf31a67fa89352574b01c7d79", size = 4010053 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/23/db/6efda6381778eec7f35875b5cbefd194904832a1153d68d36d6b269d81a8/ruff-0.11.5-py3-none-linux_armv6l.whl", hash = "sha256:2561294e108eb648e50f210671cc56aee590fb6167b594144401532138c66c7b", size = 10103150 },
{ url = "https://files.pythonhosted.org/packages/44/f2/06cd9006077a8db61956768bc200a8e52515bf33a8f9b671ee527bb10d77/ruff-0.11.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ac12884b9e005c12d0bd121f56ccf8033e1614f736f766c118ad60780882a077", size = 10898637 },
{ url = "https://files.pythonhosted.org/packages/18/f5/af390a013c56022fe6f72b95c86eb7b2585c89cc25d63882d3bfe411ecf1/ruff-0.11.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:4bfd80a6ec559a5eeb96c33f832418bf0fb96752de0539905cf7b0cc1d31d779", size = 10236012 },
{ url = "https://files.pythonhosted.org/packages/b8/ca/b9bf954cfed165e1a0c24b86305d5c8ea75def256707f2448439ac5e0d8b/ruff-0.11.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0947c0a1afa75dcb5db4b34b070ec2bccee869d40e6cc8ab25aca11a7d527794", size = 10415338 },
{ url = "https://files.pythonhosted.org/packages/d9/4d/2522dde4e790f1b59885283f8786ab0046958dfd39959c81acc75d347467/ruff-0.11.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ad871ff74b5ec9caa66cb725b85d4ef89b53f8170f47c3406e32ef040400b038", size = 9965277 },
{ url = "https://files.pythonhosted.org/packages/e5/7a/749f56f150eef71ce2f626a2f6988446c620af2f9ba2a7804295ca450397/ruff-0.11.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e6cf918390cfe46d240732d4d72fa6e18e528ca1f60e318a10835cf2fa3dc19f", size = 11541614 },
{ url = "https://files.pythonhosted.org/packages/89/b2/7d9b8435222485b6aac627d9c29793ba89be40b5de11584ca604b829e960/ruff-0.11.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:56145ee1478582f61c08f21076dc59153310d606ad663acc00ea3ab5b2125f82", size = 12198873 },
{ url = "https://files.pythonhosted.org/packages/00/e0/a1a69ef5ffb5c5f9c31554b27e030a9c468fc6f57055886d27d316dfbabd/ruff-0.11.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e5f66f8f1e8c9fc594cbd66fbc5f246a8d91f916cb9667e80208663ec3728304", size = 11670190 },
{ url = "https://files.pythonhosted.org/packages/05/61/c1c16df6e92975072c07f8b20dad35cd858e8462b8865bc856fe5d6ccb63/ruff-0.11.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80b4df4d335a80315ab9afc81ed1cff62be112bd165e162b5eed8ac55bfc8470", size = 13902301 },
{ url = "https://files.pythonhosted.org/packages/79/89/0af10c8af4363304fd8cb833bd407a2850c760b71edf742c18d5a87bb3ad/ruff-0.11.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3068befab73620b8a0cc2431bd46b3cd619bc17d6f7695a3e1bb166b652c382a", size = 11350132 },
{ url = "https://files.pythonhosted.org/packages/b9/e1/ecb4c687cbf15164dd00e38cf62cbab238cad05dd8b6b0fc68b0c2785e15/ruff-0.11.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:f5da2e710a9641828e09aa98b92c9ebbc60518fdf3921241326ca3e8f8e55b8b", size = 10312937 },
{ url = "https://files.pythonhosted.org/packages/cf/4f/0e53fe5e500b65934500949361e3cd290c5ba60f0324ed59d15f46479c06/ruff-0.11.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:ef39f19cb8ec98cbc762344921e216f3857a06c47412030374fffd413fb8fd3a", size = 9936683 },
{ url = "https://files.pythonhosted.org/packages/04/a8/8183c4da6d35794ae7f76f96261ef5960853cd3f899c2671961f97a27d8e/ruff-0.11.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:b2a7cedf47244f431fd11aa5a7e2806dda2e0c365873bda7834e8f7d785ae159", size = 10950217 },
{ url = "https://files.pythonhosted.org/packages/26/88/9b85a5a8af21e46a0639b107fcf9bfc31da4f1d263f2fc7fbe7199b47f0a/ruff-0.11.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:81be52e7519f3d1a0beadcf8e974715b2dfc808ae8ec729ecfc79bddf8dbb783", size = 11404521 },
{ url = "https://files.pythonhosted.org/packages/fc/52/047f35d3b20fd1ae9ccfe28791ef0f3ca0ef0b3e6c1a58badd97d450131b/ruff-0.11.5-py3-none-win32.whl", hash = "sha256:e268da7b40f56e3eca571508a7e567e794f9bfcc0f412c4b607931d3af9c4afe", size = 10320697 },
{ url = "https://files.pythonhosted.org/packages/b9/fe/00c78010e3332a6e92762424cf4c1919065707e962232797d0b57fd8267e/ruff-0.11.5-py3-none-win_amd64.whl", hash = "sha256:6c6dc38af3cfe2863213ea25b6dc616d679205732dc0fb673356c2d69608f800", size = 11378665 },
{ url = "https://files.pythonhosted.org/packages/43/7c/c83fe5cbb70ff017612ff36654edfebec4b1ef79b558b8e5fd933bab836b/ruff-0.11.5-py3-none-win_arm64.whl", hash = "sha256:67e241b4314f4eacf14a601d586026a962f4002a475aa702c69980a38087aa4e", size = 10460287 },
{ url = "https://files.pythonhosted.org/packages/6e/1f/8848b625100ebcc8740c8bac5b5dd8ba97dd4ee210970e98832092c1635b/ruff-0.11.6-py3-none-linux_armv6l.whl", hash = "sha256:d84dcbe74cf9356d1bdb4a78cf74fd47c740bf7bdeb7529068f69b08272239a1", size = 10248105 },
{ url = "https://files.pythonhosted.org/packages/e0/47/c44036e70c6cc11e6ee24399c2a1e1f1e99be5152bd7dff0190e4b325b76/ruff-0.11.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9bc583628e1096148011a5d51ff3c836f51899e61112e03e5f2b1573a9b726de", size = 11001494 },
{ url = "https://files.pythonhosted.org/packages/ed/5b/170444061650202d84d316e8f112de02d092bff71fafe060d3542f5bc5df/ruff-0.11.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f2959049faeb5ba5e3b378709e9d1bf0cab06528b306b9dd6ebd2a312127964a", size = 10352151 },
{ url = "https://files.pythonhosted.org/packages/ff/91/f02839fb3787c678e112c8865f2c3e87cfe1744dcc96ff9fc56cfb97dda2/ruff-0.11.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63c5d4e30d9d0de7fedbfb3e9e20d134b73a30c1e74b596f40f0629d5c28a193", size = 10541951 },
{ url = "https://files.pythonhosted.org/packages/9e/f3/c09933306096ff7a08abede3cc2534d6fcf5529ccd26504c16bf363989b5/ruff-0.11.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:26a4b9a4e1439f7d0a091c6763a100cef8fbdc10d68593df6f3cfa5abdd9246e", size = 10079195 },
{ url = "https://files.pythonhosted.org/packages/e0/0d/a87f8933fccbc0d8c653cfbf44bedda69c9582ba09210a309c066794e2ee/ruff-0.11.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b5edf270223dd622218256569636dc3e708c2cb989242262fe378609eccf1308", size = 11698918 },
{ url = "https://files.pythonhosted.org/packages/52/7d/8eac0bd083ea8a0b55b7e4628428203441ca68cd55e0b67c135a4bc6e309/ruff-0.11.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:f55844e818206a9dd31ff27f91385afb538067e2dc0beb05f82c293ab84f7d55", size = 12319426 },
{ url = "https://files.pythonhosted.org/packages/c2/dc/d0c17d875662d0c86fadcf4ca014ab2001f867621b793d5d7eef01b9dcce/ruff-0.11.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d8f782286c5ff562e4e00344f954b9320026d8e3fae2ba9e6948443fafd9ffc", size = 11791012 },
{ url = "https://files.pythonhosted.org/packages/f9/f3/81a1aea17f1065449a72509fc7ccc3659cf93148b136ff2a8291c4bc3ef1/ruff-0.11.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:01c63ba219514271cee955cd0adc26a4083df1956d57847978383b0e50ffd7d2", size = 13949947 },
{ url = "https://files.pythonhosted.org/packages/61/9f/a3e34de425a668284e7024ee6fd41f452f6fa9d817f1f3495b46e5e3a407/ruff-0.11.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15adac20ef2ca296dd3d8e2bedc6202ea6de81c091a74661c3666e5c4c223ff6", size = 11471753 },
{ url = "https://files.pythonhosted.org/packages/df/c5/4a57a86d12542c0f6e2744f262257b2aa5a3783098ec14e40f3e4b3a354a/ruff-0.11.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4dd6b09e98144ad7aec026f5588e493c65057d1b387dd937d7787baa531d9bc2", size = 10417121 },
{ url = "https://files.pythonhosted.org/packages/58/3f/a3b4346dff07ef5b862e2ba06d98fcbf71f66f04cf01d375e871382b5e4b/ruff-0.11.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:45b2e1d6c0eed89c248d024ea95074d0e09988d8e7b1dad8d3ab9a67017a5b03", size = 10073829 },
{ url = "https://files.pythonhosted.org/packages/93/cc/7ed02e0b86a649216b845b3ac66ed55d8aa86f5898c5f1691797f408fcb9/ruff-0.11.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:bd40de4115b2ec4850302f1a1d8067f42e70b4990b68838ccb9ccd9f110c5e8b", size = 11076108 },
{ url = "https://files.pythonhosted.org/packages/39/5e/5b09840fef0eff1a6fa1dea6296c07d09c17cb6fb94ed5593aa591b50460/ruff-0.11.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:77cda2dfbac1ab73aef5e514c4cbfc4ec1fbef4b84a44c736cc26f61b3814cd9", size = 11512366 },
{ url = "https://files.pythonhosted.org/packages/6f/4c/1cd5a84a412d3626335ae69f5f9de2bb554eea0faf46deb1f0cb48534042/ruff-0.11.6-py3-none-win32.whl", hash = "sha256:5151a871554be3036cd6e51d0ec6eef56334d74dfe1702de717a995ee3d5b287", size = 10485900 },
{ url = "https://files.pythonhosted.org/packages/42/46/8997872bc44d43df986491c18d4418f1caff03bc47b7f381261d62c23442/ruff-0.11.6-py3-none-win_amd64.whl", hash = "sha256:cce85721d09c51f3b782c331b0abd07e9d7d5f775840379c640606d3159cae0e", size = 11558592 },
{ url = "https://files.pythonhosted.org/packages/d7/6a/65fecd51a9ca19e1477c3879a7fda24f8904174d1275b419422ac00f6eee/ruff-0.11.6-py3-none-win_arm64.whl", hash = "sha256:3567ba0d07fb170b1b48d944715e3294b77f5b7679e8ba258199a250383ccb79", size = 10682766 },
]
[[package]]
name = "s3transfer"
version = "0.11.4"
version = "0.11.5"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "botocore" },
]
sdist = { url = "https://files.pythonhosted.org/packages/0f/ec/aa1a215e5c126fe5decbee2e107468f51d9ce190b9763cb649f76bb45938/s3transfer-0.11.4.tar.gz", hash = "sha256:559f161658e1cf0a911f45940552c696735f5c74e64362e515f333ebed87d679", size = 148419 }
sdist = { url = "https://files.pythonhosted.org/packages/c4/2b/5c9562795c2eb2b5f63536961754760c25bf0f34af93d36aa28dea2fb303/s3transfer-0.11.5.tar.gz", hash = "sha256:8c8aad92784779ab8688a61aefff3e28e9ebdce43142808eaa3f0b0f402f68b7", size = 149107 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/86/62/8d3fc3ec6640161a5649b2cddbbf2b9fa39c92541225b33f117c37c5a2eb/s3transfer-0.11.4-py3-none-any.whl", hash = "sha256:ac265fa68318763a03bf2dc4f39d5cbd6a9e178d81cc9483ad27da33637e320d", size = 84412 },
{ url = "https://files.pythonhosted.org/packages/45/39/13402e323666d17850eca87e4cd6ecfcf9fd7809cac9efdcce10272fc29d/s3transfer-0.11.5-py3-none-any.whl", hash = "sha256:757af0f2ac150d3c75bc4177a32355c3862a98d20447b69a0161812992fe0bd4", size = 84782 },
]
[[package]]
@ -2885,11 +2887,11 @@ wheels = [
[[package]]
name = "setuptools"
version = "78.1.0"
version = "79.0.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/a9/5a/0db4da3bc908df06e5efae42b44e75c81dd52716e10192ff36d0c1c8e379/setuptools-78.1.0.tar.gz", hash = "sha256:18fd474d4a82a5f83dac888df697af65afa82dec7323d09c3e37d1f14288da54", size = 1367827 }
sdist = { url = "https://files.pythonhosted.org/packages/7d/19/fecb7e2825616270f34512b3394cdcf6f45a79b5b6d94fdbd86a509e67b5/setuptools-79.0.0.tar.gz", hash = "sha256:9828422e7541213b0aacb6e10bbf9dd8febeaa45a48570e09b6d100e063fc9f9", size = 1367685 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/54/21/f43f0a1fa8b06b32812e0975981f4677d28e0f3271601dc88ac5a5b83220/setuptools-78.1.0-py3-none-any.whl", hash = "sha256:3e386e96793c8702ae83d17b853fb93d3e09ef82ec62722e61da5cd22376dcd8", size = 1256108 },
{ url = "https://files.pythonhosted.org/packages/cc/ea/d53f2f8897c46a36df085964d07761ea4c2d1f2cf92019693b6742b7aabb/setuptools-79.0.0-py3-none-any.whl", hash = "sha256:b9ab3a104bedb292323f53797b00864e10e434a3ab3906813a7169e4745b912a", size = 1256065 },
]
[[package]]
@ -3014,7 +3016,7 @@ wheels = [
[[package]]
name = "trio"
version = "0.29.0"
version = "0.30.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "attrs" },
@ -3024,9 +3026,9 @@ dependencies = [
{ name = "sniffio" },
{ name = "sortedcontainers" },
]
sdist = { url = "https://files.pythonhosted.org/packages/a1/47/f62e62a1a6f37909aed0bf8f5d5411e06fa03846cfcb64540cd1180ccc9f/trio-0.29.0.tar.gz", hash = "sha256:ea0d3967159fc130acb6939a0be0e558e364fee26b5deeecc893a6b08c361bdf", size = 588952 }
sdist = { url = "https://files.pythonhosted.org/packages/01/c1/68d582b4d3a1c1f8118e18042464bb12a7c1b75d64d75111b297687041e3/trio-0.30.0.tar.gz", hash = "sha256:0781c857c0c81f8f51e0089929a26b5bb63d57f927728a5586f7e36171f064df", size = 593776 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c9/55/c4d9bea8b3d7937901958f65124123512419ab0eb73695e5f382521abbfb/trio-0.29.0-py3-none-any.whl", hash = "sha256:d8c463f1a9cc776ff63e331aba44c125f423a5a13c684307e828d930e625ba66", size = 492920 },
{ url = "https://files.pythonhosted.org/packages/69/8e/3f6dfda475ecd940e786defe6df6c500734e686c9cd0a0f8ef6821e9b2f2/trio-0.30.0-py3-none-any.whl", hash = "sha256:3bf4f06b8decf8d3cf00af85f40a89824669e2d033bb32469d34840edcfc22a5", size = 499194 },
]
[[package]]

View File

@ -2,15 +2,11 @@
node_modules
# don't lint build output (make sure it's set to your correct build folder name)
dist
out
# don't lint nyc coverage output
coverage
# Import order matters
poly.ts
src/locale-codes.ts
src/locales/
storybook-static/
# Prettier breaks the tsconfig file
tsconfig.json
.storybook/css-import-maps*
package.json
packages/**/package.json

791
web/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,44 @@
{
"name": "@goauthentik/web",
"version": "0.0.0",
"license": "MIT",
"private": true,
"scripts": {
"build": "wireit",
"build-locales": "wireit",
"build-locales:build": "wireit",
"build-proxy": "wireit",
"build:sfe": "wireit",
"esbuild:watch": "node scripts/build-web.mjs --watch",
"extract-locales": "wireit",
"format": "wireit",
"lint": "wireit",
"lint:imports": "wireit",
"lint:lockfile": "wireit",
"lint:nightmare": "wireit",
"lint:precommit": "wireit",
"lint:types": "wireit",
"lit-analyse": "wireit",
"postinstall": "bash scripts/patch-spotlight.sh",
"precommit": "wireit",
"prettier": "wireit",
"prettier-check": "wireit",
"pseudolocalize": "wireit",
"storybook": "storybook dev -p 6006",
"storybook:build": "wireit",
"test": "wireit",
"test:e2e": "wireit",
"test:e2e:watch": "wireit",
"test:watch": "wireit",
"tsc": "wireit",
"watch": "run-s build-locales esbuild:watch"
},
"type": "module",
"exports": {
"./package.json": "./package.json",
"./paths": "./paths.js",
"./scripts/*": "./scripts/*.mjs"
},
"dependencies": {
"@codemirror/lang-css": "^6.3.1",
"@codemirror/lang-html": "^6.4.9",
@ -12,7 +50,7 @@
"@floating-ui/dom": "^1.6.11",
"@formatjs/intl-listformat": "^7.5.7",
"@fortawesome/fontawesome-free": "^6.6.0",
"@goauthentik/api": "^2025.2.4-1745519715",
"@goauthentik/api": "^2025.4.0-1746018955",
"@lit-labs/ssr": "3.2.2",
"@lit/context": "^1.1.2",
"@lit/localize": "^0.12.2",
@ -62,6 +100,7 @@
"devDependencies": {
"@eslint/js": "^9.11.1",
"@goauthentik/esbuild-plugin-live-reload": "^1.0.4",
"@goauthentik/monorepo": "^1.0.0",
"@goauthentik/prettier-config": "^1.0.4",
"@goauthentik/tsconfig": "^1.0.4",
"@hcaptcha/types": "^1.0.4",
@ -93,13 +132,13 @@
"@wdio/spec-reporter": "^9.1.2",
"chromedriver": "^131.0.1",
"esbuild": "^0.25.0",
"esbuild-plugin-copy": "^2.1.1",
"esbuild-plugin-polyfill-node": "^0.3.0",
"esbuild-plugins-node-modules-polyfill": "^1.7.0",
"eslint": "^9.11.1",
"eslint-plugin-lit": "^1.15.0",
"eslint-plugin-wc": "^2.1.1",
"github-slugger": "^2.0.0",
"glob": "^11.0.0",
"globals": "^15.10.0",
"knip": "^5.30.6",
"lit-analyzer": "^2.0.3",
@ -110,7 +149,6 @@
"rollup-plugin-postcss-lit": "^2.1.0",
"storybook": "^8.3.4",
"storybook-addon-mock": "^5.0.0",
"syncpack": "^13.0.0",
"turnstile-types": "^1.2.3",
"typescript": "^5.6.2",
"typescript-eslint": "^8.8.0",
@ -118,10 +156,6 @@
"vite-tsconfig-paths": "^5.0.1",
"wireit": "^0.14.9"
},
"engines": {
"node": ">=20"
},
"license": "MIT",
"optionalDependencies": {
"@esbuild/darwin-arm64": "^0.24.0",
"@esbuild/linux-amd64": "^0.18.11",
@ -130,48 +164,6 @@
"@rollup/rollup-linux-arm64-gnu": "4.23.0",
"@rollup/rollup-linux-x64-gnu": "4.23.0"
},
"overrides": {
"rapidoc": {
"@apitools/openapi-parser@": "0.0.37"
},
"chromedriver": {
"axios": "^1.8.4"
}
},
"prettier": "@goauthentik/prettier-config",
"private": true,
"scripts": {
"build": "wireit",
"build-locales": "wireit",
"build-locales:build": "wireit",
"build-proxy": "wireit",
"build:sfe": "wireit",
"esbuild:watch": "node scripts/build-web.mjs --watch",
"extract-locales": "wireit",
"format": "wireit",
"lint": "wireit",
"lint:imports": "wireit",
"lint:lockfile": "wireit",
"lint:nightmare": "wireit",
"lint:package": "wireit",
"lint:precommit": "wireit",
"lint:types": "wireit",
"lit-analyse": "wireit",
"postinstall": "bash scripts/patch-spotlight.sh",
"precommit": "wireit",
"prettier": "wireit",
"prettier-check": "wireit",
"pseudolocalize": "wireit",
"storybook": "storybook dev -p 6006",
"storybook:build": "wireit",
"test": "wireit",
"test:e2e": "wireit",
"test:e2e:watch": "wireit",
"test:watch": "wireit",
"tsc": "wireit",
"watch": "run-s build-locales esbuild:watch"
},
"type": "module",
"wireit": {
"build": {
"#comment": [
@ -248,10 +240,7 @@
"command": "lit-localize extract"
},
"format": {
"command": "prettier --write .",
"dependencies": [
"lint:package"
]
"command": "prettier --write ."
},
"format:packages": {
"dependencies": [
@ -290,9 +279,6 @@
"./packages/sfe:lint:lockfile"
]
},
"lint:package": {
"command": "syncpack format -i ' '"
},
"lint:nightmare": {
"command": "${NODE_RUNNER} ./scripts/eslint.mjs --nightmare",
"env": {
@ -323,7 +309,6 @@
"lint:types",
"lint:components",
"lint:spelling",
"lint:package",
"lint:lockfile",
"lint:lockfiles",
"lint:precommit",
@ -388,8 +373,20 @@
]
}
},
"engines": {
"node": ">=20"
},
"workspaces": [
".",
"./packages/*"
]
],
"prettier": "@goauthentik/prettier-config",
"overrides": {
"rapidoc": {
"@apitools/openapi-parser@": "0.0.37"
},
"chromedriver": {
"axios": "^1.8.4"
}
}
}

View File

@ -1,22 +1,11 @@
{
"name": "@goauthentik/esbuild-plugin-live-reload",
"description": "ESBuild plugin to watch for file changes and trigger client-side reloads.",
"version": "1.0.4",
"dependencies": {
"find-free-ports": "^3.1.1"
},
"devDependencies": {
"@goauthentik/prettier-config": "^1.0.4",
"@goauthentik/tsconfig": "^1.0.4",
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
"@types/node": "^22.14.1",
"esbuild": "^0.25.0",
"prettier": "^3.3.3",
"typescript": "^5.6.2"
},
"engines": {
"node": ">=20.11"
},
"description": "ESBuild plugin to watch for file changes and trigger client-side reloads.",
"license": "MIT",
"private": true,
"main": "index.js",
"type": "module",
"exports": {
"./package.json": "./package.json",
".": {
@ -32,22 +21,33 @@
"import": "./plugin/index.js"
}
},
"dependencies": {
"find-free-ports": "^3.1.1"
},
"devDependencies": {
"@goauthentik/prettier-config": "^1.0.4",
"@goauthentik/tsconfig": "^1.0.4",
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
"@types/node": "^22.14.1",
"esbuild": "^0.25.0",
"prettier": "^3.3.3",
"typescript": "^5.6.2"
},
"peerDependencies": {
"esbuild": "^0.25.0"
},
"engines": {
"node": ">=20.11"
},
"types": "./out/index.d.ts",
"files": [
"./index.js",
"client/**/*",
"plugin/**/*",
"out/**/*"
],
"license": "MIT",
"main": "index.js",
"peerDependencies": {
"esbuild": "^0.25.0"
},
"prettier": "@goauthentik/prettier-config",
"private": true,
"publishConfig": {
"access": "public"
},
"type": "module",
"types": "./out/index.d.ts"
}
}

View File

@ -2,4 +2,3 @@
This package contains utility scripts common to all TypeScript and JavaScript packages in the
`@goauthentik` monorepo.

View File

@ -0,0 +1,42 @@
/**
* @file Utility functions for building and copying files.
*/
/**
* A source environment variable, which can be a string, number, boolean, null, or undefined.
* @typedef {string | number | boolean | null | undefined} EnvironmentVariable
*/
/**
* A type helper for serializing environment variables.
*
* @template {EnvironmentVariable} T
* @typedef {T extends string ? `"${T}"` : T} JSONify
*/
/**
* Given an object of environment variables, returns a new object with the same keys and values, but
* with the values serialized as strings.
*
* @template {Record<string, EnvironmentVariable>} EnvRecord
* @template {string} [Prefix='process.env.']
*
* @param {EnvRecord} input
* @param {Prefix} [prefix='process.env.']
*
* @returns {{[K in keyof EnvRecord as `${Prefix}${K}`]: JSONify<EnvRecord[K]>}}
*/
export function serializeEnvironmentVars(input, prefix = /** @type {Prefix} */ ("process.env.")) {
/**
* @type {Record<string, string>}
*/
const env = {};
for (const [key, value] of Object.entries(input)) {
const namespaceKey = prefix + key;
env[namespaceKey] = JSON.stringify(value || "");
}
return /** @type {any} */ (env);
}

View File

@ -1,8 +1,9 @@
/**
* @file Constants for JavaScript and TypeScript files.
*
*/
/// <reference types="../../types/global.js" />
/**
* The current Node.js environment, defaulting to "development" when not set.
*
@ -12,6 +13,4 @@
* ensure that module tree-shaking works correctly.
*
*/
export const NodeEnvironment = /** @type {'development' | 'production'} */ (
process.env.NODE_ENV || "development"
);
export const NodeEnvironment = process.env.NODE_ENV || "development";

View File

@ -1,4 +1,7 @@
/// <reference types="./types/global.js" />
export * from "./paths.js";
export * from "./constants.js";
export * from "./build.js";
export * from "./version.js";
export * from "./scripting.js";

View File

@ -0,0 +1,28 @@
{
"name": "@goauthentik/monorepo",
"version": "1.0.0",
"description": "Utilities for the authentik monorepo.",
"license": "MIT",
"private": true,
"main": "index.js",
"type": "module",
"exports": {
"./package.json": "./package.json",
".": {
"types": "./out/index.d.ts",
"import": "./index.js"
}
},
"devDependencies": {
"@goauthentik/prettier-config": "^1.0.4",
"@goauthentik/tsconfig": "^1.0.4",
"@types/node": "^22.14.1",
"prettier": "^3.3.3",
"typescript": "^5.6.2"
},
"engines": {
"node": ">=20.11"
},
"types": "./out/index.d.ts",
"prettier": "@goauthentik/prettier-config"
}

View File

@ -0,0 +1,45 @@
import { createRequire } from "node:module";
import { dirname, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";
const relativeDirname = dirname(fileURLToPath(import.meta.url));
/**
* @typedef {'~authentik'} MonoRepoRoot
*/
/**
* The root of the authentik monorepo.
*/
// TODO: Revise when this package is moved to the monorepo's `packages/monorepo` directory.
export const MonoRepoRoot = /** @type {MonoRepoRoot} */ (
resolve(relativeDirname, "..", "..", "..")
);
const require = createRequire(import.meta.url);
/**
* Resolve a package name to its location in the monorepo to the single node_modules directory.
* @param {string} packageName
*
* @returns {string} The resolved path to the package.
* @throws {Error} If the package cannot be resolved.
*/
export function resolvePackage(packageName) {
const relativePackageJSONPath = join(packageName, "package.json");
/** @type {string} */
let absolutePackageJSONPath;
try {
absolutePackageJSONPath = require.resolve(relativePackageJSONPath);
} catch (cause) {
const error = new Error(`Failed to resolve package "${packageName}"`);
error.cause = cause;
throw error;
}
return dirname(absolutePackageJSONPath);
}

15
web/packages/monorepo/types/global.d.ts vendored Normal file
View File

@ -0,0 +1,15 @@
declare module "process" {
global {
namespace NodeJS {
interface ProcessEnv {
/**
* An environment variable used to determine
* whether Node.js is running in production mode.
*
* @see {@link https://nodejs.org/en/learn/getting-started/nodejs-the-difference-between-development-and-production | The difference between development and production}
*/
NODE_ENV?: "production" | "development";
}
}
}
}

View File

@ -1,6 +1,6 @@
import { execSync } from "node:child_process";
import PackageJSON from "../../package.json" with { type: "json" };
import PackageJSON from "../../../package.json" with { type: "json" };
import { MonoRepoRoot } from "./paths.js";
/**

78
web/paths.js Normal file
View File

@ -0,0 +1,78 @@
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
const relativeDirname = dirname(fileURLToPath(import.meta.url));
//#region Base paths
/**
* @typedef {'@goauthentik/web'} WebPackageIdentifier
*/
/**
* The root of the web package.
*/
export const PackageRoot = /** @type {WebPackageIdentifier} */ (resolve(relativeDirname));
/**
* The name of the distribution directory.
*/
export const DistDirectoryName = "dist";
/**
* Path to the web package's distribution directory.
*
* This is where the built files are located after running the build process.
*/
export const DistDirectory = /** @type {`${WebPackageIdentifier}/${DistDirectoryName}`} */ (
resolve(relativeDirname, DistDirectoryName)
);
//#endregion
//#region Entry points
/**
* @typedef {{ in: string, out: string }} EntryPointTarget
*
* ESBuild entrypoint target.
* Matches the type defined in the ESBuild context.
*/
/**
* Entry points available for building.
*
* @satisfies {Record<string, EntryPointTarget>}
*/
export const EntryPoint = /** @type {const} */ ({
Admin: {
in: resolve(PackageRoot, "src", "admin", "AdminInterface", "index.entrypoint.ts"),
out: resolve(DistDirectory, "admin", "AdminInterface"),
},
User: {
in: resolve(PackageRoot, "src", "user", "index.entrypoint.ts"),
out: resolve(DistDirectory, "user", "UserInterface"),
},
Flow: {
in: resolve(PackageRoot, "src", "flow", "index.entrypoint.ts"),
out: resolve(DistDirectory, "flow", "FlowInterface"),
},
Standalone: {
in: resolve(PackageRoot, "src", "standalone", "api-browser/index.entrypoint.ts"),
out: resolve(DistDirectory, "standalone", "api-browser", "index"),
},
StandaloneLoading: {
in: resolve(PackageRoot, "src", "standalone", "loading/index.entrypoint.ts"),
out: resolve(DistDirectory, "standalone", "loading", "index"),
},
RAC: {
in: resolve(PackageRoot, "src", "rac", "index.entrypoint.ts"),
out: resolve(DistDirectory, "rac", "index"),
},
Polyfill: {
in: resolve(PackageRoot, "src", "polyfill", "index.entrypoint.ts"),
out: resolve(DistDirectory, "poly"),
},
});
//#endregion

View File

@ -4,138 +4,86 @@
* @import { BuildOptions } from "esbuild";
*/
import { liveReloadPlugin } from "@goauthentik/esbuild-plugin-live-reload/plugin";
import { execFileSync } from "child_process";
import {
MonoRepoRoot,
NodeEnvironment,
readBuildIdentifier,
resolvePackage,
serializeEnvironmentVars,
} from "@goauthentik/monorepo";
import { DistDirectory, DistDirectoryName, EntryPoint, PackageRoot } from "@goauthentik/web/paths";
import { deepmerge } from "deepmerge-ts";
import esbuild from "esbuild";
import copy from "esbuild-plugin-copy";
import { polyfillNode } from "esbuild-plugin-polyfill-node";
import { copyFileSync, mkdirSync, readFileSync, statSync } from "fs";
import { globSync } from "glob";
import * as path from "path";
import { cwd } from "process";
import process from "process";
import { fileURLToPath } from "url";
import * as fs from "node:fs/promises";
import * as path from "node:path";
import { mdxPlugin } from "./esbuild/build-mdx-plugin.mjs";
const __dirname = fileURLToPath(new URL(".", import.meta.url));
let authentikProjectRoot = path.join(__dirname, "..", "..");
const logPrefix = "[Build]";
try {
// Use the package.json file in the root folder, as it has the current version information.
authentikProjectRoot = execFileSync("git", ["rev-parse", "--show-toplevel"], {
encoding: "utf8",
}).replace("\n", "");
} catch (_error) {
// We probably don't have a .git folder, which could happen in container builds.
}
const definitions = serializeEnvironmentVars({
NODE_ENV: NodeEnvironment,
CWD: process.cwd(),
AK_API_BASE_PATH: process.env.AK_API_BASE_PATH,
});
const packageJSONPath = path.join(authentikProjectRoot, "./package.json");
const rootPackage = JSON.parse(readFileSync(packageJSONPath, "utf8"));
const NODE_ENV = process.env.NODE_ENV || "development";
const AK_API_BASE_PATH = process.env.AK_API_BASE_PATH || "";
const environmentVars = new Map([
["NODE_ENV", NODE_ENV],
["CWD", cwd()],
["AK_API_BASE_PATH", AK_API_BASE_PATH],
]);
const definitions = Object.fromEntries(
Array.from(environmentVars).map(([key, value]) => {
return [`process.env.${key}`, JSON.stringify(value)];
}),
);
const patternflyPath = resolvePackage("@patternfly/patternfly");
/**
* All is magic is just to make sure the assets are copied into the right places. This is a very
* stripped down version of what the rollup-copy-plugin does, without any of the features we don't
* use, and using globSync instead of globby since we already had globSync lying around thanks to
* Typescript. If there's a third argument in an array entry, it's used to replace the internal path
* before concatenating it all together as the destination target.
* @type {Array<[string, string, string?]>}
*/
const assetsFileMappings = [
["node_modules/@patternfly/patternfly/patternfly.min.css", "."],
["node_modules/@patternfly/patternfly/assets/**", ".", "node_modules/@patternfly/patternfly/"],
["src/common/styles/**", "."],
["src/assets/images/**", "./assets/images"],
["./icons/*", "./assets/icons"],
];
/**
* @param {string} filePath
*/
const isFile = (filePath) => statSync(filePath).isFile();
/**
* @param {string} src Source file
* @param {string} dest Destination folder
* @param {string} [strip] Path to strip from the source file
*/
function nameCopyTarget(src, dest, strip) {
const target = path.join(dest, strip ? src.replace(strip, "") : path.parse(src).base);
return [src, target];
}
for (const [source, rawdest, strip] of assetsFileMappings) {
const matchedPaths = globSync(source);
const dest = path.join("dist", rawdest);
const copyTargets = matchedPaths.map((path) => nameCopyTarget(path, dest, strip));
for (const [src, dest] of copyTargets) {
if (isFile(src)) {
mkdirSync(path.dirname(dest), { recursive: true });
copyFileSync(src, dest);
}
}
}
/**
* @typedef {[source: string, destination: string]} EntryPoint
*/
/**
* This starts the definitions used for esbuild: Our targets, our arguments, the function for
* running a build, and three options for building: watching, building, and building the proxy.
* Ordered by largest to smallest interface to build even faster
*
* @type {EntryPoint[]}
*/
const entryPoints = [
["admin/AdminInterface/AdminInterface.ts", "admin"],
["user/UserInterface.ts", "user"],
["flow/FlowInterface.ts", "flow"],
["standalone/api-browser/index.ts", "standalone/api-browser"],
["rac/index.ts", "rac"],
["standalone/loading/index.ts", "standalone/loading"],
["polyfill/poly.ts", "."],
];
/**
* @type {import("esbuild").BuildOptions}
* @type {Readonly<BuildOptions>}
*/
const BASE_ESBUILD_OPTIONS = {
entryNames: `[dir]/[name]-${readBuildIdentifier()}`,
chunkNames: "[dir]/chunks/[name]-[hash]",
assetNames: "assets/[dir]/[name]-[hash]",
publicPath: path.join("/static", DistDirectoryName),
outdir: DistDirectory,
bundle: true,
write: true,
sourcemap: true,
minify: NODE_ENV === "production",
minify: NodeEnvironment === "production",
legalComments: "external",
splitting: true,
treeShaking: true,
external: ["*.woff", "*.woff2"],
tsconfig: path.resolve(__dirname, "..", "tsconfig.build.json"),
tsconfig: path.resolve(PackageRoot, "tsconfig.build.json"),
loader: {
".css": "text",
},
plugins: [
copy({
assets: [
{
from: path.join(patternflyPath, "patternfly.min.css"),
to: ".",
},
{
from: path.join(patternflyPath, "assets", "**"),
to: "./assets",
},
{
from: path.resolve(PackageRoot, "src", "common", "styles", "**"),
to: ".",
},
{
from: path.resolve(PackageRoot, "src", "assets", "images", "**"),
to: "./assets/images",
},
{
from: path.resolve(PackageRoot, "icons", "*"),
to: "./assets/icons",
},
],
}),
polyfillNode({
polyfills: {
path: true,
},
}),
mdxPlugin({
root: authentikProjectRoot,
root: MonoRepoRoot,
}),
],
define: definitions,
@ -151,69 +99,43 @@ const BASE_ESBUILD_OPTIONS = {
},
};
/**
* Creates a version ID for the build.
* @returns {string}
*/
function composeVersionID() {
const { version } = rootPackage;
const buildHash = process.env.GIT_BUILD_HASH;
async function cleanDistDirectory() {
const timerLabel = `${logPrefix} ♻️ Cleaning previous builds...`;
if (buildHash) {
return `${version}+${buildHash}`;
}
console.time(timerLabel);
return version;
await fs.rm(DistDirectory, {
recursive: true,
force: true,
});
await fs.mkdir(DistDirectory, {
recursive: true,
});
console.timeEnd(timerLabel);
}
/**
* Build a single entry point.
* Creates an ESBuild options, extending the base options with the given overrides.
*
* @param {EntryPoint} buildTarget
* @param {Partial<esbuild.BuildOptions>} [overrides]
* @throws {Error} on build failure
* @param {BuildOptions} overrides
* @returns {BuildOptions}
*/
function createEntryPointOptions([source, dest], overrides = {}) {
const outdir = path.join(__dirname, "..", "dist", dest);
export function createESBuildOptions(overrides) {
/**
* @type {esbuild.BuildOptions}
* @type {BuildOptions}
*/
const mergedOptions = deepmerge(BASE_ESBUILD_OPTIONS, overrides);
const entryPointConfig = {
entryPoints: [`./src/${source}`],
entryNames: `[dir]/[name]-${composeVersionID()}`,
publicPath: path.join("/static", "dist", dest),
outdir,
};
/**
* @type {esbuild.BuildOptions}
*/
const mergedConfig = deepmerge(BASE_ESBUILD_OPTIONS, entryPointConfig, overrides);
return mergedConfig;
}
/**
* Build all entry points in parallel.
*
* @param {EntryPoint[]} entryPoints
* @returns {Promise<esbuild.BuildResult[]>}
*/
async function buildParallel(entryPoints) {
return Promise.all(
entryPoints.map((entryPoint) => {
return esbuild.build(createEntryPointOptions(entryPoint));
}),
);
return mergedOptions;
}
function doHelp() {
console.log(`Build the authentik UI
options:
-w, --watch: Build all ${entryPoints.length} interfaces
-w, --watch: Build all interfaces
-p, --proxy: Build only the polyfills and the loading application
-h, --help: This help message
`);
@ -222,27 +144,29 @@ function doHelp() {
}
async function doWatch() {
console.log("Watching all entry points...");
console.group(`${logPrefix} 🤖 Watching entry points`);
const buildContexts = await Promise.all(
entryPoints.map((entryPoint) => {
return esbuild.context(
createEntryPointOptions(entryPoint, {
define: definitions,
plugins: [
liveReloadPlugin({
logPrefix: `Build Observer (${entryPoint[1]})`,
relativeRoot: path.join(__dirname, ".."),
}),
],
}),
);
}),
);
const entryPoints = Object.entries(EntryPoint).map(([entrypointID, target]) => {
console.log(entrypointID);
await Promise.all(buildContexts.map((context) => context.rebuild()));
return target;
});
await Promise.allSettled(buildContexts.map((context) => context.watch()));
console.groupEnd();
const buildOptions = createESBuildOptions({
entryPoints,
plugins: [
liveReloadPlugin({
relativeRoot: PackageRoot,
}),
],
});
const buildContext = await esbuild.context(buildOptions);
await buildContext.rebuild();
await buildContext.watch();
return /** @type {Promise<void>} */ (
new Promise((resolve) => {
@ -254,15 +178,34 @@ async function doWatch() {
}
async function doBuild() {
console.log("Building all entry points");
console.group(`${logPrefix} 🚀 Building entry points:`);
return buildParallel(entryPoints);
const entryPoints = Object.entries(EntryPoint).map(([entrypointID, target]) => {
console.log(entrypointID);
return target;
});
console.groupEnd();
const buildOptions = createESBuildOptions({
entryPoints,
});
await esbuild.build(buildOptions);
console.log("Build complete");
}
async function doProxy() {
return buildParallel(
entryPoints.filter(([_, dest]) => ["standalone/loading", "."].includes(dest)),
);
const entryPoints = [EntryPoint.StandaloneLoading];
const buildOptions = createESBuildOptions({
entryPoints,
});
await esbuild.build(buildOptions);
console.log("Proxy build complete");
}
async function delegateCommand() {
@ -284,12 +227,16 @@ async function delegateCommand() {
}
}
await delegateCommand()
.then(() => {
console.log("Build complete");
process.exit(0);
})
.catch((error) => {
console.error(error);
process.exit(1);
});
await cleanDistDirectory()
// ---
.then(() =>
delegateCommand()
.then(() => {
console.log("Build complete");
process.exit(0);
})
.catch((error) => {
console.error(error);
process.exit(1);
}),
);

View File

@ -1,5 +0,0 @@
import { AdminInterface } from "./AdminInterface";
import "./AdminInterface";
export { AdminInterface };
export default AdminInterface;

View File

@ -1,4 +1,4 @@
import { AdminInterface } from "@goauthentik/admin/AdminInterface";
import type { AdminInterface } from "@goauthentik/admin/AdminInterface/index.entrypoint.js";
import "@goauthentik/admin/users/ServiceAccountForm";
import "@goauthentik/admin/users/UserActiveForm";
import "@goauthentik/admin/users/UserForm";

View File

@ -3,7 +3,7 @@ export const SUCCESS_CLASS = "pf-m-success";
export const ERROR_CLASS = "pf-m-danger";
export const PROGRESS_CLASS = "pf-m-in-progress";
export const CURRENT_CLASS = "pf-m-current";
export const VERSION = "2025.2.4";
export const VERSION = "2025.4.0";
export const TITLE_DEFAULT = "authentik";
export const ROUTE_SEPARATOR = ";";

View File

@ -1,4 +1,4 @@
import type { AdminInterface } from "@goauthentik/admin/AdminInterface/AdminInterface";
import type { AdminInterface } from "@goauthentik/admin/AdminInterface/index.entrypoint.js";
import { globalAK } from "@goauthentik/common/global";
import { AKElement, rootInterface } from "@goauthentik/elements/Base";
import { WithLicenseSummary } from "@goauthentik/elements/Interface/licenseSummaryProvider";

View File

@ -1,3 +1,4 @@
// sort-imports-ignore
import "construct-style-sheets-polyfill";
import "@webcomponents/webcomponentsjs";
import "lit/polyfill-support.js";

View File

@ -6,7 +6,7 @@ import { AKElement, rootInterface } from "@goauthentik/elements/Base";
import "@goauthentik/elements/Expand";
import "@goauthentik/user/LibraryApplication/RACLaunchEndpointModal";
import type { RACLaunchEndpointModal } from "@goauthentik/user/LibraryApplication/RACLaunchEndpointModal";
import { UserInterface } from "@goauthentik/user/UserInterface";
import type { UserInterface } from "@goauthentik/user/index.entrypoint.js";
import { msg } from "@lit/localize";
import { CSSResult, TemplateResult, css, html, nothing } from "lit";

View File

@ -5,7 +5,7 @@ import "@goauthentik/elements/Tabs";
import "@goauthentik/elements/user/SessionList";
import "@goauthentik/elements/user/UserConsentList";
import "@goauthentik/elements/user/sources/SourceSettings";
import { UserInterface } from "@goauthentik/user/UserInterface";
import type { UserInterface } from "@goauthentik/user/index.entrypoint.js";
import "@goauthentik/user/user-settings/details/UserPassword";
import "@goauthentik/user/user-settings/details/UserSettingsFlowExecutor";
import "@goauthentik/user/user-settings/mfa/MFADevicesPage";

View File

@ -61,5 +61,5 @@
{
"path": "./packages/esbuild-plugin-live-reload"
}
],
]
}

24
web/types/global.d.ts vendored
View File

@ -2,17 +2,27 @@
* @file Environment variables available via ESBuild.
*/
declare module "module" {
global {
/**
* @deprecated This is not present in ESM files.
*
* ```js
* import { dirname } from "node:path";
* import { fileURLToPath } from "node:url";
*
* const relativeDirname = dirname(fileURLToPath(import.meta.url));
* ```
*/
// eslint-disable-next-line no-var
var __dirname: string;
}
}
declare module "process" {
global {
namespace NodeJS {
interface ProcessEnv {
NODE_ENV: "production" | "development";
/**
*
* @todo Determine where this is used and if it is needed,
* give it a better name.
* @deprecated
*/
CWD: string;
/**
* @todo Determine where this is used and if it is needed,

View File

@ -42,7 +42,7 @@ By default, the captcha test keys are used. You can get a proper key [here](http
## Recovery with email verification
Flow: right-click [here](https://version-2024-12.goauthentik.io/assets/files/flows-recovery-email-verification-408d6afeff2fbf276bf43a949e332ef6.yaml) and save the file.
Flow: right-click [here](/blueprints/example/flows-recovery-email-verification.yaml) and save the file.
Recovery flow, the user is sent an email after they've identified themselves. After they click on the link in the email, they are prompted for a new password and immediately logged on.

View File

@ -13,6 +13,7 @@ This integration creates the following objects:
- Secret to store the token
- Prometheus ServiceMonitor (if the Prometheus Operator is installed in the target cluster)
- Ingress (only Proxy outposts)
- HTTPRoute (only Proxy outposts, when the Gateway API resources are installed in the target cluster, and the `kubernetes_httproute_parent_refs` setting is set, see below)
- Traefik Middleware (only Proxy outposts with forward auth enabled)
The following outpost settings are used:
@ -24,6 +25,8 @@ The following outpost settings are used:
- `kubernetes_ingress_annotations`: Any additional annotations to add to the ingress object, for example cert-manager
- `kubernetes_ingress_secret_name`: Name of the secret that is used for TLS connections, can be empty to disable TLS config
- `kubernetes_ingress_class_name`: Optionally set the ingress class used for the generated ingress, requires authentik 2022.11.0
- `kubernetes_httproute_parent_refs`: Define which Gateways the HTTPRoute wants to be attached to.
- `kubernetes_httproute_annotations`: Any additional annotations to add to the HTTPRoute object
- `kubernetes_service_type`: Service kind created, can be set to LoadBalancer for LDAP outposts for example
- `kubernetes_disabled_components`: Disable any components of the kubernetes integration, can be any of
- 'secret'
@ -32,6 +35,7 @@ The following outpost settings are used:
- 'prometheus servicemonitor'
- 'ingress'
- 'traefik middleware'
- 'httproute'
- `kubernetes_image_pull_secrets`: If the above docker image is in a private repository, use these secrets to pull. (NOTE: The secret must be created manually in the namespace first.)
- `kubernetes_json_patches`: Applies an RFC 6902 compliant JSON patch to the Kubernetes objects.

View File

@ -1,18 +1,20 @@
# Device code flow
---
title: Device code flow
---
(Also known as device flow and [RFC 8628](https://datatracker.ietf.org/doc/html/rfc8628))
The device code flow is also known as _device flow_ or _device authorization grant flow_. This type of authentication flow is useful for devices with limited input capabilities and/or devices without browsers. The Request for Comments (RFC) 8628) abstract for this flow states:
This type of authentication flow is useful for devices with limited input abilities and/or devices without browsers.
> The OAuth 2.0 device authorization grant is designed for Internet-connected devices that either lack a browser to perform a user-agent-based authorization or are input constrained to the extent that requiring the user to input text in order to authenticate during the authorization flow is impractical. It enables OAuth clients on such devices (like smart TVs, media consoles, digital picture frames, and printers) to obtain user authorization to access protected resources by using a user agent on a separate device.
### Requirements
This device flow is only possible if the active brand has a device code flow setup. This device code flow is run _after_ the user logs in, and before the user authenticates.
This device flow is only possible if the active [brand](../../../sys-mgmt/brands.md) has a device code flow configured. This flow is run _after_ the user logs in, and before the user authenticates.
authentik doesn't ship with a default flow for this usecase, so it is recommended to create a new flow for this usecase with the designation of _Stage configuration_
authentik does not include a default flow for this use case, so it is necessary to create a new one with a **Designation** of `Stage Configuration`.
### Device-side
### Device flow initiation
The flow is initiated by sending a POST request to the device authorization endpoint, `/application/o/device/` with the following contents:
The flow is initiated by sending a POST request to the device authorization endpoint, `/application/o/device/`, with the following contents:
```http
POST /application/o/device/ HTTP/1.1
@ -32,8 +34,6 @@ The response contains the following fields:
- `expires_in`: The total seconds after which this token will expire
- `interval`: The interval in seconds for how often the device should check the token status
---
With this response, the device can start checking the status of the token by sending requests to the token endpoint like this:
```http
@ -50,7 +50,7 @@ If the user has not opened the link above yet, or has not finished the authentic
If the user _has_ finished the authentication and authorization, the response will be similar to any other generic OAuth2 Token request, containing `access_token` and `id_token`.
### Creating and applying a device code flow
### Create and apply a device code flow
1. Log in to authentik as an admin, and open the authentik Admin interface.
2. Navigate to **Flows and Stages** > **Flows** and click **Create**.

View File

@ -64,7 +64,7 @@ When using an OAuth 2.0 provider in authentik, the OP must validate the provided
When you create a new OAuth 2.0 provider and app in authentik and you leave the **Redirect URI** field empty, then the first time a user opens that app, authentik uses that URL as the saved redirect URL.
For advanced use cases, an authentik admin can use regular expressions (regex) instead of a redirect URL. For example, if you want to list 10 diff applications, instead of listing all ten you can create an expression with wildcards. Be aware, when using regex, that authetnik uses a dot as a separator in the URL, but in regex a dot means "one of any character", a wildcard. So you should escape the dot to prevent its interpration as a wildcard.
For advanced use cases, an authentik admin can use regular expressions (regex) instead of a redirect URL. For example, if you want to list ten different applications, instead of listing them all individually, you can create an expression with wildcards. When using regex, be aware that authentik uses a dot as a separator in the URL, but in regex a dot means "one of any character", a wildcard. You should therefore escape the dot with `\.` to prevent its interpretation as a wildcard.
## OAuth 2.0 flows and grant types

View File

@ -0,0 +1,13 @@
---
title: WebFinger support
---
## About WebFinger
The [WebFinger protocol](https://webfinger.net/) allows for the discovery of information about individuals or entities on the Internet through standard HTTP methods. It enables the retrieval of information associated with a URI that might not be directly usable as a locator, such as those for accounts or email addresses.
## authentik WebFinger support
authentik provides a WebFinger endpoint when the **Default application** setting uses an OIDC provider. Instructions on how to set a **Default application** can be found in the [authentik Branding documentation](../../../sys-mgmt/brands.md#external-user-settings).
The WebFinger endpoint is available at: `https://authentik.company/.well-known/webfinger` (where authentik.company is the FQDN of your authentik instance)

View File

@ -66,6 +66,10 @@ Starting with authentik 2022.11.0, the following checks can also be done with th
- Check the password hash against the database of [Have I Been Pwned](https://haveibeenpwned.com/). Only the first 5 characters of the hashed password are transmitted, the rest is compared in authentik
- Check the password against the password complexity checker [zxcvbn](https://github.com/dropbox/zxcvbn), which detects weak password on various metrics.
### Password Uniqueness Policy
This policy prevents users from reusing their previous passwords when setting a new password. For detailed information, see [Password Uniqueness Policy](./unique_password.md).
### Reputation Policy
authentik keeps track of failed login attempts by source IP and attempted username. These values are saved as scores. Each failed login decreases the score for the client IP as well as the targeted username by 1 (one).

View File

@ -0,0 +1,46 @@
---
title: Password Uniqueness Policy
sidebar_label: Password Uniqueness Policy
support_level: authentik
tags:
- policy
- password
- security
- enterprise
authentik_version: "2025.4.0"
authentik_enterprise: true
---
The Password Uniqueness policy prevents users from reusing their previous passwords when setting a new password. To use this feature, you will need to create a Password Uniqueness policy, using the instructions below.
## How it works
This policy maintains a record of previously used passwords for each user. When a new password is created, it is compared against this historical log. If a match is found with any previous password, the policy is not met, and the user is required to choose a different password.
The password history is maintained automatically when this policy is in use. Old password hashes are stored securely in authentik's database.
:::info
This policy takes effect after the first password change following policy activation. Before that first change, there's no password history data to compare against.
:::
## Integration with other policies
For comprehensive password security, consider using this policy alongside:
- [Password Policy](./index.md#password-policy) - To enforce password complexity rules
- [Password-Expiry Policy](./index.md#password-expiry-policy) - To enforce regular password rotation
## Implement a Password Uniqueness policy
To implement a policy that prevents users from reusing their previous passwords, follow these steps:
1. In the Admin interface, navigate to **Customization** > **Policies**.
2. Click **Create** to define a new Password Uniqueness Policy.
- **Name**: provide a descriptive name for the policy.
- **Password field**: enter the name of the input field to check for the new password. By default, if no custom flows are used, the field name is `password`. This field name must match the field name used in your Prompt stage.
- **Number of previous passwords to check**: enter the number of past passwords that you want to set as the number of previous passwords that are checked and stored for each user, with a default of 1. For instance, if set to 3, users will not be able to reuse any of their last 3 passwords.
3. Bind the policy to your **password prompt stage**: For example, if you're using the `default-password-change` flow, edit the `default-password-change-prompt` stage and add the policy in the **Validation Policies** section.
:::info
Password history records are stored securely and cannot be used to reconstruct original passwords.
:::

View File

@ -40,7 +40,7 @@ Always include cross-references to related content. If a concept is referenced e
### Relative vs. absolute paths
Use relative paths when linking to other documentation files. This will ensure links are automatically updated if file paths change in the future. If you are linking between our Integration Guides and our regular technical docs, then use an absolute path.
Use relative paths when linking to other documentation files. This will ensure links are automatically updated if file paths change in the future. If you are linking between another authentik resource that is not in the same repository and our regular technical docs, then use an absolute path.
### Markdown file type
@ -52,16 +52,19 @@ Try to write procedural (How To) docs generically enough that it does not endors
## Terminology
### authentik product naming conventions
### authentik product name and terms
- The product name **authentik** should always be written with a lowercase "a" and a "k" at the end, even if it begins a sentence. This consistent style should be followed throughout the documentation.
- The company name is **Authentik Security, Inc.**, but for non-legal documentation, you may shorten it to **Authentik Security**.
- When referring to the authentik Admin interface, capitalize "Admin" like it is in the UI, but do not bold the phrase "Admin interface" unless in a sentence that explicitly says "Click on **Admin interface**". However, if you are referring to a user or role that is an administrator, or has administrative rights, then do not capitalize it and spell out the full word "administrator" or "administrative".
### Industry terms and technology names
- When referring to external tools or industry terms, always use the exact capitalization and naming conventions that the product or company uses. Refer to their website or official documentation for the proper formatting. For example, use "OAuth", "SAML", or "Docker" as per the official conventions.
- Avoid abbreviations unless they are well-known and widely recognized (e.g., SSO, MFA, RBAC).
- If an acronym is used less frequently, spell out its full meaning when first mentioned, followed by the acronym in parentheses. For instance, "Security Assertion Markup Language (SAML)".
- If an acronym is used less frequently, spell out its full meaning when first mentioned, followed by the acronym in parentheses. For instance, "Security Assertion Markup Language (SAML)". In some cases the acronym can come first, followed by the full term in parentheses.
## Writing style
@ -73,10 +76,6 @@ The tone of the authentik documentation should be friendly but professional. It
The documentation uses **American English** spelling conventions (e.g., "customize" instead of "customise").
### Punctuation
For Ken's sake, and many others, try to not use too many commas (avoid commaitis). Use a comma when needed to separate clauses, or for "slowing the pace" or clarity. Please **do** use the Oxford comma.
### Voice
Use **active voice** and **present tense** for clear, direct communication.
@ -91,6 +90,20 @@ Avoid phrasing that blames the user. Be subjective and polite when providing ins
- **DON'T:** "Never modify the default file."
- **DO:** "We recommend that you do not modify the default file, as doing so may result in unexpected issues."
### Punctuation
For Ken's sake, and many others, try to not use too many commas (avoid commaitis). Use a comma when needed to separate clauses, or for "slowing the pace" or clarity. Please **do** use the Oxford comma.
### Capitalization
#### Titles and headers
Titles and headers (H1, H2, H3, etc.) should follow **sentence case capitalization**, meaning only the first word is capitalized, except for proper nouns or product names.For more information, see [below](#titles-and-headers)
#### Following a colon
Whether to capitalize after a colon depends on the context. Typically, we do not capitalize the first word after a colon _unless_ it's a proper noun or if it is the start of a complete sentence. If the colon introduces a list, do not capitalize the first word unless it's a proper noun. In headings and titles, capitalize the first word after the colon.
## Word choices
### "May" versus "Might" versus "Can"
@ -135,7 +148,7 @@ When writing out steps in a procedural topic, avoid starting with "Once...". Ins
### Fonts and font styling
- When referring to internal components in authentik, like the policy engine, or blueprints, do not use any special formatting. Link to the relevant documentation when possible.
- When referring to internal components in authentik, like the policy engine, or blueprints, do not use any special formatting, and do not capitalize. Link to the relevant documentation when possible.
- When referring to authentik functionality and features, such as flows, stages, sources, or policies, do not capitalize and do not use bold or italic text. When possible link to the corresponding documentation.
@ -172,7 +185,7 @@ When writing out steps in a procedural topic, avoid starting with "Once...". Ins
- Ensure titles and headers are descriptive and clearly convey the purpose of the section. Avoid vague titles like "Overview." Instead, opt for something more specific, like "About authentik policies."
- Use the **imperative verb form** in procedural topics. For example, use "Configure your instance" instead of "Configuring your instance."
- Use the **imperative verb form** in procedural topics, not gerunds. For example, use "Configure your instance" instead of "Configuring your instance."
### Examples

View File

@ -70,6 +70,8 @@ To check if your config has been applied correctly, you can run the following co
- `AUTHENTIK_POSTGRESQL__USER`: Database user
- `AUTHENTIK_POSTGRESQL__PORT`: Database port, defaults to 5432
- `AUTHENTIK_POSTGRESQL__PASSWORD`: Database password, defaults to the environment variable `POSTGRES_PASSWORD`
- `AUTHENTIK_POSTGRESQL__USE_POOL`: Use a [connection pool](https://docs.djangoproject.com/en/stable/ref/databases/#connection-pool) for PostgreSQL connections. Defaults to `false`. :ak-version[2025.4]
- `AUTHENTIK_POSTGRESQL__POOL_OPTIONS`: Extra configuration to pass to the [ConnectionPool object](https://www.psycopg.org/psycopg3/docs/api/pool.html#psycopg_pool.ConnectionPool) when it is created. Must be a base64-encoded JSON dictionary. Ignored when `USE_POOL` is set to `false`. :ak-version[2025.4]
- `AUTHENTIK_POSTGRESQL__USE_PGBOUNCER`: Adjust configuration to support connection to PgBouncer. Deprecated, see below
- `AUTHENTIK_POSTGRESQL__USE_PGPOOL`: Adjust configuration to support connection to Pgpool. Deprecated, see below
- `AUTHENTIK_POSTGRESQL__SSLMODE`: Strictness of ssl verification. Defaults to `"verify-ca"`

File diff suppressed because it is too large Load Diff

View File

@ -27,9 +27,9 @@ This guide outlines the critical components to back up and restore in authentik.
### Backup
- **Role:** Manages temporary data:
- User sessions (lost data = users must reauthenticate).
- Pending tasks (e.g., queued emails, outpost syncs).
- **Impact of Loss:** Service interruptions (e.g., users logged out), and potential permanent data loss (e.g., queued emails).
- Cache
- **Impact of Loss:** Temporary performance loss (while cache gets rebuilt), and potential permanent data loss (e.g., queued emails).
- **Backup Guidance:**
- Use Redis' [`SAVE`](https://redis.io/commands/save) or [`BGSAVE`](https://redis.io/commands/bgsave).
- **Official Documentation:** [Redis Persistence](https://redis.io/docs/management/persistence/)

View File

@ -0,0 +1,66 @@
---
title: "Initial permissions"
description: "Set permissions for object creation."
authentik_version: "2025.4.0"
authentik_preview: true
---
Initial permissions automatically assigns [object-level permissions](./permissions.md#object-permissions) between a newly created object and its creator.
The purpose of initial permissions is to assign a specific user (or role) a set of pre-selected permissions that are required for them to accomplish their tasks.
An authentik administrator creates an initial permissions object (a set of selected permissions) and then associates it with either: 1) an individual user 2) a role - in which case everyone in a group with that role will have the same initial permissions.
## Common use cases
Imagine you have a new team tasked with creating [flows](../../add-secure-apps/flows-stages/flow/index.md) and [stages](../../add-secure-apps/flows-stages/stages/index.md). These team members need the ability to view and manage all the flow and stage objects created by other team members. However, they should not have permissions to perform any other actions within the Admin interface.
In the example use case above, the specific objects that the users or role create and manage could be any object. For example, you might have a team responsible for creating new users and managing those user objects, but they should not be able to create flows, blueprints, or brands.
## High-level workflow
The fundamental steps to implement initial permissions are as follows:
1. Create a role. Initial permissions will be assigned whenever a user with this role creates a new object.
2. Create a group, and assign the new role to it, and add any members that you want to use the initial permissions set. You can also create new users later, and add them to the group.
3. Create an initial permissions object, and add all needed permissions to it.
4. Optionally, create additional users and add them to the group to which the role is assigned.
Because the new initial permissions object is coupled with the role (and that role is assigned to a group), the initial permissions object is applied automatically to any new objects (users or flows or any object) that the member user creates.
:::info
Typically, initial permissions are assigned to a user or role that is not a super-user nor administrator. In this scenario, the administrator needs to verify that the user has the `Can view Admin interface` permission (which allows the user to access the Admin interface). For details, see Step 5 below.
Be aware that any rights beyond viewing the Admin interface will need to be assigned as well; for example, if you want a non-administrator user to be able to create flows in the Admin interface, you need to grant those global permissions to add flows.
:::
## Create and implement initial permissions
To create a new set of initial permissions and apply them to either a single user or a role (and every user with that role), follow these steps:
1. Log in to authentik as an administrator, and open the authentik Admin interface.
2. [Create a new role](../roles/manage_roles.md): navigate to **Directory** > **Roles** and click **Create**.
3. [Create a new group](../groups/manage_groups.mdx): navigate to **Directory** > **Groups** and click **Create**. After creating the group:
- [assign the new role to the group](../groups/manage_groups.mdx#assign-a-role-to-a-group)
- [add any members](../user/user_basic_operations.md#add-a-user-to-a-group) that require the initial permissions. You can add already existing users, or [create new users](../user/user_basic_operations.md#create-a-user).
4. Create an initial permissions object: navigate to **Directory** > **Initial Permissions** and click **Create**. Configure the following settings:
- **Name**: Provide a descriptive name for the new initial permissions object.
- **Role**: Select the role to which you want to apply initial permissions. When a member of a group with this assigned role creates an object, initial permissions will be applied to that object.
- **Mode**: select whether you want to attach the initial permission to a _role_ or to a _single user_.
- **Role**: select this to allow everyone with that role (i.e. everyone in a group to which this role is assigned) to be able to see each others' objects.
- **User**: select this to apply the initial permissions _only_ to a user
- **Permissions**: select all permissions to add to the initial permissions object.
5. To ensure that the user or role (whichever you selected in the **Mode** configuration step above) to whom you assign the initial permissions _also_ has access to the Admin interface, check to see if the users also need [the global permission `Can view admin interface`](./manage_permissions#assign-can-view-admin-interface-permissions). Furthermore, verify that the user(s) has the global permissions to add specific objects.
6. Optionally, create new users and add them to the group. Each new user added to the group will automatically have the set of permissions included within the initial permissions object.

View File

@ -3,7 +3,9 @@ title: "Manage permissions"
description: "Learn how to use global and object permissions in authentik."
---
Refer to the following topics for instructions to view and manage permissions. To learn more about the concepts and fundamanetals of authentik permissions, refer to [About Permissions](./permissions.md).
For instructions on viewing and managing permissions, see the following topics.To learn more about the concepts and fundamentals of authentik permissions, refer to [About Permissions](./permissions.md).
To learn about using Initial Permissions, a pre-defined set of permissions, refer to our [documentation](./initial_permissions.mdx).
## View permissions
@ -30,7 +32,7 @@ To view _object_ permissions for a specific user or role:
### View stage permissions
\_These instructions apply to all objects that **do not** have a detail page.\_\_
_These instructions apply to all objects that **do not** have a detail page._
1. Go to the Admin interface and navigate to **Flows and Stages -> Stages**.
2. On the row for the specific stage whose permissions you want to view, click the **lock icon**.
@ -68,14 +70,30 @@ To assign or remove _global_ permissions for a user:
6. In the **Assign permission to user** box, click the plus sign (**+**) and then click the checkbox beside each permission that you want to assign to the user. To remove permissions, deselect the checkbox.
7. Click **Add**, and then click **Assign** to save your changes and close the box.
### Assign or remove permissions on a specific group
### Assign `Can view Admin interface` permissions
You can grant regular users, who are not superusers nor Admins, the right to view the Admin interface. This can be useful in scenarios where you have a team who needs to be able to create certain objects (flows, other users, etc) but who should not have full access to the Admin interface.
To assign the `Can view Admin interface` permission to a user (follow the same steps for a role):
1. Go to the Admin interface and navigate to **Directory -> User**.
2. Select a specific user the clicking on the user's name.
3. Click the **Permissions** tab at the top of the page.
4. Click **Assigned Global Permissions** to the left.
5. In the **Assign permissions** area, click **Assign Permission**.
6. In the **Assign permission to user** box, click the plus sign (**+**), enter `admin` in the Search field and click the search icon.
7. Select the returned permission, click **Add**, and then click **Assign** to save your changes and close the box.
Be aware that any rights beyond viewing the Admin interface will need to be assigned as well; for example, if you want a non-administrator user to be able to create flows in the Admin interface, you need to grant those global permissions to add flows.
### Assign or remove object permissions on a group
:::info
Note that groups themselves do not have permissions. Rather, users and roles have permissions assigned that allow them to create, modify, delete, etc., a group.
Also there are no global permissions for groups.
:::
To assign or remove _object_ permissions on a specific group by users and roles:
To assign or remove _object_ permissions on a specific group for users and roles:
1. Go to the Admin interface and navigate to **Directory -> Groups**.
2. Select a specific group by clicking the group's name.

View File

@ -18,6 +18,8 @@ There are two main types of permissions in authentik:
- [**Global permissions**](#global-permissions)
- [**Object permissions**](#object-permissions)
Additionally, authentik employs _initial permissions_ to streamline the process of granting object-level permissions when an object (user or role) is created. This feature enables an Admin to proactively assign specific rights to a user for object creation, as well as for viewing and managing those objects and other objects created by individuals in the same role. For more details, refer to [Initial permissions](./initial_permissions.mdx).
### Global permissions
Global permissions define who can do what on a global level across the entire system. Some examples in authentik are the ability to add new [flows](../../add-secure-apps/flows-stages/flow/index.md) or to create a URL for users to recover their login credentials.

View File

@ -31,7 +31,7 @@ Starting with authentik version 2025.2, the permission to change super-user stat
To [add or remove users](../user/user_basic_operations.md#add-a-user-to-a-group) from the group, or to manage permissions assigned to the group, click on the name of the group to go to the group's detail page and then click on the **Permissions** tab.
For more information about permissions, refer to [Assign or remove permissions for a specific group](../access-control/manage_permissions.md#assign-or-remove-permissions-on-a-specific-group).
For more information about permissions, refer to [Assign or remove permissions for a specific group](../access-control/manage_permissions.md#assign-or-remove-object-permissions-on-a-group).
## Delete a group
@ -47,7 +47,7 @@ You can assign a role to a group, and then all users in the group inherit the pe
## Delegating group member management:ak-version[2024.4]
To give a specific Role or User the ability to manage group members, the following permissions need to be granted on the matching Group object:
To give a specific role or user the ability to manage group members, the following permissions need to be granted on the matching group object:
- Can view group
- Can add user to group

View File

@ -7,66 +7,79 @@ support_level: community
The following placeholders are used in this guide:
- `ad.company` is the Name of the Active Directory domain.
- `ad.company` is the name of the Active Directory domain.
- `authentik.company` is the FQDN of the authentik install.
## Active Directory setup
## Active Directory configuration
1. Open Active Directory Users and Computers
To support the integration of Active Directory with authentik, you need to create a service account in Active Directory.
2. Create a user in Active Directory, matching your naming scheme
1. Open **Active Directory Users and Computers** on a domain controller or computer with **Active Directory Remote Server Administration Tools** installed.
2. Navigate to an Organizational Unit, right click on it, and select **New** > **User**.
3. Create a service account, matching your naming scheme, for example:
![](./01_user_create.png)
3. Give the User a password, generated using for example `pwgen 64 1` or `openssl rand 36 | base64 -w 0`.
4. Set the password for the service account. Ensure that the **Reset user password and force password change at next logon** option is not checked.
4. Open the Delegation of Control Wizard by right-clicking the domain and selecting "All Tasks".
Either one of the following commands can be used to generate the password:
5. Select the authentik service user you've just created.
```sh
pwgen 64 1
```
6. Ensure the "Reset user password and force password change at next logon" Option is checked.
```sh
openssl rand 36 | base64 -w 0
```
5. Open the **Delegation of Control Wizard** by right-clicking the domain Active Directory Users and Computers, and selecting **All Tasks**.
6. Select the authentik service account that you've just created.
7. Grant these additional permissions (only required when _User password writeback_ is enabled on the LDAP source in authentik, and dependent on your AD Domain)
![](./02_delegate.png)
7. Grant these additional permissions (only required when _Sync users' password_ is enabled, and dependent on your AD Domain)
## authentik Setup
To support the integration of authentik with Active Directory, you will need to create a new LDAP Source in authentik.
1. Log in to authentik as an admin, and open the authentik Admin interface.
2. Navigate to **Directory** > **Federation & Social login**.
3. Click **Create** and select **LDAP Source** as the type.
4. Provide a name, slug, and the following required configurations:
Under **Connection Settings**:
- **Server URI**: `ldap://ad.company`
:::note
For authentik to be able to write passwords back to Active Directory, make sure to use `ldaps://` as a prefix. You can verify that LDAPS is working by opening the `ldp.exe` tool on a domain controller and attempting a connection to the server via port 636. If a connection can be established, LDAPS is functioning as expected. More information can be found in the [Microsoft LDAPS documentation](https://learn.microsoft.com/en-us/troubleshoot/windows-server/active-directory/ldap-over-ssl-connection-issues).
Multiple servers can be specified by separating URIs with a comma (e.g. `ldap://dc1.ad.company,ldap://dc2.ad.company`). If a DNS entry with multiple records is used, authentik will select a random entry when first connecting.
:::
- **Bind CN**: `<service account>@ad.company`
- **Bind Password**: the password of the service account created in the previous section.
- **Base DN**: the base DN which you want authentik to sync.
Under **LDAP Attribute Mapping**:
- **User Property Mappings**: select all Mappings which start with "authentik default LDAP" and "authentik default Active Directory"
- **Group Property Mappings**: select "authentik default LDAP Mapping: Name"
Under **Additional Settings** _(optional)_ configurations that may need to be adjusted based on the setup of your domain:
- **Group**: if enabled, all synchronized groups will be given this group as a parent.
- **Addition User/Group DN**: additional DN which is _prepended_ to your Base DN configured above, to limit the scope of synchronization for Users and Groups.
- **User object filter**: which objects should be considered users (e.g. `(objectClass=user)`). For Active Directory set it to `(&(objectClass=user)(!(objectClass=computer)))` to exclude Computer accounts.
- **Group object filter**: which objects should be considered groups (e.g `(objectClass=group)`).
- **Lookup using a user attribute**: acquire group membership from a User object attribute (`memberOf`) instead of a Group attribute (`member`). This works with directories and nested groups memberships (Active Directory, RedHat IDM/FreeIPA), using `memberOf:1.2.840.113556.1.4.1941:` as the group membership field.
- **Group membership field**: the user object attribute or the group object attribute that determines the group membership of a user (e.g. `member`). If **Lookup using a user attribute** is set, this should be a user object attribute, otherwise a group object attribute.
- **Object uniqueness field**: a user attribute that contains a unique identifier (e.g. `objectSid`).
5. Click **Finish** to save the LDAP Source. An LDAP synchronization will begin in the background. Once completed, you can view the summary by navigating to **Dashboards** > **System Tasks**:
![](./03_additional_perms.png)
Additional info: https://support.microfocus.com/kb/doc.php?id=7023371
6. To finalise the Active Directory setup, you need to enable the backend "authentik LDAP" in the Password Stage.
## authentik Setup
In authentik, create a new LDAP Source in Directory -> Federation & Social login.
Use these settings:
- Server URI: `ldap://ad.company`
For authentik to be able to write passwords back to Active Directory, make sure to use `ldaps://`. You can test to verify LDAPS is working using `ldp.exe`.
You can specify multiple servers by separating URIs with a comma, like `ldap://dc1.ad.company,ldap://dc2.ad.company`.
When using a DNS entry with multiple Records, authentik will select a random entry when first connecting.
- Bind CN: `<name of your service user>@ad.company`
- Bind Password: The password you've given the user above
- Base DN: The base DN which you want authentik to sync
- Property mappings: Control/Command-select all Mappings which start with "authentik default LDAP" and "authentik default Active Directory"
- Group property mappings: Select "authentik default LDAP Mapping: Name"
Additional settings that might need to be adjusted based on the setup of your domain:
- Group: If enabled, all synchronized groups will be given this group as a parent.
- Addition User/Group DN: Additional DN which is _prepended_ to your Base DN configured above to limit the scope of synchronization for Users and Groups
- User object filter: Which objects should be considered users. For Active Directory set it to `(&(objectClass=user)(!(objectClass=computer)))` to exclude Computer accounts.
- Group object filter: Which objects should be considered groups.
- Group membership field: Which user field saves the group membership
- Object uniqueness field: A user field which contains a unique Identifier
After you save the source, a synchronization will start in the background. When its done, you can see the summary under Dashboards -> System Tasks.
![](./03_additional_perms.png)
To finalise the Active Directory setup, you need to enable the backend "authentik LDAP" in the Password Stage.
![](./11_ak_stage.png)
![](./11_ak_stage.png)

Some files were not shown because too many files have changed in this diff Show More