Assign Auth0 Roles Based on Okta Groups Using Post-Login Action
This article provides a code example for a Post-Login Action. The script verifies the group assignment of a user signing in through an Okta OpenID Connect (OIDC) connection, assigns the corresponding Auth0 role, and updates the user's application metadata.
- Auth0 Post-Login Actions
- Okta OpenID Connect (OIDC) Connections
-
Configure the following secrets in the Action:
ROLE_ID_ADMIN,ROLE_ID_USER,M2M_DOMAIN,M2M_CLIENT_ID, andM2M_CLIENT_SECRET. -
Add the
auth0npm module to the Action's dependencies. -
Use the following code to implement the logic. Ensure that the connection name in the code matches the Okta connection name (currently set to "okta").
const { ManagementClient } = require('auth0');
exports.onExecutePostLogin = async (event, api) => {
console.log(`[debug] Connection Strategy: ${event.connection.strategy}, Name: ${event.connection.name}`);
const isOkta = event.connection.strategy === "oidc" &&
event.connection.name === "okta";
const adminRoleId = event.secrets.ROLE_ID_ADMIN;
const userRoleId = event.secrets.ROLE_ID_USER;
let role = event.user.app_metadata?.role || userRoleId;
if (isOkta) {
const identity = event.user.identities.find(id => id.provider === 'oidc');
console.log(`[debug] Raw Profile Groups: ${JSON.stringify(identity?.profileData?.groups)}`);
console.log(`[debug] Root User Groups: ${JSON.stringify(event.user.groups)}`);
const groups =
event.user.groups ||
identity?.profileData?.groups ||
[];
console.log(`[debug] Final Groups Array used for logic: ${JSON.stringify(groups)}`);
let roleIdToAssign = null;
if (groups.includes("Admin")) {
console.log("[debug] match: Admin Group detected.");
role = adminRoleId;
roleIdToAssign = adminRoleId;
} else if (groups.includes("Users")) {
console.log("[debug] match: User Group detected.");
role = userRoleId;
roleIdToAssign = userRoleId;
} else {
console.log("[debug] no match: No specific group matched. Keeping default role.");
}
if (roleIdToAssign) {
if (!event.secrets.M2M_CLIENT_ID) {
console.log("[error] M2M_CLIENT_ID secret is missing. Cannot call API.");
} else {
try {
console.log("[debug] Attempting Management API connection.");
const management = new ManagementClient({
domain: event.secrets.M2M_DOMAIN,
clientId: event.secrets.M2M_CLIENT_ID,
clientSecret: event.secrets.M2M_CLIENT_SECRET,
});
const userId = event.user.user_id;
console.log(`[debug] API Call: Assigning role ${roleIdToAssign}...`);
await management.users.roles.assign({ id: userId }, { roles: [roleIdToAssign] });
console.log("[debug] API Success: Roles updated.");
} catch (err) {
console.log("[error] Management API Failed:", err);
console.log("[error] Full Error Object:", JSON.stringify(err));
}
}
}
}
const isDatabase =
event.connection.strategy === "auth0" ||
event.connection.strategy === "email";
if (isDatabase) {
if (event.user.app_metadata?.role) {
role = event.user.app_metadata.role;
}
}
console.log(`[debug] Final Role ID in Token: ${role}`);
api.idToken.setCustomClaim("https://<namespace>/role", role);
api.accessToken.setCustomClaim("https://<namespace>/role", role);
api.user.setAppMetadata("role", role);
};