How we got Single Sign-On to work with Snowflake, SAML2 and Keycloak! Without client side signed certificates…

Stefan Frost
5 min readJun 2, 2021

When we actually started setting up Single Sign-On, we couldn’t really find the appropriate documentation, so we contacted support.

Support techs told us SSO wasn’t possible with Keycloak and that SAML2 and OpenId still was on the roadmap. However, sales reps of Snowflake had previously told us SSO was possible with Snowflake.

What to do now? We couldn’t really afford a show stopper at this point…

My college Anna Skorokhodova insisted that we could get it to work since Snowflake had pointed us in the direction of the following link: SAML 2.0 compliant federated Identity Providers

And the quote…

“Snowflake supports using most SAML 2.0-compliant vendors as an IdP”

Fortunately for us, Anna Skorokhodova would never give up! So she “forced” me to assist :) and together we got it all to work.

This post is a guide to the required steps. If you require client side signed certificates, continue to this other post that describes that process instead.

Otherwise continue reading…

Ok, so how was it done then?

In order to get the accurate information to put inside Snowflake SAML IdP definition, we must first configure Keycloak.

Option 1: SSO with client side signed certificates disabled

Step 1; Gather configuration

In order to gather the Keycloak SAML Identity Provider metadata, access KeyClock adminstration and goto “configure->Realm Settings”. On the “General tab”, click on the link “Endpoints- SAML 2.0 Identity Provider Metadata”.

Remember to pick the realm that you will use!

A page containing an XML document with metadata will be presented, similar to ours in the picture below. Copy entityID, Certificate and the Single Sign On Service POST link.

Please bear in mind that Realm names are case sensitive. So, copy the values to Snowflake configuration exactly as stated in the metadata.

Step 2; Create a Snowflake client

Next step (still in Keycloak), is to create a Snowflake client. Go to “configuration->Clients” press the button “Create” and enter the following information:

Client ID: https://<account>.<region>.snowflakecomputing.com
Client Protocol: saml
Client Signature Required: OFF
Force POST Binding: ON
Name ID Format: username
Valid Redirect URIs: https://<account>.<region>.snowflakecomputing.com/fed/login/
Master SAML Processing URL: https://<account>.<region>.snowflakecomputing.com
Assertion Consumer Service POST Binding URL: https://<account>.<region>.snowflakecomputing.com/fed/login/
Logout Service Redirect Binding URL: https://<account>.<region>.snowflakecomputing.com/fed/logout/

It is important to have the <account> name in all URL’s in the same case as in Snowflake. i.e. if you set ACCOUNT in capital letters in the Snowflake configuration, the same must be configured in Keycloak.

All settings that we used are presented in the picture below:

NOTE! Keycloak identifies the snowflake client id in UPPERCASE when Client Signature Required is set to OFF.

Step 3; Setup Snowflake!

First logon to Snowflake using a user with “accountadmin” authorities and define the SAML idP with a statement similar to this one;

use role accountadmin;

alter account set saml_identity_provider = ‘{
“certificate”: “tHiSISaF@keC3rt1fc@t3”,
“ssoUrl”:“https://your.keycloak.server/auth/realms/YourRealm/protocol/saml”,
“type” : “Custom”,
“label” : “SingleSignOn”
}’;

See that we have copied in values from the SAML metadata previously described. If the provided information (certificate, ssoUrl) is not exactly the same in both Snowflake and Keycloak, then the integration will definitely fail.

certificate must equal the value of the <ds:x509certificate></ds:x509certificate> tag
ssoURL must equal the value of the Location attribute for the binding at <md:SingleSignOnService Binding=”urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST” Location=https://your.keycloak.server/auth/realms/YourRealm/protocol/saml/>

Ok. So we now have a SAML2 integration setup in Snowflake.

In order to test our SSO, we must first create a user.

Defining the user the right way, was actually the failing part for us and the reason for contacting Snowflake support in the first place.

So after hours of digging and reading, we came across

And please note,

2. In the interface, create a user for each person who will need access to Snowflake. When creating users, make sure to include an email address for each user. Email addresses are required to connect the users in the IdP with their corresponding users in Snowflake

Which came to be of great significance….

Basically custom identity provider communicate using login_name and email. So if you do not use your email as login_name, authentication will fail.

So if you wish to save a few hours, then construct your own create user statement similar to the example below and run it in Snowflake.

create user SOMEUSER
password = ‘*****’
login_name = ‘your-email-as-it-is-in-keycloak@your-domain.url’
display_name = ‘SOMEUSER’
email = ‘your-email-as-it-is-in-keycloak@your-domain.url’
default_role = ‘AROLE’
default_warehouse = ‘awarehouse’
must_change_password = FALSE ;

Great, you are now able to test your SSO. Go to the corresponding link of your Snowflake account:

https://<account>.<region>.snowflakecomputing.com/console/login?fedpreview=true

Press the new button with the label SingleSignOn and you should be able to logon.

If you are happy with your SSO integration, make it permanent using the following statement in Snowflake

alter account set sso_login_page = true ;

Voila your SSO is now a part of your normal login page!

https://<account>.<region>.snowflakecomputing.com/console/login#/

BUT, please be aware that any user will still be able to logon using username and password without SSO. So in order to fix that, simple execute;

alter user SOMEUSER set password = ‘’;

BTW we additionally followed the guide for OATH and Tableau and got SSO to work end-to-end by a single line of Snowflake code :)

create security integration Tableau
type = oauth
enabled = true
oauth_client = tableau_server
oauth_refresh_token_validity = 86400;

I really hope this post will save you a few hours of head banging :)

--

--

Stefan Frost

Data engineer, data architect and data platform automation entusiast. Building cloud based data platforms and tools, for improved productivity.