Skip to content

Custom User Provisioning Logic with Groovy

AuthM supports custom Groovy scripts that allow dynamic determination of user attributes and group memberships during the authentication process. This provides fine-grained control over user provisioning and group assignment based on identity provider (IdP) data.

Purpose

Custom provisioning logic is especially useful when:

  • The identity provider (IdP) returns user claims that need to be transformed or mapped.
  • Users and groups should be auto-created or updated during login.
  • You want to enforce specific rules or filters before finalizing authentication.

Configuration Requirements

To enable and use a custom Groovy provisioning script:

  1. Set the script path in the AuthM configuration file:
...
openid.configs[x].post-authentication-script=<script_name>.groovy

or 

...
saml2.configs[x].post-authentication-script=<script_name>.groovy
  1. Place the script file under the directory specified by the property:
groovy-scripts-directory=<absolute_path_to_scripts_folder>

Script Environment

When your Groovy script executes, the following global variables are available:

VariableDescription
logA logger instance for logging within the script.
idpTypeThe IdP type of authentication: OpenId or Saml2
externalUsernameThe external username retrieved from the IdP
attributesA map of all claims (attributes) returned from the IdP.
userA User object representing the existing user (if already present in the system). If the user does not exist yet, this will be null.

Return Format

The script must return a Map containing the following optional keys:

KeyTypeDescription
UserMapA map with the user data to be created or updated.
GroupsList<String>A list of groups that the user should be assigned to.

Example:

groovy
return [
  User: [
    username: attributes.email,
    email: attributes.email,
    fullName: attributes.name
  ],
  Groups: ['default-users', 'admins']
]

Auto-Provisioning & Group Mapping

  • If the user does not exist (user == null), the User map will be used to create the user.
  • If the user exists, the User map will be used to update the user.
  • Any groups listed in the Groups list will be created (if needed) and assigned to the user.

INFO

  • Group assignment is handled automatically.
  • Returning null or an empty map will skip user and group provisioning but allow authentication to continue (if permitted).

WARNING

Be cautious with logic that depends on claim availability — always check for nulls.

Examples:

  1. Creating/updating a user after a successful authentication
groovy
// log.info("user attributes {{ attributes: ${attributes} }}")
//
//      attributes: [
//          primaryPhone:[+000 000 000 000],
//          firstName:[John],
//          lastName:[Doe],
//          displayName:[john Doe],
//          notOnOrAfter:2025-05-28T09:19:31.577Z,
//          email:[email protected],
//          notBefore:2025-05-28T09:09:31.577Z],
//         roles: [admin]
//    }}

def contact = attributes["primaryPhone"]?.get(0)
contact = contact != null ? contact.replaceAll(" ", "") : null

def user = [
        name    : attributes["displayName"][0],
        email    : attributes["email"],
        contact : contact,
        externalUsername: externalUsername
]

// Keep existing groups that are part of the CoB Platform
def finalGroups = user?.groups.findAll { it -> it == "System" } ?: []

// Add roles returned from IDP as user groups
attributes.roles.each {it -> finalGroups << "FUNC ${IT}" }

return [user: user, groups: finalGroups]