Snowflake Security Hardening: Network Policies, MFA, Privilege Governance, and Data Masking

Retool's new app builder is where AI-generated code ships safely
Building apps with AI is easy. Getting them to production safely is another story.
A default Snowflake account has ACCOUNTADMIN-capable users with password-only authentication, no network policy restricting access, all users in the PUBLIC role able to query shared objects, and no column-level masking on sensitive columns. These defaults are convenient for a trial account and dangerous for production. The hardening steps below address each of these in the order of risk reduction.
Authentication: MFA Enforcement via SSO
Snowflake supports password-only auth, MFA, and federated SSO (SAML 2.0, OAuth). For production accounts, federated SSO with an identity provider is the recommended authentication model: MFA is enforced at the IdP, password reset is governed by the IdP, and there is no Snowflake-local credential to phish.
Configure SSO via your IdP (Okta, Entra ID, Google)
In Snowflake Admin Console: Account > Authentication Policies > configure SAML 2.0 integration with your IdP. In Okta: add Snowflake from the integration catalog, configure the SAML assertion to include the Snowflake user's login_name as the NameID. Once SSO is configured, create an Authentication Policy requiring SSO for all user types: CREATE AUTHENTICATION POLICY sso_required_policy AUTHENTICATION_METHODS = ('SAML') CLIENT_TYPES = ('SNOWFLAKE_UI', 'DRIVERS', 'ODBC', 'JDBC', 'PYTHON_DRIVER'); ALTER ACCOUNT SET AUTHENTICATION POLICY sso_required_policy.
Enforce MFA for users who must use Snowflake-native auth
For service accounts that cannot use SSO, enforce MFA at the account level: ALTER USER [service_user] SET MINS_TO_BYPASS_MFA = 0. Require MFA enrollment: CREATE AUTHENTICATION POLICY mfa_required_policy MULTI_FACTOR_AUTHENTICATION_FORCE = REQUIRED; ALTER USER [human_user] SET AUTHENTICATION POLICY mfa_required_policy. Verify MFA enrollment status: SELECT name, has_mfa FROM SNOWFLAKE.ACCOUNT_USAGE.USERS WHERE has_mfa = FALSE AND disabled = FALSE.
Lock down ACCOUNTADMIN to break-glass only
Audit ACCOUNTADMIN holders: SHOW GRANTS OF ROLE ACCOUNTADMIN. Revoke from all accounts that do not require it: REVOKE ROLE ACCOUNTADMIN FROM USER [user]. Create a dedicated break-glass account with ACCOUNTADMIN for emergency use, store its credentials in a PAM vault with session recording enabled, and alert on every ACCOUNTADMIN login. The break-glass account should require explicit PAM checkout and generate a PagerDuty alert.
Rotate service account credentials with secrets manager integration
Service account passwords in Snowflake should be stored in and rotated by AWS Secrets Manager or HashiCorp Vault. Use Vault's Snowflake dynamic secrets to generate short-lived credentials per request: vault read database/creds/snowflake-role returns a temporary username/password valid for 1 hour. This eliminates static service account passwords from application configuration files and forces rotation.
Network Policies: Restricting Access to Known IPs
Snowflake network policies restrict which IP addresses can connect to the account. Without a network policy, any IP address with valid credentials can connect: including an attacker who has stolen credentials.
Create account-level network policies
Identify all IP ranges that legitimately connect to Snowflake: application server egress IPs, analyst workstation ranges (or VPN egress), ETL tool egress IPs, Snowflake's own IP ranges (for internal traffic). CREATE NETWORK POLICY prod_access_policy ALLOWED_IP_LIST = ('10.0.1.0/24', '203.0.113.50/32', '198.51.100.0/24'); ALTER ACCOUNT SET NETWORK_POLICY = prod_access_policy. Test before applying: ALTER NETWORK POLICY prod_access_policy VALIDATE.
Create user-level network policies for privileged accounts
Apply stricter network policies to ACCOUNTADMIN and SECURITYADMIN holders: ALTER USER [admin_user] SET NETWORK_POLICY = admin_only_policy where admin_only_policy allows only your PAM solution's egress IP. This means even if an admin's credentials are stolen, they can only be used from the PAM system.
Block access from Snowflake's web UI for service accounts
Service accounts should never log in via the Snowflake web UI: they authenticate only via application code or ETL tools. Restrict service accounts to driver access: ALTER USER [service_user] SET DEFAULT_ROLE = app_role; ALTER AUTHENTICATION POLICY driver_only_policy AUTHENTICATION_METHODS = ('PASSWORD') CLIENT_TYPES = ('DRIVERS', 'ODBC', 'JDBC', 'PYTHON_DRIVER'); ALTER USER [service_user] SET AUTHENTICATION POLICY driver_only_policy.
Briefings like this, every morning before 9am.
Threat intel, active CVEs, and campaign alerts, distilled for practitioners. 50,000+ subscribers. No noise.
Role Hierarchy and Least Privilege
Snowflake's role system uses inheritance: granting role A to role B means everything A can do, B can also do. The default PUBLIC role is granted to every user, so any object granted to PUBLIC is accessible to every user in the account.
Audit and clean up PUBLIC role grants
Review what PUBLIC can access: SHOW GRANTS TO ROLE PUBLIC. Revoke grants to PUBLIC that are not intended to be universal: REVOKE SELECT ON SCHEMA [sensitive_schema] FROM ROLE PUBLIC. Most production databases should have nothing granted directly to PUBLIC: create specific roles for each consumer group and grant database and schema access only to those roles.
Design a functional role hierarchy
Create functional roles (reader, writer, transformer, admin) scoped to specific databases and schemas, then create user roles that inherit functional roles: GRANT ROLE analytics_reader TO ROLE data_analyst_user_role. Apply the user role to users: GRANT ROLE data_analyst_user_role TO USER [analyst]. This separation between what-a-role-can-do (functional) and who-gets-it (user role) makes privilege reviews auditable.
Enforce least-privilege on warehouse access
Snowflake virtual warehouses consume compute credits when running. Restrict USAGE on warehouses to the roles that need them: GRANT USAGE ON WAREHOUSE analytics_wh TO ROLE analytics_reader. Service accounts should have USAGE only on the warehouse sized for their workload, not on large warehouses intended for ad-hoc analyst queries.
Review access with ACCOUNT_USAGE.GRANTS_TO_USERS
Quarterly privilege review: SELECT grantee_name, role, granted_by, created_on FROM SNOWFLAKE.ACCOUNT_USAGE.GRANTS_TO_USERS WHERE deleted_on IS NULL ORDER BY created_on DESC. This shows all current role grants with who granted them and when. Compare against the expected state from your IaC (Terraform or Permifrost) to identify drift.
Column-Level Security with Data Masking Policies
Snowflake Dynamic Data Masking applies masking policies at the column level, replacing sensitive data in query results based on the calling role without requiring application changes.
Create a masking policy for PII columns
CREATE MASKING POLICY mask_ssn AS (val STRING) RETURNS STRING -> CASE WHEN CURRENT_ROLE() IN ('pii_reader', 'ACCOUNTADMIN') THEN val ELSE '***-**-' || RIGHT(val, 4) END; ALTER TABLE customers MODIFY COLUMN ssn SET MASKING POLICY mask_ssn. Analysts without the pii_reader role see the last 4 digits only; analysts with pii_reader see the full value. The masking policy executes at query time: no data is physically altered.
Use Row Access Policies for multi-tenant data isolation
CREATE ROW ACCESS POLICY region_isolation AS (region_id VARCHAR) RETURNS BOOLEAN -> CURRENT_ROLE() = 'global_admin' OR region_id = CURRENT_USER(). ALTER TABLE sales_data ADD ROW ACCESS POLICY region_isolation ON (region_id). Row access policies restrict which rows a user can see based on their role or user attributes: useful for multi-tenant data where each client's data must be isolated.
Apply masking policies via tags for automated coverage
Use Snowflake object tags to apply masking policies to all tagged columns automatically: CREATE TAG pii_column; CREATE MASKING POLICY pii_mask AS ...; ALTER TAG pii_column SET MASKING POLICY pii_mask. Now any column tagged with pii_column automatically receives the masking policy. This scales masking across hundreds of tables without individually altering each column.
Audit Logging and SIEM Integration
Snowflake's ACCOUNT_USAGE schema and ACCESS_HISTORY view provide comprehensive audit data. Forward this to your SIEM for alerting on suspicious access patterns.
Query ACCESS_HISTORY for PII column access
SELECT query_start_time, user_name, role_name, base_objects_accessed FROM SNOWFLAKE.ACCOUNT_USAGE.ACCESS_HISTORY WHERE ARRAY_CONTAINS('SSN'::VARIANT, base_objects_accessed) AND query_start_time > DATEADD('day', -7, CURRENT_TIMESTAMP()) ORDER BY query_start_time DESC. This shows every query that accessed the SSN column in the last 7 days, including the user and role. Schedule this as a daily export to your SIEM.
Alert on ACCOUNTADMIN login events
SELECT event_timestamp, user_name, client_ip, reported_client_type FROM SNOWFLAKE.ACCOUNT_USAGE.LOGIN_HISTORY WHERE ROLES_USED LIKE '%ACCOUNTADMIN%' AND event_timestamp > DATEADD('hour', -1, CURRENT_TIMESTAMP()). Send this query result to your SIEM on a 15-minute schedule and alert on any non-zero result. ACCOUNTADMIN interactive logins should be rare and always require immediate review.
Forward Snowflake login and query events to your SIEM
Use Snowflake's Telemetry integration or a SIEM connector (Splunk Add-on for Snowflake, Sentinel Snowflake connector) to stream ACCOUNT_USAGE events to your SIEM in near-real-time. At minimum, stream LOGIN_HISTORY (authentication events), QUERY_HISTORY (query execution including query text), and GRANTS_TO_USERS (privilege changes). These three tables cover the primary security investigation needs.
The bottom line
Snowflake's three highest-risk default configurations are: ACCOUNTADMIN-privileged users with password-only auth, no network policy restricting access to known IPs, and PII columns unmasked to all analysts. Fixing all three requires under two hours of work and zero application changes. Start with the network policy (fastest to implement, immediately limits attack surface), then enforce SSO/MFA via authentication policy, then build the least-privilege role hierarchy. Data masking and audit-to-SIEM are the next tier and deliver the compliance and monitoring posture required for SOC 2 and data privacy regulation evidence.
Frequently asked questions
How does Snowflake authentication work and what are the options?
Snowflake supports three authentication modes: (1) Password: Snowflake-managed username/password, weakest option; (2) Multi-Factor Authentication: Snowflake's built-in MFA using TOTP (Duo-based), requires each user to enroll; (3) Federated SSO: SAML 2.0 or OAuth integration with an external IdP (Okta, Entra ID, Google Workspace), which delegates authentication entirely to the IdP and benefits from the IdP's MFA enforcement, password policies, and session management. The recommended production configuration is federated SSO for all human users and short-lived token-based auth (key pair or OAuth) for service accounts.
What is the Snowflake network policy and how do I test it before applying?
A Snowflake network policy is an allowlist of IP ranges that can connect to the account (or to a specific user). Connections from IPs outside the allowlist are rejected with an authentication error. To test before applying account-wide: CREATE NETWORK POLICY test_policy ALLOWED_IP_LIST = ('your_ip/32'); ALTER USER [your_user] SET NETWORK_POLICY = test_policy. Log out and back in to confirm your IP is allowed. Once verified, apply to additional users before the account-wide application. The account-wide policy takes effect for all new sessions; existing sessions are unaffected until they reconnect.
How does Snowflake's role hierarchy differ from traditional database RBAC?
Snowflake uses a hierarchical role model where roles can inherit other roles. Granting role A to role B means role B has all of role A's privileges. There is no concept of 'deny': access is additive through inheritance. The four system roles (ACCOUNTADMIN, SECURITYADMIN, SYSADMIN, PUBLIC) form the top of the hierarchy. ACCOUNTADMIN owns SECURITYADMIN and SYSADMIN. Every user inherits the PUBLIC role. This means any privilege granted to PUBLIC is available to every user: the single most common misconfiguration is accidentally granting access to sensitive objects to the PUBLIC role.
What does Snowflake Dynamic Data Masking actually mask: the stored data or the query result?
Dynamic Data Masking applies at query time: the underlying stored data is unchanged. When a user runs SELECT ssn FROM customers, Snowflake evaluates the masking policy associated with the ssn column, determines the caller's current role, and applies the masking function to the result set before returning it. The full SSN remains stored in Snowflake's encrypted storage. This means masking policies can be updated without migrating data, and privileged roles can still query unmasked values for legitimate purposes. TDE (Snowflake's storage encryption) protects the stored data from physical access; masking protects query access from insufficient-privilege users.
How do I govern service account credentials in Snowflake securely?
Three approaches in order of security: (1) Key pair authentication: generate an RSA key pair, assign the public key to the Snowflake user (ALTER USER [svc_user] SET RSA_PUBLIC_KEY='...'), and store the private key in your secrets manager; application authenticates with the private key rather than a password; (2) OAuth client credentials: use Snowflake's OAuth server to issue access tokens for service clients; tokens have configurable expiration; (3) Dynamic secrets via Vault: HashiCorp Vault's database secrets engine creates a temporary Snowflake login per request with a TTL matching the job's runtime. Avoid static passwords stored in environment variables or configuration files for any production service account.
Does Snowflake have a native SIEM integration or do I need a third-party tool?
Snowflake does not have a native push integration to SIEMs, but provides the ACCOUNT_USAGE schema (with 45-minute data latency) and the INFORMATION_SCHEMA (real-time, current account only) for querying audit data. SIEM integrations are available via: Splunk Add-on for Snowflake (queries ACCOUNT_USAGE on a scheduled basis and indexes events into Splunk), Microsoft Sentinel Snowflake connector (Logic App that polls and pushes to Sentinel), and Panther Security (direct streaming integration with zero-latency). For teams without a native connector, a Lambda/Cloud Function that queries ACCOUNT_USAGE every 5 minutes and ships results to your SIEM via HTTP endpoint is a viable alternative.
What Snowflake configurations does SOC 2 or HIPAA typically require?
For SOC 2 Type II: MFA enforcement for all human users (CC6.1), network policies restricting access to known sources (CC6.6), role-based access control with access reviews (CC6.3), audit logging to an external SIEM (CC7.2), data masking for sensitive columns (CC6.7). For HIPAA: encryption in transit (TLS: Snowflake enforces this by default) and at rest (Snowflake encrypts all storage by default using AES-256), access controls with audit trails for ePHI access (ACCOUNT_USAGE.ACCESS_HISTORY serves this), and a Business Associate Agreement (BAA) with Snowflake (available for Business Critical and Enterprise tiers). Most HIPAA-covered Snowflake deployments also require the Enterprise tier minimum for tri-secret secure (customer-managed encryption keys).
Sources & references
Free resources
Critical CVE Reference Card 2025–2026
25 actively exploited vulnerabilities with CVSS scores, exploit status, and patch availability. Print it, pin it, share it with your SOC team.
Ransomware Incident Response Playbook
Step-by-step 24-hour IR checklist covering detection, containment, eradication, and recovery. Built for SOC teams, IR leads, and CISOs.
Get threat intel before your inbox does.
50,000+ security professionals read Decryption Digest for early warnings on zero-days, ransomware, and nation-state campaigns. Free, daily, no spam.
Unsubscribe anytime. We never sell your data.

Founder & Cybersecurity Evangelist, Decryption Digest
Cybersecurity professional with expertise in threat intelligence, vulnerability research, and enterprise security. Covers zero-days, ransomware, and nation-state operations for 50,000+ security professionals every morning.
Win a $2,495 Black Hat pass.
Full-access to Black Hat USA 2026 in Las Vegas. Subscribe free to enter.
