Snowflake access control & privilege security checks
Admin roles, standing privileges, permission scopes and policy enforcement — the settings that decide how much damage one compromised account can do.
On Snowflake, Black Cat runs 11 checks in this area on every scan. Each one below lists its severity, how to fix it, and the compliance controls it satisfies where a control applies. See what access the Snowflake connector needs.
Checks (11)
severity: high Password Only Auth fix difficulty: medium #
Replace password-only authentication with MFA or key pair authentication
- Connect to Snowflake as ACCOUNTADMIN or SECURITYADMIN
- For human users, enforce MFA via authentication policy — run: ALTER USER <username> SET AUTHENTICATION POLICY require_mfa;
- For service accounts, configure key pair authentication — generate an RSA key pair and run: ALTER USER <username> SET RSA_PUBLIC_KEY = '<public_key>';
- Optionally disable password for service accounts: ALTER USER <username> SET DISABLE_MFA = TRUE; and remove password access
- Verify the update: SHOW USERS LIKE '<username>';
- Confirm the user can authenticate with the new method before revoking password access
Satisfies: ISO 27001:2022 A.5.15 SOC 2 Type II CC6.1 CIS Controls v8 CIS-06.1 NIST CSF 2.0 PR.AA-05 GDPR (SaaS Security) GDPR-32.1b.i HIPAA (SaaS Security) HIPAA-312.a NIS2 Directive NIS2-21.i.1 DORA (SaaS Security) DORA-9.2
severity: high Service Account Password Auth fix difficulty: medium #
Switch service account authentication from password to key pair and set user type to SERVICE
- Connect to Snowflake as ACCOUNTADMIN or USERADMIN
- Generate an RSA key pair (2048-bit or 4096-bit) for the service account
- Assign the public key to the user: ALTER USER <username> SET RSA_PUBLIC_KEY = '<public_key>';
- Set the user type to SERVICE to signal this is a non-human account: ALTER USER <username> SET TYPE = SERVICE;
- Remove or expire the password: ALTER USER <username> SET PASSWORD = '' MUST_CHANGE_PASSWORD = FALSE;
- Update the calling application to use key pair authentication and verify connectivity
Satisfies: ISO 27001:2022 A.5.15 SOC 2 Type II CC6.1 CIS Controls v8 CIS-06.1 NIST CSF 2.0 PR.AA-05 GDPR (SaaS Security) GDPR-25.2 HIPAA (SaaS Security) HIPAA-312.a NIS2 Directive NIS2-21.i.1 DORA (SaaS Security) DORA-9.2
severity: high ACCOUNTADMIN Default Role fix difficulty: easy #
Change the user's default role from ACCOUNTADMIN to a lower-privilege role
- Connect to Snowflake as ACCOUNTADMIN
- Identify an appropriate lower-privilege role for the user (e.g., SYSADMIN, a custom role)
- Run: ALTER USER <username> SET DEFAULT_ROLE = '<lower_privilege_role>';
- Verify the change: SHOW USERS LIKE '<username>';
- Confirm the user can still perform their work with the new default role
- The user can still USE ROLE ACCOUNTADMIN when explicitly needed
Satisfies: ISO 27001:2022 A.5.15 SOC 2 Type II CC6.1 CIS Controls v8 CIS-06.1 NIST CSF 2.0 PR.AA-05 GDPR (SaaS Security) GDPR-25.2 HIPAA (SaaS Security) HIPAA-312.a NIS2 Directive NIS2-21.i.1 DORA (SaaS Security) DORA-9.2
severity: high Excessive Admin Roles fix difficulty: medium #
Reduce the number of users with ACCOUNTADMIN or SYSADMIN roles to the minimum necessary
- Connect to Snowflake as ACCOUNTADMIN
- Review the current list of admin role holders: SHOW GRANTS OF ROLE ACCOUNTADMIN;
- For each user who does not require admin access, revoke the role: REVOKE ROLE ACCOUNTADMIN FROM USER <username>;
- Create custom roles with least-privilege permissions for users who need specific capabilities
- Assign the custom role: GRANT ROLE <custom_role> TO USER <username>;
- Document which users retain admin access and the business justification
Satisfies: ISO 27001:2022 A.5.15 SOC 2 Type II CC6.1 CIS Controls v8 CIS-06.1 NIST CSF 2.0 PR.AA-05 GDPR (SaaS Security) GDPR-25.2 HIPAA (SaaS Security) HIPAA-312.a NIS2 Directive NIS2-21.i.1 DORA (SaaS Security) DORA-9.2
severity: high No Separation Of Duties fix difficulty: medium #
Revoke conflicting admin roles so no single user holds both ACCOUNTADMIN and SYSADMIN or SECURITYADMIN
- Connect to Snowflake as ACCOUNTADMIN
- Identify users with conflicting role combinations: SHOW GRANTS TO USER <username>;
- Determine which role is appropriate for the user's primary function
- Revoke the conflicting role: REVOKE ROLE SYSADMIN FROM USER <username>; (or SECURITYADMIN as applicable)
- Create dedicated accounts for administrative tasks requiring elevated roles
- Verify the user's remaining roles: SHOW GRANTS TO USER <username>;
Satisfies: ISO 27001:2022 A.5.15 SOC 2 Type II CC6.1 CIS Controls v8 CIS-06.1 NIST CSF 2.0 PR.AA-05 GDPR (SaaS Security) GDPR-25.2 HIPAA (SaaS Security) HIPAA-312.a NIS2 Directive NIS2-21.i.1 DORA (SaaS Security) DORA-9.2
severity: high Disabled User With Active Grants fix difficulty: easy #
Revoke all role grants from disabled Snowflake user accounts
- Connect to Snowflake as ACCOUNTADMIN or SECURITYADMIN
- List all roles granted to the disabled user: SHOW GRANTS TO USER <username>;
- Revoke each role: REVOKE ROLE <role_name> FROM USER <username>;
- Repeat for all granted roles identified in the previous step
- Verify no roles remain: SHOW GRANTS TO USER <username>;
- Consider dropping the user if the account is no longer needed: DROP USER <username>;
Satisfies: ISO 27001:2022 A.5.15 SOC 2 Type II CC6.1 CIS Controls v8 CIS-06.1 NIST CSF 2.0 PR.AA-05 GDPR (SaaS Security) GDPR-25.2 HIPAA (SaaS Security) HIPAA-308.a3 NIS2 Directive NIS2-21.i.1 DORA (SaaS Security) DORA-9.2
severity: medium Dormant User fix difficulty: easy #
Disable or remove dormant user accounts that have been inactive for 90+ days
- Connect to Snowflake as ACCOUNTADMIN or USERADMIN
- Review dormant users: SELECT name, last_success_login, disabled FROM snowflake.account_usage.users WHERE last_success_login < DATEADD(day, -90, CURRENT_TIMESTAMP);
- Contact the user or their manager to confirm whether access is still needed
- Disable the account: ALTER USER <username> SET DISABLED = TRUE;
- If the user is confirmed no longer needed, drop the account: DROP USER <username>;
- Review and revoke any object ownership or grants as needed
Satisfies: ISO 27001:2022 A.5.15 SOC 2 Type II CC6.1 CIS Controls v8 CIS-06.1 NIST CSF 2.0 PR.AA-05 GDPR (SaaS Security) GDPR-25.2 HIPAA (SaaS Security) HIPAA-308.a3 NIS2 Directive NIS2-21.i.1 DORA (SaaS Security) DORA-9.2
severity: medium User Not Disabled fix difficulty: easy #
Disable long-inactive user accounts that have not logged in for 180+ days
- Connect to Snowflake as ACCOUNTADMIN or USERADMIN
- Identify inactive users: SELECT name, last_success_login FROM snowflake.account_usage.users WHERE last_success_login < DATEADD(day, -180, CURRENT_TIMESTAMP) AND disabled = FALSE;
- Verify with the user's team that the account is no longer needed
- Disable the account: ALTER USER <username> SET DISABLED = TRUE;
- Revoke active role grants: REVOKE ROLE <role> FROM USER <username>;
- Schedule a follow-up to drop the user if not re-enabled within 30 days
Satisfies: ISO 27001:2022 A.5.15 SOC 2 Type II CC6.1 CIS Controls v8 CIS-06.1 NIST CSF 2.0 PR.AA-05 GDPR (SaaS Security) GDPR-25.2 HIPAA (SaaS Security) HIPAA-308.a3 NIS2 Directive NIS2-21.i.1 DORA (SaaS Security) DORA-9.2
severity: high ACCOUNTADMIN Excessive Grants fix difficulty: medium #
Reduce the number of users granted the ACCOUNTADMIN role to three or fewer
- Connect to Snowflake as ACCOUNTADMIN
- List all ACCOUNTADMIN grantees: SHOW GRANTS OF ROLE ACCOUNTADMIN;
- Identify users who do not require full account administrator access
- Create a least-privilege role for each user's actual needs and grant appropriate privileges
- Revoke ACCOUNTADMIN from non-essential users: REVOKE ROLE ACCOUNTADMIN FROM USER <username>;
- Retain ACCOUNTADMIN only for break-glass emergency accounts and at most 2–3 designated administrators
Satisfies: ISO 27001:2022 A.5.15 SOC 2 Type II CC6.1 CIS Controls v8 CIS-06.1 NIST CSF 2.0 PR.AA-05 GDPR (SaaS Security) GDPR-25.2 HIPAA (SaaS Security) HIPAA-312.a NIS2 Directive NIS2-21.i.1 DORA (SaaS Security) DORA-9.2
severity: medium Weak Password Policy fix difficulty: easy #
Strengthen the Snowflake password policy to enforce minimum length, expiry, and lockout requirements
- Connect to Snowflake as ACCOUNTADMIN or SECURITYADMIN
- Identify the password policy: SHOW PASSWORD POLICIES;
- Update the policy with stronger settings: ALTER PASSWORD POLICY <policy_name> SET PASSWORD_MIN_LENGTH = 14 PASSWORD_MAX_AGE_DAYS = 90 PASSWORD_MAX_RETRIES = 5 PASSWORD_LOCKOUT_TIME_MINS = 15;
- Verify the updated policy: DESCRIBE PASSWORD POLICY <policy_name>;
- Ensure the policy is attached to the account or the appropriate users
- Notify users of the new requirements and set MUST_CHANGE_PASSWORD for users with non-compliant passwords
Satisfies: ISO 27001:2022 A.5.15 SOC 2 Type II CC6.1 CIS Controls v8 CIS-06.1 NIST CSF 2.0 PR.AA-05 GDPR (SaaS Security) GDPR-32.1b.i HIPAA (SaaS Security) HIPAA-312.d NIS2 Directive NIS2-21.i.1 DORA (SaaS Security) DORA-9.2
severity: high OAuth Integration Permissive fix difficulty: medium #
Restrict the OAuth security integration by attaching a network policy and scoping allowed roles
- Connect to Snowflake as ACCOUNTADMIN or SECURITYADMIN
- Review the current OAuth integration settings: DESCRIBE INTEGRATION <integration_name>;
- Create or identify a restrictive network policy for the integration
- Attach the network policy: ALTER SECURITY INTEGRATION <integration_name> SET NETWORK_POLICY = '<policy_name>';
- Restrict the OAuth allowed roles if applicable: ALTER SECURITY INTEGRATION <integration_name> SET OAUTH_ALLOWED_AUTHORIZATION_ROLE = '<role>';
- Verify: DESCRIBE INTEGRATION <integration_name>; and test OAuth flows from an authorized IP
Satisfies: ISO 27001:2022 A.5.15 SOC 2 Type II CC6.1 CIS Controls v8 CIS-06.1 NIST CSF 2.0 PR.AA-05 GDPR (SaaS Security) GDPR-28.1 HIPAA (SaaS Security) HIPAA-308.a4 HIPAA (SaaS Security) HIPAA-314.a NIS2 Directive NIS2-21.i.1 DORA (SaaS Security) DORA-9.2