What you will be able to do
- Configure key-pair authentication and rotate keys without downtime
- Generate programmatic access tokens and control their expiry, network and role requirements with a PAT_POLICY
- Choose the right CREATE SECRET type for authenticating to an external API
- Set idle-timeout and maximum-lifespan session policies and monitor sessions
- Explain how leaked password protection and Malicious IP Protection respond, and manage low-risk opt-outs
1.Key-pair authentication for programmatic clients
Programmatic clients and service users authenticate without a human typing a password. Key-pair authentication is the established option. Snowflake's security overview calls workload identity federation the preferred method for service-to-service workloads. A user configured for it shows HAS_WORKLOAD_IDENTITY = TRUE in DESC USER. A related capability lets Snowflake workloads authenticate to external services, with Snowflake acting as the OIDC provider. The minimum key is a 2048-bit RSA pair. Snowflake also accepts RS256/384/512 signatures, plus ECDSA keys in the Python driver only. An encrypted private key is generally safer. Its passphrase protects only the local key file and is never sent to Snowflake. Use AES-256-CBC, because Triple DES is not recommended.
openssl genrsa 2048 | openssl pkcs8 -topk8 -v2 aes-256-cbc -inform PEM -out rsa_key.p8Assigning a public key requires OWNERSHIP of the user or the MODIFY PROGRAMMATIC AUTHENTICATION METHODS privilege on it. That privilege lets a service team manage its own service user's keys without owning the user. Snowflake recommends a named key pair, because it supports role restriction, named key management and expiry. The older SET RSA_PUBLIC_KEY approach supports none of these.
ALTER USER example_user ADD KEY PAIR my_key
PUBLIC_KEY = 'MIIBIjANBgkqh...';To verify the setup, compare the user's RSA_PUBLIC_KEY_FP from DESC USER with the SHA-256 digest of your local public key. When they match, point the client at the private key.
Checkpoint 1 of 7· Put it in order
Put the key-pair setup steps in order
- 1.Generate the private key with OpenSSL
- 2.Compare the user's public key fingerprint with your local key's digest
- 3.Assign the public key to the Snowflake user
- 4.Generate the public key from the private key
- 5.Configure the client to use key-pair authentication
The public key is derived from the private key and then registered. Checking the fingerprint confirms the registration before any client depends on it.
“From the command line, generate the public key by referencing the private key.”Source: docs.snowflake.com
Role restriction also applies to PATs, which are controlled through the PAT_POLICY of an authentication policy. By default, a PAT for a service user must specify a role restriction. Setting REQUIRE_ROLE_RESTRICTION_FOR_SERVICE_USERS = FALSE lifts that for service users, on the account or on specific users. Changing it from FALSE back to TRUE invalidates service-user tokens that were generated without a role restriction. For person users, no role restriction is required by default. Setting REQUIRE_ROLE_RESTRICTION_FOR_PERSON_USERS to TRUE requires one.
2.Programmatic access tokens (PATs)
A programmatic access token (PAT) is a bearer credential. It works against the REST and SQL APIs, Snowpark Container Services endpoints and SCIM. It can also stand in for a password in drivers, the CLI and tools such as Tableau. Both human users (TYPE=PERSON) and service users (SERVICE, SERVICE_AGENT) can have PATs, and you generate one with ALTER USER … ADD PROGRAMMATIC ACCESS TOKEN. By default, service users must give each token a role restriction. That role is used for privilege evaluation in sessions the token authenticates.
The default safeguard is a network policy requirement, and it applies differently to each user type. A service user can neither generate nor use a token unless a network policy applies to them. A service agent user needs no network policy at all. A human user can generate a token without one but needs one to authenticate with it. The NETWORK_POLICY_EVALUATION setting in an authentication policy's PAT_POLICY changes this default:
| Value | Network policy required? | Network policy enforced if present? |
|---|---|---|
| ENFORCED_REQUIRED (default) | Yes | Yes |
| ENFORCED_NOT_REQUIRED | No | Yes |
| NOT_ENFORCED | No | No |
Two more PAT settings matter. First, any authentication policy that limits AUTHENTICATION_METHODS has to list 'PROGRAMMATIC_ACCESS_TOKEN', or PATs stop working entirely. Second, expiry is controlled by the policy. Tokens default to 15 days, and the ceiling is 365 days unless MAX_EXPIRY_IN_DAYS lowers it.
CREATE AUTHENTICATION POLICY my_authentication_policy
PAT_POLICY=(
MAX_EXPIRY_IN_DAYS=100
);Checkpoint 2 of 7· Check yourself
A human user (TYPE=PERSON) has no network policy, and the account uses default PAT settings. What happens?
For human users, generating a token doesn't require a network policy, but authenticating with it does. Only service agent users are exempt on both counts.
“the user must be subject to a network policy to authenticate with this token.”Source: docs.snowflake.com
Sources3
3.Rotating credentials without downtime
Rotate keys on your internal schedule. With named key pairs, generate a new pair and swap in the new public key. In-flight clients keep working on the old key during the grace period. Set EXPIRE_ROTATED_KEY_PAIR_AFTER_HOURS to change the period, where 0 expires the old key immediately.
Checkpoint 3 of 7· Fill the gap
Which keyword replaces the public key on an existing named key pair?
ALTER USER example_user ? KEY PAIR my_key PUBLIC_KEY = 'JERUEHtcve...';ROTATE swaps the public key and keeps the old one for the grace period. ADD registers a new named pair, and MODIFY changes the pair's other settings.
Source: docs.snowflake.comUsers set up the legacy way have two key slots, RSA_PUBLIC_KEY and RSA_PUBLIC_KEY_2. Load the new key into the unused slot and switch clients to the new private key. Snowflake matches whichever key is active. Then run ALTER USER example_user UNSET RSA_PUBLIC_KEY; to remove the old key.
For PATs, the default lifetime and the MAX_EXPIRY_IN_DAYS cap force regular replacement. A token can be revoked with ALTER USER … REMOVE PROGRAMMATIC ACCESS TOKEN. The SHOW USER PROGRAMMATIC ACCESS TOKENS output includes a rotated_to column alongside expires_at and status. These sources do not show the syntax of a dedicated PAT rotate command, so check the current command reference for it.
Passwords are credentials too. DESC USER shows PASSWORD_LAST_SET_TIME, the time the last non-NULL password was set. MUST_CHANGE_PASSWORD set to TRUE forces the user to change their password on next login. After a leaked-password detection, an administrator sends a reset link, and the new password must meet the account's password policies.
Checkpoint 4 of 7· Exam question
A data-ingestion service signs JWTs with an RSA key pair assigned to a TYPE = SERVICE user. Policy requires rotating the key with no failed logins. The current public key sits in RSA_PUBLIC_KEY. Which sequence achieves this?
Correct answer: B — Set the new public key in RSA_PUBLIC_KEY_2, move the service to the new private key, then run ALTER USER with UNSET RSA_PUBLIC_KEY to retire the old key.
- A. Incorrect: overwriting RSA_PUBLIC_KEY invalidates the old private key immediately, so the service fails until it is redeployed.
- B. Correct: a user can hold two public keys, so registering the new one in the free slot lets both private keys work during cutover; the old slot is then unset.
- C. Incorrect: the fingerprint is a read-only value derived from the registered key; it is not settable and creates no 24-hour grace period.
- D. Incorrect: unsetting the only key first leaves a window where no key authenticates, which is exactly the outage to avoid.
4.Secrets for authenticating to external APIs
Authentication also runs in the other direction, when Snowflake code calls an external service. Credentials for those calls belong in a secret, which is a schema-level object, rather than in code. Pick the secret's TYPE to match how the external API authenticates. OAuth secrets point at a security integration through API_AUTHENTICATION, and the integration holds the OAuth client configuration. A WORKLOAD_IDENTITY_FEDERATION secret is the type for workload identity federation, where Snowflake workloads authenticate to external services with Snowflake acting as the OIDC provider. Only roles granted READ on a secret may use an integration containing it in a UDF or procedure. How a secret is wired into an external access integration is covered in the external access lesson.
CREATE [ OR REPLACE ] SECRET [ IF NOT EXISTS ] <name>
TYPE = OAUTH2
API_AUTHENTICATION = <security_integration_name>
OAUTH_SCOPES = ( '<scope_1>' [ , '<scope_2>' ... ] )
[ COMMENT = '<string_literal>' ]| TYPE | Use it for | Key properties |
|---|---|---|
| OAUTH2 | OAuth client credentials or authorization code grant | API_AUTHENTICATION, OAUTH_SCOPES or OAUTH_REFRESH_TOKEN |
| PASSWORD | Basic authentication | USERNAME, PASSWORD |
| GENERIC_STRING | An arbitrary string such as an API key | SECRET_STRING |
| CLOUD_PROVIDER_TOKEN | Cloud provider tokens | API_AUTHENTICATION |
| SYMMETRIC_KEY | A generated symmetric key | ALGORITHM = GENERIC |
| WORKLOAD_IDENTITY_FEDERATION | Workload identity federation | COMMENT (optional) |
Checkpoint 5 of 7· Check yourself
An API uses OAuth with a refresh token from an authorization code grant. Which secret type stores it?
Both OAuth flows use TYPE = OAUTH2. The authorization-code variant stores OAUTH_REFRESH_TOKEN and its expiry, and refers to a security integration.
“OAuth with authorization code grant flow:”Source: docs.snowflake.com
5.Session policies and session monitoring
Authentication starts a session, and a session policy limits how long that session lasts. Snowflake sessions are independent of IdP sessions. If a Snowflake session expires while the IdP session is still active, the user can sign back in silently. A policy sets two limits: an idle timeout, and a maximum lifespan that ends the session even while it is in use. Each limit has separate properties for Snowsight and for programmatic clients:
| Property | Applies to | Default / range |
|---|---|---|
| SESSION_IDLE_TIMEOUT_MINS | Programmatic and Snowflake clients | Default 240 min; 5 min to 24 h |
| SESSION_UI_IDLE_TIMEOUT_MINS | Snowsight | Default 1080 min; 5 min to 24 h |
| SESSION_MAX_LIFESPAN_MINS | Programmatic and Snowflake clients | Default 0 (none); up to 43200 |
| SESSION_UI_MAX_LIFESPAN_MINS | Snowsight | Default 0 (none); up to 43200 |
You can set policies on the account and on individual users, and a user-level policy overrides the account one. When a session closes, its running queries are terminated shortly afterwards. To monitor sessions, query the SESSIONS view in ACCOUNT_USAGE, or open the Sessions tab under Governance & security » Network policies. The tab shows the user, start time, client driver, address and authentication method of each session.
Checkpoint 6 of 7· Check yourself
The account session policy sets a 60-minute idle timeout. A user-level policy on analyst_1 sets 30 minutes. Which applies to analyst_1?
Precedence is by level, not by strictness. A user-level session policy overrides the account policy, even when the user-level value is the looser one.
“If a user is associated with both an account and user-level session policy, the user-level session policy takes precedence.”Source: docs.snowflake.com
Sources6
6.Leaked password and malicious IP protection
Two built-in services defend sign-in without any setup. Leaked password protection is always on and cannot be disabled. It runs in the background and checks whether passwords found in external breach data still work. All user types are scanned. If a leaked password still authenticates, Snowflake unsets it, permanently rejects it for that user, and emails both the user and the administrator. The user can still sign in by other methods, such as SSO. To get a password back, they ask an administrator for a reset link, and the new password must meet the account's password policies. If the leaked password belongs to an administrator and no other administrator can reset it, that administrator must contact Snowflake Support.
Malicious IP Protection blocks sign-in attempts from a curated threat-intelligence list of IPv4 and IPv6 addresses. All categories are blocked by default:
| Category | Description |
|---|---|
| ANONYMOUS_VPN | Anonymous VPN services |
| ANONYMOUS_PROXIES | Anonymous proxy servers |
| MALICIOUS_BEHAVIOR | Known malware and behavior such as brute-force logins |
| TOR_EXITS | Tor exit nodes |
Blocked attempts appear in LOGIN_HISTORY with IS_SUCCESS = 'NO', ERROR_CODE 390422 and ERROR_MESSAGE 'INCOMING_REQUEST_BLOCKED'. Their login_details field shows the category, the risk classification and the result.
SELECT *
FROM SNOWFLAKE.ACCOUNT_USAGE.LOGIN_HISTORY
WHERE NOT is_success AND login_details IS NOT NULL
ORDER BY event_timestamp DESC;The risk classification, LOW or HIGH, is recorded in login_details for each blocked IP address, so read it there rather than assuming it from the category name. The sources do not list which categories are low or high. ACCOUNTADMIN can opt out of blocking for a category when the blocked IPs in it were classified as low-risk, either account-wide or for a single user, by calling SYSTEM$OPT_OUT_MALICIOUS_IP_PROTECTION_BY_CATEGORY. IPs classified as high-risk can't be opted out of. Passing '' re-enables blocking.
USE ROLE ACCOUNTADMIN;
SELECT SYSTEM$OPT_OUT_MALICIOUS_IP_PROTECTION_BY_CATEGORY('ANONYMOUS_VPN', 'JSMITH');Checkpoint 7 of 7· Check yourself
Sign-ins by one consultant were blocked in a low-risk category. You want to unblock only that consultant. What do you do?
The optional second argument limits the opt-out to one user. Without it, the opt-out applies to every user in the account.
“If no user is provided, the opt-out applies to all users in the account.”Source: docs.snowflake.com
Exam traps
Each one states something that sounds right. Open it to see what is actually true.
1.Lowering MAX_EXPIRY_IN_DAYS only affects tokens generated afterwards.Why is that wrong?
Existing tokens whose expiry exceeds the new maximum stop authenticating immediately.
Covered in Programmatic access tokens (PATs)
2.Calling the malicious-IP opt-out function again adds the new category to the existing opt-outs.Why is that wrong?
Each call replaces the previous one. To keep several categories opted out, list all of them in a single call.
Covered in Leaked password and malicious IP protection
3.A short idle timeout is enough to cap how long an actively used session stays open.Why is that wrong?
Idle timeout only ends inactive sessions. Capping an active session takes a maximum lifespan, which ends the session after a set duration regardless of activity.
Covered in Session policies and session monitoring
Practise it for real
Set up key-pair authentication for a test user, then rotate the key without downtime
1.Run: openssl genrsa 2048 | openssl pkcs8 -topk8 -v2 aes-256-cbc -inform PEM -out rsa_key.p8, then openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub
Why: Creates an AES-256-encrypted private key and derives its public key
You should see: rsa_key.p8 starts with BEGIN ENCRYPTED PRIVATE KEY and rsa_key.pub with BEGIN PUBLIC KEY
2.Run ALTER USER example_user ADD KEY PAIR my_key PUBLIC_KEY = '<key body without delimiters>'
Why: Registers a named key pair, which supports expiry and role restriction
You should see: SHOW USER KEY PAIRS lists my_key
3.Compare the RSA_PUBLIC_KEY_FP from DESC USER with: openssl rsa -pubin -in rsa_key.pub -outform DER | openssl dgst -sha256 -binary | openssl enc -base64
Why: Confirms Snowflake stored the key you generated
You should see: Both outputs match
4.Generate a second key pair and run ALTER USER example_user ROTATE KEY PAIR my_key PUBLIC_KEY = '<new key body>'
Why: Replaces the key while the old one stays valid for the grace period
You should see: Connections with either private key succeed until the 24-hour default grace period ends
Stuck? Get a nudge
If the fingerprints differ, check that you removed the BEGIN/END PUBLIC KEY lines before pasting the key.
Sources
Every claim above is drawn from one of these pages, quoted as it was written on the date shown.
- 1.
“This authentication method requires, as a minimum, a 2048-bit RSA key pair.”
↩︎ Key-pair authentication for programmatic clients“The passphrase is only used for protecting the private key and will never be sent to Snowflake.”
↩︎ Key-pair authentication for programmatic clients“This approach does not support role restriction or expiration.”
↩︎ Key-pair authentication for programmatic clients“The prior public key is retained for a configurable grace period so that in-flight clients can transition without downtime.”
↩︎ Rotating credentials without downtime“Snowflake also supports the RSA_PUBLIC_KEY and RSA_PUBLIC_KEY_2 properties on ALTER USER for associating up to 2 public keys with a user.”
↩︎ Rotating credentials without downtime“From the command line, generate the public key by referencing the private key.”
↩︎ Checkpoint“By default, the prior key remains valid for 24 hours.”
↩︎ Prediction - 2.https://docs.snowflake.com/en/guides-overview-secureOfficial docs
“Preferred authentication method for service-to-service workloads accessing Snowflake data.”
↩︎ Key-pair authentication for programmatic clients“Using workload identity federation so that Snowflake workloads can authenticate to external services, with Snowflake acting as the OIDC provider.”
↩︎ Key-pair authentication for programmatic clients“Configuring Snowflake to authenticate to external services.”
↩︎ Secrets for authenticating to external APIs - 3.
“You can require a role restriction for person users by setting REQUIRE_ROLE_RESTRICTION_FOR_PERSON_USERS to TRUE in the PAT_POLICY clause”
↩︎ Key-pair authentication for programmatic clients“you can only generate or use a token if the user is subject to a network policy.”
↩︎ Programmatic access tokens (PATs)“By default, a programmatic access token expires after 15 days.”
↩︎ Programmatic access tokens (PATs)“Users can’t generate and use programmatic access tokens unless you add 'PROGRAMMATIC_ACCESS_TOKEN' to the AUTHENTICATION_METHODS list.”
↩︎ Programmatic access tokens (PATs)“with expiration times that exceed the new maximum expiration time, attempts to authenticate with those tokens will fail.”
↩︎ Exam trap 1“the user must be subject to a network policy to authenticate with this token.”
↩︎ Checkpoint - 4.
“If TRUE, the user is forced to change their password on next login”
↩︎ Rotating credentials without downtime - 5.
“Creates a new secret in the current or specified schema or replaces an existing secret.”
↩︎ Secrets for authenticating to external APIs“TYPE = WORKLOAD_IDENTITY_FEDERATION”
↩︎ Secrets for authenticating to external APIs“OAuth with authorization code grant flow:”
↩︎ Checkpoint - 6.
“A session is independent of an identity provider (IdP) session.”
↩︎ Session policies and session monitoring“Query the SESSIONS view in the ACCOUNT USAGE schema of the shared SNOWFLAKE database to monitor session usage.”
↩︎ Session policies and session monitoring“A session policy can also enforce a maximum session lifespan, which ends the session after a set duration regardless of activity.”
↩︎ Exam trap 3“If a user is associated with both an account and user-level session policy, the user-level session policy takes precedence.”
↩︎ Checkpoint - 7.
“Snowflake disables the leaked password by unsetting the password for the user”
↩︎ Leaked password and malicious IP protection“the user cannot authenticate using their password, but the user can use other methods of authentication, such as SSO, if available.”
↩︎ Leaked password and malicious IP protection“If no other administrator is available to reset the password of another administrator, then the administrator must contact Snowflake Support.”
↩︎ Leaked password and malicious IP protection - 8.
“You can’t opt out of blocking IP addresses that are categorized as high-risk.”
↩︎ Leaked password and malicious IP protection - 9.https://docs.snowflake.com/en/sql-reference/functions/system_opt_out_malicious_ip_protection_by_categoryOfficial docs
“Find rows with IS_SUCCESS = 'NO', ERROR_CODE = 390422, and ERROR_MESSAGE = 'INCOMING_REQUEST_BLOCKED'.”
↩︎ Leaked password and malicious IP protection“Only account administrators, which are users with the ACCOUNTADMIN role, can execute this function.”
↩︎ Leaked password and malicious IP protection“Each call of this function overwrites results of the previous call.”
↩︎ Exam trap 2“If no user is provided, the opt-out applies to all users in the account.”
↩︎ Checkpoint