SAML Authentication
Poweradmin supports SAML 2.0 for single sign-on (SSO) authentication with enterprise identity providers like Azure AD, Okta, Auth0, and Keycloak.
Overview
SAML (Security Assertion Markup Language) allows users to authenticate using their organization's identity provider. When enabled, users see additional "Sign in with..." buttons on the login page.
Key features:
- Automatic user provisioning from SAML assertions
- Link SAML accounts to existing users by email
- Sync user information from SAML attributes
- Map SAML groups/roles to Poweradmin permission templates
- Support for multiple providers simultaneously
- SP metadata generation for easy IdP configuration
Global Settings
| Setting | Default | Description |
|---|---|---|
saml.enabled |
false | Enable SAML authentication |
saml.auto_provision |
true | Auto-create users from SAML assertions |
saml.link_by_email |
true | Link SAML accounts to existing users by email |
saml.sync_user_info |
true | Sync user info on each login |
saml.default_permission_template |
"" | Default permission template for new users |
Permission Template Mapping
Map SAML groups/roles to Poweradmin permission templates:
'saml' => [
'enabled' => true,
'permission_template_mapping' => [
'poweradmin-admins' => 'Administrator',
'dns-operators' => 'DNS Operator',
'dns-viewers' => 'Read Only',
],
],
Group Membership Mapping
Separate from permission templates, you can also map SAML groups to Poweradmin groups. This controls zone ownership and access through group membership.
Key differences from permission template mapping:
permission_template_mappingassigns one permission template per usergroup_mappingassigns multiple Poweradmin groups per user
'saml' => [
'enabled' => true,
'group_mapping' => [
'external-admins' => 'Administrators',
'dns-managers' => 'Zone Managers',
'dns-editors' => 'Editors',
'dns-viewers' => 'Viewers',
'dns-guests' => 'Guests',
],
],
A single SAML group can also be mapped to multiple Poweradmin groups by giving an array as the value (added in 4.4.0). The user is added to every Poweradmin group listed:
'group_mapping' => [
'team1' => ['Editors', 'Viewers'],
'team2' => ['Editors'],
'platform-admins' => 'Administrators', // single-value form still works
],
Predefined Poweradmin groups:
- Administrators - Full administrative access to all system functions
- Zone Managers - Full zone management including creation, editing, and deletion
- Editors - Edit zone records but cannot modify SOA and NS records
- Viewers - Read-only access to zones with search capability
- Guests - Temporary group with no permissions (awaiting approval)
Note: Both
permission_template_mappingandgroup_mappingread from the same SAML attribute specified byuser_mapping.groups. Group memberships are re-evaluated on every login - users are added to or removed from mapped groups based on their current SAML assertion.
Service Provider (SP) Configuration
Poweradmin acts as a SAML Service Provider. Configure SP settings in the sp section:
| Setting | Default | Description |
|---|---|---|
sp.entity_id |
(auto) | SP Entity ID (defaults to {base_url}/saml/metadata) |
sp.assertion_consumer_service_url |
(auto) | ACS URL (defaults to {base_url}/saml/acs) |
sp.single_logout_service_url |
(auto) | SLO URL (defaults to {base_url}/saml/sls) |
sp.name_id_format |
emailAddress | NameID format |
sp.x509cert |
"" | SP certificate for signing (optional) |
sp.private_key |
"" | SP private key for signing (optional) |
'saml' => [
'enabled' => true,
'sp' => [
'entity_id' => 'https://poweradmin.example.com/saml/metadata',
'name_id_format' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress',
],
],
SP Metadata
Poweradmin can generate SP metadata for your identity provider. Access it at:
https://your-poweradmin.com/saml/metadata/{provider-id}
For example: https://your-poweradmin.com/saml/metadata/azure
Provider Configuration
Each provider requires IdP-specific configuration:
| Field | Required | Description |
|---|---|---|
name |
Yes | Internal provider identifier |
display_name |
Yes | Text shown on login button |
entity_id |
Yes | IdP Entity ID |
sso_url |
Yes | IdP Single Sign-On URL |
slo_url |
No | IdP Single Logout URL |
x509cert |
Yes | IdP X.509 certificate (PEM string, with or without -----BEGIN CERTIFICATE-----/-----END CERTIFICATE----- headers and line breaks) |
user_mapping |
Yes | Map SAML attributes to user fields |
Azure AD (SAML)
- In Azure Portal, go to Enterprise Applications > New Application
- Create a non-gallery application
- Configure Single Sign-On > SAML
- Set Entity ID:
https://your-poweradmin.com/saml/metadata/azure - Set Reply URL (ACS):
https://your-poweradmin.com/saml/acs - Download the Certificate (Base64)
'saml' => [
'enabled' => true,
'providers' => [
'azure' => [
'name' => 'Microsoft Azure AD',
'display_name' => 'Sign in with Microsoft',
'entity_id' => 'https://sts.windows.net/{tenant-id}/',
'sso_url' => 'https://login.microsoftonline.com/{tenant-id}/saml2',
'slo_url' => 'https://login.microsoftonline.com/{tenant-id}/saml2',
'x509cert' => 'MIICnTCCAYUCBgF...', // Base64 cert body, or a full PEM string
'user_mapping' => [
'username' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name',
'email' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress',
'first_name' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname',
'last_name' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname',
'display_name' => 'http://schemas.microsoft.com/identity/claims/displayname',
'groups' => 'http://schemas.microsoft.com/ws/2008/06/identity/claims/groups',
],
],
],
],
Okta (SAML)
- In Okta Admin Console, go to Applications > Create App Integration
- Select SAML 2.0
- Set Single Sign-On URL:
https://your-poweradmin.com/saml/acs - Set Audience URI (SP Entity ID):
https://your-poweradmin.com/saml/metadata/okta - Configure attribute statements
- Download the IdP metadata or certificate
'saml' => [
'enabled' => true,
'providers' => [
'okta' => [
'name' => 'Okta',
'display_name' => 'Sign in with Okta',
'entity_id' => 'http://www.okta.com/{app-id}',
'sso_url' => 'https://{domain}.okta.com/app/{app-name}/{app-id}/sso/saml',
'slo_url' => 'https://{domain}.okta.com/app/{app-name}/{app-id}/slo/saml',
'x509cert' => 'MIIDpDCCAoygAwIBAgIGAX...', // Certificate
'user_mapping' => [
'username' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name',
'email' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress',
'first_name' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname',
'last_name' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname',
'groups' => 'http://schemas.xmlsoap.org/claims/Group',
],
],
],
],
Auth0 (SAML)
- In Auth0 Dashboard, go to Applications > Create Application
- Enable SAML2 Web App addon
- Configure SAML settings
- Download IdP metadata
'saml' => [
'enabled' => true,
'providers' => [
'auth0' => [
'name' => 'Auth0',
'display_name' => 'Sign in with Auth0',
'entity_id' => 'urn:auth0:{tenant}:{connection}',
'sso_url' => 'https://{tenant}.auth0.com/samlp/{client-id}',
'slo_url' => 'https://{tenant}.auth0.com/samlp/{client-id}/logout',
'x509cert' => 'MIIDDTCCAfWgAwIBAgIJAP...', // Certificate
'user_mapping' => [
'username' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier',
'email' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress',
'first_name' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname',
'last_name' => 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname',
'groups' => 'http://schemas.auth0.com/roles',
],
],
],
],
Keycloak (SAML)
- In Keycloak Admin Console, create a new Client
- Set Client Protocol to "saml"
- Set Client ID:
https://your-poweradmin.com/saml/metadata/keycloak - Configure endpoints and download certificate
'saml' => [
'enabled' => true,
'providers' => [
'keycloak' => [
'name' => 'Keycloak',
'display_name' => 'Sign in with Keycloak',
'entity_id' => 'https://keycloak.example.com/realms/{realm}',
'sso_url' => 'https://keycloak.example.com/realms/{realm}/protocol/saml',
'slo_url' => 'https://keycloak.example.com/realms/{realm}/protocol/saml',
'x509cert' => 'MIIClTCCAX0CBgF...', // Certificate
'user_mapping' => [
'username' => 'username',
'email' => 'email',
'first_name' => 'firstName',
'last_name' => 'lastName',
'display_name' => 'name',
'groups' => 'groups',
],
],
],
],
Generic SAML Provider
For other SAML identity providers:
'saml' => [
'enabled' => true,
'providers' => [
'custom' => [
'name' => 'Custom SAML IdP',
'display_name' => 'Sign in with SSO',
'entity_id' => 'https://idp.example.com/metadata',
'sso_url' => 'https://idp.example.com/sso',
'slo_url' => 'https://idp.example.com/slo',
'x509cert' => 'MIIDpDCCAoygAwIBAgIGAX...',
'user_mapping' => [
'username' => 'uid',
'email' => 'email',
'first_name' => 'firstName',
'last_name' => 'lastName',
'display_name' => 'displayName',
'groups' => 'groups',
],
'security' => [
'wantAssertionsSigned' => true,
'wantNameId' => true,
],
],
],
],
User Mapping
SAML attributes are mapped to Poweradmin user fields. Common attribute formats:
XML URI Format (Azure AD, Okta, Auth0):
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname
Simple Format (Keycloak):
email
firstName
lastName
| Poweradmin Field | Description |
|---|---|
username |
User's login name |
email |
Email address |
first_name |
First name |
last_name |
Last name |
display_name |
Display name |
groups |
Group/role memberships |
Security Settings
Configure security options per provider:
'security' => [
'nameIdEncrypted' => false,
'authnRequestsSigned' => false,
'logoutRequestSigned' => false,
'logoutResponseSigned' => false,
'signMetadata' => false,
'wantAssertionsSigned' => true,
'wantNameId' => true,
'wantAssertionsEncrypted' => false,
'signatureAlgorithm' => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
'digestAlgorithm' => 'http://www.w3.org/2001/04/xmlenc#sha256',
],
| Setting | Default | Description |
|---|---|---|
wantAssertionsSigned |
true | Require signed assertions |
wantNameId |
true | Require NameID in assertions |
authnRequestsSigned |
false | Sign authentication requests |
signatureAlgorithm |
rsa-sha256 | Signature algorithm |
SP Signing (Optional)
For IdPs that require signed requests, generate a certificate and key:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout sp-private.key \
-out sp-certificate.crt \
-subj "/CN=poweradmin-sp"
Configure in settings:
'saml' => [
'sp' => [
'x509cert' => file_get_contents('/path/to/sp-certificate.crt'),
'private_key' => file_get_contents('/path/to/sp-private.key'),
],
],
Docker Configuration
Use environment variables with the PA_SAML_ prefix:
environment:
PA_SAML_ENABLED: "true"
PA_SAML_AUTO_PROVISION: "true"
PA_SAML_AZURE_ENTITY_ID: "https://sts.windows.net/tenant-id/"
PA_SAML_AZURE_SSO_URL: "https://login.microsoftonline.com/tenant-id/saml2"
Note: The
permission_template_mappingandgroup_mappingsettings can be configured via environment variables using the=delimiter and comma-separated entries:
yaml PA_SAML_PERMISSION_TEMPLATE_MAPPING: "admins=Administrator,editors=Viewer" PA_SAML_GROUP_MAPPING: "admins=Administrators,editors=Editors"Group names containing colons (e.g., SAML URNs) are supported. Whitespace around commas and delimiters is trimmed automatically.
For 1:n group mappings, separate the Poweradmin groups with a pipe (
|) so one SAML group can grant access to several Poweradmin groups (added in 4.4.0):
yaml PA_SAML_GROUP_MAPPING: "team1=Editors|Viewers,team2=Administrators"
For certificates and keys, use Docker secrets:
secrets:
saml_idp_cert:
file: ./secrets/idp-certificate.crt
saml_sp_key:
file: ./secrets/sp-private.key
services:
poweradmin:
environment:
PA_SAML_AZURE_X509_CERT__FILE: /run/secrets/saml_idp_cert
PA_SAML_SP_PRIVATE_KEY__FILE: /run/secrets/saml_sp_key
secrets:
- saml_idp_cert
- saml_sp_key
Multiple Providers
Configure multiple SAML providers:
'saml' => [
'enabled' => true,
'providers' => [
'azure' => [
// Azure AD configuration...
],
'okta' => [
// Okta configuration...
],
],
],
Troubleshooting
"Invalid signature" error
- Verify the IdP certificate is correct and not expired
- Check if your IdP rotated certificates
User not created after login
- Check
auto_provisionis enabled - Verify user mapping includes required fields
- Check that required attributes are released by IdP
NameID missing error
- Configure NameID format in IdP to match SP expectations
- Ensure IdP is configured to send NameID
Groups not mapped
- Verify IdP is configured to release group claims
- Check the attribute name matches
user_mapping.groups - For Azure AD, configure Group claims in Token configuration
Redirect loop
- Clear browser cookies
- Verify ACS URL matches exactly in IdP configuration
- Check for mixed HTTP/HTTPS issues
Certificate errors
- Paste the certificate exactly as your IdP exports it (Base64 download from
Azure / Okta / Keycloak is fine). Both raw Base64 bodies and full PEM
strings (
-----BEGIN CERTIFICATE-----...-----END CERTIFICATE-----) are accepted, with or without embedded line breaks. - If the login page logs "x509cert is not a valid X.509 certificate" the
pasted value cannot be parsed by
openssl_x509_read- check for stray characters, truncation, or that you copied the certificate body rather than the metadata wrapper.