Authentik: Enforcing login (developer guide)
This guide explains how login enforcement works when using Authentik (OIDC) and how to extend or customize it as a developer.
When is login enforced?
Login is enforced automatically when OIDC is enabled. Set these environment variables:
OIDC_ISSUER=http://localhost:9000/application/o/rediflow/
OIDC_CLIENT_ID=your-client-id
OIDC_CLIENT_SECRET=your-client-secret
When OIDC_ISSUER and OIDC_CLIENT_ID are set, the app:
- Registers a
before_requesthook (before_request_oidcinapp/auth/oidc.py) - For every request to a non-public path: if the user is not logged in, redirects to
/login /loginredirects to Authentik; after successful auth, the callback setssession["oidc_user_id"]and redirects back to the original URL
No extra code is needed to enforce login on new routes. All routes are protected by default; only paths in the public allowlist bypass auth.
Request flow
User requests /project/xxx/capacity
↓
before_request_oidc() runs
↓
Is path public? (OIDC_PUBLIC_PATHS or OIDC_PUBLIC_PREFIXES)
├─ Yes → allow request
└─ No → Is g.current_user_id set?
├─ Yes → allow request
└─ No → redirect to /login?next=/project/xxx/capacity
↓
/login redirects to Authentik
↓
User logs in at Authentik
↓
/oauth/callback receives code, exchanges for token,
creates/loads User, sets session, redirects to next
Public paths (no login required)
Paths that bypass auth are defined in app/auth/oidc.py:
| Constant | Purpose |
|---|---|
OIDC_PUBLIC_PATHS |
Exact path matches: /login, /oauth/callback, /set-locale, /logout, /static/ |
OIDC_PUBLIC_PREFIXES |
Path prefixes: /static/, /s/ (share links) |
Adding a new public path
To allow unauthenticated access to a route:
-
Exact path: Add the path to
OIDC_PUBLIC_PATHSinapp/auth/oidc.py:OIDC_PUBLIC_PATHS = frozenset({ "/login", "/oauth/callback", "/set-locale", "/logout", "/static/", "/your-public-path", # add here }) -
Path prefix: Add a prefix to
OIDC_PUBLIC_PREFIXES:OIDC_PUBLIC_PREFIXES = ("/static/", "/s/", "/public-api/")
Security: Only add paths that are intentionally public (e.g. health checks, public landing pages, share links). Do not expose sensitive data.
After login: policy and authorization
Login only proves identity. Authorization (what a user can see or edit) is handled by the Policy module (app/services/policy.py). Routes check policy before rendering or mutating data:
from app.services.policy import Policy
@bp.route("/project/<uuid:project_uuid>/capacity")
def capacity_index(project_uuid):
project = Project.query.get_or_404(project_uuid)
policy = Policy.from_request(request)
if not policy.can_view_project(project):
abort(403)
policy.ensure_project_visible(project, request)
# ... render
Common policy methods:
| Method | Purpose |
|---|---|
can_view_system() |
Access to home, settings, help |
can_view_project(project) |
View project data |
can_edit_project(project) |
Edit project data |
can_manage_calendars() |
Edit org calendars |
projects_visible_filter(request) |
Filter projects by visibility (org/assigned) |
Policy uses g.current_user and g.authentik_groups (set by the auth layer). Group names like rediflow-admins, rediflow-editors, rediflow-viewers determine permissions.
Without OIDC (no Authentik)
When OIDC_ISSUER and OIDC_CLIENT_ID are not set:
- No login redirect;
g.current_userandg.authentik_groupsstay empty POLICY_NO_AUTH_DEFAULTcontrols behaviour:allow_all(default) orview_only- Useful for local development without Authentik
Configuration checklist (enforce login)
| Step | Variable / action |
|---|---|
| 1 | Set OIDC_ISSUER, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET |
| 2 | Ensure redirect URI in Authentik matches app (e.g. http://localhost:5000/oauth/callback) |
| 3 | Restart the app |
That is all. Login is enforced for all non-public paths.
Code references
| File | Role |
|---|---|
app/auth/oidc.py |
OIDC client, login/callback routes, before_request_oidc, public path allowlist |
app/__init__.py |
Registers before_request_oidc when OIDC_ENABLED |
app/services/policy.py |
Authorization (can_view, can_edit, visibility filters) |
config/base.py |
oidc_enabled, oidc_issuer, oidc_client_id, oidc_client_secret |
See also: Authentik setup for deployment and OIDC provider configuration.