Configure SAML2 JIT user provisioning

Configure a SAML2 security integration to automatically create Snowflake user accounts when a user logs in for the first time through that integration.

Prerequisites

  • A Snowflake account with JIT user provisioning enabled. Contact Snowflake Support to enable this feature for your account.
  • ACCOUNTADMIN role, or a role with the CREATE INTEGRATION privilege.
  • A SAML2 security integration, or permissions to create one. See CREATE SECURITY INTEGRATION (SAML2).

Configure JIT provisioning on a new integration

Use the SAML2_JIT_USER_PROVISIONING parameter when creating a SAML2 security integration.

For Okta, Microsoft Entra ID, or OneLogin, use the corresponding preset to apply the default claim name mappings for that provider:

CREATE SECURITY INTEGRATION my_idp
  TYPE = SAML2
  ENABLED = TRUE
  METADATA_URL = 'https://my-org.okta.com/app/exampleapp/sso/saml/metadata'
  SAML2_JIT_USER_PROVISIONING = (
    ATTRIBUTE_MAPPING_PRESET = 'OKTA'
  );

Configure JIT provisioning on an existing integration

Use ALTER SECURITY INTEGRATION to add JIT provisioning to an existing integration:

ALTER SECURITY INTEGRATION my_idp SET
  SAML2_JIT_USER_PROVISIONING = (
    ATTRIBUTE_MAPPING_PRESET = 'ENTRA_ID'
  );

Map roles from the IdP

To grant Snowflake roles based on the user’s group memberships in the IdP, map the ROLE property to the claim that contains group values:

ALTER SECURITY INTEGRATION my_idp SET
  SAML2_JIT_USER_PROVISIONING = (
    ATTRIBUTE_MAPPING_PRESET = 'OKTA'
    ATTRIBUTE_MAPPING = (
      ROLE = ( ATTRIBUTE = 'groups' )
    )
  );

Important

Snowflake matches claim values to role names, not group IDs. The value in the SAML assertion must be the exact name of an existing Snowflake role. If your IdP sends group object IDs or other identifiers instead of names, you must configure the IdP to send the display name or use a claim transformation before the assertion reaches Snowflake.

How group memberships are sent in SAML assertions varies by identity provider. Consult your IdP’s documentation to find the correct claim name and to confirm that values are emitted as names your Snowflake roles can match. For the most common providers:

  • Okta: see Define group attribute statements in the Okta documentation. Configure a group attribute statement that filters to the groups you want, and use the claim name (for example, groups) in your ATTRIBUTE mapping. Okta sends group display names by default.
  • Microsoft Entra ID: see below. Entra ID sends object IDs by default and requires additional configuration to send names.
  • Other providers: refer to your IdP’s SAML attribute or claim mapping documentation to identify the claim that contains group memberships and confirm that values are emitted as names.

Unquoted values are uppercased automatically, so a claim value of analyst matches the role ANALYST. To match a case-sensitive role name, the claim value must include the double quotes: "analyst" matches the role analyst.

The claim can be multivalued. Snowflake flattens both multiple AttributeValue elements in the SAML assertion and comma-separated values within a single element. All roles must exist in the account and be grantable by the integration owner role, or provisioning fails.

How assertion values map to role names

Given these Snowflake roles:

CREATE ROLE ANALYST;
CREATE ROLE DEVELOPER;
CREATE ROLE "streamlit_viewer";  -- case-sensitive

The following SAML assertion grants ANALYST and DEVELOPER to the new user:

<saml:Attribute Name="groups">
  <saml:AttributeValue>analyst</saml:AttributeValue>
  <saml:AttributeValue>DEVELOPER</saml:AttributeValue>
</saml:Attribute>

Unquoted values analyst and DEVELOPER are both uppercased, matching roles ANALYST and DEVELOPER. To grant the case-sensitive role streamlit_viewer, the assertion must send the value with quotes preserved:

<saml:Attribute Name="groups">
  <saml:AttributeValue>"streamlit_viewer"</saml:AttributeValue>
</saml:Attribute>

Comma-separated values in a single AttributeValue element are also supported:

<saml:Attribute Name="groups">
  <saml:AttributeValue>ANALYST,DEVELOPER</saml:AttributeValue>
</saml:Attribute>

Microsoft Entra ID: group names vs. object IDs {#label-entra-groups-as-names}

By default, Microsoft Entra ID sends group object IDs in SAML assertions, not display names. An assertion from a default Entra ID configuration looks like this:

<saml:Attribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/groups">
  <saml:AttributeValue>89268571-3c63-44ea-8e73-c34d6d3e7b0e</saml:AttributeValue>
</saml:Attribute>

Snowflake would attempt to find a role named 89268571-3C63-44EA-8E73-C34D6D3E7B0E, which almost certainly doesn’t exist, and provisioning would fail.

To send group display names instead, configure the Entra ID enterprise application to emit the sAMAccountName attribute or enable the Group claims setting to use display names. See Configure group claims for applications by using Microsoft Entra ID in the Microsoft documentation. Once configured, the assertion sends values that match your Snowflake role names:

<saml:Attribute Name="groups">
  <saml:AttributeValue>ANALYST</saml:AttributeValue>
  <saml:AttributeValue>DEVELOPER</saml:AttributeValue>
</saml:Attribute>

Provide a fallback role when the claim is absent

To grant a role when the groups claim is absent or empty, add a DEFAULT to the ROLE mapping:

ALTER SECURITY INTEGRATION my_idp SET
  SAML2_JIT_USER_PROVISIONING = (
    ATTRIBUTE_MAPPING_PRESET = 'OKTA'
    ATTRIBUTE_MAPPING = (
      ROLE = ( ATTRIBUTE = 'groups' DEFAULT = 'STREAMLIT_VIEWER' )
    )
  );

When the assertion includes the groups claim with values, Snowflake grants those roles and ignores the default. When the claim is absent or empty, Snowflake grants STREAMLIT_VIEWER instead.

Always grant a baseline role

To grant a fixed role to every provisioned user regardless of the assertion, omit ATTRIBUTE and use only DEFAULT:

ALTER SECURITY INTEGRATION my_idp SET
  SAML2_JIT_USER_PROVISIONING = (
    ATTRIBUTE_MAPPING_PRESET = 'OKTA'
    ATTRIBUTE_MAPPING = (
      ROLE         = ( DEFAULT = 'STREAMLIT_VIEWER' )
      PRIMARY_ROLE = ( DEFAULT = 'STREAMLIT_VIEWER' )
    )
  );

Use this pattern when all users provisioned through this integration should have the same role regardless of their IdP group assignments.

Set the user’s default role

Use PRIMARY_ROLE to control which role is set as the user’s default role at login. You can map it to a claim or provide a static value:

ALTER SECURITY INTEGRATION my_idp SET
  SAML2_JIT_USER_PROVISIONING = (
    ATTRIBUTE_MAPPING_PRESET = 'OKTA'
    ATTRIBUTE_MAPPING = (
      ROLE         = ( ATTRIBUTE = 'groups' )
      PRIMARY_ROLE = ( DEFAULT = 'ANALYST' )
    )
  );

Snowflake grants PRIMARY_ROLE to the user (in addition to any roles from ROLE) and sets it as the user’s default role. If this role doesn’t exist or can’t be granted, provisioning fails.

Use a custom attribute mapping

If your identity provider uses non-standard claim names, or if you’re not using one of the built-in presets, define the mapping manually. You can omit ATTRIBUTE_MAPPING_PRESET and specify all properties explicitly:

ALTER SECURITY INTEGRATION my_idp SET
  SAML2_JIT_USER_PROVISIONING = (
    ATTRIBUTE_MAPPING = (
      LOGIN_NAME   = ( ATTRIBUTE = 'email' )
      EMAIL        = ( ATTRIBUTE = 'email' )
      FIRST_NAME   = ( ATTRIBUTE = 'given_name' )
      LAST_NAME    = ( ATTRIBUTE = 'family_name' )
      ROLE         = ( ATTRIBUTE = 'group_membership' )
      PRIMARY_ROLE = ( DEFAULT = 'PUBLIC' )
    )
  );

You can also override individual entries from a preset while keeping the rest:

ALTER SECURITY INTEGRATION my_idp SET
  SAML2_JIT_USER_PROVISIONING = (
    ATTRIBUTE_MAPPING_PRESET = 'OKTA'
    ATTRIBUTE_MAPPING = (
      LOGIN_NAME = ( ATTRIBUTE = 'preferred_username' )
    )
  );

Restrict provisioned user interface access

To control which Snowflake interfaces a provisioned user can access, map the ALLOWED_INTERFACES property. Use DEFAULT to apply a fixed value to every user provisioned through this integration:

ALTER SECURITY INTEGRATION my_idp SET
  SAML2_JIT_USER_PROVISIONING = (
    ATTRIBUTE_MAPPING_PRESET = 'OKTA'
    ATTRIBUTE_MAPPING = (
      ROLE               = ( ATTRIBUTE = 'groups' )
      ALLOWED_INTERFACES = ( DEFAULT = 'STREAMLIT' )
    )
  );

For valid values, see ALLOWED_INTERFACES in the CREATE USER reference. For behavior within JIT provisioning, see Interface access provisioning.

Note

ALLOWED_INTERFACES requires the ENABLE_USER_ALLOWED_INTERFACES feature to be enabled for your account separately from JIT provisioning. Contact Snowflake Support to enable it.

Verify the configuration

Run DESC SECURITY INTEGRATION to confirm that JIT provisioning is configured and review the current attribute mapping:

DESC SECURITY INTEGRATION my_idp;

The output includes the SAML2_JIT_USER_PROVISIONING property and its configured value.

Disable JIT provisioning

To remove JIT provisioning from an integration:

ALTER SECURITY INTEGRATION my_idp UNSET SAML2_JIT_USER_PROVISIONING;

Existing users provisioned by JIT are not affected. Snowflake no longer creates new users automatically through this integration after you run this command.