Compare commits

..

50 Commits

Author SHA1 Message Date
2bc318d167 website: changelog for security releases (#15291)
* website: changelog for security releases

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* format

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
# Conflicts:
#	website/docs/releases/2025/v2025.6.md
2025-06-27 15:43:34 +02:00
b34665fabd release: 2025.4.3 2025-06-27 15:34:22 +02:00
0e07414e97 security: fix CVE-2025-52553 (#15289)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
# Conflicts:
#	website/sidebars/docs.mjs
2025-06-27 15:28:27 +02:00
dcbf5f323c website/docs: fixes misplaced sentence (cherry-pick #14998) (#15181)
website/docs: fixes misplaced sentence (#14998)

fixes misplaced sentence

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: Tana M Berry <tana@goauthentik.io>
2025-06-22 00:58:42 +02:00
c3f1d6587d website/docs: fix egregious maintenance fail (cherry-pick #15176) (#15179)
website/docs: fix egregious maintenance fail (#15176)

fix egregious maintenance fail

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: Tana M Berry <tana@goauthentik.io>
2025-06-22 00:58:28 +02:00
7254c11cb9 website/docs: remove commented out config options (cherry-pick #15064) (#15066)
website/docs: remove commented out config options (#15064)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2025-06-16 16:56:22 +02:00
ca4e6a10f5 website/docs: also hide the postgres pool_options setting (cherry-pick #15023) (#15033)
Co-authored-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-06-13 15:40:52 +02:00
bda30c5ad5 release: 2025.4.2 2025-06-04 15:27:50 +02:00
588a7ff2e1 website/docs: release notes for 2025.4.2 (cherry-pick #14868) (#14873)
website/docs: release notes for `2025.4.2` (#14868)

Co-authored-by: Simonyi Gergő <28359278+gergosimonyi@users.noreply.github.com>
2025-06-04 15:27:08 +02:00
599d0f701f website/docs: release notes for 2025.4.1 (cherry-pick #14526) (#14872)
website/docs: release notes for 2025.4.1 (#14526)

* website/docs: release notes for 2025.4.1



* format



---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2025-06-04 15:22:52 +02:00
967e4cce9d website/docs: fix leftover placeholder in release notes (cherry-pick #14377) (#14871)
website/docs: fix leftover placeholder in release notes (#14377)

Update v2025.4.md

changed download URL to match version 2025.4. Otherwise it will give a 404

Signed-off-by: finkerle <145992792+finkerle@users.noreply.github.com>
Co-authored-by: finkerle <145992792+finkerle@users.noreply.github.com>
2025-06-04 15:22:39 +02:00
f1c5f43419 website/docs: fix dry-run release highlight (cherry-pick #14337) (#14870)
website/docs: fix dry-run release highlight (#14337)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2025-06-04 15:22:00 +02:00
b5b68fc829 website/docs: clarify 2025.4 breaking Reputation changes (cherry-pick #14284) (#14869)
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



* change to bump build checks

* another tweak to bounce after rebase

---------

Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: Simonyi Gergő <28359278+gergosimonyi@users.noreply.github.com>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: Tana M Berry <tana@goauthentik.io>
2025-06-04 15:21:28 +02:00
1d7be5e770 core: Migrate permissions before deleteing OldAuthenticatedSession (cherry-pick #14788) (#14791)
core: Migrate permissions before deleteing OldAuthenticatedSession (#14788)

* add migrate_permissions_before_delete to authentik_core 0047 migration

* fix linting

* new approach

* fixup! new approach

---------

Co-authored-by: Marcelo Elizeche Landó <marcelo@goauthentik.io>
Co-authored-by: Simonyi Gergő <gergo@goauthentik.io>
2025-05-30 18:05:52 +02:00
489ef7a0a1 ci: fix broken cache (cherry-pick #14725) (#14792)
ci: fix broken cache (#14725)

* ci: fix broken cache



* fix commit hash



---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2025-05-30 17:28:51 +02:00
668f35cd5b sources/scim: fix all users being added to group when no members are given (cherry-pick #14645) (#14666)
sources/scim: fix all users being added to group when no members are given (#14645)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2025-05-23 17:24:27 +02:00
42f0528a1d lifecycle: fix arguments not being passed to worker command (cherry-pick #14574) (#14620)
Co-authored-by: Jens L. <jens@goauthentik.io>
fix arguments not being passed to worker command (#14574)
2025-05-22 13:51:08 +02:00
ae47624761 release: 2025.4.1 2025-05-15 19:10:52 +02:00
14a6430e21 core: fix unable to create group if no enable_group_superuser permission is given (cherry-pick #14510) (#14521)
core: fix unable to create group if no enable_group_superuser permission is given (#14510)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2025-05-15 15:05:04 +02:00
ed0a9d6a0a core: remove OldAuthenticatedSession content type (cherry-pick #14507) (#14509)
core: remove `OldAuthenticatedSession` content type (#14507)

* core: remove `OldAuthenticatedSession` content type

This was left out from https://github.com/goauthentik/authentik/pull/9736

* remove stale content types in `repair_permissions`



* run `remove_stale_contenttypes` for each tenant

---------

Co-authored-by: Simonyi Gergő <28359278+gergosimonyi@users.noreply.github.com>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2025-05-14 15:33:14 +02:00
53143e0c40 enterprise: fix expired license's users being counted (cherry-pick #14451) (#14496)
enterprise: fix expired license's users being counted (#14451)

* enterprise: fix expired license's users being counted



* tests to the rescue



* hmm



---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2025-05-13 16:07:08 +02:00
178e010ed4 root: backport SFE Build fix (#14495)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-05-13 14:32:13 +02:00
49b666fbde root: temporarily deactivate database pool option (cherry-pick #14443) (#14479)
root: temporarily deactivate database pool option (#14443)

* root: temporarily deactivate database pool option



* format



* deactivate tests



---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2025-05-12 19:13:09 +02:00
c343e3a7f4 core: fix session migration when old session can't be loaded (cherry-pick #14466) (#14480)
core: fix session migration when old session can't be loaded (#14466)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2025-05-12 16:09:05 +02:00
5febf3ce5b core: bump h11 from 0.14.0 to v0.16.0 (cherry-pick #14352) (#14472)
core: bump h11 from 0.14.0 to v0.16.0 (#14352)

Co-authored-by: Marcelo Elizeche Landó <marcelo@goauthentik.io>
2025-05-11 15:09:22 +02:00
b8c5bd678b web/flows/sfe: fix global background image not being loaded (cherry-pick #14442) (#14450)
web/flows/sfe: fix global background image not being loaded (#14442)

* web/flows/sfe: add initial loading spinner



* fix brand-level default flow background not working with SFE and loading original image with full flow interface

https://github.com/goauthentik/authentik/pull/13079#issuecomment-2853357407


---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2025-05-09 18:14:21 +02:00
4dd5eccbaa lifecycle: fix ak dump_config (cherry-pick #14445) (#14448)
lifecycle: fix ak dump_config (#14445)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2025-05-09 18:14:06 +02:00
2410884006 outposts: fix tmpdir in containers not being set (cherry-pick #14444) (#14449)
outposts: fix tmpdir in containers not being set (#14444)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2025-05-09 18:13:41 +02:00
3cb921b0f9 rbac: fix RoleObjectPermissionTable not showing add_user_to_group (cherry-pick #14312) (#14334)
rbac: fix RoleObjectPermissionTable not showing `add_user_to_group` (#14312)

fix RoleObjectPermissionTable not showing `add_user_to_group`

Co-authored-by: Simonyi Gergő <28359278+gergosimonyi@users.noreply.github.com>
2025-05-02 18:35:13 +02:00
535f92981f website/docs: docs about initial perms (cherry-pick #14263) (#14282)
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




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




* 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 <tanamarieberry@yahoo.com>
Co-authored-by: Tana M Berry <tana@goauthentik.io>
Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
2025-05-01 22:25:36 +02:00
955d69d5b7 brands: fix CSS Migration not updating brands (cherry-pick #14306) (#14308)
brands: fix CSS Migration not updating brands (#14306)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
2025-04-30 23:04:38 +02:00
fb01d8e96a website/docs: initial permissions: fix usage of term admin (cherry-pick #14300) (#14302)
Co-authored-by: Dominic R <dominic@sdko.org>
fix usage of term admin (#14300)
2025-04-30 15:44:44 +02:00
6d39efd3e3 ci: cleanup post uv migration (cherry-pick #13538) (#14297)
Co-authored-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-30 15:05:46 +02:00
3020c31bcd website/docs: add gateway API to release notes and documentation (cherry-pick #14278) (#14298)
Co-authored-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-30 14:52:38 +02:00
22412729e2 release: 2025.4.0 2025-04-29 16:16:32 -03:00
a02868a27d 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 15:56:28 -03:00
bfbb4a8ebc website/docs: sessions in database (#13507)
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-29 15:56:21 -03:00
6c0e827677 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 15:56:13 -03:00
29884cbf81 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 15:56:01 -03:00
0f02985b0c 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 15:55:54 -03:00
2244e026c2 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 15:55:47 -03:00
429c03021c 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 15:55:41 -03:00
f47e8d9d72 docs/website: Update 2025.4 notes (#14272)
Fix styling
2025-04-29 15:55:35 -03:00
3e7d2587c4 website/docs: update 2025.4 release notes (#14251)
* Update release notes for 2025.4

* fix typo

* Add/improve highlights, features and descriptions

* Fix linting and remove API changes

* remove minor changes

* fix linting

* Add helm chart stuff and integrations guide

* fix linting

* Restore SECURITY.md and sidebar.js

* 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>

* 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>

* 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>

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

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

* password history - add compliance note

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

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

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

* please the linter

* use current version

* add .md

* fix badges

---------

Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Fletcher Heisler <fheisler@users.noreply.github.com>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: Fletcher Heisler <fheisler@users.noreply.github.com>
2025-04-29 15:54:55 -03:00
55a38d4a36 rbac: add name to Permissions search (cherry-pick #14269) (#14270)
rbac: add `name` to Permissions search (#14269)

Co-authored-by: Simonyi Gergő <28359278+gergosimonyi@users.noreply.github.com>
2025-04-28 19:04:05 +02:00
6021bb932d web: fix bug that was causing charts to be too tall (cherry-pick #14253) (#14254)
Co-authored-by: Ken Sternberg <133134217+kensternberg-authentik@users.noreply.github.com>
fix bug that was causing charts to be too tall (#14253)
2025-04-28 13:51:49 +02:00
54a5d95717 release: 2025.4.0-rc2 2025-04-25 13:50:44 +02:00
a0a1275452 lifecycle: fix test-all in docker (cherry-pick #14244) (#14246)
Co-authored-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
fix test-all in docker (#14244)
2025-04-25 13:50:27 +02:00
919aa5df59 core, web: update translations (cherry-pick #14243) (#14245)
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
Co-authored-by: rissson <18313093+rissson@users.noreply.github.com>
2025-04-25 13:39:50 +02:00
cedf7cf683 release: 2025.4.0-rc1 2025-04-25 01:53:53 -03:00
53 changed files with 429 additions and 217 deletions

View File

@ -1,5 +1,5 @@
[bumpversion]
current_version = 2025.4.0
current_version = 2025.4.3
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

@ -36,7 +36,7 @@ runs:
with:
go-version-file: "go.mod"
- name: Setup docker cache
uses: ScribeMD/docker-cache@0.5.0
uses: AndreKurait/docker-cache@0fe76702a40db986d9663c24954fc14c6a6031b7
with:
key: docker-images-${{ runner.os }}-${{ hashFiles('.github/actions/setup/docker-compose.yml', 'Makefile') }}-${{ inputs.postgresql_version }}
- name: Setup dependencies

View File

@ -40,7 +40,8 @@ COPY ./web /work/web/
COPY ./website /work/website/
COPY ./gen-ts-api /work/web/node_modules/@goauthentik/api
RUN npm run build
RUN npm run build && \
npm run build:sfe
# Stage 3: Build go proxy
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.24-bookworm AS go-builder
@ -94,7 +95,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.7.0 AS uv
FROM ghcr.io/astral-sh/uv:0.6.16 AS uv
# Stage 6: Base python image
FROM ghcr.io/goauthentik/fips-python:3.12.10-slim-bookworm-fips AS python-base

View File

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

View File

@ -99,18 +99,17 @@ class GroupSerializer(ModelSerializer):
if superuser
else "authentik_core.disable_group_superuser"
)
has_perm = user.has_perm(perm)
if self.instance and not has_perm:
has_perm = user.has_perm(perm, self.instance)
if not has_perm:
raise ValidationError(
_(
(
"User does not have permission to set "
"superuser status to {superuser_status}."
).format_map({"superuser_status": superuser})
if self.instance or superuser:
has_perm = user.has_perm(perm) or user.has_perm(perm, self.instance)
if not has_perm:
raise ValidationError(
_(
(
"User does not have permission to set "
"superuser status to {superuser_status}."
).format_map({"superuser_status": superuser})
)
)
)
return superuser
class Meta:

View File

@ -2,6 +2,7 @@
from django.apps import apps
from django.contrib.auth.management import create_permissions
from django.core.management import call_command
from django.core.management.base import BaseCommand, no_translations
from guardian.management import create_anonymous_user
@ -16,6 +17,10 @@ class Command(BaseCommand):
"""Check permissions for all apps"""
for tenant in Tenant.objects.filter(ready=True):
with tenant:
# See https://code.djangoproject.com/ticket/28417
# Remove potential lingering old permissions
call_command("remove_stale_contenttypes", "--no-input")
for app in apps.get_app_configs():
self.stdout.write(f"Checking app {app.name} ({app.label})\n")
create_permissions(app, verbosity=0)

View File

@ -31,7 +31,10 @@ class PickleSerializer:
def loads(self, data):
"""Unpickle data to be loaded from redis"""
return pickle.loads(data) # nosec
try:
return pickle.loads(data) # nosec
except Exception:
return {}
def _migrate_session(
@ -76,6 +79,7 @@ def _migrate_session(
AuthenticatedSession.objects.using(db_alias).create(
session=session,
user=old_auth_session.user,
uuid=old_auth_session.uuid,
)

View File

@ -0,0 +1,103 @@
# Generated by Django 5.1.9 on 2025-05-14 11:15
from django.apps.registry import Apps, apps as global_apps
from django.db import migrations
from django.contrib.contenttypes.management import create_contenttypes
from django.contrib.auth.management import create_permissions
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
def migrate_authenticated_session_permissions(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
"""Migrate permissions from OldAuthenticatedSession to AuthenticatedSession"""
db_alias = schema_editor.connection.alias
# `apps` here is just an instance of `django.db.migrations.state.AppConfigStub`, we need the
# real config for creating permissions and content types
authentik_core_config = global_apps.get_app_config("authentik_core")
# These are only ran by django after all migrations, but we need them right now.
# `global_apps` is needed,
create_permissions(authentik_core_config, using=db_alias, verbosity=1)
create_contenttypes(authentik_core_config, using=db_alias, verbosity=1)
# But from now on, this is just a regular migration, so use `apps`
Permission = apps.get_model("auth", "Permission")
ContentType = apps.get_model("contenttypes", "ContentType")
try:
old_ct = ContentType.objects.using(db_alias).get(
app_label="authentik_core", model="oldauthenticatedsession"
)
new_ct = ContentType.objects.using(db_alias).get(
app_label="authentik_core", model="authenticatedsession"
)
except ContentType.DoesNotExist:
# This should exist at this point, but if not, let's cut our losses
return
# Get all permissions for the old content type
old_perms = Permission.objects.using(db_alias).filter(content_type=old_ct)
# Create equivalent permissions for the new content type
for old_perm in old_perms:
new_perm = (
Permission.objects.using(db_alias)
.filter(
content_type=new_ct,
codename=old_perm.codename,
)
.first()
)
if not new_perm:
# This should exist at this point, but if not, let's cut our losses
continue
# Global user permissions
User = apps.get_model("authentik_core", "User")
User.user_permissions.through.objects.using(db_alias).filter(
permission=old_perm
).all().update(permission=new_perm)
# Global role permissions
DjangoGroup = apps.get_model("auth", "Group")
DjangoGroup.permissions.through.objects.using(db_alias).filter(
permission=old_perm
).all().update(permission=new_perm)
# Object user permissions
UserObjectPermission = apps.get_model("guardian", "UserObjectPermission")
UserObjectPermission.objects.using(db_alias).filter(permission=old_perm).all().update(
permission=new_perm, content_type=new_ct
)
# Object role permissions
GroupObjectPermission = apps.get_model("guardian", "GroupObjectPermission")
GroupObjectPermission.objects.using(db_alias).filter(permission=old_perm).all().update(
permission=new_perm, content_type=new_ct
)
def remove_old_authenticated_session_content_type(
apps: Apps, schema_editor: BaseDatabaseSchemaEditor
):
db_alias = schema_editor.connection.alias
ContentType = apps.get_model("contenttypes", "ContentType")
ContentType.objects.using(db_alias).filter(model="oldauthenticatedsession").delete()
class Migration(migrations.Migration):
dependencies = [
("authentik_core", "0047_delete_oldauthenticatedsession"),
]
operations = [
migrations.RunPython(
code=migrate_authenticated_session_permissions,
reverse_code=migrations.RunPython.noop,
),
migrations.RunPython(
code=remove_old_authenticated_session_content_type,
reverse_code=migrations.RunPython.noop,
),
]

View File

@ -124,6 +124,16 @@ class TestGroupsAPI(APITestCase):
{"is_superuser": ["User does not have permission to set superuser status to True."]},
)
def test_superuser_no_perm_no_superuser(self):
"""Test creating a group without permission and without superuser flag"""
assign_perm("authentik_core.add_group", self.login_user)
self.client.force_login(self.login_user)
res = self.client.post(
reverse("authentik_api:group-list"),
data={"name": generate_id(), "is_superuser": False},
)
self.assertEqual(res.status_code, 201)
def test_superuser_update_no_perm(self):
"""Test updating a superuser group without permission"""
group = Group.objects.create(name=generate_id(), is_superuser=True)

View File

@ -132,13 +132,14 @@ class LicenseKey:
"""Get a summarized version of all (not expired) licenses"""
total = LicenseKey(get_license_aud(), 0, "Summarized license", 0, 0)
for lic in License.objects.all():
total.internal_users += lic.internal_users
total.external_users += lic.external_users
if lic.is_valid:
total.internal_users += lic.internal_users
total.external_users += lic.external_users
total.license_flags.extend(lic.status.license_flags)
exp_ts = int(mktime(lic.expiry.timetuple()))
if total.exp == 0:
total.exp = exp_ts
total.exp = max(total.exp, exp_ts)
total.license_flags.extend(lic.status.license_flags)
return total
@staticmethod

View File

@ -39,6 +39,10 @@ class License(SerializerModel):
internal_users = models.BigIntegerField()
external_users = models.BigIntegerField()
@property
def is_valid(self) -> bool:
return self.expiry >= now()
@property
def serializer(self) -> type[BaseSerializer]:
from authentik.enterprise.api import LicenseSerializer

View File

@ -8,6 +8,7 @@ from django.test import TestCase
from django.utils.timezone import now
from rest_framework.exceptions import ValidationError
from authentik.core.models import User
from authentik.enterprise.license import LicenseKey
from authentik.enterprise.models import (
THRESHOLD_READ_ONLY_WEEKS,
@ -71,9 +72,9 @@ class TestEnterpriseLicense(TestCase):
)
def test_valid_multiple(self):
"""Check license verification"""
lic = License.objects.create(key=generate_id())
lic = License.objects.create(key=generate_id(), expiry=expiry_valid)
self.assertTrue(lic.status.status().is_valid)
lic2 = License.objects.create(key=generate_id())
lic2 = License.objects.create(key=generate_id(), expiry=expiry_valid)
self.assertTrue(lic2.status.status().is_valid)
total = LicenseKey.get_total()
self.assertEqual(total.internal_users, 200)
@ -232,7 +233,9 @@ class TestEnterpriseLicense(TestCase):
)
def test_expiry_expired(self):
"""Check license verification"""
License.objects.create(key=generate_id())
User.objects.all().delete()
License.objects.all().delete()
License.objects.create(key=generate_id(), expiry=expiry_expired)
self.assertEqual(LicenseKey.get_total().summary().status, LicenseUsageStatus.EXPIRED)
@patch(

View File

@ -15,6 +15,7 @@
{% endblock %}
<link rel="stylesheet" type="text/css" href="{% static 'dist/sfe/bootstrap.min.css' %}">
<meta name="sentry-trace" content="{{ sentry_trace }}" />
<link rel="prefetch" href="{{ flow_background_url }}" />
{% include "base/header_js.html" %}
<style>
html,
@ -22,7 +23,7 @@
height: 100%;
}
body {
background-image: url("{{ flow.background_url }}");
background-image: url("{{ flow_background_url }}");
background-repeat: no-repeat;
background-size: cover;
}

View File

@ -5,7 +5,7 @@
{% block head_before %}
{{ block.super }}
<link rel="prefetch" href="{{ flow.background_url }}" />
<link rel="prefetch" href="{{ flow_background_url }}" />
{% if flow.compatibility_mode and not inspector %}
<script>ShadyDOM = { force: !navigator.webdriver };</script>
{% endif %}
@ -21,7 +21,7 @@ window.authentik.flow = {
<script src="{% versioned_script 'dist/flow/FlowInterface-%v.js' %}" type="module"></script>
<style>
:root {
--ak-flow-background: url("{{ flow.background_url }}");
--ak-flow-background: url("{{ flow_background_url }}");
}
</style>
{% endblock %}

View File

@ -13,7 +13,9 @@ class FlowInterfaceView(InterfaceView):
"""Flow interface"""
def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
kwargs["flow"] = get_object_or_404(Flow, slug=self.kwargs.get("flow_slug"))
flow = get_object_or_404(Flow, slug=self.kwargs.get("flow_slug"))
kwargs["flow"] = flow
kwargs["flow_background_url"] = flow.background_url(self.request)
kwargs["inspector"] = "inspector" in self.request.GET
return super().get_context_data(**kwargs)

View File

@ -363,6 +363,9 @@ def django_db_config(config: ConfigLoader | None = None) -> dict:
pool_options = config.get_dict_from_b64_json("postgresql.pool_options", True)
if not pool_options:
pool_options = True
# FIXME: Temporarily force pool to be deactivated.
# See https://github.com/goauthentik/authentik/issues/14320
pool_options = False
db = {
"default": {

View File

@ -494,86 +494,88 @@ class TestConfig(TestCase):
},
)
def test_db_pool(self):
"""Test DB Config with pool"""
config = ConfigLoader()
config.set("postgresql.host", "foo")
config.set("postgresql.name", "foo")
config.set("postgresql.user", "foo")
config.set("postgresql.password", "foo")
config.set("postgresql.port", "foo")
config.set("postgresql.test.name", "foo")
config.set("postgresql.use_pool", True)
conf = django_db_config(config)
self.assertEqual(
conf,
{
"default": {
"ENGINE": "authentik.root.db",
"HOST": "foo",
"NAME": "foo",
"OPTIONS": {
"pool": True,
"sslcert": None,
"sslkey": None,
"sslmode": None,
"sslrootcert": None,
},
"PASSWORD": "foo",
"PORT": "foo",
"TEST": {"NAME": "foo"},
"USER": "foo",
"CONN_MAX_AGE": 0,
"CONN_HEALTH_CHECKS": False,
"DISABLE_SERVER_SIDE_CURSORS": False,
}
},
)
# FIXME: Temporarily force pool to be deactivated.
# See https://github.com/goauthentik/authentik/issues/14320
# def test_db_pool(self):
# """Test DB Config with pool"""
# config = ConfigLoader()
# config.set("postgresql.host", "foo")
# config.set("postgresql.name", "foo")
# config.set("postgresql.user", "foo")
# config.set("postgresql.password", "foo")
# config.set("postgresql.port", "foo")
# config.set("postgresql.test.name", "foo")
# config.set("postgresql.use_pool", True)
# conf = django_db_config(config)
# self.assertEqual(
# conf,
# {
# "default": {
# "ENGINE": "authentik.root.db",
# "HOST": "foo",
# "NAME": "foo",
# "OPTIONS": {
# "pool": True,
# "sslcert": None,
# "sslkey": None,
# "sslmode": None,
# "sslrootcert": None,
# },
# "PASSWORD": "foo",
# "PORT": "foo",
# "TEST": {"NAME": "foo"},
# "USER": "foo",
# "CONN_MAX_AGE": 0,
# "CONN_HEALTH_CHECKS": False,
# "DISABLE_SERVER_SIDE_CURSORS": False,
# }
# },
# )
def test_db_pool_options(self):
"""Test DB Config with pool"""
config = ConfigLoader()
config.set("postgresql.host", "foo")
config.set("postgresql.name", "foo")
config.set("postgresql.user", "foo")
config.set("postgresql.password", "foo")
config.set("postgresql.port", "foo")
config.set("postgresql.test.name", "foo")
config.set("postgresql.use_pool", True)
config.set(
"postgresql.pool_options",
base64.b64encode(
dumps(
{
"max_size": 15,
}
).encode()
).decode(),
)
conf = django_db_config(config)
self.assertEqual(
conf,
{
"default": {
"ENGINE": "authentik.root.db",
"HOST": "foo",
"NAME": "foo",
"OPTIONS": {
"pool": {
"max_size": 15,
},
"sslcert": None,
"sslkey": None,
"sslmode": None,
"sslrootcert": None,
},
"PASSWORD": "foo",
"PORT": "foo",
"TEST": {"NAME": "foo"},
"USER": "foo",
"CONN_MAX_AGE": 0,
"CONN_HEALTH_CHECKS": False,
"DISABLE_SERVER_SIDE_CURSORS": False,
}
},
)
# def test_db_pool_options(self):
# """Test DB Config with pool"""
# config = ConfigLoader()
# config.set("postgresql.host", "foo")
# config.set("postgresql.name", "foo")
# config.set("postgresql.user", "foo")
# config.set("postgresql.password", "foo")
# config.set("postgresql.port", "foo")
# config.set("postgresql.test.name", "foo")
# config.set("postgresql.use_pool", True)
# config.set(
# "postgresql.pool_options",
# base64.b64encode(
# dumps(
# {
# "max_size": 15,
# }
# ).encode()
# ).decode(),
# )
# conf = django_db_config(config)
# self.assertEqual(
# conf,
# {
# "default": {
# "ENGINE": "authentik.root.db",
# "HOST": "foo",
# "NAME": "foo",
# "OPTIONS": {
# "pool": {
# "max_size": 15,
# },
# "sslcert": None,
# "sslkey": None,
# "sslmode": None,
# "sslrootcert": None,
# },
# "PASSWORD": "foo",
# "PORT": "foo",
# "TEST": {"NAME": "foo"},
# "USER": "foo",
# "CONN_MAX_AGE": 0,
# "CONN_HEALTH_CHECKS": False,
# "DISABLE_SERVER_SIDE_CURSORS": False,
# }
# },
# )

View File

@ -66,7 +66,10 @@ class RACClientConsumer(AsyncWebsocketConsumer):
def init_outpost_connection(self):
"""Initialize guac connection settings"""
self.token = (
ConnectionToken.filter_not_expired(token=self.scope["url_route"]["kwargs"]["token"])
ConnectionToken.filter_not_expired(
token=self.scope["url_route"]["kwargs"]["token"],
session__session__session_key=self.scope["session"].session_key,
)
.select_related("endpoint", "provider", "session", "session__user")
.first()
)

View File

@ -87,3 +87,22 @@ class TestRACViews(APITestCase):
)
body = loads(flow_response.content)
self.assertEqual(body["component"], "ak-stage-access-denied")
def test_different_session(self):
"""Test request"""
self.client.force_login(self.user)
response = self.client.get(
reverse(
"authentik_providers_rac:start",
kwargs={"app": self.app.slug, "endpoint": str(self.endpoint.pk)},
)
)
self.assertEqual(response.status_code, 302)
flow_response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})
)
body = loads(flow_response.content)
next_url = body["to"]
self.client.logout()
final_response = self.client.get(next_url)
self.assertEqual(final_response.url, reverse("authentik_core:if-user"))

View File

@ -65,7 +65,10 @@ class RACInterface(InterfaceView):
def dispatch(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse:
# Early sanity check to ensure token still exists
token = ConnectionToken.filter_not_expired(token=self.kwargs["token"]).first()
token = ConnectionToken.filter_not_expired(
token=self.kwargs["token"],
session__session__session_key=request.session.session_key,
).first()
if not token:
return redirect("authentik_core:if-user")
self.token = token

View File

@ -97,7 +97,8 @@ class GroupsView(SCIMObjectView):
self.logger.warning("Invalid group member", exc=exc)
continue
query |= Q(uuid=member.value)
group.users.set(User.objects.filter(query))
if query:
group.users.set(User.objects.filter(query))
if not connection:
connection, _ = SCIMSourceGroup.objects.get_or_create(
source=self.source,

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.4.0 Blueprint schema",
"title": "authentik 2025.4.3 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.4.0}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.4.3}
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.4.0}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.4.3}
restart: unless-stopped
command: worker
environment:

View File

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

View File

@ -56,6 +56,7 @@ EXPOSE 3389 6636 9300
USER 1000
ENV GOFIPS=1
ENV TMPDIR=/dev/shm/ \
GOFIPS=1
ENTRYPOINT ["/ldap"]

View File

@ -83,7 +83,8 @@ if [[ "$1" == "server" ]]; then
run_authentik
elif [[ "$1" == "worker" ]]; then
set_mode "worker"
check_if_root "python -m manage worker"
shift
check_if_root "python -m manage worker $@"
elif [[ "$1" == "worker-status" ]]; then
wait_for_db
celery -A authentik.root.celery flower \
@ -97,6 +98,7 @@ elif [[ "$1" == "test-all" ]]; then
elif [[ "$1" == "healthcheck" ]]; then
run_authentik healthcheck $(cat $MODE_FILE)
elif [[ "$1" == "dump_config" ]]; then
shift
exec python -m authentik.lib.config $@
elif [[ "$1" == "debug" ]]; then
exec sleep infinity

View File

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

Binary file not shown.

Binary file not shown.

View File

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

View File

@ -76,6 +76,7 @@ EXPOSE 9000 9300 9443
USER 1000
ENV GOFIPS=1
ENV TMPDIR=/dev/shm/ \
GOFIPS=1
ENTRYPOINT ["/proxy"]

View File

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

View File

@ -56,6 +56,7 @@ HEALTHCHECK --interval=5s --retries=20 --start-period=3s CMD [ "/rac", "healthch
USER 1000
ENV GOFIPS=1
ENV TMPDIR=/dev/shm/ \
GOFIPS=1
ENTRYPOINT ["/rac"]

View File

@ -56,6 +56,7 @@ EXPOSE 1812/udp 9300
USER 1000
ENV GOFIPS=1
ENV TMPDIR=/dev/shm/ \
GOFIPS=1
ENTRYPOINT ["/radius"]

View File

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

14
uv.lock generated
View File

@ -165,7 +165,7 @@ wheels = [
[[package]]
name = "authentik"
version = "2025.4.0"
version = "2025.4.3"
source = { editable = "." }
dependencies = [
{ name = "argon2-cffi" },
@ -1436,11 +1436,11 @@ wheels = [
[[package]]
name = "h11"
version = "0.14.0"
version = "0.16.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 }
sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 },
{ url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515 },
]
[[package]]
@ -1467,15 +1467,15 @@ wheels = [
[[package]]
name = "httpcore"
version = "1.0.8"
version = "1.0.9"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "certifi" },
{ name = "h11" },
]
sdist = { url = "https://files.pythonhosted.org/packages/9f/45/ad3e1b4d448f22c0cff4f5692f5ed0666658578e358b8d58a19846048059/httpcore-1.0.8.tar.gz", hash = "sha256:86e94505ed24ea06514883fd44d2bc02d90e77e7979c8eb71b90f41d364a1bad", size = 85385 }
sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/18/8d/f052b1e336bb2c1fc7ed1aaed898aa570c0b61a09707b108979d9fc6e308/httpcore-1.0.8-py3-none-any.whl", hash = "sha256:5254cf149bcb5f75e9d1b2b9f729ea4a4b883d1ad7379fc632b727cec23674be", size = 78732 },
{ url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784 },
]
[[package]]

8
web/package-lock.json generated
View File

@ -24,7 +24,7 @@
"@floating-ui/dom": "^1.6.11",
"@formatjs/intl-listformat": "^7.5.7",
"@fortawesome/fontawesome-free": "^6.6.0",
"@goauthentik/api": "^2025.4.0-1746018955",
"@goauthentik/api": "^2025.2.4-1745519715",
"@lit-labs/ssr": "3.2.2",
"@lit/context": "^1.1.2",
"@lit/localize": "^0.12.2",
@ -1583,9 +1583,9 @@
}
},
"node_modules/@goauthentik/api": {
"version": "2025.4.0-1746018955",
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2025.4.0-1746018955.tgz",
"integrity": "sha512-e+X3L+UYzQtAmBAdxKV9rHO6KsJBJ754IKc1Q9eT0lxS/zbvcNIEb0Fck9Sj/TzjqWlWkXNiCgrT4CdlaTFwxg=="
"version": "2025.2.4-1745519715",
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2025.2.4-1745519715.tgz",
"integrity": "sha512-R8uNdIKx3mTPT8Qp9a3SIJ47l79nbkzUOcP2bbxf1uMlTqezV6ACCAI3Iu4PKEJuVMzIdsOAQ5W8NRQsk/ifXA=="
},
"node_modules/@goauthentik/esbuild-plugin-live-reload": {
"resolved": "packages/esbuild-plugin-live-reload",

View File

@ -12,7 +12,7 @@
"@floating-ui/dom": "^1.6.11",
"@formatjs/intl-listformat": "^7.5.7",
"@fortawesome/fontawesome-free": "^6.6.0",
"@goauthentik/api": "^2025.4.0-1746018955",
"@goauthentik/api": "^2025.2.4-1745519715",
"@lit-labs/ssr": "3.2.2",
"@lit/context": "^1.1.2",
"@lit/localize": "^0.12.2",

View File

@ -47,7 +47,16 @@ class SimpleFlowExecutor {
return `${ak().api.base}api/v3/flows/executor/${this.flowSlug}/?query=${encodeURIComponent(window.location.search.substring(1))}`;
}
loading() {
this.container.innerHTML = `<div class="d-flex justify-content-center">
<div class="spinner-border spinner-border-md" role="status">
<span class="sr-only">Loading...</span>
</div>
</div>`;
}
start() {
this.loading();
$.ajax({
type: "GET",
url: this.apiURL,

View File

@ -89,19 +89,24 @@ export class RoleObjectPermissionForm extends ModelForm<RoleAssignData, number>
>
</ak-search-select>
</ak-form-element-horizontal>
${this.modelPermissions?.results.map((perm) => {
return html` <ak-form-element-horizontal name="permissions.${perm.codename}">
<label class="pf-c-switch">
<input class="pf-c-switch__input" type="checkbox" />
<span class="pf-c-switch__toggle">
<span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
${this.modelPermissions?.results
.filter((perm) => {
const [_app, model] = this.model?.split(".") || "";
return perm.codename !== `add_${model}`;
})
.map((perm) => {
return html` <ak-form-element-horizontal name="permissions.${perm.codename}">
<label class="pf-c-switch">
<input class="pf-c-switch__input" type="checkbox" />
<span class="pf-c-switch__toggle">
<span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
</span>
<span class="pf-c-switch__label">${perm.name}</span>
</label>
</ak-form-element-horizontal>`;
})}
<span class="pf-c-switch__label">${perm.name}</span>
</label>
</ak-form-element-horizontal>`;
})}
</form>`;
}
}

View File

@ -45,7 +45,7 @@ export class RoleAssignedObjectPermissionTable extends Table<RoleAssignedObjectP
ordering: "codename",
});
modelPermissions.results = modelPermissions.results.filter((value) => {
return !value.codename.startsWith("add_");
return value.codename !== `add_${this.model?.split(".")[1]}`;
});
this.modelPermissions = modelPermissions;
return perms;

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.4.0";
export const VERSION = "2025.4.3";
export const TITLE_DEFAULT = "authentik";
export const ROUTE_SEPARATOR = ";";

View File

@ -1,11 +1,10 @@
import { EVENT_SIDEBAR_TOGGLE } from "@goauthentik/common/constants";
import { globalAK } from "@goauthentik/common/global";
import { AKElement } from "@goauthentik/elements/Base";
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
import { themeImage } from "@goauthentik/elements/utils/images";
import { msg } from "@lit/localize";
import { CSSResult, TemplateResult, css, html, nothing } from "lit";
import { CSSResult, TemplateResult, css, html } from "lit";
import { customElement } from "lit/decorators.js";
import PFButton from "@patternfly/patternfly/components/Button/button.css";
@ -71,10 +70,7 @@ export class SidebarBrand extends WithBrandConfig(AKElement) {
}
render(): TemplateResult {
const logoUrl =
globalAK().brand.brandingLogo || this.brand?.brandingLogo || DefaultBrand.brandingLogo;
return html`${window.innerWidth <= MIN_WIDTH
return html` ${window.innerWidth <= MIN_WIDTH
? html`
<button
class="sidebar-trigger pf-c-button"
@ -90,10 +86,14 @@ export class SidebarBrand extends WithBrandConfig(AKElement) {
<i class="fas fa-bars"></i>
</button>
`
: nothing}
: html``}
<a href="#/" class="pf-c-page__header-brand-link">
<div class="pf-c-brand ak-brand">
<img src=${themeImage(logoUrl)} alt="${msg("authentik Logo")}" loading="lazy" />
<img
src=${themeImage(this.brand?.brandingLogo ?? DefaultBrand.brandingLogo)}
alt="${msg("authentik Logo")}"
loading="lazy"
/>
</div>
</a>`;
}

View File

@ -1,18 +1,18 @@
# Device code flow
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:
(Also known as device flow and [RFC 8628](https://datatracker.ietf.org/doc/html/rfc8628))
> 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.
This type of authentication flow is useful for devices with limited input abilities and/or devices without browsers.
### Requirements
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.
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.
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`.
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_
### Device flow initiation
### Device-side
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,6 +32,8 @@ 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
@ -47,17 +49,3 @@ device_code=device_code_from_above
If the user has not opened the link above yet, or has not finished the authentication and authorization yet, the response will contain an `error` element set to `authorization_pending`. The device should re-send the request in the interval set above.
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`.
### 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**.
3. Set the following required configurations:
- **Name**: provide a name (e.g. `default-device-code-flow`)
- **Title**: provide a title (e.g. `Device code flow`)
- **Slug**: provide a slug (e.g `default-device-code-flow`)
- **Designation**: `Stage Configuration`
- **Authentication**: `Require authentication`
4. Click **Create**.
5. Navigate to **System** > **Brands** and click the **Edit** icon on the default brand.
6. Set **Default code flow** to the newly created device code flow and click **Update**.

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 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.
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.
## OAuth 2.0 flows and grant types

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 another authentik resource that is not in the same repository 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 our Integration Guides and our regular technical docs, then use an absolute path.
### Markdown file type
@ -52,19 +52,16 @@ Try to write procedural (How To) docs generically enough that it does not endors
## Terminology
### authentik product name and terms
### authentik product naming conventions
- 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)". In some cases the acronym can come first, followed by the full term in parentheses.
- 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)".
## Writing style
@ -76,6 +73,10 @@ 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.
@ -90,20 +91,6 @@ 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"
@ -148,7 +135,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, and do not capitalize. 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. 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.
@ -185,7 +172,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, not gerunds. For example, use "Configure your instance" instead of "Configuring your instance."
- Use the **imperative verb form** in procedural topics. For example, use "Configure your instance" instead of "Configuring your instance."
### Examples

View File

@ -70,8 +70,6 @@ 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"`
@ -84,7 +82,7 @@ To check if your config has been applied correctly, you can run the following co
The PostgreSQL settings `HOST`, `PORT`, `USER`, and `PASSWORD` support hot-reloading. Adding and removing read replicas doesn't support hot-reloading.
- `AUTHENTIK_POSTGRESQL__DEFAULT_SCHEMA`:ak-version[2024.12]
- `AUTHENTIK_POSTGRESQL__DEFAULT_SCHEMA` :ak-version[2024.12]
The name of the schema used by default in the database. Defaults to `public`.

View File

@ -7,13 +7,14 @@ slug: "/releases/2025.4"
- **Improve membership resolution for the LDAP Source** Allow lookups of LDAP group memberships from user attributes as an alternative to lookups from group attributes. This also allows for nested group lookups in Active Directory.
- **Support for PostgreSQL Connection Pools** PostgreSQL Connection Pools provides a set of open connections in order to reduce latency.
<!-- TODO: Temporarily deactivated feature, see https://github.com/goauthentik/authentik/issues/14320 -->
<!-- - **Support for PostgreSQL Connection Pools** PostgreSQL Connection Pools provides a set of open connections in order to reduce latency. -->
- **RBAC: Initial Permissions** :ak-preview Provides more flexible access control by assigning permissions to the user/role creating a new object in authentik. Use **Initial Permissions** as a pragmatic way to implement the principle of least privilege.
- **Password History Policy** <span class="badge badge--primary">Enterprise</span> A new policy (the Password Uniqueness policy) can be implemented to prevent users from reusing previous passwords; admins are able to configure how many previous password hashes the system will store and evaluate. This new policy makes it easier to enforce password reuse requirements, such as for FedRAMP compliance.
- **Source Sync Dry Run** :ak-preview Add the option for dry-run syncs for SCIM, Google Workspace, and Entra to preview the results of a sync without affecting live accounts.
- **Provider Sync Dry Run** :ak-preview Add the option for dry-run syncs for SCIM, Google Workspace, and Microsoft Entra providers to preview the results of a sync without affecting live accounts.
## Breaking changes
@ -64,13 +65,13 @@ Previously, sessions were stored by default in the cache. Now, they are stored i
Reputation scores now have a configurable numerical limit in addition to the [already existing temporal limit](https://docs.goauthentik.io/docs/install-config/configuration/#authentik_reputation_expiry).
- **Support for PostgreSQL Connection Pools**: See [description](#highlights) under Highlights. Refer to our [documentation](../../install-config/configuration/configuration.mdx).
<!-- - **Support for PostgreSQL Connection Pools**: See [description](#highlights) under Highlights. Refer to our [documentation](../../install-config/configuration/configuration.mdx). -->
- **Password History Policy**: See [description](#highlights) under Highlights. Refer to our [documentation](../../customize/policies/unique_password.md).
- **Improve membership resolution for the LDAP Source**: See [description](#highlights) under Highlights. Refer to our [documentation](../../users-sources/sources/directory-sync/active-directory/index.md).
- **Source Sync Dry Run**: See [description](#highlights) under Highlights.
- **Provider Sync Dry Run**: See [description](#highlights) under Highlights.
- **Gateway API support** :ak-preview
@ -108,7 +109,7 @@ When you upgrade, be aware that the version of the authentik instance and of any
To upgrade, download the new docker-compose file and update the Docker stack with the new version, using these commands:
```shell
wget -O docker-compose.yml https://goauthentik.io/version/xxxx.x/docker-compose.yml
wget -O docker-compose.yml https://goauthentik.io/version/2025.4/docker-compose.yml
docker compose up -d
```
@ -269,6 +270,31 @@ helm upgrade authentik authentik/authentik -f values.yaml --version ^2025.4
- Revert "website/docs: Prepare for monorepo. (#14119)" (#14239)
- Revert package-lock.json changes from "web: add `remember me` feature to IdentificationStage (#10397)" (#14212)
## Fixed in 2025.4.1
- brands: fix CSS Migration not updating brands (cherry-pick #14306) (#14308)
- core: bump h11 from 0.14.0 to v0.16.0 (cherry-pick #14352) (#14472)
- core: fix session migration when old session can't be loaded (cherry-pick #14466) (#14480)
- core: fix unable to create group if no enable_group_superuser permission is given (cherry-pick #14510) (#14521)
- core: remove `OldAuthenticatedSession` content type (cherry-pick #14507) (#14509)
- enterprise: fix expired license's users being counted (cherry-pick #14451) (#14496)
- lifecycle: fix ak dump_config (cherry-pick #14445) (#14448)
- outposts: fix tmpdir in containers not being set (cherry-pick #14444) (#14449)
- rbac: fix RoleObjectPermissionTable not showing `add_user_to_group` (cherry-pick #14312) (#14334)
- root: backport SFE Build fix (#14495)
- root: temporarily deactivate database pool option (cherry-pick #14443) (#14479)
- web/flows/sfe: fix global background image not being loaded (cherry-pick #14442) (#14450)
## Fixed in 2025.4.2
- core: Migrate permissions before deleting OldAuthenticatedSession (cherry-pick #14788) (#14791)
- lifecycle: fix arguments not being passed to worker command (cherry-pick #14574) (#14620)
- sources/scim: fix all users being added to group when no members are given (cherry-pick #14645) (#14666)
## Fixed in 2025.4.3
- security: fix CVE-2025-52553 (#15289)
## API Changes
#### What's New

View File

@ -0,0 +1,27 @@
# CVE-2025-52553
_Reported by [SPIEGEL-Verlag](https://gruppe.spiegel.de)_
## Insufficient Session verification for Remote Access Control endpoint access
### Summary
After authorizing access to a RAC endpoint, authentik creates a token which is used for a single connection and is sent to the client in the URL. This token is intended to only be valid for the session of the user who authorized the connection, however this check is currently missing.
### Patches
authentik 2025.4.3 and 2025.6.3 fix this issue.
### Impact
When for example using RAC during a screenshare, a malicious user could access the same session by copying the URL from the shown browser.
### Workarounds
As a workaround it is recommended to decrease the duration a token is valid for (in the RAC Provider settings, set **Connection expiry** to `minutes=5` for example). We also recommend enabling the option **Delete authorization on disconnect**.
### For more information
If you have any questions or comments about this advisory:
- Email us at [security@goauthentik.io](mailto:security@goauthentik.io).

View File

@ -2,18 +2,22 @@
title: Events
---
Events are authentik's built-in logging system. Whenever any of the following actions occur, an event is created:
Events are authentik's built-in logging system. Every event is logged, whether it is initiated by a user or by authentik.
Events can be used to define [notification rules](notifications.md), with specified [transport options](transports.md) of local (in the authentik UI), email or webhook.
Certain information is stripped from events, to ensure no passwords or other credentials are saved in the log.
## Event retention
The event retention is configured in the system settings interface, with the default being set to 365 days.
The event retention is configured in the **System > Settings** area of the Admin interface, with the default being set to 365 days.
If you want to forward these events to another application, forward the log output of all authentik containers. Every event creation is logged with the log level "info". For this configuration, it is also recommended to set the internal retention pretty low (for example, `days=1`).
## Event actions
Whenever any of the following actions occur, an event is created.
### `login`
A user logs in (including the source, if available)

View File

@ -8,9 +8,7 @@ To prevent infinite loops (events created by policies which are attached to a No
## Filtering Events
Starting with authentik 0.15, you can create notification rules, which can alert you based on the creation of certain events.
Filtering is done by using the Policy Engine. You can do simple filtering using the "Event Matcher Policy" type.
An authentik administrator can create notification rules based on the creation of specified events. Filtering is done by using the Policy Engine. You can do simple filtering using the "Event Matcher Policy" type.
![](./event_matcher.png)

View File

@ -48,7 +48,7 @@ Add the following environment variables to your Homarr configuration. Make sure
AUTH_PROVIDERS="oidc,credentials"
AUTH_OIDC_CLIENT_ID=<Client ID from authentik>
AUTH_OIDC_CLIENT_SECRET=<Client secret from authentik>
AUTH_OIDC_ISSUER=https://authentik.company/application/o/<slug from authentik>/
AUTH_OIDC_ISSUER=https://authentik.company/application/o/<slug from authentik>
AUTH_OIDC_URI=https://authentik.company/application/o/authorize
AUTH_OIDC_CLIENT_NAME=authentik
OAUTH_ALLOW_DANGEROUS_EMAIL_ACCOUNT_LINKING=true

View File

@ -716,7 +716,7 @@ export default {
{
type: "category",
label: "2025",
items: ["security/cves/CVE-2025-29928"],
items: ["security/cves/CVE-2025-52553", "security/cves/CVE-2025-29928"],
},
{
type: "category",