Using Authentik As Forward-Auth for App With Nginx Ingress ( Authentication Using OAuth2.0 Through IdP )
Introduction
Authentik is an open-source identity provider (IdP) that provides a unified authentication and authorization solution for your applications. It supports various protocols including OAuth2, SAML, LDAP, and forward authentication.
Key Features
Single Sign-On (SSO)
Multi-factor Authentication (MFA)
User management and self-service
Application access control
Forward authentication for reverse proxies
LDAP/SAML/OAuth2/OIDC support
Customizable authentication flows
Architecture Overview
Authentik consists of two main components:
Core Server: Handles authentication, user management, and administration
Outpost: Lightweight component that handles authentication requests for applications
Core Concepts & Terminologies
Application
An application represents a service or system that users need to access. Applications are the user-facing configuration that ties together providers and policies.
Key Properties:
Name and slug (unique identifier)
Provider (authentication method)
Launch URL (where users go after authentication)
Icon and metadata
Policy bindings (who can access)
Source
Sources are methods of authenticating users or fetching user information. They define where users come from and how they authenticate. Sources are different ways people can prove who they to get access to the application. Basically, sources answer the question "How do you prove you're really John Smith?" It's WHERE your login credentials come from.
Example scenarios:
"I'll login with my company username/password" → Built-in source
"I'll login with my Google account" → OAuth source
"I'll login with my Windows password" → LDAP source
Types of Sources:
Built-in: Local Authentik database
LDAP: Active Directory, OpenLDAP
OAuth: Google, GitHub, Azure AD
SAML: External SAML IdPs
SCIM: User provisioning
Provider
Providers define how applications authenticate with Authentik. They implement specific authentication protocols. Providers determine HOW an application will verify users. It's the "language" Authentik speaks to your application.
Provider Types:
Proxy Provider (Forward Auth)
Think of this as a security guard who checks your ID before letting you into specific rooms
Single Application: One provider per app
Domain Level: One provider for multiple subdomains
OAuth2/OIDC Provider
For applications supporting OAuth2
SAML Provider
For enterprise applications
LDAP Provider
For legacy applications
Example:
Application: "I need to verify users"
Provider: "I'll handle that using method X"
Policy
Policies are rules that determine whether a user can access an application or perform an action. Policies are your security rules. They answer "Should this person be allowed in?"
Examples:
Expression Policy: "If user's email ends with @company.com, let them in"
Group Policy: "Only members of 'Developers' group can access"
Password Policy: "Password must have 8 characters, 1 number, 1 symbol"
Reputation Policy: "Block anyone who tries wrong password 5 times"
Policy Types:
Expression Policy
# Allow only users with email from company domain
return request.user.email.endswith("@company.com")
Password Policy
password_field: "password"
amount_uppercase: 1
amount_lowercase: 1
amount_symbols: 1
length_min: 8
Group Membership Policy
groups:
- "developers"
- "admins"
Reputation Policy
Prevents brute force attacks
threshold: -5
check_ip: true
check_username: true
Flow & Stages
Flows define the authentication process users go through. Stages are individual steps within a flow. It is a step-by-step process someone goes through to gain access the application
Flow = The complete journey from "I want to login" to "I'm logged in"
Stage = Each checkpoint in that journey
Flow Types:
Authentication: Login process
Enrollment: User registration
Recovery: Password reset
Unenrollment: Account deletion
Authorization: Post-login consent
Common Stages:
Identification Stage
user_fields:
- "username"
- "email"
show_source_labels: true
Password Stage
backends:
- "authentik.core.auth.InbuiltBackend"
- "authentik.core.auth.LDAPBackend"
MFA Stages
TOTP Authenticator
WebAuthn
SMS
Email
Consent Stage
mode: "always_require"
consent_expire_in: "weeks=4"
User Write Stage
Creates/updates user during enrollment
Flow Configuration Example:
name: "default-authentication-flow"
title: "Welcome to Authentik"
designation: "authentication"
stages:
- identification-stage
- password-stage
- mfa-validation-stage
- user-login-stage
Property Mappings
Property mappings transform user attributes between Authentik and applications. They're used to pass user information to applications. Different applications expect user data in different formats. Property mappings transform the data to match what each app expects.
Outpost
Outpost act as a bridge between your apps and Authentik. Remote security checkpoints stationed at each building entrance. Outposts are lightweight security agents that:
Sit between users and your applications
Check with Authentik: "Is this person allowed in?"
Handle the authentication without sending users away
Types:
Embedded Outpost: Runs within Authentik
Standalone Outpost: Separate deployment
Outpost Configuration:
name: "production-outpost"
type: "proxy"
service_connection: "local-kubernetes"
providers:
- "app1-proxy-provider"
- "app2-proxy-provider"
System Tasks
Automated background jobs that keep Authentik running smoothly. You don't see them, but they're essentia. These are background tasks that maintain Authentik's health and functionality.
Key System Tasks:
Cache Cleaning
Removes expired sessions
Cleans temporary data
Token Expiration
Removes expired OAuth tokens
Cleans up refresh tokens
Outpost Service Connection Monitor
Checks outpost health
Syncs configuration
LDAP Sync
Synchronizes users from LDAP
Updates group memberships
Configuring OIDC Federation ( IdP OAuth2.0 Configuration )
Click create
Select “OpenID OAuth Source )
Configure following
name: idp
slug: idp
user_matching_mode: Use the user's email address, but deny enrollment when email address already exists
group_matchind_mode: Use group name, but deny enrollment
user_path: goauthentik.io/sources/%(slug)s
icon: leave empty
Protocol settings:
consumer key: Oauth client ID ( from IdP portal )
consumer secret: client secret ( from IdP portal)
scopes: profile email openid ( separated by space )
URL settings:
authorization_url : https://company.idp.com/oidc/2/auth
token_url : https://company.idp.com/oidc/2/token
profile_url: https://company.idp.com/oidc/2/me
oidc_well_known_url: https://company.idp.com/oidc/2/.well-known/openid-configuration
oidc_jwks_url: https://company.idp.com/oidc/2/certs
ODIC_jwks: leave as is
authorization_code & authentication method: include client ID and secret as request parameters
Click Finish
Adding IdP login button to Authentik login screen
Go to Flow & stages
Click flows
Click “default-authentication-flow"
Click “stage binding” tab
Edit default-authentication-identification stage ( click Edit Stage )
Scroll down to “source settings”
Move IdP to right
Click update
Adding new app to Authentik ( NGINX Auth Integration )
Prerequisites
Authentik installed and running
DNS configured for your domain and subdomains
SSL certificates (wildcard recommended: *.company.com)
NGINX Ingress Controller installed
Steps
Create the Domain-Level Provider if it doesn’t exists. If it exists, the use existing
Login to Authentik Admin
Go to Applications → Providers
Click Create
Configure provider settings
name: "app-proxy"
authorization_flow: "default-provider-authorization-explicit-consent (Authorize Application)"
mode: "forward_auth_domain_level"
authentication_url: "https://app1.company.com"
cookie_domain: ".company.com"
token_validity: "24h"
authentication_setting:
intercept_header_authentication: enabled
Save the provider and click create
Note the provider's ID/name for later use
Go to Applications → Applications
Click Create
Configure application
name: "My App"
slug: "my-app"
provider: "app-proxy" ( or proxy from drop dowm menu )
launch_url: "https://app1.company.com"
group: leave as is
backchannl: leave as is
policy: leave as is
Click Create
Go to Outposts → Outposts
Find authentik Embedded Outpost
Click Edit
Ensure your provider is in Selected Providers
Click Update
Update ingress and annotations
...
nginx.ingress.kubernetes.io/auth-url: "https://authentik.company.com/outpost.goauthentik.io/auth/nginx"
nginx.ingress.kubernetes.io/auth-signin: "https://authentik.company.com/if/flow/default-authentication-flow/?rd=$escaped_request_uri"
nginx.ingress.kubernetes.io/auth-response-headers: "authorization,x-authentik-username,x-authentik-groups,x-authentik-email,x-authentik-name,x-authentik-uid"
nginx.ingress.kubernetes.io/auth-snippet: |
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
proxy_set_header X-Forwarded-Proto $scheme;
....
Apply change
Once this is done, when you try to access application, it should be intercepted by authentik for authentication
What to use when
"I want users to login with..."
Company credentials → Use Built-in Source
Google/Microsoft accounts → Use OAuth Source
Existing Windows passwords → Use LDAP Source
"My application is..."
A simple website → Use Proxy Provider
A modern app with OAuth support → Use OAuth Provider
An enterprise app needing SAML → Use SAML Provider
An old app needing LDAP → Use LDAP Provider
"I want to restrict access to..."
Certain email domains → Use Expression Policy
Specific teams → Use Group Policy
Strong passwords → Use Password Policy
Prevent brute force → Use Reputation Policy
Configuration Guide
Basic Configuration
Initial Setup
Access Authentik at https://authentik.company.com/if/flow/initial-setup/
Create admin user
Set admin password
Configure Email
# In Authentik Admin → System → Settings
AUTHENTIK_EMAIL__HOST: "smtp.gmail.com"
AUTHENTIK_EMAIL__PORT: 587
AUTHENTIK_EMAIL__USERNAME: "your-email@gmail.com"
AUTHENTIK_EMAIL__PASSWORD: "app-password"
AUTHENTIK_EMAIL__USE_TLS: true
AUTHENTIK_EMAIL__FROM: "noreply@company.com"
Security Configuration
Session Security
AUTHENTIK_COOKIE_DOMAIN: ".company.com" // this should be
AUTHENTIK_SESSION_COOKIE_SECURE: true
AUTHENTIK_SESSION_COOKIE_SAMESITE: "lax"
CSRF Protection
AUTHENTIK_CSRF_COOKIE_SECURE: true
AUTHENTIK_CSRF_TRUSTED_ORIGINS:
- "https://authentik.company.com"
Security Headers
AUTHENTIK_DEFAULT_USER_CHANGE_USERNAME: false
AUTHENTIK_IMPERSONATION: false
Common scenarios
Scenario 1: "Protect internal website"
Create Application: "Internal Wiki"
Use Provider: Proxy (security guard approach)
Set Policy: "Only @company.com emails"
Result: Guard checks everyone trying to visit
Scenario 2: "Add login to modern app"
Create Application: "New Dashboard"
Use Provider: OAuth2 (modern approach)
App receives: User info + access token
Result: Seamless integration
Scenario 3: "Connect old system"
Create Application: "Legacy System"
Use Provider: LDAP (old-school approach)
Map Properties: Convert modern → legacy format
Result: Old system thinks nothing changed
References
For more information, visit:
Official Documentation: https://goauthentik.io/docs/
Community Forum: https://github.com/goauthentik/authentik/discussions