OpenID Connect (OIDC) Authentication
Poweradmin supports OpenID Connect (OIDC) for single sign-on (SSO) authentication with identity providers like Azure AD, Google, Keycloak, Okta, Authentik, and Auth0.
Overview
OIDC allows users to authenticate using their existing identity provider credentials. When enabled, users see additional "Sign in with..." buttons on the login page.
Key features:
- Automatic user provisioning from OIDC provider
- Link OIDC accounts to existing users by email
- Sync user information (name, email) from provider
- Map OIDC groups to Poweradmin permission templates
- Support for multiple providers simultaneously
- PKCE (Proof Key for Code Exchange) for enhanced security
Global Settings
| Setting | Default | Description |
|---|---|---|
oidc.enabled |
false | Enable OIDC authentication |
oidc.auto_provision |
true | Auto-create users from OIDC provider |
oidc.link_by_email |
true | Link OIDC accounts to existing users by email |
oidc.sync_user_info |
true | Sync user info (name, email) on each login |
oidc.default_permission_template |
"" | Default permission template for new users |
Permission Template Mapping
Map OIDC groups to Poweradmin permission templates for automatic role assignment:
'oidc' => [
'enabled' => true,
'permission_template_mapping' => [
'poweradmin-admins' => 'Administrator',
'dns-operators' => 'DNS Operator',
'dns-viewers' => 'Read Only',
],
],
When a user logs in, their OIDC groups are matched against this mapping. The first match determines their permission template.
Provider Configuration
Each provider requires specific configuration. All providers share these common fields:
| Field | Required | Description |
|---|---|---|
name |
Yes | Internal provider identifier |
display_name |
Yes | Text shown on login button |
client_id |
Yes | OAuth client ID from provider |
client_secret |
Yes | OAuth client secret from provider |
auto_discovery |
No | Use OpenID Connect Discovery (default: true) |
metadata_url |
Conditional | OpenID Configuration endpoint (if auto_discovery) |
scopes |
No | OAuth scopes (default: openid profile email) |
logout_url |
No | Provider logout endpoint |
user_mapping |
No | Map OIDC claims to user fields |
Azure AD (Microsoft)
- Register an application in Azure Portal > App registrations
- Add a redirect URI:
https://your-poweradmin.com/oidc/callback - Create a client secret
- Configure optional claims for groups if needed
'oidc' => [
'enabled' => true,
'providers' => [
'azure' => [
'name' => 'Microsoft Azure AD',
'display_name' => 'Sign in with Microsoft',
'client_id' => 'your-client-id',
'client_secret' => 'your-client-secret',
'tenant' => 'your-tenant-id', // or 'common' for multi-tenant
'auto_discovery' => true,
'metadata_url' => 'https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration',
'logout_url' => 'https://login.microsoftonline.com/{tenant}/oauth2/v2.0/logout',
'scopes' => 'openid profile email',
'user_mapping' => [
'username' => 'email',
'email' => 'email',
'first_name' => 'given_name',
'last_name' => 'family_name',
'display_name' => 'name',
'groups' => 'groups',
],
],
],
],
Note: For group claims, configure "Group claims" in Azure AD App > Token configuration.
- Go to Google Cloud Console > APIs & Services > Credentials
- Create an OAuth 2.0 Client ID
- Add authorized redirect URI:
https://your-poweradmin.com/oidc/callback
'oidc' => [
'enabled' => true,
'providers' => [
'google' => [
'name' => 'Google',
'display_name' => 'Sign in with Google',
'client_id' => 'your-client-id.apps.googleusercontent.com',
'client_secret' => 'your-client-secret',
'auto_discovery' => true,
'metadata_url' => 'https://accounts.google.com/.well-known/openid-configuration',
'logout_url' => 'https://accounts.google.com/logout',
'scopes' => 'openid profile email',
'user_mapping' => [
'username' => 'email',
'email' => 'email',
'first_name' => 'given_name',
'last_name' => 'family_name',
'display_name' => 'name',
],
],
],
],
Keycloak
- Create a client in Keycloak Admin Console
- Set Access Type to "confidential"
- Add valid redirect URI:
https://your-poweradmin.com/oidc/callback - Enable "groups" scope if using group mapping
'oidc' => [
'enabled' => true,
'providers' => [
'keycloak' => [
'name' => 'Keycloak',
'display_name' => 'Sign in with Keycloak',
'client_id' => 'poweradmin',
'client_secret' => 'your-client-secret',
'base_url' => 'https://keycloak.example.com',
'realm' => 'master',
'auto_discovery' => true,
'metadata_url' => '{base_url}/realms/{realm}/.well-known/openid-configuration',
'logout_url' => '{base_url}/realms/{realm}/protocol/openid-connect/logout',
'scopes' => 'openid profile email groups',
'user_mapping' => [
'username' => 'preferred_username',
'email' => 'email',
'first_name' => 'given_name',
'last_name' => 'family_name',
'display_name' => 'name',
'groups' => 'groups',
],
],
],
],
Okta
- Create an OIDC application in Okta Admin Console
- Set Sign-in redirect URI:
https://your-poweradmin.com/oidc/callback - Note your Okta domain (e.g., your-org.okta.com)
'oidc' => [
'enabled' => true,
'providers' => [
'okta' => [
'name' => 'Okta',
'display_name' => 'Sign in with Okta',
'client_id' => 'your-client-id',
'client_secret' => 'your-client-secret',
'domain' => 'your-org.okta.com',
'auto_discovery' => true,
'metadata_url' => 'https://{domain}/.well-known/openid-configuration',
'logout_url' => 'https://{domain}/oauth2/v1/logout',
'scopes' => 'openid profile email groups',
'user_mapping' => [
'username' => 'preferred_username',
'email' => 'email',
'first_name' => 'given_name',
'last_name' => 'family_name',
'display_name' => 'name',
'groups' => 'groups',
],
],
],
],
Authentik
- Create an OAuth2/OpenID Provider in Authentik
- Create an Application linked to the provider
- Add redirect URI:
https://your-poweradmin.com/oidc/callback
'oidc' => [
'enabled' => true,
'providers' => [
'authentik' => [
'name' => 'Authentik',
'display_name' => 'Sign in with Authentik',
'client_id' => 'your-client-id',
'client_secret' => 'your-client-secret',
'base_url' => 'https://authentik.example.com',
'application_slug' => 'poweradmin',
'auto_discovery' => true,
'metadata_url' => '{base_url}/application/o/{application_slug}/.well-known/openid-configuration',
'logout_url' => '{base_url}/application/o/{application_slug}/end-session/',
'scopes' => 'openid profile email',
'user_mapping' => [
'username' => 'preferred_username',
'email' => 'email',
'first_name' => 'given_name',
'last_name' => 'family_name',
'display_name' => 'name',
'groups' => 'groups',
],
],
],
],
Auth0
- Create an application in Auth0 Dashboard
- Set Application Type to "Regular Web Application"
- Add callback URL:
https://your-poweradmin.com/oidc/callback
'oidc' => [
'enabled' => true,
'providers' => [
'auth0' => [
'name' => 'Auth0',
'display_name' => 'Sign in with Auth0',
'client_id' => 'your-client-id',
'client_secret' => 'your-client-secret',
'domain' => 'your-tenant.auth0.com',
'auto_discovery' => true,
'metadata_url' => 'https://{domain}/.well-known/openid-configuration',
'logout_url' => 'https://{domain}/v2/logout',
'scopes' => 'openid profile email',
'user_mapping' => [
'username' => 'nickname',
'email' => 'email',
'first_name' => 'given_name',
'last_name' => 'family_name',
'display_name' => 'name',
'groups' => 'groups',
],
],
],
],
Generic OIDC Provider
For providers not listed above, use manual endpoint configuration:
'oidc' => [
'enabled' => true,
'providers' => [
'custom' => [
'name' => 'Custom OIDC',
'display_name' => 'Sign in with SSO',
'client_id' => 'your-client-id',
'client_secret' => 'your-client-secret',
'auto_discovery' => false,
'authorize_url' => 'https://provider.example.com/oauth/authorize',
'token_url' => 'https://provider.example.com/oauth/token',
'userinfo_url' => 'https://provider.example.com/oauth/userinfo',
'logout_url' => 'https://provider.example.com/oauth/logout',
'scopes' => 'openid profile email',
'user_mapping' => [
'username' => 'preferred_username',
'email' => 'email',
'first_name' => 'given_name',
'last_name' => 'family_name',
'display_name' => 'name',
'groups' => 'groups',
],
],
],
],
User Mapping
The user_mapping array maps OIDC claims to Poweradmin user fields:
| Poweradmin Field | Common OIDC Claims | Description |
|---|---|---|
username |
preferred_username, email | User's login name |
email |
Email address | |
first_name |
given_name | First name |
last_name |
family_name | Last name |
display_name |
name | Display name |
groups |
groups | Group memberships |
avatar |
picture | Profile picture URL |
Docker Configuration
Use environment variables with the PA_OIDC_ prefix:
environment:
PA_OIDC_ENABLED: "true"
PA_OIDC_AUTO_PROVISION: "true"
PA_OIDC_KEYCLOAK_CLIENT_ID: "poweradmin"
PA_OIDC_KEYCLOAK_CLIENT_SECRET: "your-secret"
PA_OIDC_KEYCLOAK_BASE_URL: "https://keycloak.example.com"
PA_OIDC_KEYCLOAK_REALM: "master"
For secrets, use the __FILE suffix:
secrets:
oidc_client_secret:
file: ./secrets/oidc_client_secret.txt
services:
poweradmin:
environment:
PA_OIDC_KEYCLOAK_CLIENT_SECRET__FILE: /run/secrets/oidc_client_secret
secrets:
- oidc_client_secret
Multiple Providers
You can configure multiple OIDC providers. Users will see all enabled providers on the login page:
'oidc' => [
'enabled' => true,
'providers' => [
'azure' => [
// Azure AD configuration...
],
'google' => [
// Google configuration...
],
],
],
Security Considerations
- Use HTTPS: OIDC requires HTTPS for redirect URIs in production
- Protect client secrets: Use Docker secrets or environment variables, never commit secrets to version control
- Validate redirect URIs: Configure exact redirect URIs in your identity provider
- PKCE: Poweradmin uses PKCE (Proof Key for Code Exchange) automatically for enhanced security
- State validation: CSRF protection via state parameter is enabled by default
Troubleshooting
Login redirects fail
- Verify the redirect URI in your provider matches exactly:
https://your-poweradmin.com/oidc/callback - Check that your Poweradmin URL is accessible from the user's browser
- For reverse proxy setups, ensure
X-Forwarded-Protoheader is set
User not created after login
- Check
auto_provisionis enabled - Verify the user mapping includes required fields (username, email)
- Check application logs for provisioning errors
Groups not mapped
- Ensure the
groupsscope is requested - Verify your provider returns groups in the expected claim
- Check the
user_mapping.groupsmatches your provider's claim name - In Azure AD, configure Group claims in Token configuration
"Invalid state" error
- Clear browser cookies and try again
- Check session configuration in Poweradmin
- Verify server time is synchronized (NTP)