
Integrating Auth0 SAML SSO with Wazuh Dashboard
Wazuh Dashboard is built on top of OpenSearch Dashboards, which means SSO authentication is handled through the OpenSearch Security plugin. This guide walks you through connecting Auth0 as a SAML 2.0 Identity Provider so your team can log in to Wazuh using their Auth0 credentials.
Prerequisites
- Wazuh installed (package/bare metal, not Docker)
- An Auth0 account with an application created
- SAML2 Web App add-on enabled on your Auth0 application
- Access to the Wazuh server as root
Step 1: Configure the SAML2 Add-on in Auth0
Go to Auth0 → Applications → Your App → Addons → SAML2 Web App.
Set the Application Callback URL (SP ACS URL):
https://<YOUR_WAZUH_DASHBOARD_URL>/_opendistro/_security/saml/acs
Then paste the following JSON into the Settings field:
{
"audience": "wazuh-saml",
"recipient": "https://<YOUR_WAZUH_DASHBOARD_URL>/_opendistro/_security/saml/acs",
"destination": "https://<YOUR_WAZUH_DASHBOARD_URL>/_opendistro/_security/saml/acs",
"mappings": {
"email": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
"name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
},
"nameIdentifierFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
"nameIdentifierProbes": [
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
],
"signResponse": true
}
Replace
<YOUR_WAZUH_DASHBOARD_URL>with your actual domain throughout this guide.
Also go to Applications → Your App → Settings → Application URIs and add your ACS URL to Allowed Callback URLs.
Step 2: Add Role Injection via Auth0 Action (Recommended)
To assign roles to users automatically, create a Login Action in Auth0.
Go to Auth0 → Actions → Flows → Login → Create Action:
exports.onExecutePostLogin = async (event, api) => {
api.samlResponse.setAttribute(
"http://schemas.xmlsoap.org/claims/Group",
["wazuh-admin"]
);
};
This injects a Group attribute into the SAML assertion, which OpenSearch Security will use for role mapping.
Step 3: Configure OpenSearch Security (config.yml)
Edit the security configuration file:
nano /etc/wazuh-indexer/opensearch-security/config.yml
Ensure the file starts with --- (no backslash). Add the saml_auth_domain block inside authc:
---
_meta:
type: "config"
config_version: 2
config:
dynamic:
authc:
saml_auth_domain:
http_enabled: true
transport_enabled: false
order: 1
http_authenticator:
type: saml
challenge: true
config:
idp:
metadata_url: https://<YOUR_AUTH0_DOMAIN>/samlp/metadata/<CLIENT_ID>
entity_id: 'urn:<YOUR_AUTH0_DOMAIN>'
sp:
entity_id: 'wazuh-saml'
kibana_url: 'https://<YOUR_WAZUH_DASHBOARD_URL>'
subject_key: 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress'
roles_key: 'http://schemas.xmlsoap.org/claims/Group'
exchange_key: '<RANDOM_64_CHAR_HEX_STRING>'
authentication_backend:
type: noop
basic_internal_auth_domain:
description: "Authenticate via HTTP Basic against internal users database"
http_enabled: true
transport_enabled: true
order: 0
http_authenticator:
type: basic
challenge: false
authentication_backend:
type: intern
exchange_keymust be a random string of at least 32 characters. Generate one with:openssl rand -hex 32
Validate the YAML before applying:
python3 -c "import yaml; yaml.safe_load(open('/etc/wazuh-indexer/opensearch-security/config.yml'))" && echo "YAML valid"
Step 4: Configure Wazuh Dashboard (opensearch_dashboards.yml)
nano /etc/wazuh-dashboard/opensearch_dashboards.yml
Add or update these lines:
opensearch_security.auth.type: "saml"
opensearch_security.cookie.secure: true
opensearch_security.cookie.password: "<RANDOM_32_CHAR_STRING>"
server.xsrf.allowlist:
- "/_opendistro/_security/saml/acs"
- "/_opendistro/_security/saml/logout"
- "/_opendistro/_security/saml/acs/idpinitiated"
Step 5: Map Auth0 Roles to Wazuh Roles
Edit roles_mapping.yml:
nano /etc/wazuh-indexer/opensearch-security/roles_mapping.yml
Map the wazuh-admin backend role (sent by Auth0) to all_access:
all_access:
reserved: false
hidden: false
backend_roles:
- "wazuh-admin"
hosts: []
users: []
and_backend_roles: []
If you want to grant access to a specific user directly (without role injection):
all_access:
reserved: false
users:
- "[email protected]"
Step 6: Apply Security Configuration
Apply config.yml:
export JAVA_HOME=/usr/share/wazuh-indexer/jdk/
bash /usr/share/wazuh-indexer/plugins/opensearch-security/tools/securityadmin.sh \
-f /etc/wazuh-indexer/opensearch-security/config.yml \
-t config \
-icl \
-key /etc/wazuh-indexer/certs/admin-key.pem \
-cert /etc/wazuh-indexer/certs/admin.pem \
-cacert /etc/wazuh-indexer/certs/root-ca.pem \
-h 127.0.0.1
Apply roles_mapping.yml:
bash /usr/share/wazuh-indexer/plugins/opensearch-security/tools/securityadmin.sh \
-f /etc/wazuh-indexer/opensearch-security/roles_mapping.yml \
-t rolesmapping \
-icl \
-key /etc/wazuh-indexer/certs/admin-key.pem \
-cert /etc/wazuh-indexer/certs/admin.pem \
-cacert /etc/wazuh-indexer/certs/root-ca.pem \
-h 127.0.0.1
Step 7: Restart Services
systemctl restart wazuh-indexer
systemctl restart wazuh-dashboard
Verification
Open your Wazuh Dashboard URL in a browser. You should be redirected to the Auth0 login page. After authenticating, you will be redirected back to Wazuh Dashboard with full access.
To confirm the login flow is working correctly, monitor the logs:
journalctl -u wazuh-dashboard -f --no-pager | grep -i "saml\|error\|auth"
grep -i "saml\|error" /var/log/wazuh-indexer/wazuh-cluster.log | tail -20
Troubleshooting
| Symptom | Likely Cause | Fix |
|---|---|---|
Authentication Exception in logs | sp.entity_id does not match audience in Auth0 | Ensure both are exactly wazuh-saml |
No subject found in JWT token | nameIdentifierProbes not set in Auth0 | Add email probe to Auth0 SAML settings |
backend_roles=[], permission denied | Auth0 not sending Group attribute | Add Auth0 Login Action to inject roles |
YAML format error on securityadmin | Malformed YAML or \--- at start of file | Fix with sed -i '1s/\\---/---/' config.yml |
Unable to read type from file | Missing -t config flag | Always use -t config or -t rolesmapping |
Summary
| Component | Value |
|---|---|
| SP Entity ID | wazuh-saml |
| ACS URL | https://<WAZUH_URL>/_opendistro/_security/saml/acs |
| IdP Entity ID | urn:<AUTH0_DOMAIN> |
| Subject Key | http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress |
| Roles Key | http://schemas.xmlsoap.org/claims/Group |
