Compare commits
1 Commits
version/20
...
endpoints
Author | SHA1 | Date | |
---|---|---|---|
19c5b28cb2 |
@ -1,5 +1,5 @@
|
||||
[bumpversion]
|
||||
current_version = 2025.6.1
|
||||
current_version = 2025.4.1
|
||||
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*))?
|
||||
@ -21,8 +21,6 @@ optional_value = final
|
||||
|
||||
[bumpversion:file:package.json]
|
||||
|
||||
[bumpversion:file:package-lock.json]
|
||||
|
||||
[bumpversion:file:docker-compose.yml]
|
||||
|
||||
[bumpversion:file:schema.yml]
|
||||
@ -33,4 +31,6 @@ optional_value = final
|
||||
|
||||
[bumpversion:file:internal/constants/constants.go]
|
||||
|
||||
[bumpversion:file:web/src/common/constants.ts]
|
||||
|
||||
[bumpversion:file:lifecycle/aws/template.yaml]
|
||||
|
@ -20,8 +20,8 @@ Even if the issue is not a CVE, we still greatly appreciate your help in hardeni
|
||||
|
||||
| Version | Supported |
|
||||
| --------- | --------- |
|
||||
| 2025.2.x | ✅ |
|
||||
| 2025.4.x | ✅ |
|
||||
| 2025.6.x | ✅ |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
from os import environ
|
||||
|
||||
__version__ = "2025.6.1"
|
||||
__version__ = "2025.4.1"
|
||||
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"
|
||||
|
||||
|
||||
|
@ -79,7 +79,6 @@ def _migrate_session(
|
||||
AuthenticatedSession.objects.using(db_alias).create(
|
||||
session=session,
|
||||
user=old_auth_session.user,
|
||||
uuid=old_auth_session.uuid,
|
||||
)
|
||||
|
||||
|
||||
|
@ -1,81 +1,10 @@
|
||||
# Generated by Django 5.1.9 on 2025-05-14 11:15
|
||||
|
||||
from django.apps.registry import Apps, apps as global_apps
|
||||
from django.apps.registry import 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
|
||||
):
|
||||
@ -92,12 +21,7 @@ class Migration(migrations.Migration):
|
||||
]
|
||||
|
||||
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,
|
||||
),
|
||||
]
|
||||
|
0
authentik/endpoints/__init__.py
Normal file
0
authentik/endpoints/__init__.py
Normal file
12
authentik/endpoints/apps.py
Normal file
12
authentik/endpoints/apps.py
Normal file
@ -0,0 +1,12 @@
|
||||
"""authentik endpoints app config"""
|
||||
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikEndpointsConfig(ManagedAppConfig):
|
||||
"""authentik endpoints app config"""
|
||||
|
||||
name = "authentik.endpoints"
|
||||
label = "authentik_endpoints"
|
||||
verbose_name = "authentik Endpoints"
|
||||
default = True
|
47
authentik/endpoints/common_data.py
Normal file
47
authentik/endpoints/common_data.py
Normal file
@ -0,0 +1,47 @@
|
||||
from enum import Enum
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class UNSUPPORTED(BaseModel):
|
||||
pass
|
||||
|
||||
|
||||
class OSFamily(Enum):
|
||||
|
||||
linux = "linux"
|
||||
unix = "unix"
|
||||
bsd = "bsd"
|
||||
windows = "windows"
|
||||
macOS = "mac_os"
|
||||
android = "android"
|
||||
iOS = "i_os"
|
||||
other = "other"
|
||||
|
||||
class CommonDeviceData(BaseModel):
|
||||
class Disk(BaseModel):
|
||||
encryption: bool
|
||||
|
||||
class OS(BaseModel):
|
||||
firewall_enabled: bool
|
||||
family: OSFamily
|
||||
name: str
|
||||
version: str
|
||||
|
||||
class Network(BaseModel):
|
||||
hostname: str
|
||||
dns_servers: list[str]
|
||||
|
||||
class Hardware(BaseModel):
|
||||
model: str
|
||||
manufacturer: str
|
||||
|
||||
class Software(BaseModel):
|
||||
name: str
|
||||
version: str
|
||||
|
||||
os: OS | UNSUPPORTED
|
||||
disks: list[Disk] | UNSUPPORTED
|
||||
network: Network | UNSUPPORTED
|
||||
hardware: Hardware | UNSUPPORTED
|
||||
software: list[Software] | UNSUPPORTED
|
16
authentik/endpoints/connector.py
Normal file
16
authentik/endpoints/connector.py
Normal file
@ -0,0 +1,16 @@
|
||||
from authentik.blueprints import models
|
||||
|
||||
|
||||
class EnrollmentMethods(models.TextChoices):
|
||||
AUTOMATIC_USER = "automatic_user" # Automatically enrolled through user action
|
||||
AUTOMATIC_API = "automatic_api" # Automatically enrolled through connector integration
|
||||
MANUAL_USER = "manual_user" # Manually enrolled
|
||||
|
||||
|
||||
class BaseConnector:
|
||||
|
||||
def __init__(self) -> None:
|
||||
pass
|
||||
|
||||
def supported_enrollment_methods(self) -> list[EnrollmentMethods]:
|
||||
return []
|
0
authentik/endpoints/connectors/__init__.py
Normal file
0
authentik/endpoints/connectors/__init__.py
Normal file
@ -0,0 +1,7 @@
|
||||
from authentik.endpoints.connector import BaseConnector, EnrollmentMethods
|
||||
|
||||
|
||||
class GoogleChromeConnector(BaseConnector):
|
||||
|
||||
def supported_enrollment_methods(self) -> list[EnrollmentMethods]:
|
||||
return [EnrollmentMethods.AUTOMATIC_USER]
|
7
authentik/endpoints/connectors/google_chrome/models.py
Normal file
7
authentik/endpoints/connectors/google_chrome/models.py
Normal file
@ -0,0 +1,7 @@
|
||||
from django.db import models
|
||||
|
||||
from authentik.endpoints.models import Connector
|
||||
|
||||
|
||||
class GoogleChromeConnector(Connector):
|
||||
credentials = models.JSONField()
|
125
authentik/endpoints/migrations/0001_initial.py
Normal file
125
authentik/endpoints/migrations/0001_initial.py
Normal file
@ -0,0 +1,125 @@
|
||||
# Generated by Django 5.0.9 on 2024-09-24 19:16
|
||||
|
||||
import django.db.models.deletion
|
||||
import uuid
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="Connector",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
||||
),
|
||||
),
|
||||
("connector_uuid", models.UUIDField(default=uuid.uuid4)),
|
||||
("name", models.TextField()),
|
||||
(
|
||||
"enrollment_method",
|
||||
models.TextField(
|
||||
choices=[
|
||||
("automatic_user", "Automatic User"),
|
||||
("automatic_api", "Automatic Api"),
|
||||
("manual_user", "Manual User"),
|
||||
]
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"abstract": False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Device",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
||||
),
|
||||
),
|
||||
("device_uuid", models.UUIDField(default=uuid.uuid4)),
|
||||
("identifier", models.TextField(unique=True)),
|
||||
],
|
||||
options={
|
||||
"abstract": False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="DeviceConnection",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
||||
),
|
||||
),
|
||||
("device_connection_uuid", models.UUIDField(default=uuid.uuid4)),
|
||||
("data", models.JSONField(default=dict)),
|
||||
(
|
||||
"connection",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="authentik_endpoints.connector",
|
||||
),
|
||||
),
|
||||
(
|
||||
"device",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE, to="authentik_endpoints.device"
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="device",
|
||||
name="connections",
|
||||
field=models.ManyToManyField(
|
||||
through="authentik_endpoints.DeviceConnection", to="authentik_endpoints.connector"
|
||||
),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="DeviceUser",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
||||
),
|
||||
),
|
||||
("device_user_uuid", models.UUIDField(default=uuid.uuid4)),
|
||||
("is_primary", models.BooleanField()),
|
||||
(
|
||||
"device",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE, to="authentik_endpoints.device"
|
||||
),
|
||||
),
|
||||
(
|
||||
"user",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="device",
|
||||
name="users",
|
||||
field=models.ManyToManyField(
|
||||
through="authentik_endpoints.DeviceUser", to=settings.AUTH_USER_MODEL
|
||||
),
|
||||
),
|
||||
]
|
0
authentik/endpoints/migrations/__init__.py
Normal file
0
authentik/endpoints/migrations/__init__.py
Normal file
40
authentik/endpoints/models.py
Normal file
40
authentik/endpoints/models.py
Normal file
@ -0,0 +1,40 @@
|
||||
from uuid import uuid4
|
||||
|
||||
from django.db import models
|
||||
from django.utils.functional import cached_property
|
||||
|
||||
from authentik.core.models import User
|
||||
from authentik.endpoints.common_data import CommonDeviceData
|
||||
from authentik.lib.models import SerializerModel
|
||||
|
||||
|
||||
class Device(SerializerModel):
|
||||
device_uuid = models.UUIDField(default=uuid4)
|
||||
|
||||
identifier = models.TextField(unique=True)
|
||||
users = models.ManyToManyField(User, through="DeviceUser")
|
||||
connections = models.ManyToManyField("Connector", through="DeviceConnection")
|
||||
|
||||
@cached_property
|
||||
def data(self) -> CommonDeviceData:
|
||||
pass
|
||||
|
||||
|
||||
class DeviceUser(models.Model):
|
||||
device_user_uuid = models.UUIDField(default=uuid4)
|
||||
device = models.ForeignKey("Device", on_delete=models.CASCADE)
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
is_primary = models.BooleanField()
|
||||
|
||||
|
||||
class DeviceConnection(models.Model):
|
||||
device_connection_uuid = models.UUIDField(default=uuid4)
|
||||
device = models.ForeignKey("Device", on_delete=models.CASCADE)
|
||||
connection = models.ForeignKey("Connector", on_delete=models.CASCADE)
|
||||
data = models.JSONField(default=dict)
|
||||
|
||||
|
||||
class Connector(SerializerModel):
|
||||
connector_uuid = models.UUIDField(default=uuid4)
|
||||
|
||||
name = models.TextField()
|
@ -81,6 +81,7 @@ debugger: false
|
||||
|
||||
log_level: info
|
||||
|
||||
session_storage: cache
|
||||
sessions:
|
||||
unauthenticated_age: days=1
|
||||
|
||||
|
@ -130,7 +130,7 @@ class SyncTasks:
|
||||
def sync_objects(
|
||||
self, object_type: str, page: int, provider_pk: int, override_dry_run=False, **filter
|
||||
):
|
||||
_object_type: type[Model] = path_to_class(object_type)
|
||||
_object_type = path_to_class(object_type)
|
||||
self.logger = get_logger().bind(
|
||||
provider_type=class_to_path(self._provider_model),
|
||||
provider_pk=provider_pk,
|
||||
@ -156,11 +156,7 @@ class SyncTasks:
|
||||
messages.append(
|
||||
asdict(
|
||||
LogEvent(
|
||||
_(
|
||||
"Syncing page {page} of {object_type}".format(
|
||||
page=page, object_type=_object_type._meta.verbose_name_plural
|
||||
)
|
||||
),
|
||||
_("Syncing page {page} of groups".format(page=page)),
|
||||
log_level="info",
|
||||
logger=f"{provider._meta.verbose_name}@{object_type}",
|
||||
)
|
||||
|
@ -166,6 +166,7 @@ class ConnectionToken(ExpiringModel):
|
||||
always_merger.merge(settings, default_settings)
|
||||
always_merger.merge(settings, self.endpoint.provider.settings)
|
||||
always_merger.merge(settings, self.endpoint.settings)
|
||||
always_merger.merge(settings, self.settings)
|
||||
|
||||
def mapping_evaluator(mappings: QuerySet):
|
||||
for mapping in mappings:
|
||||
@ -190,7 +191,6 @@ class ConnectionToken(ExpiringModel):
|
||||
mapping_evaluator(
|
||||
RACPropertyMapping.objects.filter(endpoint__in=[self.endpoint]).order_by("name")
|
||||
)
|
||||
always_merger.merge(settings, self.settings)
|
||||
|
||||
settings["drive-path"] = f"/tmp/connection/{self.token}" # nosec
|
||||
settings["create-drive-path"] = "true"
|
||||
|
@ -90,6 +90,23 @@ class TestModels(TransactionTestCase):
|
||||
"resize-method": "display-update",
|
||||
},
|
||||
)
|
||||
# Set settings in token
|
||||
token.settings = {
|
||||
"level": "token",
|
||||
}
|
||||
token.save()
|
||||
self.assertEqual(
|
||||
token.get_settings(),
|
||||
{
|
||||
"hostname": self.endpoint.host.split(":")[0],
|
||||
"port": "1324",
|
||||
"client-name": f"authentik - {self.user}",
|
||||
"drive-path": path,
|
||||
"create-drive-path": "true",
|
||||
"level": "token",
|
||||
"resize-method": "display-update",
|
||||
},
|
||||
)
|
||||
# Set settings in property mapping (provider)
|
||||
mapping = RACPropertyMapping.objects.create(
|
||||
name=generate_id(),
|
||||
@ -134,22 +151,3 @@ class TestModels(TransactionTestCase):
|
||||
"resize-method": "display-update",
|
||||
},
|
||||
)
|
||||
# Set settings in token
|
||||
token.settings = {
|
||||
"level": "token",
|
||||
}
|
||||
token.save()
|
||||
self.assertEqual(
|
||||
token.get_settings(),
|
||||
{
|
||||
"hostname": self.endpoint.host.split(":")[0],
|
||||
"port": "1324",
|
||||
"client-name": f"authentik - {self.user}",
|
||||
"drive-path": path,
|
||||
"create-drive-path": "true",
|
||||
"foo": "true",
|
||||
"bar": "6",
|
||||
"resize-method": "display-update",
|
||||
"level": "token",
|
||||
},
|
||||
)
|
||||
|
@ -47,16 +47,15 @@ class SCIMGroupClient(SCIMClient[Group, SCIMProviderGroup, SCIMGroupSchema]):
|
||||
|
||||
def to_schema(self, obj: Group, connection: SCIMProviderGroup) -> SCIMGroupSchema:
|
||||
"""Convert authentik user into SCIM"""
|
||||
raw_scim_group = super().to_schema(obj, connection)
|
||||
raw_scim_group = super().to_schema(
|
||||
obj,
|
||||
connection,
|
||||
schemas=(SCIM_GROUP_SCHEMA,),
|
||||
)
|
||||
try:
|
||||
scim_group = SCIMGroupSchema.model_validate(delete_none_values(raw_scim_group))
|
||||
except ValidationError as exc:
|
||||
raise StopSync(exc, obj) from exc
|
||||
if SCIM_GROUP_SCHEMA not in scim_group.schemas:
|
||||
scim_group.schemas.insert(0, SCIM_GROUP_SCHEMA)
|
||||
# As this might be unset, we need to tell pydantic it's set so ensure the schemas
|
||||
# are included, even if its just the defaults
|
||||
scim_group.schemas = list(scim_group.schemas)
|
||||
if not scim_group.externalId:
|
||||
scim_group.externalId = str(obj.pk)
|
||||
|
||||
|
@ -31,16 +31,15 @@ class SCIMUserClient(SCIMClient[User, SCIMProviderUser, SCIMUserSchema]):
|
||||
|
||||
def to_schema(self, obj: User, connection: SCIMProviderUser) -> SCIMUserSchema:
|
||||
"""Convert authentik user into SCIM"""
|
||||
raw_scim_user = super().to_schema(obj, connection)
|
||||
raw_scim_user = super().to_schema(
|
||||
obj,
|
||||
connection,
|
||||
schemas=(SCIM_USER_SCHEMA,),
|
||||
)
|
||||
try:
|
||||
scim_user = SCIMUserSchema.model_validate(delete_none_values(raw_scim_user))
|
||||
except ValidationError as exc:
|
||||
raise StopSync(exc, obj) from exc
|
||||
if SCIM_USER_SCHEMA not in scim_user.schemas:
|
||||
scim_user.schemas.insert(0, SCIM_USER_SCHEMA)
|
||||
# As this might be unset, we need to tell pydantic it's set so ensure the schemas
|
||||
# are included, even if its just the defaults
|
||||
scim_user.schemas = list(scim_user.schemas)
|
||||
if not scim_user.externalId:
|
||||
scim_user.externalId = str(obj.uid)
|
||||
return scim_user
|
||||
|
@ -91,57 +91,6 @@ class SCIMUserTests(TestCase):
|
||||
},
|
||||
)
|
||||
|
||||
@Mocker()
|
||||
def test_user_create_custom_schema(self, mock: Mocker):
|
||||
"""Test user creation with custom schema"""
|
||||
schema = SCIMMapping.objects.create(
|
||||
name="custom_schema",
|
||||
expression="""return {"schemas": ["foo"]}""",
|
||||
)
|
||||
self.provider.property_mappings.add(schema)
|
||||
scim_id = generate_id()
|
||||
mock.get(
|
||||
"https://localhost/ServiceProviderConfig",
|
||||
json={},
|
||||
)
|
||||
mock.post(
|
||||
"https://localhost/Users",
|
||||
json={
|
||||
"id": scim_id,
|
||||
},
|
||||
)
|
||||
uid = generate_id()
|
||||
user = User.objects.create(
|
||||
username=uid,
|
||||
name=f"{uid} {uid}",
|
||||
email=f"{uid}@goauthentik.io",
|
||||
)
|
||||
self.assertEqual(mock.call_count, 2)
|
||||
self.assertEqual(mock.request_history[0].method, "GET")
|
||||
self.assertEqual(mock.request_history[1].method, "POST")
|
||||
self.assertJSONEqual(
|
||||
mock.request_history[1].body,
|
||||
{
|
||||
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User", "foo"],
|
||||
"active": True,
|
||||
"emails": [
|
||||
{
|
||||
"primary": True,
|
||||
"type": "other",
|
||||
"value": f"{uid}@goauthentik.io",
|
||||
}
|
||||
],
|
||||
"externalId": user.uid,
|
||||
"name": {
|
||||
"familyName": uid,
|
||||
"formatted": f"{uid} {uid}",
|
||||
"givenName": uid,
|
||||
},
|
||||
"displayName": f"{uid} {uid}",
|
||||
"userName": uid,
|
||||
},
|
||||
)
|
||||
|
||||
@Mocker()
|
||||
def test_user_create_different_provider_same_id(self, mock: Mocker):
|
||||
"""Test user creation with multiple providers that happen
|
||||
|
@ -73,6 +73,7 @@ TENANT_APPS = [
|
||||
"authentik.admin",
|
||||
"authentik.api",
|
||||
"authentik.crypto",
|
||||
"authentik.endpoints",
|
||||
"authentik.flows",
|
||||
"authentik.outposts",
|
||||
"authentik.policies.dummy",
|
||||
|
@ -103,7 +103,6 @@ class LDAPSourceSerializer(SourceSerializer):
|
||||
"user_object_filter",
|
||||
"group_object_filter",
|
||||
"group_membership_field",
|
||||
"user_membership_attribute",
|
||||
"object_uniqueness_field",
|
||||
"password_login_update_internal_password",
|
||||
"sync_users",
|
||||
@ -140,7 +139,6 @@ class LDAPSourceViewSet(UsedByMixin, ModelViewSet):
|
||||
"user_object_filter",
|
||||
"group_object_filter",
|
||||
"group_membership_field",
|
||||
"user_membership_attribute",
|
||||
"object_uniqueness_field",
|
||||
"password_login_update_internal_password",
|
||||
"sync_users",
|
||||
|
@ -1,32 +0,0 @@
|
||||
# Generated by Django 5.1.9 on 2025-05-29 11:22
|
||||
|
||||
from django.apps.registry import Apps
|
||||
from django.db import migrations, models
|
||||
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
|
||||
|
||||
|
||||
def set_user_membership_attribute(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
|
||||
LDAPSource = apps.get_model("authentik_sources_ldap", "LDAPSource")
|
||||
db_alias = schema_editor.connection.alias
|
||||
|
||||
LDAPSource.objects.using(db_alias).filter(group_membership_field="memberUid").all().update(
|
||||
user_membership_attribute="ldap_uniq"
|
||||
)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("authentik_sources_ldap", "0009_groupldapsourceconnection_validated_by_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="ldapsource",
|
||||
name="user_membership_attribute",
|
||||
field=models.TextField(
|
||||
default="distinguishedName",
|
||||
help_text="Attribute which matches the value of `group_membership_field`.",
|
||||
),
|
||||
),
|
||||
migrations.RunPython(set_user_membership_attribute, migrations.RunPython.noop),
|
||||
]
|
@ -100,10 +100,6 @@ class LDAPSource(Source):
|
||||
default="(objectClass=person)",
|
||||
help_text=_("Consider Objects matching this filter to be Users."),
|
||||
)
|
||||
user_membership_attribute = models.TextField(
|
||||
default=LDAP_DISTINGUISHED_NAME,
|
||||
help_text=_("Attribute which matches the value of `group_membership_field`."),
|
||||
)
|
||||
group_membership_field = models.TextField(
|
||||
default="member", help_text=_("Field which contains members of a group.")
|
||||
)
|
||||
|
@ -71,11 +71,17 @@ class MembershipLDAPSynchronizer(BaseLDAPSynchronizer):
|
||||
if not ak_group:
|
||||
continue
|
||||
|
||||
membership_mapping_attribute = LDAP_DISTINGUISHED_NAME
|
||||
if self._source.group_membership_field == "memberUid":
|
||||
# If memberships are based on the posixGroup's 'memberUid'
|
||||
# attribute we use the RDN instead of the FDN to lookup members.
|
||||
membership_mapping_attribute = LDAP_UNIQUENESS
|
||||
|
||||
users = User.objects.filter(
|
||||
Q(**{f"attributes__{self._source.user_membership_attribute}__in": members})
|
||||
Q(**{f"attributes__{membership_mapping_attribute}__in": members})
|
||||
| Q(
|
||||
**{
|
||||
f"attributes__{self._source.user_membership_attribute}__isnull": True,
|
||||
f"attributes__{membership_mapping_attribute}__isnull": True,
|
||||
"ak_groups__in": [ak_group],
|
||||
}
|
||||
)
|
||||
|
@ -269,56 +269,12 @@ class LDAPSyncTests(TestCase):
|
||||
self.source.group_membership_field = "memberUid"
|
||||
self.source.user_object_filter = "(objectClass=posixAccount)"
|
||||
self.source.group_object_filter = "(objectClass=posixGroup)"
|
||||
self.source.user_membership_attribute = "uid"
|
||||
self.source.user_property_mappings.set(
|
||||
[
|
||||
*LDAPSourcePropertyMapping.objects.filter(
|
||||
Q(managed__startswith="goauthentik.io/sources/ldap/default")
|
||||
| Q(managed__startswith="goauthentik.io/sources/ldap/openldap")
|
||||
).all(),
|
||||
LDAPSourcePropertyMapping.objects.create(
|
||||
name="name",
|
||||
expression='return {"attributes": {"uid": list_flatten(ldap.get("uid"))}}',
|
||||
),
|
||||
]
|
||||
)
|
||||
self.source.group_property_mappings.set(
|
||||
LDAPSourcePropertyMapping.objects.filter(
|
||||
managed="goauthentik.io/sources/ldap/openldap-cn"
|
||||
Q(managed__startswith="goauthentik.io/sources/ldap/default")
|
||||
| Q(managed__startswith="goauthentik.io/sources/ldap/openldap")
|
||||
)
|
||||
)
|
||||
connection = MagicMock(return_value=mock_slapd_connection(LDAP_PASSWORD))
|
||||
with patch("authentik.sources.ldap.models.LDAPSource.connection", connection):
|
||||
self.source.save()
|
||||
user_sync = UserLDAPSynchronizer(self.source)
|
||||
user_sync.sync_full()
|
||||
group_sync = GroupLDAPSynchronizer(self.source)
|
||||
group_sync.sync_full()
|
||||
membership_sync = MembershipLDAPSynchronizer(self.source)
|
||||
membership_sync.sync_full()
|
||||
# Test if membership mapping based on memberUid works.
|
||||
posix_group = Group.objects.filter(name="group-posix").first()
|
||||
self.assertTrue(posix_group.users.filter(name="user-posix").exists())
|
||||
|
||||
def test_sync_groups_openldap_posix_group_nonstandard_membership_attribute(self):
|
||||
"""Test posix group sync"""
|
||||
self.source.object_uniqueness_field = "cn"
|
||||
self.source.group_membership_field = "memberUid"
|
||||
self.source.user_object_filter = "(objectClass=posixAccount)"
|
||||
self.source.group_object_filter = "(objectClass=posixGroup)"
|
||||
self.source.user_membership_attribute = "cn"
|
||||
self.source.user_property_mappings.set(
|
||||
[
|
||||
*LDAPSourcePropertyMapping.objects.filter(
|
||||
Q(managed__startswith="goauthentik.io/sources/ldap/default")
|
||||
| Q(managed__startswith="goauthentik.io/sources/ldap/openldap")
|
||||
).all(),
|
||||
LDAPSourcePropertyMapping.objects.create(
|
||||
name="name",
|
||||
expression='return {"attributes": {"cn": list_flatten(ldap.get("cn"))}}',
|
||||
),
|
||||
]
|
||||
)
|
||||
self.source.group_property_mappings.set(
|
||||
LDAPSourcePropertyMapping.objects.filter(
|
||||
managed="goauthentik.io/sources/ldap/openldap-cn"
|
||||
|
@ -151,7 +151,9 @@ class AuthenticatorValidateStageWebAuthnTests(FlowTestCase):
|
||||
webauthn_user_verification=UserVerification.PREFERRED,
|
||||
)
|
||||
stage.webauthn_allowed_device_types.set(
|
||||
WebAuthnDeviceType.objects.filter(description="YubiKey 5 Series")
|
||||
WebAuthnDeviceType.objects.filter(
|
||||
description="Android Authenticator with SafetyNet Attestation"
|
||||
)
|
||||
)
|
||||
session = self.client.session
|
||||
plan = FlowPlan(flow_pk=flow.pk.hex)
|
||||
@ -337,7 +339,9 @@ class AuthenticatorValidateStageWebAuthnTests(FlowTestCase):
|
||||
device_classes=[DeviceClasses.WEBAUTHN],
|
||||
)
|
||||
stage.webauthn_allowed_device_types.set(
|
||||
WebAuthnDeviceType.objects.filter(description="YubiKey 5 Series")
|
||||
WebAuthnDeviceType.objects.filter(
|
||||
description="Android Authenticator with SafetyNet Attestation"
|
||||
)
|
||||
)
|
||||
session = self.client.session
|
||||
plan = FlowPlan(flow_pk=flow.pk.hex)
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -141,7 +141,9 @@ class TestAuthenticatorWebAuthnStage(FlowTestCase):
|
||||
"""Test registration with restricted devices (fail)"""
|
||||
webauthn_mds_import.delay(force=True).get()
|
||||
self.stage.device_type_restrictions.set(
|
||||
WebAuthnDeviceType.objects.filter(description="YubiKey 5 Series")
|
||||
WebAuthnDeviceType.objects.filter(
|
||||
description="Android Authenticator with SafetyNet Attestation"
|
||||
)
|
||||
)
|
||||
|
||||
plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()])
|
||||
|
@ -11,7 +11,7 @@ from rest_framework.fields import BooleanField, CharField
|
||||
from authentik.core.models import Session, User
|
||||
from authentik.events.middleware import audit_ignore
|
||||
from authentik.flows.challenge import ChallengeResponse, WithUserInfoChallenge
|
||||
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER
|
||||
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, PLAN_CONTEXT_SOURCE
|
||||
from authentik.flows.stage import ChallengeStageView
|
||||
from authentik.lib.utils.time import timedelta_from_string
|
||||
from authentik.root.middleware import ClientIPMiddleware
|
||||
@ -108,6 +108,10 @@ class UserLoginStageView(ChallengeStageView):
|
||||
flow_slug=self.executor.flow.slug,
|
||||
session_duration=delta,
|
||||
)
|
||||
# Only show success message if we don't have a source in the flow
|
||||
# as sources show their own success messages
|
||||
if not self.executor.plan.context.get(PLAN_CONTEXT_SOURCE, None):
|
||||
messages.success(self.request, _("Successfully logged in!"))
|
||||
if self.executor.current_stage.terminate_other_sessions:
|
||||
Session.objects.filter(
|
||||
authenticatedsession__user=user,
|
||||
|
@ -2,7 +2,7 @@
|
||||
"$schema": "http://json-schema.org/draft-07/schema",
|
||||
"$id": "https://goauthentik.io/blueprints/schema.json",
|
||||
"type": "object",
|
||||
"title": "authentik 2025.6.1 Blueprint schema",
|
||||
"title": "authentik 2025.4.1 Blueprint schema",
|
||||
"required": [
|
||||
"version",
|
||||
"entries"
|
||||
@ -8147,12 +8147,6 @@
|
||||
"title": "Group membership field",
|
||||
"description": "Field which contains members of a group."
|
||||
},
|
||||
"user_membership_attribute": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"title": "User membership attribute",
|
||||
"description": "Attribute which matches the value of `group_membership_field`."
|
||||
},
|
||||
"object_uniqueness_field": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
|
@ -31,7 +31,7 @@ services:
|
||||
volumes:
|
||||
- redis:/data
|
||||
server:
|
||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.6.1}
|
||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.4.1}
|
||||
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.6.1}
|
||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.4.1}
|
||||
restart: unless-stopped
|
||||
command: worker
|
||||
environment:
|
||||
|
2
go.mod
2
go.mod
@ -27,7 +27,7 @@ require (
|
||||
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.2025041.4
|
||||
goauthentik.io/api/v3 v3.2025041.2
|
||||
golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab
|
||||
golang.org/x/oauth2 v0.30.0
|
||||
golang.org/x/sync v0.14.0
|
||||
|
4
go.sum
4
go.sum
@ -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.2025041.4 h1:cGqzWYnUHrWDoaXWDpIL/kWnX9sFrIhkYDye0P0OEAo=
|
||||
goauthentik.io/api/v3 v3.2025041.4/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw=
|
||||
goauthentik.io/api/v3 v3.2025041.2 h1:vFYYnhcDcxL95RczZwhzt3i4LptFXMvIRN+vgf8sQYg=
|
||||
goauthentik.io/api/v3 v3.2025041.2/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=
|
||||
|
@ -33,4 +33,4 @@ func UserAgent() string {
|
||||
return fmt.Sprintf("authentik@%s", FullVersion())
|
||||
}
|
||||
|
||||
const VERSION = "2025.6.1"
|
||||
const VERSION = "2025.4.1"
|
||||
|
@ -3,7 +3,6 @@ package application
|
||||
type ProxyClaims struct {
|
||||
UserAttributes map[string]interface{} `json:"user_attributes"`
|
||||
BackendOverride string `json:"backend_override"`
|
||||
HostHeader string `json:"host_header"`
|
||||
IsSuperuser bool `json:"is_superuser"`
|
||||
}
|
||||
|
||||
|
@ -74,18 +74,13 @@ func (a *Application) proxyModifyRequest(ou *url.URL) func(req *http.Request) {
|
||||
r.URL.Scheme = ou.Scheme
|
||||
r.URL.Host = ou.Host
|
||||
claims := a.getClaimsFromSession(r)
|
||||
if claims != nil && claims.Proxy != nil {
|
||||
if claims.Proxy.BackendOverride != "" {
|
||||
u, err := url.Parse(claims.Proxy.BackendOverride)
|
||||
if err != nil {
|
||||
a.log.WithField("backend_override", claims.Proxy.BackendOverride).WithError(err).Warning("failed parse user backend override")
|
||||
} else {
|
||||
r.URL.Scheme = u.Scheme
|
||||
r.URL.Host = u.Host
|
||||
}
|
||||
}
|
||||
if claims.Proxy.HostHeader != "" {
|
||||
r.Host = claims.Proxy.HostHeader
|
||||
if claims != nil && claims.Proxy != nil && claims.Proxy.BackendOverride != "" {
|
||||
u, err := url.Parse(claims.Proxy.BackendOverride)
|
||||
if err != nil {
|
||||
a.log.WithField("backend_override", claims.Proxy.BackendOverride).WithError(err).Warning("failed parse user backend override")
|
||||
} else {
|
||||
r.URL.Scheme = u.Scheme
|
||||
r.URL.Host = u.Host
|
||||
}
|
||||
}
|
||||
a.log.WithField("upstream_url", r.URL.String()).Trace("final upstream url")
|
||||
|
@ -26,7 +26,7 @@ Parameters:
|
||||
Description: authentik Docker image
|
||||
AuthentikVersion:
|
||||
Type: String
|
||||
Default: 2025.6.1
|
||||
Default: 2025.4.1
|
||||
Description: authentik Docker image tag
|
||||
AuthentikServerCPU:
|
||||
Type: Number
|
||||
|
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-02 00:12+0000\n"
|
||||
"POT-Creation-Date: 2025-05-28 11:25+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@ -2226,10 +2226,6 @@ msgstr ""
|
||||
msgid "Consider Objects matching this filter to be Users."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/sources/ldap/models.py
|
||||
msgid "Attribute which matches the value of `group_membership_field`."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/sources/ldap/models.py
|
||||
msgid "Field which contains members of a group."
|
||||
msgstr ""
|
||||
@ -3497,6 +3493,10 @@ msgstr ""
|
||||
msgid "No Pending user to login."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/user_login/stage.py
|
||||
msgid "Successfully logged in!"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/user_logout/models.py
|
||||
msgid "User Logout Stage"
|
||||
msgstr ""
|
||||
|
@ -975,11 +975,11 @@ msgstr "开始全量提供程序同步"
|
||||
|
||||
#: authentik/lib/sync/outgoing/tasks.py
|
||||
msgid "Syncing users"
|
||||
msgstr "正在同步用户"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/lib/sync/outgoing/tasks.py
|
||||
msgid "Syncing groups"
|
||||
msgstr "正在同步组"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/lib/sync/outgoing/tasks.py
|
||||
#, python-brace-format
|
||||
@ -2291,7 +2291,7 @@ msgstr "基于用户属性而非组属性查询组成员身份。这允许在 Fr
|
||||
msgid ""
|
||||
"Delete authentik users and groups which were previously supplied by this "
|
||||
"source, but are now missing from it."
|
||||
msgstr "删除之前由此源提供,但现已缺失的用户和组。"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/sources/ldap/models.py
|
||||
msgid "LDAP Source"
|
||||
@ -2312,7 +2312,7 @@ msgstr "LDAP 源属性映射"
|
||||
#: authentik/sources/ldap/models.py
|
||||
msgid ""
|
||||
"Unique ID used while checking if this object still exists in the directory."
|
||||
msgstr "检查此对象是否仍在目录中时使用的唯一 ID。"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/sources/ldap/models.py
|
||||
msgid "User LDAP Source Connection"
|
||||
@ -2694,7 +2694,7 @@ msgstr "组 SAML 源连接"
|
||||
#: authentik/sources/saml/views.py
|
||||
#, python-brace-format
|
||||
msgid "Continue to {source_name}"
|
||||
msgstr "继续前往 {source_name}"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/sources/scim/models.py
|
||||
msgid "SCIM Source"
|
||||
@ -3064,7 +3064,7 @@ msgstr "用户同意授权"
|
||||
|
||||
#: authentik/stages/consent/stage.py
|
||||
msgid "Invalid consent token, re-showing prompt"
|
||||
msgstr "无效的同意令牌,将重新显示输入"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/deny/models.py
|
||||
msgid "Deny Stage"
|
||||
@ -3084,11 +3084,11 @@ msgstr "虚拟阶段"
|
||||
|
||||
#: authentik/stages/email/flow.py
|
||||
msgid "Continue to confirm this email address."
|
||||
msgstr "继续以确认电子邮件地址。"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/email/flow.py
|
||||
msgid "Link was already used, please request a new link."
|
||||
msgstr "链接已被使用,请申请一个新链接。"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/email/models.py
|
||||
msgid "Password Reset"
|
||||
|
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@goauthentik/authentik",
|
||||
"version": "2025.6.1",
|
||||
"version": "2025.4.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@goauthentik/authentik",
|
||||
"version": "2025.6.1",
|
||||
"version": "2025.4.1",
|
||||
"devDependencies": {
|
||||
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
|
||||
"prettier": "^3.3.3",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@goauthentik/authentik",
|
||||
"version": "2025.6.1",
|
||||
"version": "2025.4.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"devDependencies": {
|
||||
|
@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "authentik"
|
||||
version = "2025.6.1"
|
||||
version = "2025.4.1"
|
||||
description = ""
|
||||
authors = [{ name = "authentik Team", email = "hello@goauthentik.io" }]
|
||||
requires-python = "==3.13.*"
|
||||
@ -61,7 +61,7 @@ dependencies = [
|
||||
"setproctitle==1.3.6",
|
||||
"structlog==25.3.0",
|
||||
"swagger-spec-validator==3.0.4",
|
||||
"tenant-schemas-celery==3.0.0",
|
||||
"tenant-schemas-celery==4.0.1",
|
||||
"twilio==9.6.1",
|
||||
"ua-parser==1.0.1",
|
||||
"unidecode==1.4.0",
|
||||
|
17
schema.yml
17
schema.yml
@ -1,7 +1,7 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: authentik
|
||||
version: 2025.6.1
|
||||
version: 2025.4.1
|
||||
description: Making authentication simple.
|
||||
contact:
|
||||
email: hello@goauthentik.io
|
||||
@ -28581,10 +28581,6 @@ paths:
|
||||
name: sync_users_password
|
||||
schema:
|
||||
type: boolean
|
||||
- in: query
|
||||
name: user_membership_attribute
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: user_object_filter
|
||||
schema:
|
||||
@ -47897,9 +47893,6 @@ components:
|
||||
group_membership_field:
|
||||
type: string
|
||||
description: Field which contains members of a group.
|
||||
user_membership_attribute:
|
||||
type: string
|
||||
description: Attribute which matches the value of `group_membership_field`.
|
||||
object_uniqueness_field:
|
||||
type: string
|
||||
description: Field which contains a unique Identifier.
|
||||
@ -48113,10 +48106,6 @@ components:
|
||||
type: string
|
||||
minLength: 1
|
||||
description: Field which contains members of a group.
|
||||
user_membership_attribute:
|
||||
type: string
|
||||
minLength: 1
|
||||
description: Attribute which matches the value of `group_membership_field`.
|
||||
object_uniqueness_field:
|
||||
type: string
|
||||
minLength: 1
|
||||
@ -53454,10 +53443,6 @@ components:
|
||||
type: string
|
||||
minLength: 1
|
||||
description: Field which contains members of a group.
|
||||
user_membership_attribute:
|
||||
type: string
|
||||
minLength: 1
|
||||
description: Attribute which matches the value of `group_membership_field`.
|
||||
object_uniqueness_field:
|
||||
type: string
|
||||
minLength: 1
|
||||
|
10
uv.lock
generated
10
uv.lock
generated
@ -164,7 +164,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "authentik"
|
||||
version = "2025.6.1"
|
||||
version = "2025.4.1"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "argon2-cffi" },
|
||||
@ -321,7 +321,7 @@ requires-dist = [
|
||||
{ name = "setproctitle", specifier = "==1.3.6" },
|
||||
{ name = "structlog", specifier = "==25.3.0" },
|
||||
{ name = "swagger-spec-validator", specifier = "==3.0.4" },
|
||||
{ name = "tenant-schemas-celery", specifier = "==3.0.0" },
|
||||
{ name = "tenant-schemas-celery", specifier = "==4.0.1" },
|
||||
{ name = "twilio", specifier = "==9.6.1" },
|
||||
{ name = "ua-parser", specifier = "==1.0.1" },
|
||||
{ name = "unidecode", specifier = "==1.4.0" },
|
||||
@ -3100,14 +3100,14 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "tenant-schemas-celery"
|
||||
version = "3.0.0"
|
||||
version = "4.0.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "celery" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d0/fe/cfe19eb7cc3ad8e39d7df7b7c44414bf665b6ac6660c998eb498f89d16c6/tenant_schemas_celery-3.0.0.tar.gz", hash = "sha256:6be3ae1a5826f262f0f3dd343c6a85a34a1c59b89e04ae37de018f36562fed55", size = 15954, upload-time = "2024-05-19T11:16:41.837Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/19/f8/cf055bf171b5d83d6fe96f1840fba90d3d274be2b5c35cd21b873302b128/tenant_schemas_celery-4.0.1.tar.gz", hash = "sha256:8b8f055fcd82aa53274c09faf88653a935241518d93b86ab2d43a3df3b70c7f8", size = 18870, upload-time = "2025-04-22T18:23:51.061Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/db/2c/376e1e641ad08b374c75d896468a7be2e6906ce3621fd0c9f9dc09ff1963/tenant_schemas_celery-3.0.0-py3-none-any.whl", hash = "sha256:ca0f69e78ef698eb4813468231df5a0ab6a660c08e657b65f5ac92e16887eec8", size = 18108, upload-time = "2024-05-19T11:16:39.92Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/a8/fd663c461550d6fedfb24e987acc1557ae5b6615ca08fc6c70dbaaa88aa5/tenant_schemas_celery-4.0.1-py3-none-any.whl", hash = "sha256:d06a3ff6956db3a95168ce2051b7bff2765f9ce0d070e14df92f07a2b60ae0a0", size = 21364, upload-time = "2025-04-22T18:23:49.899Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
8
web/package-lock.json
generated
8
web/package-lock.json
generated
@ -22,7 +22,7 @@
|
||||
"@floating-ui/dom": "^1.6.11",
|
||||
"@formatjs/intl-listformat": "^7.7.11",
|
||||
"@fortawesome/fontawesome-free": "^6.6.0",
|
||||
"@goauthentik/api": "^2025.4.1-1748622869",
|
||||
"@goauthentik/api": "^2025.4.1-1748431399",
|
||||
"@lit/context": "^1.1.2",
|
||||
"@lit/localize": "^0.12.2",
|
||||
"@lit/reactive-element": "^2.0.4",
|
||||
@ -1721,9 +1721,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@goauthentik/api": {
|
||||
"version": "2025.4.1-1748622869",
|
||||
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2025.4.1-1748622869.tgz",
|
||||
"integrity": "sha512-nH7+dQVA5yPoR4x0g3mct+M9VCwkBh/7ginUTwzb9O+Fj7HHGeAk/4xFC7Zy1oc6CIOHZbSMrOM5EdkEKE18Og=="
|
||||
"version": "2025.4.1-1748431399",
|
||||
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2025.4.1-1748431399.tgz",
|
||||
"integrity": "sha512-j4ygP36DXqzBCFi3v8KWFLPLUmV616POZb8zx35RaCskuZ5BFNDaArLDtGHvCkEV3qJouR2w43hD4cX18BFIQw=="
|
||||
},
|
||||
"node_modules/@goauthentik/core": {
|
||||
"resolved": "packages/core",
|
||||
|
@ -93,7 +93,7 @@
|
||||
"@floating-ui/dom": "^1.6.11",
|
||||
"@formatjs/intl-listformat": "^7.7.11",
|
||||
"@fortawesome/fontawesome-free": "^6.6.0",
|
||||
"@goauthentik/api": "^2025.4.1-1748622869",
|
||||
"@goauthentik/api": "^2025.4.1-1748431399",
|
||||
"@lit/context": "^1.1.2",
|
||||
"@lit/localize": "^0.12.2",
|
||||
"@lit/reactive-element": "^2.0.4",
|
||||
|
@ -85,8 +85,8 @@ export class AdminOverviewPage extends AdminOverviewBase {
|
||||
render(): TemplateResult {
|
||||
const username = this.user?.user.name || this.user?.user.username;
|
||||
|
||||
return html`<ak-page-header
|
||||
header=${this.user ? msg(str`Welcome, ${username || ""}.`) : msg("Welcome.")}
|
||||
return html` <ak-page-header
|
||||
header=${msg(str`Welcome, ${username || ""}.`)}
|
||||
description=${msg("General system status")}
|
||||
?hasIcon=${false}
|
||||
>
|
||||
|
@ -1,38 +1,26 @@
|
||||
import { DEFAULT_CONFIG } from "#common/api/config";
|
||||
import {
|
||||
DataProvision,
|
||||
DualSelectPair,
|
||||
DualSelectPairSource,
|
||||
} from "#elements/ak-dual-select/types";
|
||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||
|
||||
import { CertificateKeyPair, CryptoApi } from "@goauthentik/api";
|
||||
|
||||
const certToSelect = (cert: CertificateKeyPair): DualSelectPair<CertificateKeyPair> => {
|
||||
return [cert.pk, cert.name, cert.name, cert];
|
||||
};
|
||||
const certToSelect = (s: CertificateKeyPair) => [s.pk, s.name, s.name, s];
|
||||
|
||||
export async function certificateProvider(page = 1, search = ""): Promise<DataProvision> {
|
||||
return new CryptoApi(DEFAULT_CONFIG)
|
||||
.cryptoCertificatekeypairsList({
|
||||
ordering: "name",
|
||||
pageSize: 20,
|
||||
search: search.trim(),
|
||||
page,
|
||||
hasKey: undefined,
|
||||
})
|
||||
.then(({ pagination, results }) => {
|
||||
return {
|
||||
pagination,
|
||||
options: results.map(certToSelect),
|
||||
};
|
||||
});
|
||||
export async function certificateProvider(page = 1, search = "") {
|
||||
const certificates = await new CryptoApi(DEFAULT_CONFIG).cryptoCertificatekeypairsList({
|
||||
ordering: "name",
|
||||
pageSize: 20,
|
||||
search: search.trim(),
|
||||
page,
|
||||
hasKey: undefined,
|
||||
});
|
||||
return {
|
||||
pagination: certificates.pagination,
|
||||
options: certificates.results.map(certToSelect),
|
||||
};
|
||||
}
|
||||
|
||||
export function certificateSelector(
|
||||
instanceMappings?: string[],
|
||||
): DualSelectPairSource<CertificateKeyPair> {
|
||||
export function certificateSelector(instanceMappings?: string[]) {
|
||||
if (!instanceMappings) {
|
||||
return () => Promise.resolve([]);
|
||||
return [];
|
||||
}
|
||||
|
||||
return async () => {
|
||||
|
@ -361,7 +361,7 @@ export class LDAPSourceForm extends BaseSourceForm<LDAPSource> {
|
||||
<p class="pf-c-form__helper-text">${placeholderHelperText}</p>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Additional User DN")}
|
||||
label=${msg("Addition User DN")}
|
||||
name="additionalUserDn"
|
||||
>
|
||||
<input
|
||||
@ -374,7 +374,7 @@ export class LDAPSourceForm extends BaseSourceForm<LDAPSource> {
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Additional Group DN")}
|
||||
label=${msg("Addition Group DN")}
|
||||
name="additionalGroupDn"
|
||||
>
|
||||
<input
|
||||
@ -429,25 +429,10 @@ export class LDAPSourceForm extends BaseSourceForm<LDAPSource> {
|
||||
/>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg(
|
||||
"Field which contains members of a group. The value of this field is matched against User membership attribute.",
|
||||
"Field which contains members of a group. Note that if using the \"memberUid\" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'. When selecting 'Lookup using a user attribute', this should be a user attribute, otherwise a group attribute.",
|
||||
)}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("User membership attribute")}
|
||||
?required=${true}
|
||||
name="userMembershipAttribute"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
value="${this.instance?.userMembershipAttribute || "distinguishedName"}"
|
||||
class="pf-c-form-control"
|
||||
required
|
||||
/>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Attribute which matches the value of Group membership field.")}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal name="lookupGroupsFromUser">
|
||||
<label class="pf-c-switch">
|
||||
<input
|
||||
|
@ -201,10 +201,6 @@ select[multiple] option:checked {
|
||||
--pf-c-input-group--BackgroundColor: transparent;
|
||||
}
|
||||
|
||||
select.pf-c-form-control {
|
||||
--pf-c-form-control__select--BackgroundUrl: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 320 512'%3E%3Cpath fill='%23fafafa' d='M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.pf-c-form-control {
|
||||
--pf-c-form-control--BorderTopColor: transparent !important;
|
||||
--pf-c-form-control--BorderRightColor: transparent !important;
|
||||
|
@ -147,7 +147,7 @@ export class AKPageNavbar
|
||||
}
|
||||
|
||||
.accent-icon {
|
||||
height: 1.2em;
|
||||
height: 1em;
|
||||
width: 1em;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
@ -157,7 +157,6 @@ export class AKPageNavbar
|
||||
}
|
||||
|
||||
&.page-description {
|
||||
padding-top: 0.3em;
|
||||
grid-area: description;
|
||||
margin-block-end: var(--pf-global--spacer--md);
|
||||
|
||||
|
@ -4,7 +4,7 @@ import { ref } from "lit/directives/ref.js";
|
||||
|
||||
import { AkDualSelectProvider } from "./ak-dual-select-provider.js";
|
||||
import "./ak-dual-select.js";
|
||||
import type { DualSelectPair, DualSelectPairSource } from "./types.js";
|
||||
import type { DualSelectPair } from "./types.js";
|
||||
|
||||
/**
|
||||
* @element ak-dual-select-dynamic-provider
|
||||
@ -22,7 +22,7 @@ export class AkDualSelectDynamic extends AkDualSelectProvider {
|
||||
* @attr
|
||||
*/
|
||||
@property({ attribute: false })
|
||||
selector?: DualSelectPairSource;
|
||||
selector: (_: DualSelectPair[]) => Promise<DualSelectPair[]> = () => Promise.resolve([]);
|
||||
|
||||
#didFirstUpdate = false;
|
||||
|
||||
@ -37,7 +37,7 @@ export class AkDualSelectDynamic extends AkDualSelectProvider {
|
||||
|
||||
this.#didFirstUpdate = true;
|
||||
|
||||
this.selector?.(this.options).then((selected) => {
|
||||
this.selector(this.options).then((selected) => {
|
||||
this.selected = selected;
|
||||
});
|
||||
}
|
||||
|
@ -43,19 +43,15 @@ export type DualSelectPair<T = unknown> = [
|
||||
localMapping?: T,
|
||||
];
|
||||
|
||||
export type DualSelectPairSource<T = unknown> = (
|
||||
sourceInit: DualSelectPair<T>[],
|
||||
) => Promise<DualSelectPair<T>[]>;
|
||||
|
||||
export type BasePagination = Pick<
|
||||
Pagination,
|
||||
"startIndex" | "endIndex" | "count" | "previous" | "next"
|
||||
>;
|
||||
|
||||
export interface DataProvision<T = unknown> {
|
||||
export type DataProvision = {
|
||||
pagination?: Pagination;
|
||||
options: DualSelectPair<T>[];
|
||||
}
|
||||
options: DualSelectPair[];
|
||||
};
|
||||
|
||||
export type DataProvider = (page: number, search?: string) => Promise<DataProvision>;
|
||||
|
||||
|
@ -11,7 +11,7 @@ import { StageHost } from "#flow/stages/base";
|
||||
import "#user/user-settings/details/stages/prompt/PromptStage";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { CSSResult, TemplateResult, html } from "lit";
|
||||
import { CSSResult, PropertyValues, TemplateResult, html } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import { unsafeHTML } from "lit/directives/unsafe-html.js";
|
||||
|
||||
@ -36,7 +36,7 @@ export class UserSettingsFlowExecutor
|
||||
implements StageHost
|
||||
{
|
||||
@property()
|
||||
flowSlug = this.brand?.flowUserSettings;
|
||||
flowSlug?: string;
|
||||
|
||||
private _challenge?: ChallengeTypes;
|
||||
|
||||
@ -86,15 +86,12 @@ export class UserSettingsFlowExecutor
|
||||
});
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
if (this.flowSlug) {
|
||||
this.nextChallenge();
|
||||
}
|
||||
}
|
||||
|
||||
updated(): void {
|
||||
if (!this.flowSlug && this.brand) {
|
||||
updated(changedProperties: PropertyValues<this>): void {
|
||||
if (changedProperties.has("brand") && this.brand) {
|
||||
this.flowSlug = this.brand.flowUserSettings;
|
||||
|
||||
if (!this.flowSlug) return;
|
||||
|
||||
this.nextChallenge();
|
||||
}
|
||||
}
|
||||
|
@ -9106,6 +9106,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="sc7524ea24eeeb019">
|
||||
<source>Failed to preview prompt</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s783964a224796865">
|
||||
<source>Field which contains members of a group. Note that if using the "memberUid" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'. When selecting 'Lookup using a user attribute', this should be a user attribute, otherwise a group attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1d47b4f61ca53e8e">
|
||||
<source>Lookup using user attribute</source>
|
||||
</trans-unit>
|
||||
@ -9243,18 +9246,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="se3b26b762110bda0">
|
||||
<source>Delete authentik users and groups which were previously supplied by this source, but are now missing from it.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s0a2cb398b54a6207">
|
||||
<source>Welcome.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4e1d2cb86cf5ecd0">
|
||||
<source>Field which contains members of a group. The value of this field is matched against User membership attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s6478025f3e0174fa">
|
||||
<source>User membership attribute</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s344be99cf5d36407">
|
||||
<source>Attribute which matches the value of Group membership field.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
@ -7608,6 +7608,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="sc7524ea24eeeb019">
|
||||
<source>Failed to preview prompt</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s783964a224796865">
|
||||
<source>Field which contains members of a group. Note that if using the "memberUid" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'. When selecting 'Lookup using a user attribute', this should be a user attribute, otherwise a group attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1d47b4f61ca53e8e">
|
||||
<source>Lookup using user attribute</source>
|
||||
</trans-unit>
|
||||
@ -7745,18 +7748,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="se3b26b762110bda0">
|
||||
<source>Delete authentik users and groups which were previously supplied by this source, but are now missing from it.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s0a2cb398b54a6207">
|
||||
<source>Welcome.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4e1d2cb86cf5ecd0">
|
||||
<source>Field which contains members of a group. The value of this field is matched against User membership attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s6478025f3e0174fa">
|
||||
<source>User membership attribute</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s344be99cf5d36407">
|
||||
<source>Attribute which matches the value of Group membership field.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
@ -9167,6 +9167,9 @@ Las vinculaciones a grupos o usuarios se comparan con el usuario del evento.</ta
|
||||
<trans-unit id="sc7524ea24eeeb019">
|
||||
<source>Failed to preview prompt</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s783964a224796865">
|
||||
<source>Field which contains members of a group. Note that if using the "memberUid" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'. When selecting 'Lookup using a user attribute', this should be a user attribute, otherwise a group attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1d47b4f61ca53e8e">
|
||||
<source>Lookup using user attribute</source>
|
||||
</trans-unit>
|
||||
@ -9304,18 +9307,6 @@ Las vinculaciones a grupos o usuarios se comparan con el usuario del evento.</ta
|
||||
</trans-unit>
|
||||
<trans-unit id="se3b26b762110bda0">
|
||||
<source>Delete authentik users and groups which were previously supplied by this source, but are now missing from it.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s0a2cb398b54a6207">
|
||||
<source>Welcome.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4e1d2cb86cf5ecd0">
|
||||
<source>Field which contains members of a group. The value of this field is matched against User membership attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s6478025f3e0174fa">
|
||||
<source>User membership attribute</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s344be99cf5d36407">
|
||||
<source>Attribute which matches the value of Group membership field.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
@ -9690,6 +9690,10 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
|
||||
<source>Failed to preview prompt</source>
|
||||
<target>Échec de la prévisualisation de l'invite</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s783964a224796865">
|
||||
<source>Field which contains members of a group. Note that if using the "memberUid" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'. When selecting 'Lookup using a user attribute', this should be a user attribute, otherwise a group attribute.</source>
|
||||
<target>Champ qui contient les membres d'un groupe. Si vous utilisez le champ "memberUid", la valeur est censée contenir un nom distinctif relatif, par exemple 'memberUid=un-utilisateur' au lieu de 'memberUid=cn=un-utilisateur,ou=groups,...'. Lorsque "Recherche avec un attribut utilisateur" est sélectionné, cet attribut doit être un attribut utilisateur, sinon un attribut de groupe.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1d47b4f61ca53e8e">
|
||||
<source>Lookup using user attribute</source>
|
||||
<target>Recherche avec un attribut utilisateur</target>
|
||||
@ -9873,18 +9877,6 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
|
||||
<trans-unit id="se3b26b762110bda0">
|
||||
<source>Delete authentik users and groups which were previously supplied by this source, but are now missing from it.</source>
|
||||
<target>Supprimer les utilisateurs et les groupes authentik qui étaient auparavant fournis par cette source, mais qui en sont maintenant absents.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s0a2cb398b54a6207">
|
||||
<source>Welcome.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4e1d2cb86cf5ecd0">
|
||||
<source>Field which contains members of a group. The value of this field is matched against User membership attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s6478025f3e0174fa">
|
||||
<source>User membership attribute</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s344be99cf5d36407">
|
||||
<source>Attribute which matches the value of Group membership field.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
@ -9690,6 +9690,10 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<source>Failed to preview prompt</source>
|
||||
<target>Impossibile visualizzare l'anteprima del prompt</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s783964a224796865">
|
||||
<source>Field which contains members of a group. Note that if using the "memberUid" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'. When selecting 'Lookup using a user attribute', this should be a user attribute, otherwise a group attribute.</source>
|
||||
<target>Campo che contiene i membri di un gruppo. Si noti che se si utilizza il campo "memberUid", si presume che il valore contenga un nome relativo distinto. Ad esempio, "memberUid=some-user" invece di "memberUid=cn=some-user,ou=groups,...". Quando si seleziona "Cerca utilizzando un attributo utente", questo dovrebbe essere un attributo utente, altrimenti un attributo di gruppo.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1d47b4f61ca53e8e">
|
||||
<source>Lookup using user attribute</source>
|
||||
<target>Ricerca tramite attributo utente</target>
|
||||
@ -9856,18 +9860,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="se3b26b762110bda0">
|
||||
<source>Delete authentik users and groups which were previously supplied by this source, but are now missing from it.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s0a2cb398b54a6207">
|
||||
<source>Welcome.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4e1d2cb86cf5ecd0">
|
||||
<source>Field which contains members of a group. The value of this field is matched against User membership attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s6478025f3e0174fa">
|
||||
<source>User membership attribute</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s344be99cf5d36407">
|
||||
<source>Attribute which matches the value of Group membership field.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
@ -9075,6 +9075,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="sc7524ea24eeeb019">
|
||||
<source>Failed to preview prompt</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s783964a224796865">
|
||||
<source>Field which contains members of a group. Note that if using the "memberUid" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'. When selecting 'Lookup using a user attribute', this should be a user attribute, otherwise a group attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1d47b4f61ca53e8e">
|
||||
<source>Lookup using user attribute</source>
|
||||
</trans-unit>
|
||||
@ -9212,18 +9215,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="se3b26b762110bda0">
|
||||
<source>Delete authentik users and groups which were previously supplied by this source, but are now missing from it.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s0a2cb398b54a6207">
|
||||
<source>Welcome.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4e1d2cb86cf5ecd0">
|
||||
<source>Field which contains members of a group. The value of this field is matched against User membership attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s6478025f3e0174fa">
|
||||
<source>User membership attribute</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s344be99cf5d36407">
|
||||
<source>Attribute which matches the value of Group membership field.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
@ -8977,6 +8977,9 @@ Bindingen naar groepen/gebruikers worden gecontroleerd tegen de gebruiker van de
|
||||
<trans-unit id="sc7524ea24eeeb019">
|
||||
<source>Failed to preview prompt</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s783964a224796865">
|
||||
<source>Field which contains members of a group. Note that if using the "memberUid" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'. When selecting 'Lookup using a user attribute', this should be a user attribute, otherwise a group attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1d47b4f61ca53e8e">
|
||||
<source>Lookup using user attribute</source>
|
||||
</trans-unit>
|
||||
@ -9114,18 +9117,6 @@ Bindingen naar groepen/gebruikers worden gecontroleerd tegen de gebruiker van de
|
||||
</trans-unit>
|
||||
<trans-unit id="se3b26b762110bda0">
|
||||
<source>Delete authentik users and groups which were previously supplied by this source, but are now missing from it.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s0a2cb398b54a6207">
|
||||
<source>Welcome.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4e1d2cb86cf5ecd0">
|
||||
<source>Field which contains members of a group. The value of this field is matched against User membership attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s6478025f3e0174fa">
|
||||
<source>User membership attribute</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s344be99cf5d36407">
|
||||
<source>Attribute which matches the value of Group membership field.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
@ -9402,6 +9402,9 @@ Powiązania z grupami/użytkownikami są sprawdzane względem użytkownika zdarz
|
||||
<trans-unit id="sc7524ea24eeeb019">
|
||||
<source>Failed to preview prompt</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s783964a224796865">
|
||||
<source>Field which contains members of a group. Note that if using the "memberUid" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'. When selecting 'Lookup using a user attribute', this should be a user attribute, otherwise a group attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1d47b4f61ca53e8e">
|
||||
<source>Lookup using user attribute</source>
|
||||
</trans-unit>
|
||||
@ -9539,18 +9542,6 @@ Powiązania z grupami/użytkownikami są sprawdzane względem użytkownika zdarz
|
||||
</trans-unit>
|
||||
<trans-unit id="se3b26b762110bda0">
|
||||
<source>Delete authentik users and groups which were previously supplied by this source, but are now missing from it.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s0a2cb398b54a6207">
|
||||
<source>Welcome.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4e1d2cb86cf5ecd0">
|
||||
<source>Field which contains members of a group. The value of this field is matched against User membership attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s6478025f3e0174fa">
|
||||
<source>User membership attribute</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s344be99cf5d36407">
|
||||
<source>Attribute which matches the value of Group membership field.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
@ -9409,6 +9409,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="sc7524ea24eeeb019">
|
||||
<source>Failed to preview prompt</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s783964a224796865">
|
||||
<source>Field which contains members of a group. Note that if using the "memberUid" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'. When selecting 'Lookup using a user attribute', this should be a user attribute, otherwise a group attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1d47b4f61ca53e8e">
|
||||
<source>Lookup using user attribute</source>
|
||||
</trans-unit>
|
||||
@ -9547,16 +9550,4 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="se3b26b762110bda0">
|
||||
<source>Delete authentik users and groups which were previously supplied by this source, but are now missing from it.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s0a2cb398b54a6207">
|
||||
<source>Welcome.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4e1d2cb86cf5ecd0">
|
||||
<source>Field which contains members of a group. The value of this field is matched against User membership attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s6478025f3e0174fa">
|
||||
<source>User membership attribute</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s344be99cf5d36407">
|
||||
<source>Attribute which matches the value of Group membership field.</source>
|
||||
</trans-unit>
|
||||
</body></file></xliff>
|
||||
|
@ -9494,6 +9494,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="sc7524ea24eeeb019">
|
||||
<source>Failed to preview prompt</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s783964a224796865">
|
||||
<source>Field which contains members of a group. Note that if using the "memberUid" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'. When selecting 'Lookup using a user attribute', this should be a user attribute, otherwise a group attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1d47b4f61ca53e8e">
|
||||
<source>Lookup using user attribute</source>
|
||||
</trans-unit>
|
||||
@ -9631,18 +9634,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="se3b26b762110bda0">
|
||||
<source>Delete authentik users and groups which were previously supplied by this source, but are now missing from it.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s0a2cb398b54a6207">
|
||||
<source>Welcome.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4e1d2cb86cf5ecd0">
|
||||
<source>Field which contains members of a group. The value of this field is matched against User membership attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s6478025f3e0174fa">
|
||||
<source>User membership attribute</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s344be99cf5d36407">
|
||||
<source>Attribute which matches the value of Group membership field.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
@ -9465,6 +9465,9 @@ Gruplara/kullanıcılara yapılan bağlamalar, etkinliğin kullanıcısına kar
|
||||
<trans-unit id="sc7524ea24eeeb019">
|
||||
<source>Failed to preview prompt</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s783964a224796865">
|
||||
<source>Field which contains members of a group. Note that if using the "memberUid" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'. When selecting 'Lookup using a user attribute', this should be a user attribute, otherwise a group attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1d47b4f61ca53e8e">
|
||||
<source>Lookup using user attribute</source>
|
||||
</trans-unit>
|
||||
@ -9602,18 +9605,6 @@ Gruplara/kullanıcılara yapılan bağlamalar, etkinliğin kullanıcısına kar
|
||||
</trans-unit>
|
||||
<trans-unit id="se3b26b762110bda0">
|
||||
<source>Delete authentik users and groups which were previously supplied by this source, but are now missing from it.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s0a2cb398b54a6207">
|
||||
<source>Welcome.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4e1d2cb86cf5ecd0">
|
||||
<source>Field which contains members of a group. The value of this field is matched against User membership attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s6478025f3e0174fa">
|
||||
<source>User membership attribute</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s344be99cf5d36407">
|
||||
<source>Attribute which matches the value of Group membership field.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
@ -6215,6 +6215,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="sc7524ea24eeeb019">
|
||||
<source>Failed to preview prompt</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s783964a224796865">
|
||||
<source>Field which contains members of a group. Note that if using the "memberUid" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'. When selecting 'Lookup using a user attribute', this should be a user attribute, otherwise a group attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1d47b4f61ca53e8e">
|
||||
<source>Lookup using user attribute</source>
|
||||
</trans-unit>
|
||||
@ -6353,18 +6356,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="se3b26b762110bda0">
|
||||
<source>Delete authentik users and groups which were previously supplied by this source, but are now missing from it.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s0a2cb398b54a6207">
|
||||
<source>Welcome.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4e1d2cb86cf5ecd0">
|
||||
<source>Field which contains members of a group. The value of this field is matched against User membership attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s6478025f3e0174fa">
|
||||
<source>User membership attribute</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s344be99cf5d36407">
|
||||
<source>Attribute which matches the value of Group membership field.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -9691,6 +9691,10 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<source>Failed to preview prompt</source>
|
||||
<target>预览输入失败</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s783964a224796865">
|
||||
<source>Field which contains members of a group. Note that if using the "memberUid" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'. When selecting 'Lookup using a user attribute', this should be a user attribute, otherwise a group attribute.</source>
|
||||
<target>包含组成员的字段。请注意,如果使用 "memberUid" 字段,则假定该值包含相对可分辨名称。例如,'memberUid=some-user' 而不是 'memberUid=cn=some-user,ou=groups,...'。当选中“使用用户属性查询”时,此配置应该为用户属性,否则为组属性。</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1d47b4f61ca53e8e">
|
||||
<source>Lookup using user attribute</source>
|
||||
<target>使用用户属性查询</target>
|
||||
@ -9869,23 +9873,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s42b57339ad2f3ac7">
|
||||
<source>Delete Not Found Objects</source>
|
||||
<target>删除不存在对象</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="se3b26b762110bda0">
|
||||
<source>Delete authentik users and groups which were previously supplied by this source, but are now missing from it.</source>
|
||||
<target>删除之前由此源提供,但现已缺失的用户和组。</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s0a2cb398b54a6207">
|
||||
<source>Welcome.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4e1d2cb86cf5ecd0">
|
||||
<source>Field which contains members of a group. The value of this field is matched against User membership attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s6478025f3e0174fa">
|
||||
<source>User membership attribute</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s344be99cf5d36407">
|
||||
<source>Attribute which matches the value of Group membership field.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
@ -7308,6 +7308,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="sc7524ea24eeeb019">
|
||||
<source>Failed to preview prompt</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s783964a224796865">
|
||||
<source>Field which contains members of a group. Note that if using the "memberUid" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'. When selecting 'Lookup using a user attribute', this should be a user attribute, otherwise a group attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1d47b4f61ca53e8e">
|
||||
<source>Lookup using user attribute</source>
|
||||
</trans-unit>
|
||||
@ -7445,18 +7448,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="se3b26b762110bda0">
|
||||
<source>Delete authentik users and groups which were previously supplied by this source, but are now missing from it.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s0a2cb398b54a6207">
|
||||
<source>Welcome.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4e1d2cb86cf5ecd0">
|
||||
<source>Field which contains members of a group. The value of this field is matched against User membership attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s6478025f3e0174fa">
|
||||
<source>User membership attribute</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s344be99cf5d36407">
|
||||
<source>Attribute which matches the value of Group membership field.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
@ -9873,11 +9873,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s42b57339ad2f3ac7">
|
||||
<source>Delete Not Found Objects</source>
|
||||
<target>删除不存在对象</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="se3b26b762110bda0">
|
||||
<source>Delete authentik users and groups which were previously supplied by this source, but are now missing from it.</source>
|
||||
<target>删除之前由此源提供,但现已缺失的用户和组。</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
@ -9052,6 +9052,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="sc7524ea24eeeb019">
|
||||
<source>Failed to preview prompt</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s783964a224796865">
|
||||
<source>Field which contains members of a group. Note that if using the "memberUid" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'. When selecting 'Lookup using a user attribute', this should be a user attribute, otherwise a group attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s1d47b4f61ca53e8e">
|
||||
<source>Lookup using user attribute</source>
|
||||
</trans-unit>
|
||||
@ -9189,18 +9192,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="se3b26b762110bda0">
|
||||
<source>Delete authentik users and groups which were previously supplied by this source, but are now missing from it.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s0a2cb398b54a6207">
|
||||
<source>Welcome.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s4e1d2cb86cf5ecd0">
|
||||
<source>Field which contains members of a group. The value of this field is matched against User membership attribute.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s6478025f3e0174fa">
|
||||
<source>User membership attribute</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s344be99cf5d36407">
|
||||
<source>Attribute which matches the value of Group membership field.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
@ -8,7 +8,7 @@ Managing the applications that your team uses involves several tasks, from initi
|
||||
|
||||
To add an application to authentik and have it display on users' **My applications** page, follow these steps:
|
||||
|
||||
1. Log in to authentik as an administrator and open the authentik Admin interface.
|
||||
1. Log in to authentik as an admin, and open the authentik Admin interface.
|
||||
|
||||
2. Navigate to **Applications -> Applications** and click **Create with Provider** to create an application and provider pair. (Alternatively you can create only an application, without a provider, by clicking **Create.)**
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
---
|
||||
title: Flow Context
|
||||
toc_max_heading_level: 5
|
||||
---
|
||||
|
||||
Each flow execution has an independent _context_. This context holds all of the arbitrary data about that specific flow, data which can then be used and transformed by stages and policies.
|
||||
@ -157,7 +156,6 @@ Possible options:
|
||||
- `auth_mfa` (Authentication via MFA device without password)
|
||||
- `auth_webauthn_pwl` (Passwordless authentication via WebAuthn with Passkeys)
|
||||
- `jwt` ([M2M](../../../providers/oauth2/client_credentials.mdx) authentication via an existing JWT)
|
||||
- `mtls` (Authentication via Certificate, see [Mutual TLS Stage](../../stages/mtls/index.md))
|
||||
|
||||
##### `auth_method_args` (dictionary)
|
||||
|
||||
@ -178,10 +176,7 @@ Example:
|
||||
// JWT information when `auth_method` `jwt` was used
|
||||
"jwt": {},
|
||||
"source": null,
|
||||
"provider": null,
|
||||
// Certificate used for authentication
|
||||
// applies for `auth_method` `mtls`
|
||||
"certificate": {}
|
||||
"provider": null
|
||||
}
|
||||
```
|
||||
|
||||
@ -208,22 +203,3 @@ If _Show matched user_ is disabled, this key will be set to the user identifier
|
||||
[Set this key](../../../../customize/policies/expression/managing_flow_context_keys.md) in an Expression Policy to override [Redirect stage](../../stages/redirect/index.md) to force it to redirect to a certain URL or flow. This is useful when a flow requires that the redirection target be decided dynamically.
|
||||
|
||||
Use the format `ak-flow://{slug}` to use the Redirect stage in Flow mode. Any other format will result in the Redirect stage running in Static mode.
|
||||
|
||||
#### Mutual TLS Stage
|
||||
|
||||
##### `certificate` (dictionary):ak-version[2025.6]
|
||||
|
||||
This key is set by the Mutual TLS Stage during enrollment and contains data about the certificate supplied by the browser.
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"serial_number": "1234",
|
||||
"subject": "CN=client",
|
||||
"issuer": "CN=authentik Test CA, O=authentik, OU=Self-signed",
|
||||
"fingerprint_sha256": "08:D4:A4:79:25:CA:C3:51:28:88:BB:30:C2:96:C3:44:5A:EB:18:07:84:CA:B4:75:27:74:61:19:8A:6A:AF:FC",
|
||||
"fingerprint_sha1": "5D:14:0D:5F:A2:7E:14:B0:F1:1D:6F:CD:E3:4B:81:68:71:24:1A:70",
|
||||
"raw": "-----BEGIN CERTIFICATE-----...."
|
||||
}
|
||||
```
|
||||
|
@ -1,124 +0,0 @@
|
||||
---
|
||||
title: Mutual TLS stage
|
||||
authentik_version: "2025.6"
|
||||
authentik_preview: true
|
||||
authentik_enterprise: true
|
||||
toc_max_heading_level: 5
|
||||
---
|
||||
|
||||
The Mutual TLS stage enables authentik to use client certificates to enroll and authenticate users. These certificates can be local to the device or available via PIV Smart Cards, Yubikeys, etc.
|
||||
|
||||
Management of client certificates is out of the scope of this document.
|
||||
|
||||
## Reverse-proxy configuration
|
||||
|
||||
Using the Mutual TLS stage requires special configuration of any reverse proxy that is used in front of authentik, because the reverse-proxy interacts directly with the browser.
|
||||
|
||||
- nginx
|
||||
- [Standalone nginx](#nginx-standalone)
|
||||
- [nginx kubernetes ingress](#nginx-ingress)
|
||||
- Traefik
|
||||
- [Standalone Traefik](#traefik-standalone)
|
||||
- [Traefik kubernetes ingress](#traefik-ingress)
|
||||
- [envoy](#envoy)
|
||||
- [No reverse proxy](#no-reverse-proxy)
|
||||
|
||||
#### nginx Standalone
|
||||
|
||||
Add this configuration snippet in your authentik virtual host:
|
||||
|
||||
```nginx
|
||||
# server {
|
||||
ssl_client_certificate /etc/ssl/path-to-my-ca.pem;
|
||||
ssl_verify_client on;
|
||||
|
||||
# location / {
|
||||
proxy_set_header ssl-client-cert $ssl_client_escaped_cert;
|
||||
# }
|
||||
# }
|
||||
```
|
||||
|
||||
See [nginx documentation](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_client_certificate) for reference.
|
||||
|
||||
#### nginx Ingress
|
||||
|
||||
Add these annotations to your authentik ingress object:
|
||||
|
||||
```yaml
|
||||
nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream: "true"
|
||||
# This secret needs to contain `ca.crt` which is the certificate authority to validate against.
|
||||
nginx.ingress.kubernetes.io/auth-tls-secret: namespace/secretName
|
||||
```
|
||||
|
||||
See [ingress-nginx documentation](https://kubernetes.github.io/ingress-nginx/examples/auth/client-certs/) for reference.
|
||||
|
||||
#### Traefik Standalone
|
||||
|
||||
Add this snippet to your traefik configuration:
|
||||
|
||||
```yaml
|
||||
tls:
|
||||
options:
|
||||
default:
|
||||
clientAuth:
|
||||
# in PEM format. each file can contain multiple CAs.
|
||||
caFiles:
|
||||
- tests/clientca1.crt
|
||||
- tests/clientca2.crt
|
||||
clientAuthType: RequireAndVerifyClientCert
|
||||
```
|
||||
|
||||
See the [Traefik mTLS documentation](https://doc.traefik.io/traefik/https/tls/#client-authentication-mtls) for reference.
|
||||
|
||||
#### Traefik Ingress
|
||||
|
||||
Create a middleware object with these options:
|
||||
|
||||
```yaml
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: test-passtlsclientcert
|
||||
spec:
|
||||
passTLSClientCert:
|
||||
pem: true
|
||||
```
|
||||
|
||||
See the [Traefik PassTLSClientCert documentation](https://doc.traefik.io/traefik/middlewares/http/passtlsclientcert/) for reference.
|
||||
|
||||
#### Envoy
|
||||
|
||||
See the [Envoy mTLS documentation](https://www.envoyproxy.io/docs/envoy/latest/start/quick-start/securing#use-mutual-tls-mtls-to-enforce-client-certificate-authentication) and [Envoy header documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#x-forwarded-client-cert) for configuration.
|
||||
|
||||
#### No reverse proxy
|
||||
|
||||
When using authentik without a reverse proxy, select the certificate authorities in the corresponding [brand](../../../../sys-mgmt/brands.md#client-certificates) for the domain, under **Other global settings**.
|
||||
|
||||
## Stage configuration
|
||||
|
||||
1. Log in as an admin to authentik, and go to the Admin interface.
|
||||
|
||||
2. In the Admin interface, navigate to **System -> Certificates**
|
||||
|
||||
3. Create a new certificate for the Certificate Authority used to sign client certificates.
|
||||
|
||||
4. In the Admin interface, navigate to **Flows -> Stages**.
|
||||
|
||||
5. Click **Create**, and select **Mutual TLS Stage**, and in the **New stage** box, define the following fields:
|
||||
|
||||
- **Name**: define a descriptive name, such as "chrome-device-trust".
|
||||
|
||||
- **Stage-specific settings**
|
||||
|
||||
- **Mode**: Configure the mode this stage operates in.
|
||||
|
||||
- **Certificate optional**: When no certificate is provided by the user or the reverse proxy, the flow will continue to the next stage.
|
||||
- **Certificate required**: When no certificate is provided, the flow ends with an error message.
|
||||
|
||||
- **Certificate authorities**: Select the certificate authorities used to sign client certificates.
|
||||
|
||||
- **Certificate attribute**: Select the attribute of the certificate to be used to find a user for authentication.
|
||||
|
||||
- **User attribute**: Select the attribute of the user the certificate should be compared against.
|
||||
|
||||
6. Click **Finish**.
|
@ -9,7 +9,7 @@ For detailed instructions, refer to Microsoft Entra ID documentation.
|
||||
|
||||
## Configure Entra ID
|
||||
|
||||
1. Log in to the Azure portal and on the Home page, under Azure services, click on or search for **App registrations**.
|
||||
1. Log into the Azure portal and on the Home page, under Azure services, click on or search for **App registrations**.
|
||||
2. On the **App registrations** page, click **New registration**.
|
||||
3. On the **Register an application** page, define the **Name** of the app, and under **Supported account types** select **Accounts in this organizational directory only**. Leave **Redirect URI** empty.
|
||||
4. Click **Register**.
|
||||
|
@ -4,7 +4,7 @@ title: Create an OAuth2 provider
|
||||
|
||||
To add a provider (and the application that uses the provider for authentication) use the ** Create with provider** option, which creates both the new application and the required provider at the same time. For typical scenarios, authentik recommends that you create both the application and the provider together. (Alternatively, use our legacy process: navigate to **Applications --> Providers**, and then click **Create**.)
|
||||
|
||||
1. Log in to authentik as an administrator and open the authentik Admin interface.
|
||||
1. Log in to authentik as an admin, and open the authentik Admin interface.
|
||||
|
||||
2. Navigate to **Applications -> Applications** and click **Create with provider** to create an application and provider pair. (Alternatively you can create only an application, without a provider, by clicking **Create**.)
|
||||
|
||||
|
@ -52,7 +52,7 @@ If the user _has_ finished the authentication and authorization, the response wi
|
||||
|
||||
### Create and apply a device code flow
|
||||
|
||||
1. Log in to authentik as an administrator and open the authentik Admin interface.
|
||||
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`)
|
||||
|
@ -152,17 +152,3 @@ return {
|
||||
```
|
||||
|
||||
Afterwards, edit the _Proxy provider_ and add this new mapping. The expression is only evaluated when the user logs into the application.
|
||||
|
||||
## Host header:ak-version[2025.6.1]
|
||||
|
||||
By default, the proxy provider will use forwarded Host header received from the client. Starting with authentik 2025.6.1, it is possible to dynamically adjust the Host header with a property mapping.
|
||||
|
||||
```python
|
||||
return {
|
||||
"ak_proxy": {
|
||||
"host_header": "my-internal-host-header"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Afterwards, edit the _Proxy provider_ and add this new mapping. The expression is only evaluated when the user logs into the application.
|
||||
|
@ -26,7 +26,7 @@ Depending on whether you are connecting using RDP, SSH, or VNC, the exact config
|
||||
|
||||
The first step is to create the RAC application and provider pair.
|
||||
|
||||
1. Log in to authentik as an administrator and open the authentik Admin interface.
|
||||
1. Log in to authentik as an admin, and open the authentik Admin interface.
|
||||
2. Navigate to **Applications** > **Applications** and click **Create with provider**.
|
||||
3. Follow these [instructions](../../applications/manage_apps.mdx#instructions) to create your RAC application and provider.
|
||||
|
||||
@ -34,7 +34,7 @@ The first step is to create the RAC application and provider pair.
|
||||
|
||||
Next, you need to add property mappings for each remote machine you want to access. Property mappings allow you to pass information to external applications, and with RAC they are used to pass the host name, IP address, and access credentials of the remote machine.
|
||||
|
||||
1. Log in to authentik as an administrator and open the authentik Admin interface.
|
||||
1. Log in to authentik as an admin, and open the authentik Admin interface.
|
||||
2. Navigate to **Customization > Property Mappings** and click **Create**.
|
||||
|
||||
- **Select Type**: RAC Property Mappings
|
||||
@ -57,7 +57,7 @@ Next, you need to add property mappings for each remote machine you want to acce
|
||||
|
||||
Finally, you need to create an endpoint for each remote machine. Endpoints are defined within providers; connections between the remote machine and authentik are enabled through communication between the provider's endpoint and the remote machine.
|
||||
|
||||
1. Log in to authentik as an administrator and open the authentik Admin interface.
|
||||
1. Log in to authentik as an admin, and open the authentik Admin interface.
|
||||
2. Navigate to **Applications > Providers**.
|
||||
3. Click the **Edit** button on the RAC provider that you previously created.
|
||||
4. On the Provider page, under **Endpoints**, click **Create**, and provide the following settings:
|
||||
|
@ -36,12 +36,11 @@ The _Endpoint_ object specifies the hostname/IP of the machine to connect to, as
|
||||
|
||||
Configuration details such as credentials can be specified through _settings_, which can be specified on different levels and are all merged together when connecting:
|
||||
|
||||
1. Default settings
|
||||
2. Provider settings
|
||||
3. Endpoint settings
|
||||
1. Provider settings
|
||||
2. Endpoint settings
|
||||
3. Connection settings
|
||||
4. Provider property mapping settings
|
||||
5. Endpoint property mapping settings
|
||||
6. Connection settings
|
||||
|
||||
### Connection settings
|
||||
|
||||
|
@ -16,7 +16,7 @@ The workflow to implement an SSF provider as a [backchannel provider](../../appl
|
||||
|
||||
## Create the SSF provider
|
||||
|
||||
1. Log in to authentik as an administrator and in the Admin interface navigate to **Applications -> Providers**.
|
||||
1. Log in to authentik as an admin, and in the Admin interface navigate to **Applications -> Providers**.
|
||||
|
||||
2. Click **Create**.
|
||||
|
||||
@ -28,7 +28,7 @@ The workflow to implement an SSF provider as a [backchannel provider](../../appl
|
||||
|
||||
## Create the OIDC provider
|
||||
|
||||
1. Log in to authentik as an administrator and in the Admin interface navigate to **Applications -> Providers**.
|
||||
1. Log in to authentik as an admin, and in the Admin interface navigate to **Applications -> Providers**.
|
||||
|
||||
2. Click **Create**.
|
||||
|
||||
@ -38,7 +38,7 @@ The workflow to implement an SSF provider as a [backchannel provider](../../appl
|
||||
|
||||
## Create the application
|
||||
|
||||
1. Log in to authentik as an administrator and in the Admin interface navigate to **Applications -> Applications**.
|
||||
1. Log in to authentik as an admin, and in the Admin interface navigate to **Applications -> Applications**.
|
||||
|
||||
2. Click **Create**.
|
||||
|
||||
|
@ -357,11 +357,7 @@ Defaults to `86400`.
|
||||
|
||||
### `AUTHENTIK_SESSION_STORAGE`:ak-version[2024.4]
|
||||
|
||||
:::info Deprecated
|
||||
This setting is removed as of version 2025.4. Sessions are now exclusively stored in the database. See our [2025.4 release notes](../../releases/2025.4#sessions-are-now-stored-in-the-database) for more information.
|
||||
:::
|
||||
|
||||
If you are running a version earlier than 2025.4, you can configure if the sessions are stored in the cache or the database. Defaults to `cache`. Allowed values are `cache` and `db`. Note that changing this value will invalidate all previous sessions.
|
||||
Configure if the sessions are stored in the cache or the database. Defaults to `db`. Allowed values are `cache` and `db`. Note that changing this value will invalidate all previous sessions.
|
||||
|
||||
### `AUTHENTIK_SESSIONS__UNAUTHENTICATED_AGE`:ak-version[2025.4]
|
||||
|
||||
|
@ -14,7 +14,7 @@ authentik does not support downgrading. Make sure to back up your database in ca
|
||||
|
||||
- Make a backup of your PostgreSQL database before upgrading. You can dump your existing database to get a backup file. For more information about dumping and backing up your database, refer to [Upgrade PostgreSQL on Docker Compose](../troubleshooting/postgres/upgrade_docker.md) or [Upgrade PostgreSQL on Kubernetes](../troubleshooting/postgres/upgrade_kubernetes.md).
|
||||
|
||||
- You need to upgrade in sequence of the major releases; do not skip directly from an older major version to the most recent version. For example, if you are currently running 2023.10.3, you should first upgrade to the latest 2024.2.x release, then to the latest 2024.4.x release, and finally to the latest 2024.6.x release, in sequence. Always use the latest available patch version (_x_ in this case being the latest patch release) for each major.minor release.
|
||||
- You need to upgrade in sequence of the major releases; do not skip directly from an older major version to the most recent version. For example, if you are currently running 2023.10.3, you will need to first upgrade to 2024.2.x, then 2024.4.x, and then 2024.6.x, in sequence.
|
||||
|
||||
- The version of the authentik instance and any outposts must be the same. We recommended that you always upgrade any outposts at the same time you upgrade your authentik instance.
|
||||
|
||||
|
@ -1,576 +0,0 @@
|
||||
---
|
||||
title: Release 2025.6
|
||||
slug: "/releases/2025.6"
|
||||
---
|
||||
|
||||
## Highlights
|
||||
|
||||
- **mTLS Stage**: :ak-enterprise The Mutual TLS stage provides support for mTLS, a standard protocol that uses certificates for mutual authentication between a client and a server.
|
||||
|
||||
- **Email verification compatibility with link scanners**: We have improved compatibility for environments that have automated scanning software that inadvertently invalidated one-time links sent by authentik.
|
||||
|
||||
- **LDAP source sync forward deletions**: This option synchronizes the deletion of users and groups from LDAP sources to authentik.
|
||||
|
||||
## Breaking changes
|
||||
|
||||
- **Helm chart dependencies upgrades**:
|
||||
|
||||
- The PostgreSQL chart has been updated to version 16.7.4. The PostgreSQL image is no longer pinned in authentik's default values and has been upgraded from version 15 to 17. Follow our [PostgreSQL upgrade instructions](../../troubleshooting/postgres/upgrade_kubernetes.md) to update to the latest PostgreSQL version.
|
||||
- The Redis chart has been updated to version 21.1.6. There are no breaking changes and Redis has been upgraded from version 7 to 8.
|
||||
|
||||
- **Deprecated and frozen `:latest` container image tag after 2025.2**
|
||||
|
||||
Using the `:latest` tag with container images is not recommended as it can lead to unintentional updates and potentially broken setups. The tag will not be removed, however it will also not be updated past 2025.2. We strongly recommended the use of a specific version tag for authentik instances' container images, such as `:2025.6`.
|
||||
|
||||
- **CSS**: We’ve made some improvements to our theming system. If your authentik instance uses custom CSS, you might need to review flow and user interfaces for any visual changes.
|
||||
|
||||
## New features and improvements
|
||||
|
||||
- **mTLS stage**: :ak-enterprise The Mutual TLS stage enables authentik to use client certificates to enroll and authenticate users. These certificates can be local to the device or available via PIV Smart Cards, Yubikeys, etc. For environments where certificates are already rolled out, this can make authentication a lot more seamless. Refer to our [technical documentation](../add-secure-apps/flows-stages/stages/mtls/) for more information.
|
||||
- **Email verification compatibility with link scanners**: We have improved compatibility for environments with automated scanning software that inadvertently invalidated one-time links sent by authentik.
|
||||
- **LDAP source sync forward deletions**: With this option enabled, users or groups created in authentik via LDAP sources will also be removed from authentik if they are deleted from the LDAP source. For more information, please refer to our [LDAP source documentation](../users-sources/sources/protocols/ldap/).
|
||||
- **Provider sync performance**: We have implemented parallel scheduling for outgoing syncs to provide faster synchronization.
|
||||
- **Branding**: Custom branding should now be more consistent on initial load, without flickering.
|
||||
- **Remote Access Control (RAC) improved [documentation](https://docs.goauthentik.io/docs/add-secure-apps/providers/rac/)**: Added content about how to authenticate using a public key and improved the wording and formatting throughout the topic.
|
||||
|
||||
## New integration guides
|
||||
|
||||
An integration is how authentik connects to third-party applications, directories, and other identity providers. The following integration guides were recently added to our documentation:
|
||||
|
||||
- [Atlassian Cloud (Jira, Confluence, etc)](../../../integrations/services/atlassian/)
|
||||
- [Coder](../../../integrations/services/coder/)
|
||||
- [FileRise](../../../integrations/services/filerise/)
|
||||
- [Komodo](../../../integrations/services/komodo/)
|
||||
- [Pangolin](../../../integrations/services/pangolin/)
|
||||
- [Push Security](../../../integrations/services/push-security/)
|
||||
- [Stripe](../../../integrations/services/stripe/)
|
||||
- [Tailscale](../../../integrations/services/tailscale/)
|
||||
- [YouTrack](../../../integrations/services/youtrack/)
|
||||
|
||||
## Upgrading
|
||||
|
||||
This release does not introduce any new requirements. You can follow the upgrade instructions below; for more detailed information about upgrading authentik, refer to our [Upgrade documentation](../../install-config/upgrade.mdx).
|
||||
|
||||
:::warning
|
||||
When you upgrade, be aware that the version of the authentik instance and of any outposts must be the same. We recommended that you always upgrade any outposts at the same time you upgrade your authentik instance.
|
||||
:::
|
||||
|
||||
### Docker Compose
|
||||
|
||||
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/2025.6/docker-compose.yml
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
The `-O` flag retains the downloaded file's name, overwriting any existing local file with the same name.
|
||||
|
||||
### Kubernetes
|
||||
|
||||
Upgrade the Helm Chart to the new version, using the following commands:
|
||||
|
||||
```shell
|
||||
helm repo update
|
||||
helm upgrade authentik authentik/authentik -f values.yaml --version ^2025.6
|
||||
```
|
||||
|
||||
## Minor changes/fixes
|
||||
|
||||
- brands: fix CSS Migration not updating brands (#14306)
|
||||
- core: fix session migration when old session can't be loaded (#14466)
|
||||
- core: fix unable to create group if no enable_group_superuser permission is given (#14510)
|
||||
- core: Migrate permissions before deleting OldAuthenticatedSession (#14788)
|
||||
- core: Publish web packages. (#14648)
|
||||
- core: remove `OldAuthenticatedSession` content type (#14507)
|
||||
- enterprise: fix expired license's users being counted (#14451)
|
||||
- enterprise/stages: Add MTLS stage (#14296)
|
||||
- enterprise/stages/mtls: improve certificate validation (#14582)
|
||||
- enterprise/stages/mtls: update go & web client, fix py client generation (#14576)
|
||||
- lib/sync: fix static incorrect label of pages (#14851)
|
||||
- lib/sync/outgoing: reduce number of db queries made (#14177)
|
||||
- lib/sync/outgoing: sync in parallel (#14697)
|
||||
- lifecycle: fix ak dump_config (#14445)
|
||||
- lifecycle: fix test-all in docker (#14244)
|
||||
- outposts: fix tmpdir in containers not being set (#14444)
|
||||
- providers/ldap: retain binder and update users instead of re-creating (#14735)
|
||||
- providers/proxy: kubernetes outpost: fix reconcile when ingress class name changed (#14612)
|
||||
- providers/rac: apply ConnectionToken scoped-settings last (#14838)
|
||||
- rbac: add `name` to Permissions search (#14269)
|
||||
- rbac: fix RoleObjectPermissionTable not showing `add_user_to_group` (#14312)
|
||||
- root: backport SFE Build fix (#14495)
|
||||
- root: do not use /bin/bash directly (#14698)
|
||||
- root: improve sentry distributed tracing (#14468)
|
||||
- root: move forked dependencies to goauthentik org (#14590)
|
||||
- root: pin package version in pyproject for dependabot (#14469)
|
||||
- root: readme: use right contribution guide link (#14250)
|
||||
- root: replace raw.githubusercontent.com by checking out repo (#14567)
|
||||
- root: temporarily deactivate database pool option (#14443)
|
||||
- sources/kerberos: resolve logger warnings (#14540)
|
||||
- sources/ldap: add forward deletion option (#14718)
|
||||
- stages/email: fix email scanner voiding token (#14325)
|
||||
- tests/e2e: Add E2E tests for Flow SFE (#14484)
|
||||
- tests/e2e: add test for authentication flow in compatibility mode (#14392)
|
||||
- tests/e2e: fix flaky SAML Source test (#14708)
|
||||
- web, website: update browserslist (#14386)
|
||||
- web: Add specific Storybook dependency. (#14719)
|
||||
- web: Clean up browser-only module imports that crash WebDriverIO. (#14330)
|
||||
- web: cleanup/loading attribute always true (#14288)
|
||||
- web: Controller refinements, error handling (#14700)
|
||||
- Web: Controllers cleanup (#14616)
|
||||
- web: fix bug that was causing charts to be too tall (#14253)
|
||||
- web: fix description for signing responses in SAML provider (#14573)
|
||||
- web: Fix issue where dual select type is not specific. (#14783)
|
||||
- web: Fix issue where Storybook cannot resolve styles. (#14553)
|
||||
- web: Fix missing Enterprise sidebar entries. (#14615)
|
||||
- web: fix regression in subpath support (#14646)
|
||||
- web: NPM workspaces (#14274)
|
||||
- web: Type Tidy (#14647)
|
||||
- web: Use engine available on Github Actions. (#14699)
|
||||
- web: Use monorepo package utilities to build packages (#14159)
|
||||
- web/admin: Dual select state management, custom event dispatching. (#14490)
|
||||
- web/admin: fix enterprise menu display (#14447)
|
||||
- web/admin: fix permissions modal button missing for PolicyBindings and FlowStageBindings (#14619)
|
||||
- web/admin: Fix sidebar toggle synchronization. (#14487)
|
||||
- web/admin: prevent default logo flashing in admin interface (#13960)
|
||||
- web/flows: update default flow background (#14769)
|
||||
- web/flows/sfe: fix global background image not being loaded (#14442)
|
||||
|
||||
## API Changes
|
||||
|
||||
#### What's New
|
||||
|
||||
---
|
||||
|
||||
##### `GET` /stages/mtls/
|
||||
|
||||
##### `POST` /stages/mtls/
|
||||
|
||||
##### `GET` /stages/mtls/{stage_uuid}/
|
||||
|
||||
##### `PUT` /stages/mtls/{stage_uuid}/
|
||||
|
||||
##### `DELETE` /stages/mtls/{stage_uuid}/
|
||||
|
||||
##### `PATCH` /stages/mtls/{stage_uuid}/
|
||||
|
||||
##### `GET` /stages/mtls/{stage_uuid}/used_by/
|
||||
|
||||
#### What's Changed
|
||||
|
||||
---
|
||||
|
||||
##### `GET` /core/brands/{brand_uuid}/
|
||||
|
||||
###### Return Type:
|
||||
|
||||
Changed response : **200 OK**
|
||||
|
||||
- Changed content type : `application/json`
|
||||
|
||||
- Added property `client_certificates` (array)
|
||||
|
||||
> Certificates used for client authentication.
|
||||
|
||||
Items (string):
|
||||
|
||||
##### `PUT` /core/brands/{brand_uuid}/
|
||||
|
||||
###### Request:
|
||||
|
||||
Changed content type : `application/json`
|
||||
|
||||
- Added property `client_certificates` (array)
|
||||
> Certificates used for client authentication.
|
||||
|
||||
###### Return Type:
|
||||
|
||||
Changed response : **200 OK**
|
||||
|
||||
- Changed content type : `application/json`
|
||||
|
||||
- Added property `client_certificates` (array)
|
||||
> Certificates used for client authentication.
|
||||
|
||||
##### `PATCH` /core/brands/{brand_uuid}/
|
||||
|
||||
###### Request:
|
||||
|
||||
Changed content type : `application/json`
|
||||
|
||||
- Added property `client_certificates` (array)
|
||||
> Certificates used for client authentication.
|
||||
|
||||
###### Return Type:
|
||||
|
||||
Changed response : **200 OK**
|
||||
|
||||
- Changed content type : `application/json`
|
||||
|
||||
- Added property `client_certificates` (array)
|
||||
> Certificates used for client authentication.
|
||||
|
||||
##### `GET` /policies/event_matcher/{policy_uuid}/
|
||||
|
||||
###### Return Type:
|
||||
|
||||
Changed response : **200 OK**
|
||||
|
||||
- Changed content type : `application/json`
|
||||
|
||||
- Changed property `app` (string)
|
||||
|
||||
> Match events created by selected application. When left empty, all applications are matched.
|
||||
|
||||
Added enum value:
|
||||
|
||||
- `authentik.enterprise.stages.mtls`
|
||||
|
||||
- Changed property `model` (string)
|
||||
|
||||
> Match events created by selected model. When left empty, all models are matched. When an app is selected, all the application's models are matched.
|
||||
|
||||
Added enum value:
|
||||
|
||||
- `authentik_stages_mtls.mutualtlsstage`
|
||||
|
||||
##### `PUT` /policies/event_matcher/{policy_uuid}/
|
||||
|
||||
###### Request:
|
||||
|
||||
Changed content type : `application/json`
|
||||
|
||||
- Changed property `app` (string)
|
||||
|
||||
> Match events created by selected application. When left empty, all applications are matched.
|
||||
|
||||
Added enum value:
|
||||
|
||||
- `authentik.enterprise.stages.mtls`
|
||||
|
||||
- Changed property `model` (string)
|
||||
|
||||
> Match events created by selected model. When left empty, all models are matched. When an app is selected, all the application's models are matched.
|
||||
|
||||
Added enum value:
|
||||
|
||||
- `authentik_stages_mtls.mutualtlsstage`
|
||||
|
||||
###### Return Type:
|
||||
|
||||
Changed response : **200 OK**
|
||||
|
||||
- Changed content type : `application/json`
|
||||
|
||||
- Changed property `app` (string)
|
||||
|
||||
> Match events created by selected application. When left empty, all applications are matched.
|
||||
|
||||
Added enum value:
|
||||
|
||||
- `authentik.enterprise.stages.mtls`
|
||||
|
||||
- Changed property `model` (string)
|
||||
|
||||
> Match events created by selected model. When left empty, all models are matched. When an app is selected, all the application's models are matched.
|
||||
|
||||
Added enum value:
|
||||
|
||||
- `authentik_stages_mtls.mutualtlsstage`
|
||||
|
||||
##### `PATCH` /policies/event_matcher/{policy_uuid}/
|
||||
|
||||
###### Request:
|
||||
|
||||
Changed content type : `application/json`
|
||||
|
||||
- Changed property `app` (string)
|
||||
|
||||
> Match events created by selected application. When left empty, all applications are matched.
|
||||
|
||||
Added enum value:
|
||||
|
||||
- `authentik.enterprise.stages.mtls`
|
||||
|
||||
- Changed property `model` (string)
|
||||
|
||||
> Match events created by selected model. When left empty, all models are matched. When an app is selected, all the application's models are matched.
|
||||
|
||||
Added enum value:
|
||||
|
||||
- `authentik_stages_mtls.mutualtlsstage`
|
||||
|
||||
###### Return Type:
|
||||
|
||||
Changed response : **200 OK**
|
||||
|
||||
- Changed content type : `application/json`
|
||||
|
||||
- Changed property `app` (string)
|
||||
|
||||
> Match events created by selected application. When left empty, all applications are matched.
|
||||
|
||||
Added enum value:
|
||||
|
||||
- `authentik.enterprise.stages.mtls`
|
||||
|
||||
- Changed property `model` (string)
|
||||
|
||||
> Match events created by selected model. When left empty, all models are matched. When an app is selected, all the application's models are matched.
|
||||
|
||||
Added enum value:
|
||||
|
||||
- `authentik_stages_mtls.mutualtlsstage`
|
||||
|
||||
##### `POST` /core/brands/
|
||||
|
||||
###### Request:
|
||||
|
||||
Changed content type : `application/json`
|
||||
|
||||
- Added property `client_certificates` (array)
|
||||
> Certificates used for client authentication.
|
||||
|
||||
###### Return Type:
|
||||
|
||||
Changed response : **201 Created**
|
||||
|
||||
- Changed content type : `application/json`
|
||||
|
||||
- Added property `client_certificates` (array)
|
||||
> Certificates used for client authentication.
|
||||
|
||||
##### `GET` /core/brands/
|
||||
|
||||
###### Parameters:
|
||||
|
||||
Added: `client_certificates` in `query`
|
||||
|
||||
###### Return Type:
|
||||
|
||||
Changed response : **200 OK**
|
||||
|
||||
- Changed content type : `application/json`
|
||||
|
||||
- Changed property `results` (array)
|
||||
|
||||
Changed items (object): > Brand Serializer
|
||||
|
||||
- Added property `client_certificates` (array)
|
||||
> Certificates used for client authentication.
|
||||
|
||||
##### `POST` /policies/event_matcher/
|
||||
|
||||
###### Request:
|
||||
|
||||
Changed content type : `application/json`
|
||||
|
||||
- Changed property `app` (string)
|
||||
|
||||
> Match events created by selected application. When left empty, all applications are matched.
|
||||
|
||||
Added enum value:
|
||||
|
||||
- `authentik.enterprise.stages.mtls`
|
||||
|
||||
- Changed property `model` (string)
|
||||
|
||||
> Match events created by selected model. When left empty, all models are matched. When an app is selected, all the application's models are matched.
|
||||
|
||||
Added enum value:
|
||||
|
||||
- `authentik_stages_mtls.mutualtlsstage`
|
||||
|
||||
###### Return Type:
|
||||
|
||||
Changed response : **201 Created**
|
||||
|
||||
- Changed content type : `application/json`
|
||||
|
||||
- Changed property `app` (string)
|
||||
|
||||
> Match events created by selected application. When left empty, all applications are matched.
|
||||
|
||||
Added enum value:
|
||||
|
||||
- `authentik.enterprise.stages.mtls`
|
||||
|
||||
- Changed property `model` (string)
|
||||
|
||||
> Match events created by selected model. When left empty, all models are matched. When an app is selected, all the application's models are matched.
|
||||
|
||||
Added enum value:
|
||||
|
||||
- `authentik_stages_mtls.mutualtlsstage`
|
||||
|
||||
##### `GET` /policies/event_matcher/
|
||||
|
||||
###### Return Type:
|
||||
|
||||
Changed response : **200 OK**
|
||||
|
||||
- Changed content type : `application/json`
|
||||
|
||||
- Changed property `results` (array)
|
||||
|
||||
Changed items (object): > Event Matcher Policy Serializer
|
||||
|
||||
- Changed property `app` (string)
|
||||
|
||||
> Match events created by selected application. When left empty, all applications are matched.
|
||||
|
||||
Added enum value:
|
||||
|
||||
- `authentik.enterprise.stages.mtls`
|
||||
|
||||
- Changed property `model` (string)
|
||||
|
||||
> Match events created by selected model. When left empty, all models are matched. When an app is selected, all the application's models are matched.
|
||||
|
||||
Added enum value:
|
||||
|
||||
- `authentik_stages_mtls.mutualtlsstage`
|
||||
|
||||
##### `POST` /rbac/permissions/assigned_by_roles/{uuid}/assign/
|
||||
|
||||
###### Request:
|
||||
|
||||
Changed content type : `application/json`
|
||||
|
||||
- Changed property `model` (string)
|
||||
|
||||
Added enum value:
|
||||
|
||||
- `authentik_stages_mtls.mutualtlsstage`
|
||||
|
||||
##### `PATCH` /rbac/permissions/assigned_by_roles/{uuid}/unassign/
|
||||
|
||||
###### Request:
|
||||
|
||||
Changed content type : `application/json`
|
||||
|
||||
- Changed property `model` (string)
|
||||
|
||||
Added enum value:
|
||||
|
||||
- `authentik_stages_mtls.mutualtlsstage`
|
||||
|
||||
##### `POST` /rbac/permissions/assigned_by_users/{id}/assign/
|
||||
|
||||
###### Request:
|
||||
|
||||
Changed content type : `application/json`
|
||||
|
||||
- Changed property `model` (string)
|
||||
|
||||
Added enum value:
|
||||
|
||||
- `authentik_stages_mtls.mutualtlsstage`
|
||||
|
||||
##### `PATCH` /rbac/permissions/assigned_by_users/{id}/unassign/
|
||||
|
||||
###### Request:
|
||||
|
||||
Changed content type : `application/json`
|
||||
|
||||
- Changed property `model` (string)
|
||||
|
||||
Added enum value:
|
||||
|
||||
- `authentik_stages_mtls.mutualtlsstage`
|
||||
|
||||
##### `GET` /sources/ldap/{slug}/
|
||||
|
||||
###### Return Type:
|
||||
|
||||
Changed response : **200 OK**
|
||||
|
||||
- Changed content type : `application/json`
|
||||
|
||||
- Added property `delete_not_found_objects` (boolean)
|
||||
> Delete authentik users and groups which were previously supplied by this source, but are now missing from it.
|
||||
|
||||
##### `PUT` /sources/ldap/{slug}/
|
||||
|
||||
###### Request:
|
||||
|
||||
Changed content type : `application/json`
|
||||
|
||||
- Added property `delete_not_found_objects` (boolean)
|
||||
> Delete authentik users and groups which were previously supplied by this source, but are now missing from it.
|
||||
|
||||
###### Return Type:
|
||||
|
||||
Changed response : **200 OK**
|
||||
|
||||
- Changed content type : `application/json`
|
||||
|
||||
- Added property `delete_not_found_objects` (boolean)
|
||||
> Delete authentik users and groups which were previously supplied by this source, but are now missing from it.
|
||||
|
||||
##### `PATCH` /sources/ldap/{slug}/
|
||||
|
||||
###### Request:
|
||||
|
||||
Changed content type : `application/json`
|
||||
|
||||
- Added property `delete_not_found_objects` (boolean)
|
||||
> Delete authentik users and groups which were previously supplied by this source, but are now missing from it.
|
||||
|
||||
###### Return Type:
|
||||
|
||||
Changed response : **200 OK**
|
||||
|
||||
- Changed content type : `application/json`
|
||||
|
||||
- Added property `delete_not_found_objects` (boolean)
|
||||
> Delete authentik users and groups which were previously supplied by this source, but are now missing from it.
|
||||
|
||||
##### `GET` /rbac/permissions/assigned_by_roles/
|
||||
|
||||
###### Parameters:
|
||||
|
||||
Changed: `model` in `query`
|
||||
|
||||
##### `GET` /rbac/permissions/assigned_by_users/
|
||||
|
||||
###### Parameters:
|
||||
|
||||
Changed: `model` in `query`
|
||||
|
||||
##### `POST` /sources/ldap/
|
||||
|
||||
###### Request:
|
||||
|
||||
Changed content type : `application/json`
|
||||
|
||||
- Added property `delete_not_found_objects` (boolean)
|
||||
> Delete authentik users and groups which were previously supplied by this source, but are now missing from it.
|
||||
|
||||
###### Return Type:
|
||||
|
||||
Changed response : **201 Created**
|
||||
|
||||
- Changed content type : `application/json`
|
||||
|
||||
- Added property `delete_not_found_objects` (boolean)
|
||||
> Delete authentik users and groups which were previously supplied by this source, but are now missing from it.
|
||||
|
||||
##### `GET` /sources/ldap/
|
||||
|
||||
###### Parameters:
|
||||
|
||||
Added: `delete_not_found_objects` in `query`
|
||||
|
||||
###### Return Type:
|
||||
|
||||
Changed response : **200 OK**
|
||||
|
||||
- Changed content type : `application/json`
|
||||
|
||||
- Changed property `results` (array)
|
||||
|
||||
Changed items (object): > LDAP Source Serializer
|
||||
|
||||
- Added property `delete_not_found_objects` (boolean)
|
||||
> Delete authentik users and groups which were previously supplied by this source, but are now missing from it.
|
@ -2,17 +2,13 @@
|
||||
|
||||
## Deletion of sessions did not revoke sessions when using database session storage
|
||||
|
||||
### ADDENDUM May 30, 2025
|
||||
|
||||
As of version 2025.4, the option to store sessions in cache has been removed; sessions are now exclusively stored in the database. See our [2025.4 release notes](../../releases/2025.4#sessions-are-now-stored-in-the-database) for more information.
|
||||
|
||||
### Summary
|
||||
|
||||
When authentik was configured to use the database for session storage (which is a non-default setting), deleting sessions via the Web Interface or the API would not revoke the session and the session holder would continue to have access to authentik.
|
||||
|
||||
This also affects automatic session deletion when a user is set to inactive or a user is deleted.
|
||||
|
||||
The session backend was configured via the `AUTHENTIK_SESSION_STORAGE` setting, which was removed in version 2025.4.
|
||||
The session backend is configured via [this](../../install-config/configuration/configuration.mdx#authentik_session_storage) setting; if this settings isn't set the sessions are stored in the cache (Redis), which is not affected by this.
|
||||
|
||||
### Patches
|
||||
|
||||
|
@ -3,7 +3,7 @@ title: Brands
|
||||
slug: /brands
|
||||
---
|
||||
|
||||
As an authentik admin, you can customize your instance's appearance and behavior using brands. Brands apply to a single domain, a domain wildcard or can be set as default, in which case the brand will be used when no other brand matches the domain.
|
||||
As an authentik admin, you can customize your instance's appearance and behavior using brands. While a single authentik instance supports only one brand per domain, you can apply a separate brand to each domain.
|
||||
|
||||
For an overview of branding and other customization options in authentik refer to [Customize your instance](../customize/index.md).
|
||||
|
||||
@ -61,14 +61,4 @@ This means that if you want to select a default flow based on policy, you can le
|
||||
|
||||
## Other global settings
|
||||
|
||||
#### Web Certificate
|
||||
|
||||
The **Web Certificate** option can be used to configure which certificate authentik uses when its accessed directly via HTTPS (via port 9443).
|
||||
|
||||
#### Client Certificates:ak-version[2025.4]
|
||||
|
||||
When using the [Mutual TLS Stage](../add-secure-apps/flows-stages/stages/mtls/index.md) and accessing authentik directly, this option configures which certificate authorities clients' certificates can be issued by.
|
||||
|
||||
#### Attributes
|
||||
|
||||
Attributes such as locale, theme settings and custom attributes can be set to a per-brand default value here. Any custom attributes can be retrieved via [`group_attributes()`](../users-sources/user/user_ref.mdx#object-properties).
|
||||
Under **Other global settings** you can specify an exact web certificate.
|
||||
|
@ -1,161 +1,98 @@
|
||||
---
|
||||
title: Upgrading PostgreSQL on Kubernetes
|
||||
title: Upgrade PostgreSQL on Kubernetes
|
||||
---
|
||||
|
||||
This guide walks you through upgrading PostgreSQL in your authentik Kubernetes deployment. The process requires a brief downtime period while the database is migrated.
|
||||
## Preparation
|
||||
|
||||
:::note
|
||||
For this guide, we assume the PostgreSQL pod is named `authentik-postgresql-0`, which is the default name in the authentik Helm chart.
|
||||
:::
|
||||
- `authentik-postgresql-0` is the Kubernetes Pod running PostgreSQL.
|
||||
|
||||
## Prerequisites
|
||||
### Prerequisites
|
||||
|
||||
- `kubectl` access with permissions to `scale` deployments and `exec` into pods
|
||||
- Your existing `values.yaml` file used for authentik deployment
|
||||
- Basic understanding of Kubernetes and Helm commands
|
||||
|
||||
## Overview of workflow
|
||||
|
||||
The basic steps to upgrades PostgreSQL on Kubernetes are:
|
||||
|
||||
1. Stop authentik services
|
||||
2. Back up the database
|
||||
3. Prepare the data directory
|
||||
4. Upgrade PostgreSQL
|
||||
5. Restore database content
|
||||
6. Restart authentik services
|
||||
|
||||
## Stop authentik services
|
||||
|
||||
Begin by scaling down authentik services to prevent database access during the migration:
|
||||
This migration requires some downtime, during which authentik must be stopped. To do this, run the following command:
|
||||
|
||||
```shell
|
||||
kubectl scale deploy --replicas 0 authentik-server
|
||||
kubectl scale deploy --replicas 0 authentik-worker
|
||||
```
|
||||
|
||||
## Back up the database
|
||||
### Dump the current database
|
||||
|
||||
Connect to your PostgreSQL pod:
|
||||
Run `kubectl exec -it authentik-postgresql-0 -- bash` to get a shell in the PostgreSQL pod.
|
||||
|
||||
Run the following commands to dump the current data into a `.sql` file:
|
||||
|
||||
```shell
|
||||
kubectl exec -it authentik-postgresql-0 -- bash
|
||||
```
|
||||
|
||||
After you are connected, execute these commands to create a database backup:
|
||||
|
||||
```shell
|
||||
# Navigate to the PostgreSQL data directory
|
||||
# This is the path where the PVC is mounted, so we'll place the dump here too
|
||||
cd /bitnami/postgresql/
|
||||
|
||||
# Set the PostgreSQL password from environment variable
|
||||
# Set the postgres password based on the `POSTGRES_POSTGRES_PASSWORD` environment variable
|
||||
export PGPASSWORD=$POSTGRES_POSTGRES_PASSWORD
|
||||
|
||||
# Create a full database dump
|
||||
pg_dump -U $POSTGRES_USER $POSTGRES_DB > /bitnami/postgresql/dump.sql
|
||||
# Dump the authentik database into an sql file
|
||||
pg_dump -U $POSTGRES_USER $POSTGRES_DB > dump-11.sql
|
||||
```
|
||||
|
||||
:::tip
|
||||
Consider copying the dump file to a safe location outside the pod:
|
||||
### Stop PostgreSQL and start the upgrade
|
||||
|
||||
```shell
|
||||
# From a separate terminal
|
||||
kubectl cp authentik-postgresql-0:/bitnami/postgresql/dump.sql ./authentik-db-backup.sql
|
||||
To upgrade, change the following entries in your `values.yaml` used to deploy authentik:
|
||||
|
||||
```yaml
|
||||
postgresql:
|
||||
diagnosticMode:
|
||||
enabled: true
|
||||
image:
|
||||
tag: 15.2.0-debian-11-r26
|
||||
```
|
||||
|
||||
This ensures you have a backup even if something goes wrong with the pod or storage.
|
||||
:::
|
||||
Now run `helm upgrade --install authentik authentik/authentik -f values.yaml` to apply these changes. Depending on your configuration, you might have to repeat the steps from [Prerequisites](#prerequisites).
|
||||
|
||||
## Prepare the data directory
|
||||
After the upgrade is finished, you should have a new PostgreSQL pod running with the updated image.
|
||||
|
||||
While still connected to the PostgreSQL pod, prepare the data directory for the upgrade:
|
||||
### Remove the old data
|
||||
|
||||
Because the PVC mounted by the PostgreSQL pod still contains the old data, we need to remove/rename that data, so that PostgreSQL can initialize it with the new version.
|
||||
|
||||
Run `kubectl exec -it authentik-postgresql-0 -- bash` to get a shell in the PostgreSQL pod.
|
||||
|
||||
Run the following commands to move the old data:
|
||||
|
||||
```shell
|
||||
# Ensure you're in the PostgreSQL data directory
|
||||
# This is the path where the PVC is mounted
|
||||
cd /bitnami/postgresql/
|
||||
|
||||
# Verify the SQL dump exists and has content
|
||||
ls -lh dump.sql
|
||||
|
||||
# Preserve the existing data by renaming the directory
|
||||
mv data data-old
|
||||
# Move Postgres' data folder to data-11, which is the version we're upgrading to.
|
||||
# The data folder can also be deleted; however it is recommended to rename it first
|
||||
# in case the upgrade fails.
|
||||
mv data data-11
|
||||
```
|
||||
|
||||
:::caution
|
||||
Do not delete the old data directory immediately. Keeping it as `data-old` allows for recovery if the upgrade encounters issues.
|
||||
:::
|
||||
### Restart PostgreSQL
|
||||
|
||||
## Upgrade PostgreSQL
|
||||
In the step [Stop PostgreSQL and start the upgrade](#stop-postgresql-and-start-the-upgrade), we enabled the _diagnostic mode_, which means the PostgreSQL pod is running, but the actual Postgres process isn't running. Now that we've removed the old data directory, we can disable the diagnostic mode.
|
||||
|
||||
Now update your `values.yaml` to specify the new PostgreSQL version:
|
||||
Once again, change the following entries in your `values.yaml` used to deploy authentik:
|
||||
|
||||
```yaml
|
||||
postgresql:
|
||||
image:
|
||||
tag: <NEW_VERSION>
|
||||
tag: 15.2.0-debian-11-r26
|
||||
```
|
||||
|
||||
Apply these changes using Helm to deploy the updated configuration.
|
||||
And once again run `helm upgrade --install authentik authentik/authentik -f values.yaml` to apply these changes. Depending on your configuration, you might have to repeat the steps from [Prerequisites](#prerequisites).
|
||||
|
||||
This will restart the PostgreSQL pod with the new image. When the pod starts, PostgreSQL will initialize a new, empty data directory since the previous directory was renamed.
|
||||
After the PostgreSQL pod is running again, we need to restore the data from the dump we created above.
|
||||
|
||||
## Restore database content
|
||||
Run `kubectl exec -it authentik-postgresql-0 -- bash` to get a shell in the PostgreSQL pod.
|
||||
|
||||
Connect to the PostgreSQL pod again:
|
||||
Run the following commands to restore the data:
|
||||
|
||||
```shell
|
||||
kubectl exec -it authentik-postgresql-0 -- bash
|
||||
```
|
||||
|
||||
Restore your database from the backup:
|
||||
|
||||
```shell
|
||||
# Navigate to the PostgreSQL directory
|
||||
# This is the path where the PVC is mounted
|
||||
cd /bitnami/postgresql/
|
||||
|
||||
# Verify your dump file is still there
|
||||
ls -lh dump.sql
|
||||
|
||||
# Set the PostgreSQL password
|
||||
# Set the Postgres password based on the `POSTGRES_POSTGRES_PASSWORD` environment variable.
|
||||
export PGPASSWORD=$POSTGRES_POSTGRES_PASSWORD
|
||||
|
||||
# Import the database dump
|
||||
psql -U $POSTGRES_USER $POSTGRES_DB < dump.sql
|
||||
psql -U $POSTGRES_USER $POSTGRES_DB < dump-11.sql
|
||||
```
|
||||
|
||||
## Restart authentik services
|
||||
After the last command finishes, all of the data is restored, and you can restart authentik.
|
||||
|
||||
After the database restoration completes successfully, restart authentik using Helm with your updated configuration.
|
||||
### Restarting authentik
|
||||
|
||||
This will scale your authentik server and worker deployments back to their original replica counts.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If you encounter issues during the upgrade process:
|
||||
|
||||
- Check PostgreSQL logs:
|
||||
```shell
|
||||
kubectl logs authentik-postgresql-0
|
||||
```
|
||||
- Verify the values in your `values.yaml` file match the recommended settings
|
||||
- Ensure you have sufficient storage available for both the database dump and the database itself
|
||||
|
||||
### Dump file not found
|
||||
|
||||
If your dump file is missing after upgrading:
|
||||
|
||||
- You may need to restore from the external backup if you copied it out of the pod
|
||||
- The volume might have been recreated if you're using ephemeral storage
|
||||
|
||||
### Restoring the original database
|
||||
|
||||
For persistent problems, you can restore from the `data-old` directory if needed:
|
||||
|
||||
```shell
|
||||
kubectl exec -it authentik-postgresql-0 -- bash
|
||||
cd /bitnami/postgresql/
|
||||
mv data data-new-failed
|
||||
mv data-old data
|
||||
```
|
||||
|
||||
Then restart PostgreSQL with the original version in your `values.yaml`.
|
||||
Run `helm upgrade --install authentik authentik/authentik -f values.yaml` once again, which will restart your authentik server and worker containers.
|
||||
|
@ -42,7 +42,7 @@ To support the integration of Active Directory with authentik, you need to creat
|
||||
|
||||
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 administrator and open the authentik Admin interface.
|
||||
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:
|
||||
|
@ -13,7 +13,7 @@ The following placeholders are used in this guide:
|
||||
|
||||
## FreeIPA Setup
|
||||
|
||||
1. Log in to FreeIPA.
|
||||
1. Log into FreeIPA.
|
||||
|
||||
2. Create a user in FreeIPA, matching your naming scheme. Provide a strong password, example generation methods: `pwgen 64 1` or `openssl rand 36 | base64 -w 0`. After you are done click **Add and Edit**.
|
||||
|
||||
|
@ -19,7 +19,7 @@ For instructions to add a specific source, refer to the documentation links in t
|
||||
|
||||
To have sources show on the default login screen you will need to add them to the flow. The process below assumes that you have not created or renamed the default stages and flows.
|
||||
|
||||
1. Log in to authentik as an administrator and open the authentik Admin interface.
|
||||
1. Log in to authentik as an admin, and open the authentik Admin interface.
|
||||
2. Navigate to **Flows and Stages** > **Flows**.
|
||||
3. Click the **default-authentication-flow**.
|
||||
4. Click the **Stage Bindings** tab.
|
||||
|
@ -26,7 +26,7 @@ To automate the deployment of this configuration use a [Group policy](https://su
|
||||
|
||||
## Windows / Internet Explorer
|
||||
|
||||
Log in to the Windows machine using an account of your Kerberos realm (or administrative domain).
|
||||
Log into the Windows machine using an account of your Kerberos realm (or administrative domain).
|
||||
|
||||
Open Internet Explorer, click **Tools** and then click **Internet Options**. You can also find **Internet Options** using the system search.
|
||||
|
||||
|
@ -12,14 +12,14 @@ For FreeIPA, follow the [FreeIPA Integration](../../directory-sync/freeipa/index
|
||||
|
||||
## Configuration options for LDAP sources
|
||||
|
||||
To create or edit a source in authentik, open the Admin interface and navigate to **Directory > Federation and Social login**. There you can create a new LDAP source, or edit an existing one, using the following settings.
|
||||
To create or edit a source in authentik, open the Admin interface and navigate to **Directory > Ferderation and Social login**. There you can create a new LDAP source, or edit an existing one, using the following settings.
|
||||
|
||||
- **Enabled**: Toggle this option on to allow authentik to use the defined LDAP source.
|
||||
- **Update internal password on login**: When the user logs in to authentik using the LDAP password backend, the password is stored as a hashed value in authentik. Toggle off (default setting) if you do not want to store the hashed passwords in authentik.
|
||||
- **Sync users**: Enable or disable user synchronization between authentik and the LDAP source.
|
||||
- **User password writeback**: Enable this option if you want to write password changes that are made in authentik back to LDAP.
|
||||
- **Sync groups**: Enable/disable group synchronization between authentik and the LDAP source.
|
||||
- **Delete Not Found Objects**: :ak-version[2025.6] This option synchronizes user and group deletions from LDAP sources to authentik. User deletion requires enabling **Sync users** and group deletion requires enabling **Sync groups**.
|
||||
- **Sync groups**: Enable/disable group synchronization. Groups are synced in the background every 5 minutes.
|
||||
- **Parent group**: Optionally set this group as the parent group for all synced groups. An example use case of this would be to import Active Directory groups under a root `imported-from-ad` group.
|
||||
|
||||
#### Connection settings
|
||||
|
||||
@ -29,9 +29,9 @@ To create or edit a source in authentik, open the Admin interface and navigate t
|
||||
- **Use Server URI for SNI verification**: this setting is required for servers using TLS 1.3+
|
||||
|
||||
- **TLS Verification Certificate**: Specify a keypair to validate the remote certificate.
|
||||
- **TLS Client authentication certificate**: Client certificate keypair to authenticate against the LDAP Server's Certificate.
|
||||
- **TLS Client authentication**: Client certificate keypair to authenticate against the LDAP Server's Certificate.
|
||||
- **Bind CN**: CN of the bind user. This can also be a UPN in the format of `user@domain.tld`.
|
||||
- **Bind Password**: Password used during the bind process.
|
||||
- **Bind password**: Password used during the bind process.
|
||||
- **Base DN**: Base DN (distinguished name) used for all LDAP queries.
|
||||
|
||||
#### LDAP Attribute mapping
|
||||
@ -44,17 +44,14 @@ To create or edit a source in authentik, open the Admin interface and navigate t
|
||||
|
||||
#### Additional Settings
|
||||
|
||||
- **Parent Group**: Parent group for all the groups imported from LDAP. An example use case would be to import Active Directory groups under a root `imported-from-ad` group.
|
||||
- **Group**: Parent group for all the groups imported from LDAP.
|
||||
- **User path**: Path template for all new users created.
|
||||
- **Additional User DN**: Prepended to the base DN for user queries.
|
||||
- **Additional Group DN**: Prepended to the base DN for group queries.
|
||||
- **Addition User DN**: Prepended to the base DN for user queries.
|
||||
- **Addition Group DN**: Prepended to the base DN for group queries.
|
||||
- **User object filter**: Consider objects matching this filter to be users.
|
||||
- **Group object filter**: Consider objects matching this filter to be groups.
|
||||
- **Lookup using a user attribute**: Acquire group membership from a User object attribute (`memberOf`) instead of a Group attribute (`member`). This works with directories with 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 for a user. If **Lookup using a user attribute** is set, this should be a user object attribute, otherwise a group object attribute.
|
||||
- **User membership attribute**: Attribute name on authentik user objects which is checked against the **Group membership field**. Two common cases are:
|
||||
- If your groups have `member` attributes containing DNs, set this to `distinguishedName`. (The `distinguishedName` attribute for User objects in authentik is set automatically.)
|
||||
- If your groups have `memberUid` attributes containing `uid`s, set this to `uid`. Make sure that you've created a property mapping that creates an attribute called `uid`.
|
||||
- **Object uniqueness field**: This field contains a unique identifier.
|
||||
|
||||
## LDAP source property mappings
|
||||
|
@ -21,7 +21,7 @@ The following placeholders are used in this guide:
|
||||
|
||||
## Apple
|
||||
|
||||
1. Log in to your Apple developer account, and navigate to **Certificates, IDs & Profiles**, then click **Identifiers** in the sidebar.
|
||||
1. Log into your Apple developer account, and navigate to **Certificates, IDs & Profiles**, then click **Identifiers** in the sidebar.
|
||||
2. Register a new Identifier with the type of **App IDs**, and the subtype **App**.
|
||||
3. Choose a name that users will recognise for the **Description** field.
|
||||
4. For your bundle ID, use the reverse domain of authentik, in this case `company.authentik`.
|
||||
|
@ -48,7 +48,7 @@ Finally, you need to publish the Facebook app.
|
||||
|
||||
## authentik configuration
|
||||
|
||||
1. Log in to authentik as admin, and then navigate to **Directory -> Federation & Social login**
|
||||
1. Log into authentik as admin, and then navigate to **Directory -> Federation & Social login**
|
||||
2. Click **Create**.
|
||||
3. In the **New Source** box, for **Select type** select **Facebook OAuth Source** and then click **Next**.
|
||||
4. Define the following fields:
|
||||
|
@ -14,7 +14,7 @@ The following placeholders are used in this guide:
|
||||
|
||||
## Mailcow
|
||||
|
||||
1. Log in to mailcow as an admin and navigate to the OAuth2 Apps settings
|
||||
1. Log into mailcow as an admin and navigate to the OAuth2 Apps settings
|
||||
|
||||

|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user