JIT user provisioning
Just-in-time user provisioning (JIT provisioning) allows users to be created and updated automatically when they log in through SAML SSO or OpenID Connect (OIDC) SSO to Atlassian Data Center applications such as Jira, Confluence, Bitbucket, or Bamboo.
Before you begin
Be aware that JIT provisioning overrides all user details sourced by JIT. If you use JIT provisioning with user’s groups maintained manually, all local group memberships will be modified to match what is configured in your IdP. To maintain user access to the application, make sure that users are assigned to appropriate groups in IdP.
With JIT enabled, the following changes happen during the authentication of an existing user:
Rename the user if the username was changed.
Change the user email if it was changed.
Change the user display name if it was changed.
Remove the user from all groups that the user belongs to if those groups weren’t returned by the IdP in the authentication response.
Add the user to all groups the user currently doesn’t belong to if those groups were returned by the IdP in the authentication response.
The user data is always modified until the user is in the state that was returned from the identity provider, regardless of how the changes were made: manually or if the user was updated on the IdP’s side.
Details
Without JIT, logging in using SSO will fail if the user is not present in one of the user directories (be it a remote LDAP or the internal directory). With JIT enabled, a user can be created just-in-time, which allows for an instant login without the need for the user to have been manually created in the product beforehand. The data required to provision the user comes from the SSO response after the user is authenticated, which must be configured in your chosen identity provider (IdP).
Users provisioned JIT are created in the internal directory of your application. In order for a user to be created, their username, display name, email, and group memberships are required. These fields will be filled in with data from the SSO response. This data must be configured in your IdP and made available through attributes (when using SAML) or claims (when using OIDC). You can read more on configuring this below.
On subsequent logins (and while JIT provisioning remains enabled), the user’s data will be kept up to date with changes coming from the IdP, including any users in the internal directory that predate JIT provisioning. If SSO with JIT provisioning is enabled at the same time as a remote directory is active when a user logs in, priority will be given to the remote directory - if the user is present in it, they will be logged in from there.
What happens to deleted users when JIT is enabled with SSO authentication?
When JIT is enabled, Jira saves user data retrieved from AzureAD’s login response to Jira’s internal directory.
Since Jira doesn’t have a way to actively synchronize with AzureAD, there is no way to delete the user from Jira’s internal directory.
Because JIT relies on AzureAD’s login response, users disabled in or deleted from AzureAD won’t be able to authenticate with AzureAD. In this case, these users must be manually deleted from Jira.
Mapping Expressions
Mapping expressions come as a part of the JIT provisioning app. These are simple expressions where alongside literal text, variables can be declared which will then be replaced with supplied values when the expression is evaluated. The syntax follows the established pattern of "${variableName}", for example: "some text ${conjunction} some more text" where conjunction = "and" will evaluate to "some text and some more text".
In the context of configuring SSO and JIT provisioning, variable replacements will come from the SSO response of your chosen IdP:
For SAML, these details will be the attributes associated with the user.
For OIDC, these details will be the claims associated with the user (in the requested scopes).
The fields which require a mapping expression are:
- Username mapping
- Display name (when JIT provisioning is enabled)
- Email (when JIT provisioning is enabled)
Note that the JIT provisioning field Groups does not support mapping expressions and requires only the name of an attribute/claim containing a list of group names.
Consider a contextual example, where the value of the display name mapping is ${firstName} ${lastName} 2020 when a user is provisioned with SAML:
${firstName} will be replaced with the value of an attribute called firstName.
${lastName} will be replaced with the value of an attribute called lastName.
2020 will not be modified in any way.
If a user John Smith logs in, their display name in the product will be John Smith 2020.
Note that these attributes/claims must be present in the SSO response, if not users will encounter an error when logging in with SSO. To ensure your configuration works, see: JIT provisioning - How to test your attribute mappings
Additional Note:
- SAMLDC-77Getting issue details... STATUS
Since groups synchronized to Atlassian applications can be used to assign permissions (project, space, etc), some group names from the IdP might not be easily recognized by users. i.e. Azure AD + JIT. The aforementioned feature request is tracking improvements for this integration
Configuring the username mapping field
Another change that comes with JIT provisioning is an update to what was previously the Username claim field, only available in OpenID Connect. This field allowed you to specify a claim to use when matching the username during an SSO login. The field has now been made available for SAML (which previously defaulted to using the NameID as the source of the username), as well as been updated in a couple of ways:
- The field is now required, which is to encourage an active choice when specifying the source(s) of the username.
- The field is a mapping expression as described in the section above.
Note that any previous values (or lack thereof) will be migrated accordingly after the plugin is upgraded.
How this field affects JIT provisioning
When logging in with SSO, the user's username will be evaluated by the mapping expression in the field.
With JIT provisioning disabled, that username will be used to match the user as authenticated by the IdP to a user entry within the product (which may come from a remote directory) and log them in.
If JIT provisioning is enabled, the username can no longer be the only way in which we uniquely identify a user within the product. The reason behind this is that we are relying on the IdP to provide us with the user's data and that data, including the username, can change. This creates a scenario where every time a user changes their username in the IdP, logging into the product will cause a new user entry to be provisioned (even though it is the same user).
To avoid this scenario, your IdP and username mapping needs to be configured to support username updating. This is done by uniquely identifying the user by means of a persistent id, meaning that the value of this id does not change throughout the lifetime of the user's record, which should be provided by the IdP.
In SAML: The SAML specification (section 8.3.7) defines a persistent id format for the NameID, which you should configure in your IdP. Also in your IdP, you should then create a new attribute that will contain the changeable username and use it in your Username mapping expression, for example: "${preferredUsername}". When JIT provisioning is enabled, it is assumed the NameID is a persistent id.
In OIDC: The OIDC specification defines the Subject Identifier (the sub-claim) as standard for each user within an application, which is a persistent id and usually generated and handled automatically in IdPs. It is common practice to then use the standard claim preferred_username (found in the profile scope) as the source of the changeable username, so the Username mapping field would be configured as "${preferred_username}" for example. When JIT provisioning is enabled, it is assumed the sub-claim is a persistent id.