Configuring OAuth Authentik Clients
Overview
Follow these steps to configure an OAuth Client via Authentik.
Prerequisites
- You must be an admin on Authentik.
Step 1: Create an Application
- Navigate to Applications in Authentik.
- Create a new
Application
. - Each
Application
will create a correspondingProvider
. - Choose
OAuth2
as theProvider
type.
Authorization Flow
- Select:
default-provider-authorization-explicit-consent (Authorize Application)
. - Make the client confidential.
- Retrieve the
Client ID
andClient Secret
(needed for integration).
Step 2: Configure JupyterHub (Example)
Below is a sample JupyterHub configuration using Authentik as the OAuth provider:
hub: config: OAuthenticator: login_service: "Authentik" # This is what shows on JH UI oauth_callback_url: "https://XYZ.nrp-nautilus.io/hub/oauth_callback" # This is inputted by user authorize_url: "https://authentik.nrp-nautilus.io/application/o/authorize/" # This is provided by Authentik token_url: "https://authentik.nrp-nautilus.io/application/o/token/" # This is provided by Authentik userdata_url: "https://authentik.nrp-nautilus.io/application/o/userinfo/" # This is provided by Authentik client_id: "XYZ" # This is provided by Authentik client_secret: "XYZ" # This is provided by Authentik username_claim: "email" allow_all: "True" JupyterHub: admin_access: true authenticator_class: oauthenticator.generic.GenericOAuthenticator
Step 3: Configure Bindings (Filters & Policies)
- In Configure Bindings, define filtering rules (
blacklists
,whitelists
,user scopes
). - Authentik uses Expression Policies (Python-based) to control access.
ore details on Expression Policies: Authentik Docs
For now, finish creating the Application without attaching a policy. Next, you’ll create the policy and bind it.
Step 4: Create an Expression Policy
- Navigate to Customization → Policies → Create → Expression Policy.
- In the Expression field, enter your filtering logic.
Example:
# Allowed emails (bypass restrictions)
# Whitelist/blacklist domainswhitelist_domains = ["example.edu", "example.com"]blacklist_domains = ["bad-domain.com"]
# Normalize listswhitelist_lower = [d.lower().strip() for d in whitelist_domains]blacklist_lower = [d.lower().strip() for d in blacklist_domains]banned_lower = [b.lower().strip() for b in banned_users]allowed_lower = [a.lower().strip() for a in allowed_emails]allowed_exceptions_lower = [e.lower().strip() for e in allowed_exceptions]
# User contextuser = request.context.get("pending_user", request.user)
# Validate userif not user or not user.email: ak_message("Access denied: Invalid credentials") return False
email = user.email.lower().strip()username, domain = email.split("@")
# Access rulesif email in allowed_lower: ak_message("Access granted") return Trueelif email in banned_lower: ak_message("Account suspended - contact admins") return Falseelif whitelist_lower and domain not in whitelist_lower: if email in allowed_exceptions_lower: ak_message("Special access granted") return True ak_message(f"@{domain} not authorized") return Falseelif domain in blacklist_lower and email not in allowed_exceptions_lower: ak_message(f"@{domain} blocked") return False
ak_message("Access granted")return True
Policy Logic Flow
[Start] │ ▼Allowed Email Check → Approved? ✅ → Allow | → Not listed ❌ → Deny │ ▼Banned User Check → Blocked? ❌ → Deny │ ▼Domain Mode Check ├─ Whitelist Mode: │ ├─ Domain Approved? ✅ → Allow │ ├─ Exception User? ✅ → Allow │ └─ Else ❌ → Deny │ └─ Blacklist Mode: ├─ Domain Blocked? │ ├─ Exception User? ✅ → Allow │ └─ Else ❌ → Deny └─ Default ✅ → Allow
Policy Rules Explanation
🔹 Allowed Emails Take Priority
If allowed_emails
is not empty, only those emails will be allowed.
🔹 Banned Users Are Always Blocked
Regardless of other conditions.
🔹 Whitelist Mode vs Blacklist Mode
- If
whitelist_domains
is defined, only those domains are allowed (except explicitly allowed exceptions). - If
whitelist_domains
is empty, the system defaults to blacklist mode, where blocked domains deny access unless overridden.
Step 5: Bind the Policy to Your Application
- Go back to your Application.
- Open Policy / Group / User Bindings.
- Bind the Expression Policy you just created.
- In the Application Overview, use the Test button to verify user access.