From 0509b9eb4a5b86fd2e1135e66cd95f3fd1aed40b Mon Sep 17 00:00:00 2001 From: Fusion Date: Mon, 18 May 2026 21:46:54 +0200 Subject: [PATCH] fix: separate Authentik application slug from OAuth client ID Authentik uses different values for: - OAuth Client ID (UUID for authentication) - Application Slug (URL-friendly identifier like 'headquarter-web') Add AUTHENTIK_APPLICATION_SLUG config to build correct Authentik URLs while keeping AUTHENTIK_CLIENT_ID for OAuth token exchange. --- .env.example | 5 +++++ apps/api/src/config.py | 7 +++++-- docker-compose.traefik.yml | 1 + 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index c81d8c2..ebf32dc 100644 --- a/.env.example +++ b/.env.example @@ -27,8 +27,13 @@ AUTHENTIK_DOMAIN=authentik.local # WEB_PUBLIC_URL=https://app.example.com # Authentik Configuration +# Client ID: The OAuth client ID from Authentik (may be a UUID) AUTHENTIK_CLIENT_ID=headquarter-web AUTHENTIK_CLIENT_SECRET=change-me +# Application Slug: The URL-friendly identifier used in Authentik URLs +# This is often the same as the application identifier/slug in Authentik +# e.g., if your Authentik app URL is /application/o/headquarter-web/, use "headquarter-web" +AUTHENTIK_APPLICATION_SLUG=headquarter-web # Override Authentik URLs if they differ from the default pattern # AUTHENTIK_AUTHORIZE_URL=https://authentik.example.com/application/o/authorize/ # AUTHENTIK_TOKEN_URL=https://authentik.example.com/application/o/token/ diff --git a/apps/api/src/config.py b/apps/api/src/config.py index 3e00599..b2f28dd 100644 --- a/apps/api/src/config.py +++ b/apps/api/src/config.py @@ -34,6 +34,9 @@ class Settings(BaseSettings): # Authentik configuration - no hardcoded URLs authentik_client_id: str = "headquarter-web" authentik_client_secret: str = "change-me" + # Authentik application slug used in URLs (e.g., "headquarter-web") + # This is different from the OAuth client_id which may be a UUID + authentik_application_slug: str = "headquarter-web" authentik_authorize_url: str | None = None authentik_token_url: str | None = None authentik_jwks_url: str | None = None @@ -100,13 +103,13 @@ class Settings(BaseSettings): def resolved_authentik_jwks_url(self) -> str: if self.authentik_jwks_url: return self.authentik_jwks_url - return f"{self.authentik_base_url}/application/o/{self.authentik_client_id}/jwks/" + return f"{self.authentik_base_url}/application/o/{self.authentik_application_slug}/jwks/" @property def resolved_authentik_issuer(self) -> str: if self.authentik_issuer: return self.authentik_issuer - return f"{self.authentik_base_url}/application/o/{self.authentik_client_id}/" + return f"{self.authentik_base_url}/application/o/{self.authentik_application_slug}/" @property def cookie_secure(self) -> bool: diff --git a/docker-compose.traefik.yml b/docker-compose.traefik.yml index 8bd2976..83fcadc 100644 --- a/docker-compose.traefik.yml +++ b/docker-compose.traefik.yml @@ -84,6 +84,7 @@ services: WEB_PUBLIC_URL: ${WEB_PUBLIC_URL:-} AUTHENTIK_CLIENT_ID: ${AUTHENTIK_CLIENT_ID:-headquarter-web} AUTHENTIK_CLIENT_SECRET: ${AUTHENTIK_CLIENT_SECRET} + AUTHENTIK_APPLICATION_SLUG: ${AUTHENTIK_APPLICATION_SLUG:-headquarter-web} AUTHENTIK_AUTHORIZE_URL: ${AUTHENTIK_AUTHORIZE_URL:-} AUTHENTIK_TOKEN_URL: ${AUTHENTIK_TOKEN_URL:-} AUTHENTIK_JWKS_URL: ${AUTHENTIK_JWKS_URL:-}