Enforce Access Control for a SAML Connection Using Auth0 Post-Login Actions
Implementing custom logic during the login flow allows administrators to securely layer business rules after a user successfully authenticates, but before Auth0 grants access to an application. A Post-Login Action enforces strict access control for a specific Security Assertion Markup Language (SAML) connection by restricting logins to users with a matching email domain and an allowed IP address.
- Auth0
- Post-Login Actions
- Security Assertion Markup Language (SAML) Connections
How is access control enforced for a SAML connection using a Post-Login Action?
Implement the following Post-Login Action code to isolate the target SAML connection, validate the user's email domain and IP address, and deny access if the validation fails:
/**
* Enforces strict access control for a specific SAML connection:
* only allows logins when email domain matches AND IP is allowed.
*/
exports.onExecutePostLogin = async (event, api) => {
// --- Configuration ---
// Set the exact name of the connection, its strategy, the allowed email domain,
// and the allowed IP addresses.
const TARGET_CONNECTION = 'connection-name';
const TARGET_STRATEGY = 'samlp';
const ALLOWED_DOMAIN = 'example.com';
const ALLOWED_IPS = new Set(['1.2.3.4', '5.6.7.8']); // Add all allowed IPs here
// --- Guard clause: only enforce on the target SAML connection ---
if (
event.connection.strategy !== TARGET_STRATEGY ||
event.connection.name !== TARGET_CONNECTION
) {
// If the login is not from the target connection, do nothing and exit.
return;
}
// --- Defensive extraction of user and request properties ---
const email = event.user.email?.toLowerCase();
const emailVerified = event.user.email_verified === true;
const emailDomain = email?.split('@')[1];
const ip = event.request?.ip;
// --- Validation Logic ---
const isEmailValid = emailVerified && emailDomain === ALLOWED_DOMAIN;
const isIpAllowed = ip && ALLOWED_IPS.has(ip);
// If the email is NOT valid OR the IP is NOT allowed, block access.
if (!isEmailValid || !isIpAllowed) {
// A generic message prevents leaking which specific check failed.
return api.access.deny('Access is not permitted from your network for this application.');
}
// If both checks pass, the action completes and login proceeds.
};
NOTE: Adjust the action to meet specific organizational needs before moving it to production.
How does the Post-Login Action process the login event?
The Post-Login Action executes on every login and performs the following validation steps:
- Isolates the Connection: The action checks if the login originates from the specified SAML connection (
connection-name). If it does not, the action allows the login to proceed without further checks. - Validates the User: For the target connection, the action enforces two strict rules:
- Email Validity: The action verifies that the user's email is verified and belongs to the approved domain (
example.com). - IP Allowlist: The action checks whether the user's IP address exists in the
ALLOWED_IPSlist.
- Email Validity: The action verifies that the user's email is verified and belongs to the approved domain (
- Denies Access: If either the email check or the IP check fails, Auth0 immediately blocks the user's login and displays a generic error message.
Which event properties does the Post-Login Action use?
The action leverages the following properties from the event object provided by Auth0 during the login flow to accomplish the validation:
- event.connection.name: The display name of the connection (for example,
The-SAML-Connection). The action uses this property to target the specific connection. - event.connection.strategy: The connection type (for example,
samlp). The action uses this property to ensure it only targets SAML connections. - event.user.email: The user's email address, which the action uses to extract the domain.
- event.user.email_verified: A boolean that confirms the user has ownership of the email address, preventing bad actors from signing up with an unverified email from the domain.
- event.request.ip: The IP address of the end-user, which the action checks against the allowlist.