# Snowflake security audit - SF-LAT-20260427-004934
Account: `titan-snowflake-prod-20260427`  
Generated: 2026-04-27T00:48:36+00:00  
Total findings: **54**

| Severity | Count |
| --- | --- |
| critical | 9 |
| high | 31 |
| medium | 14 |
| low | 0 |

## Findings
### Users without MFA enrolled (critical)
- Resource: `TITANBAD_STALE`
- FID: `SF-13DB9B6D`
- Citation: HIPAA 164.312(d) Person or Entity Authentication; CIS Snowflake 1.4
- Recommendation: Enroll all human users in Duo or Snowflake-managed MFA. Service users should use RSA key-pair auth, not password+MFA.
- Fix command: `ALTER USER <name> SET MINS_TO_BYPASS_MFA = 0; -- then have user enroll in MFA`

### Users without MFA enrolled (critical)
- Resource: `TITANBAD_NOMFA2`
- FID: `SF-6E0E4AA1`
- Citation: HIPAA 164.312(d) Person or Entity Authentication; CIS Snowflake 1.4
- Recommendation: Enroll all human users in Duo or Snowflake-managed MFA. Service users should use RSA key-pair auth, not password+MFA.
- Fix command: `ALTER USER <name> SET MINS_TO_BYPASS_MFA = 0; -- then have user enroll in MFA`

### Users without MFA enrolled (critical)
- Resource: `TITANBAD_NOMFA1`
- FID: `SF-FB127BCB`
- Citation: HIPAA 164.312(d) Person or Entity Authentication; CIS Snowflake 1.4
- Recommendation: Enroll all human users in Duo or Snowflake-managed MFA. Service users should use RSA key-pair auth, not password+MFA.
- Fix command: `ALTER USER <name> SET MINS_TO_BYPASS_MFA = 0; -- then have user enroll in MFA`

### Users without MFA enrolled (critical)
- Resource: `TITANADMIN`
- FID: `SF-D2F50300`
- Citation: HIPAA 164.312(d) Person or Entity Authentication; CIS Snowflake 1.4
- Recommendation: Enroll all human users in Duo or Snowflake-managed MFA. Service users should use RSA key-pair auth, not password+MFA.
- Fix command: `ALTER USER <name> SET MINS_TO_BYPASS_MFA = 0; -- then have user enroll in MFA`

### Users without MFA enrolled (critical)
- Resource: `SVC_TITANBAD_BROAD`
- FID: `SF-759FEE07`
- Citation: HIPAA 164.312(d) Person or Entity Authentication; CIS Snowflake 1.4
- Recommendation: Enroll all human users in Duo or Snowflake-managed MFA. Service users should use RSA key-pair auth, not password+MFA.
- Fix command: `ALTER USER <name> SET MINS_TO_BYPASS_MFA = 0; -- then have user enroll in MFA`

### Users authenticating with password instead of RSA key (high)
- Resource: `TITANADMIN`
- FID: `SF-77DEBC9D`
- Citation: CIS Snowflake 1.6; NIST 800-53 IA-5
- Recommendation: Move service accounts to RSA key-pair authentication. Passwords are weaker, harder to rotate, and not auditable to per-call granularity.
- Fix command: `ALTER USER <name> SET RSA_PUBLIC_KEY='<key>'; ALTER USER <name> UNSET PASSWORD;`

### Users authenticating with password instead of RSA key (high)
- Resource: `TITANBAD_NOMFA1`
- FID: `SF-DEF9323B`
- Citation: CIS Snowflake 1.6; NIST 800-53 IA-5
- Recommendation: Move service accounts to RSA key-pair authentication. Passwords are weaker, harder to rotate, and not auditable to per-call granularity.
- Fix command: `ALTER USER <name> SET RSA_PUBLIC_KEY='<key>'; ALTER USER <name> UNSET PASSWORD;`

### Users authenticating with password instead of RSA key (high)
- Resource: `TITANBAD_NOMFA2`
- FID: `SF-5A27C20A`
- Citation: CIS Snowflake 1.6; NIST 800-53 IA-5
- Recommendation: Move service accounts to RSA key-pair authentication. Passwords are weaker, harder to rotate, and not auditable to per-call granularity.
- Fix command: `ALTER USER <name> SET RSA_PUBLIC_KEY='<key>'; ALTER USER <name> UNSET PASSWORD;`

### Users authenticating with password instead of RSA key (high)
- Resource: `TITANBAD_STALE`
- FID: `SF-166BFB83`
- Citation: CIS Snowflake 1.6; NIST 800-53 IA-5
- Recommendation: Move service accounts to RSA key-pair authentication. Passwords are weaker, harder to rotate, and not auditable to per-call granularity.
- Fix command: `ALTER USER <name> SET RSA_PUBLIC_KEY='<key>'; ALTER USER <name> UNSET PASSWORD;`

### Users authenticating with password instead of RSA key (high)
- Resource: `SVC_TITANBAD_BROAD`
- FID: `SF-B2828195`
- Citation: CIS Snowflake 1.6; NIST 800-53 IA-5
- Recommendation: Move service accounts to RSA key-pair authentication. Passwords are weaker, harder to rotate, and not auditable to per-call granularity.
- Fix command: `ALTER USER <name> SET RSA_PUBLIC_KEY='<key>'; ALTER USER <name> UNSET PASSWORD;`

### Stale users (no login in 90 days) (medium)
- Resource: `SVC_TITANBAD_BROAD`
- FID: `SF-92328D32`
- Citation: CIS Snowflake 1.10; NIST 800-53 AC-2(3)
- Recommendation: Disable users with no login in 90 days. Service accounts that legitimately do not log in should be tagged so they are not flagged.
- Fix command: `ALTER USER <name> SET DISABLED = TRUE;`

### Stale users (no login in 90 days) (medium)
- Resource: `TITANBAD_NOMFA2`
- FID: `SF-34530C97`
- Citation: CIS Snowflake 1.10; NIST 800-53 AC-2(3)
- Recommendation: Disable users with no login in 90 days. Service accounts that legitimately do not log in should be tagged so they are not flagged.
- Fix command: `ALTER USER <name> SET DISABLED = TRUE;`

### Stale users (no login in 90 days) (medium)
- Resource: `TITANBAD_STALE`
- FID: `SF-05C9A247`
- Citation: CIS Snowflake 1.10; NIST 800-53 AC-2(3)
- Recommendation: Disable users with no login in 90 days. Service accounts that legitimately do not log in should be tagged so they are not flagged.
- Fix command: `ALTER USER <name> SET DISABLED = TRUE;`

### Stale users (no login in 90 days) (medium)
- Resource: `TITANBAD_NOMFA1`
- FID: `SF-722324A5`
- Citation: CIS Snowflake 1.10; NIST 800-53 AC-2(3)
- Recommendation: Disable users with no login in 90 days. Service accounts that legitimately do not log in should be tagged so they are not flagged.
- Fix command: `ALTER USER <name> SET DISABLED = TRUE;`

### Account-level network policy not configured (high)
- Resource: `account`
- FID: `SF-15BFB696`
- Citation: HIPAA 164.312(e)(1) Transmission Security; CIS Snowflake 1.13
- Recommendation: Apply at least one account-level network policy that restricts logins to corporate egress IPs and approved cloud IP ranges.
- Fix command: `CREATE NETWORK POLICY corp_only ALLOWED_IP_LIST=('1.2.3.4/32', ...); ALTER ACCOUNT SET NETWORK_POLICY = corp_only;`

### Likely-PHI / PII columns without a masking policy (high)
- Resource: `TITAN_DEMO.PUBLIC_BAD.PATIENT_PHI.PATIENT_ID`
- FID: `SF-C42A3A46`
- Citation: HIPAA 164.502 Uses and Disclosures of PHI; CIS Snowflake 4.5
- Recommendation: Apply a masking policy on every column whose name suggests PHI / PII so non-clinician roles see hashed or redacted values. Continuous re-scan flags new columns as schemas evolve.
- Fix command: `CREATE MASKING POLICY phi_redact AS (val STRING) RETURNS STRING -> CASE WHEN IS_ROLE_IN_SESSION('CLINICIAN_RO') THEN val ELSE 'REDACTED' END; ALTER TABLE <t> MODIFY COLUMN <c> SET MASKING POLICY phi_redact;`

### Likely-PHI / PII columns without a masking policy (high)
- Resource: `TITAN_DEMO.PUBLIC_BAD.MEMBER_ACCOUNT.MEMBER_PII_SSN`
- FID: `SF-326237BE`
- Citation: HIPAA 164.502 Uses and Disclosures of PHI; CIS Snowflake 4.5
- Recommendation: Apply a masking policy on every column whose name suggests PHI / PII so non-clinician roles see hashed or redacted values. Continuous re-scan flags new columns as schemas evolve.
- Fix command: `CREATE MASKING POLICY phi_redact AS (val STRING) RETURNS STRING -> CASE WHEN IS_ROLE_IN_SESSION('CLINICIAN_RO') THEN val ELSE 'REDACTED' END; ALTER TABLE <t> MODIFY COLUMN <c> SET MASKING POLICY phi_redact;`

### Likely-PHI / PII columns without a masking policy (high)
- Resource: `TITAN_DEMO.PUBLIC_BAD.PATIENT_PHI.SSN`
- FID: `SF-6BEEAEAD`
- Citation: HIPAA 164.502 Uses and Disclosures of PHI; CIS Snowflake 4.5
- Recommendation: Apply a masking policy on every column whose name suggests PHI / PII so non-clinician roles see hashed or redacted values. Continuous re-scan flags new columns as schemas evolve.
- Fix command: `CREATE MASKING POLICY phi_redact AS (val STRING) RETURNS STRING -> CASE WHEN IS_ROLE_IN_SESSION('CLINICIAN_RO') THEN val ELSE 'REDACTED' END; ALTER TABLE <t> MODIFY COLUMN <c> SET MASKING POLICY phi_redact;`

### Likely-PHI / PII columns without a masking policy (high)
- Resource: `TITAN_DEMO.PUBLIC_BAD.PATIENT_PHI.MEMBER_ID`
- FID: `SF-90CA4264`
- Citation: HIPAA 164.502 Uses and Disclosures of PHI; CIS Snowflake 4.5
- Recommendation: Apply a masking policy on every column whose name suggests PHI / PII so non-clinician roles see hashed or redacted values. Continuous re-scan flags new columns as schemas evolve.
- Fix command: `CREATE MASKING POLICY phi_redact AS (val STRING) RETURNS STRING -> CASE WHEN IS_ROLE_IN_SESSION('CLINICIAN_RO') THEN val ELSE 'REDACTED' END; ALTER TABLE <t> MODIFY COLUMN <c> SET MASKING POLICY phi_redact;`

### Likely-PHI / PII columns without a masking policy (high)
- Resource: `TITAN_DEMO.PUBLIC_BAD.PATIENT_PHI.DOB`
- FID: `SF-0D89C4E9`
- Citation: HIPAA 164.502 Uses and Disclosures of PHI; CIS Snowflake 4.5
- Recommendation: Apply a masking policy on every column whose name suggests PHI / PII so non-clinician roles see hashed or redacted values. Continuous re-scan flags new columns as schemas evolve.
- Fix command: `CREATE MASKING POLICY phi_redact AS (val STRING) RETURNS STRING -> CASE WHEN IS_ROLE_IN_SESSION('CLINICIAN_RO') THEN val ELSE 'REDACTED' END; ALTER TABLE <t> MODIFY COLUMN <c> SET MASKING POLICY phi_redact;`

### Likely-PHI / PII columns without a masking policy (high)
- Resource: `TITAN_DEMO.PUBLIC_BAD.PATIENT_PHI.MRN`
- FID: `SF-1525D3DB`
- Citation: HIPAA 164.502 Uses and Disclosures of PHI; CIS Snowflake 4.5
- Recommendation: Apply a masking policy on every column whose name suggests PHI / PII so non-clinician roles see hashed or redacted values. Continuous re-scan flags new columns as schemas evolve.
- Fix command: `CREATE MASKING POLICY phi_redact AS (val STRING) RETURNS STRING -> CASE WHEN IS_ROLE_IN_SESSION('CLINICIAN_RO') THEN val ELSE 'REDACTED' END; ALTER TABLE <t> MODIFY COLUMN <c> SET MASKING POLICY phi_redact;`

### Likely-PHI / PII columns without a masking policy (high)
- Resource: `TITAN_DEMO.PUBLIC_BAD.PATIENT_PHI.PHONE`
- FID: `SF-6C44BD2B`
- Citation: HIPAA 164.502 Uses and Disclosures of PHI; CIS Snowflake 4.5
- Recommendation: Apply a masking policy on every column whose name suggests PHI / PII so non-clinician roles see hashed or redacted values. Continuous re-scan flags new columns as schemas evolve.
- Fix command: `CREATE MASKING POLICY phi_redact AS (val STRING) RETURNS STRING -> CASE WHEN IS_ROLE_IN_SESSION('CLINICIAN_RO') THEN val ELSE 'REDACTED' END; ALTER TABLE <t> MODIFY COLUMN <c> SET MASKING POLICY phi_redact;`

### Likely-PHI / PII columns without a masking policy (high)
- Resource: `TITAN_DEMO.PUBLIC_BAD.MEMBER_ACCOUNT.MEMBER_PII_DOB`
- FID: `SF-BD8BAB49`
- Citation: HIPAA 164.502 Uses and Disclosures of PHI; CIS Snowflake 4.5
- Recommendation: Apply a masking policy on every column whose name suggests PHI / PII so non-clinician roles see hashed or redacted values. Continuous re-scan flags new columns as schemas evolve.
- Fix command: `CREATE MASKING POLICY phi_redact AS (val STRING) RETURNS STRING -> CASE WHEN IS_ROLE_IN_SESSION('CLINICIAN_RO') THEN val ELSE 'REDACTED' END; ALTER TABLE <t> MODIFY COLUMN <c> SET MASKING POLICY phi_redact;`

### Likely-PHI / PII columns without a masking policy (high)
- Resource: `TITAN_DEMO.PUBLIC_BAD.PATIENT_PHI.EMAIL`
- FID: `SF-C0EA84A5`
- Citation: HIPAA 164.502 Uses and Disclosures of PHI; CIS Snowflake 4.5
- Recommendation: Apply a masking policy on every column whose name suggests PHI / PII so non-clinician roles see hashed or redacted values. Continuous re-scan flags new columns as schemas evolve.
- Fix command: `CREATE MASKING POLICY phi_redact AS (val STRING) RETURNS STRING -> CASE WHEN IS_ROLE_IN_SESSION('CLINICIAN_RO') THEN val ELSE 'REDACTED' END; ALTER TABLE <t> MODIFY COLUMN <c> SET MASKING POLICY phi_redact;`

### Sensitive tables without a row-access policy (medium)
- Resource: `SNOWFLAKE.TRUST_CENTER.ACCOUNT_NOTIFICATION_RECIPIENTS`
- FID: `SF-EDB0FC3F`
- Citation: HIPAA 164.312(a)(1); CIS Snowflake 4.6
- Recommendation: Apply a row-access policy on PHI / patient / member / financial tables so each role sees only its in-scope rows.
- Fix command: `CREATE ROW ACCESS POLICY tenant_scope AS (tenant STRING) RETURNS BOOLEAN -> tenant = CURRENT_ROLE(); ALTER TABLE <t> ADD ROW ACCESS POLICY tenant_scope ON (tenant_col);`

### Sensitive tables without a row-access policy (medium)
- Resource: `TITAN_DEMO.PUBLIC_BAD.MEMBER_ACCOUNT`
- FID: `SF-56E9FA46`
- Citation: HIPAA 164.312(a)(1); CIS Snowflake 4.6
- Recommendation: Apply a row-access policy on PHI / patient / member / financial tables so each role sees only its in-scope rows.
- Fix command: `CREATE ROW ACCESS POLICY tenant_scope AS (tenant STRING) RETURNS BOOLEAN -> tenant = CURRENT_ROLE(); ALTER TABLE <t> ADD ROW ACCESS POLICY tenant_scope ON (tenant_col);`

### Sensitive tables without a row-access policy (medium)
- Resource: `SNOWFLAKE.TRUST_CENTER_STATE.ACCOUNT_NOTIFICATION_METADATA`
- FID: `SF-78DC5139`
- Citation: HIPAA 164.312(a)(1); CIS Snowflake 4.6
- Recommendation: Apply a row-access policy on PHI / patient / member / financial tables so each role sees only its in-scope rows.
- Fix command: `CREATE ROW ACCESS POLICY tenant_scope AS (tenant STRING) RETURNS BOOLEAN -> tenant = CURRENT_ROLE(); ALTER TABLE <t> ADD ROW ACCESS POLICY tenant_scope ON (tenant_col);`

### Sensitive tables without a row-access policy (medium)
- Resource: `TITAN_DEMO.PUBLIC_BAD.PATIENT_PHI`
- FID: `SF-772DFFA0`
- Citation: HIPAA 164.312(a)(1); CIS Snowflake 4.6
- Recommendation: Apply a row-access policy on PHI / patient / member / financial tables so each role sees only its in-scope rows.
- Fix command: `CREATE ROW ACCESS POLICY tenant_scope AS (tenant STRING) RETURNS BOOLEAN -> tenant = CURRENT_ROLE(); ALTER TABLE <t> ADD ROW ACCESS POLICY tenant_scope ON (tenant_col);`

### Sensitive tables without a row-access policy (medium)
- Resource: `SNOWFLAKE.TRUST_CENTER_STATE.ACCOUNT_NOTIFICATION_HISTORY`
- FID: `SF-AC760964`
- Citation: HIPAA 164.312(a)(1); CIS Snowflake 4.6
- Recommendation: Apply a row-access policy on PHI / patient / member / financial tables so each role sees only its in-scope rows.
- Fix command: `CREATE ROW ACCESS POLICY tenant_scope AS (tenant STRING) RETURNS BOOLEAN -> tenant = CURRENT_ROLE(); ALTER TABLE <t> ADD ROW ACCESS POLICY tenant_scope ON (tenant_col);`

### Authentication policy not configured at account level (high)
- Resource: `account`
- FID: `SF-0AF03015`
- Citation: PCI-DSS 8.2; NIST 800-53 IA-2; HIPAA 164.308(a)(5)(ii)(D)
- Recommendation: Apply an authentication policy at account level that requires MFA, restricts auth methods to PASSWORD+MFA / KEYPAIR / SAML, and disables legacy paths.
- Fix command: `CREATE AUTHENTICATION POLICY require_mfa ALLOWED_AUTHENTICATION_METHODS=('PASSWORD','KEYPAIR','SAML') MFA_AUTHENTICATION_METHODS=('PASSWORD'); ALTER ACCOUNT SET AUTHENTICATION POLICY require_mfa;`

### Session policy missing or idle timeout above 60 minutes (medium)
- Resource: `no_session_policy`
- FID: `SF-580253AF`
- Citation: PCI-DSS 8.1.8; NIST 800-53 AC-11; HIPAA 164.312(a)(2)(iii)
- Recommendation: Apply a session policy with idle timeout no greater than 30 minutes (15 for healthcare). PCI requires 15 minutes for cardholder-data environments.
- Fix command: `CREATE SESSION POLICY tight_idle SESSION_IDLE_TIMEOUT_MINS=15; ALTER ACCOUNT SET SESSION POLICY tight_idle;`

### Sensitive tables with Time Travel retention below 7 days (medium)
- Resource: `TITAN_DEMO.PUBLIC_BAD.PATIENT_PHI`
- FID: `SF-12D3AB6F`
- Citation: HIPAA 164.316(b)(2)(i); PCI-DSS 10.5.3; SOC 2 CC7.3
- Recommendation: Sensitive tables (PHI, transactions, audit logs) should hold at least 7 days of Time Travel for incident reconstruction. Compliance frameworks frequently require longer log retention.
- Fix command: `ALTER TABLE <table> SET DATA_RETENTION_TIME_IN_DAYS = 30;`

### Customer-managed encryption keys (Tri-Secret Secure) not enabled (high)
- Resource: `account`
- FID: `SF-01536296`
- Citation: HIPAA 164.312(a)(2)(iv); FedRAMP SC-12; PCI-DSS 3.5.2
- Recommendation: Enable Tri-Secret Secure so encryption requires a customer-controlled KMS key. This is a Business Critical / Enterprise-tier feature; if your account is on a lower tier and you handle PHI / cardholder data, request the upgrade.
- Fix command: `Contact Snowflake support to enable Tri-Secret Secure on the account; provide your AWS KMS / Azure Key Vault / GCP KMS key reference.`

### No replication or failover groups for HIPAA / PCI workloads (medium)
- Resource: `account`
- FID: `SF-FD4CA6BD`
- Citation: HIPAA 164.308(a)(7) Contingency; PCI-DSS 12.10.1; SOC 2 A1.2
- Recommendation: Configure at least one failover group covering the regulated databases. RPO and RTO requirements (HIPAA: 24h backup target) are not satisfied by Time Travel alone.
- Fix command: `CREATE FAILOVER GROUP regulated_data OBJECT_TYPES=(DATABASES, ROLES) ALLOWED_DATABASES=(<list>) ALLOWED_ACCOUNTS=(<dr_account>) REPLICATION_SCHEDULE='10 MINUTE';`

### Recent Cortex AI calls invoked from likely-PHI tables (medium)
- Resource: `TITANADMIN`
- FID: `SF-AC60A281`
- Citation: HIPAA 164.502; NIST AI RMF GV-2
- Recommendation: Cortex AI calls send data to Snowflake's hosted LLM. For PHI workloads, confirm the BAA covers Cortex inference and that PHI is masked or tokenized before the call.
- Fix command: `Apply masking policy to PHI columns before they can be passed to CORTEX functions; add a row-access policy that hides PHI from the role used by Cortex callers.`

### Users without MFA enrolled (high)
- Resource: `SVC_TITANBAD_BROAD`
- FID: `SF-035143A9`
- Citation: HIPAA 164.312(d); CIS Snowflake 1.4
- Recommendation: Enrol the user in Duo or Snowflake-managed MFA. Service users must use RSA key-pair auth instead.
- Fix command: `ALTER USER SVC_TITANBAD_BROAD SET MINS_TO_BYPASS_MFA = 0; -- then enrol in MFA`

### Users without MFA enrolled (critical)
- Resource: `TITANADMIN`
- FID: `SF-1AB7DFEF`
- Citation: HIPAA 164.312(d); CIS Snowflake 1.4
- Recommendation: Enrol the user in Duo or Snowflake-managed MFA. Service users must use RSA key-pair auth instead.
- Fix command: `ALTER USER TITANADMIN SET MINS_TO_BYPASS_MFA = 0; -- then enrol in MFA`

### Users without MFA enrolled (high)
- Resource: `TITANBAD_NOMFA1`
- FID: `SF-AE0FD726`
- Citation: HIPAA 164.312(d); CIS Snowflake 1.4
- Recommendation: Enrol the user in Duo or Snowflake-managed MFA. Service users must use RSA key-pair auth instead.
- Fix command: `ALTER USER TITANBAD_NOMFA1 SET MINS_TO_BYPASS_MFA = 0; -- then enrol in MFA`

### Users without MFA enrolled (high)
- Resource: `TITANBAD_NOMFA2`
- FID: `SF-7240BD28`
- Citation: HIPAA 164.312(d); CIS Snowflake 1.4
- Recommendation: Enrol the user in Duo or Snowflake-managed MFA. Service users must use RSA key-pair auth instead.
- Fix command: `ALTER USER TITANBAD_NOMFA2 SET MINS_TO_BYPASS_MFA = 0; -- then enrol in MFA`

### Users without MFA enrolled (high)
- Resource: `TITANBAD_STALE`
- FID: `SF-A1CE6089`
- Citation: HIPAA 164.312(d); CIS Snowflake 1.4
- Recommendation: Enrol the user in Duo or Snowflake-managed MFA. Service users must use RSA key-pair auth instead.
- Fix command: `ALTER USER TITANBAD_STALE SET MINS_TO_BYPASS_MFA = 0; -- then enrol in MFA`

### PUBLIC role granted on regulated data object (critical)
- Resource: `TITAN_DEMO.PUBLIC_BAD`
- FID: `SF-1E80C553`
- Citation: HIPAA 164.502; PCI-DSS 7.1; CIS Snowflake 2.1
- Recommendation: Revoke the privilege from PUBLIC. PUBLIC is granted to every role automatically; non-default grants on PUBLIC make data world-readable inside the account.
- Fix command: `REVOKE USAGE ON SCHEMA TITAN_DEMO.PUBLIC_BAD FROM ROLE PUBLIC;`

### PUBLIC role granted on regulated data object (critical)
- Resource: `TITAN_DEMO.PUBLIC_BAD.MEMBER_ACCOUNT`
- FID: `SF-6DECC9B4`
- Citation: HIPAA 164.502; PCI-DSS 7.1; CIS Snowflake 2.1
- Recommendation: Revoke the privilege from PUBLIC. PUBLIC is granted to every role automatically; non-default grants on PUBLIC make data world-readable inside the account.
- Fix command: `REVOKE SELECT ON TABLE TITAN_DEMO.PUBLIC_BAD.MEMBER_ACCOUNT FROM ROLE PUBLIC;`

### PUBLIC role granted on regulated data object (critical)
- Resource: `TITAN_DEMO.PUBLIC_BAD.PATIENT_PHI`
- FID: `SF-E3C04A5C`
- Citation: HIPAA 164.502; PCI-DSS 7.1; CIS Snowflake 2.1
- Recommendation: Revoke the privilege from PUBLIC. PUBLIC is granted to every role automatically; non-default grants on PUBLIC make data world-readable inside the account.
- Fix command: `REVOKE SELECT ON TABLE TITAN_DEMO.PUBLIC_BAD.PATIENT_PHI FROM ROLE PUBLIC;`

### Role holds 10 distinct privileges (medium)
- Resource: `R_TITANBAD_EXPLOSION`
- FID: `SF-11E5CD9F`
- Citation: NIST 800-53 AC-6 Least Privilege; CIS Snowflake 2.5
- Recommendation: Split this role into purpose-specific sub-roles. A single role with many privileges is hard to audit and tends to accumulate over-grant.
- Fix command: `Identify each functional purpose; CREATE sub-roles; GRANT specific privileges; over time REVOKE direct grants.`

### PHI / PII column without masking policy (high)
- Resource: `TITAN_DEMO.PUBLIC_BAD.PATIENT_PHI.EMAIL`
- FID: `SF-0D571CCF`
- Citation: HIPAA 164.502; CIS Snowflake 4.5
- Recommendation: Apply a masking policy on every column whose name suggests PHI / PII so non-clinician roles see hashed or redacted values.
- Fix command: `CREATE MASKING POLICY phi_redact AS (val STRING) RETURNS STRING -> CASE WHEN IS_ROLE_IN_SESSION('CLINICIAN_RO') THEN val ELSE 'REDACTED' END; ALTER TABLE <table> MODIFY COLUMN EMAIL SET MASKING POLICY phi_redact;`

### PHI / PII column without masking policy (high)
- Resource: `TITAN_DEMO.PUBLIC_BAD.PATIENT_PHI.MEMBER_ID`
- FID: `SF-FA8B1085`
- Citation: HIPAA 164.502; CIS Snowflake 4.5
- Recommendation: Apply a masking policy on every column whose name suggests PHI / PII so non-clinician roles see hashed or redacted values.
- Fix command: `CREATE MASKING POLICY phi_redact AS (val STRING) RETURNS STRING -> CASE WHEN IS_ROLE_IN_SESSION('CLINICIAN_RO') THEN val ELSE 'REDACTED' END; ALTER TABLE <table> MODIFY COLUMN MEMBER_ID SET MASKING POLICY phi_redact;`

### PHI / PII column without masking policy (high)
- Resource: `TITAN_DEMO.PUBLIC_BAD.PATIENT_PHI.DOB`
- FID: `SF-86C71FA7`
- Citation: HIPAA 164.502; CIS Snowflake 4.5
- Recommendation: Apply a masking policy on every column whose name suggests PHI / PII so non-clinician roles see hashed or redacted values.
- Fix command: `CREATE MASKING POLICY phi_redact AS (val STRING) RETURNS STRING -> CASE WHEN IS_ROLE_IN_SESSION('CLINICIAN_RO') THEN val ELSE 'REDACTED' END; ALTER TABLE <table> MODIFY COLUMN DOB SET MASKING POLICY phi_redact;`

### PHI / PII column without masking policy (high)
- Resource: `TITAN_DEMO.PUBLIC_BAD.PATIENT_PHI.SSN`
- FID: `SF-F96D6021`
- Citation: HIPAA 164.502; CIS Snowflake 4.5
- Recommendation: Apply a masking policy on every column whose name suggests PHI / PII so non-clinician roles see hashed or redacted values.
- Fix command: `CREATE MASKING POLICY phi_redact AS (val STRING) RETURNS STRING -> CASE WHEN IS_ROLE_IN_SESSION('CLINICIAN_RO') THEN val ELSE 'REDACTED' END; ALTER TABLE <table> MODIFY COLUMN SSN SET MASKING POLICY phi_redact;`

### PHI / PII column without masking policy (high)
- Resource: `TITAN_DEMO.PUBLIC_BAD.PATIENT_PHI.PHONE`
- FID: `SF-1D90D5C8`
- Citation: HIPAA 164.502; CIS Snowflake 4.5
- Recommendation: Apply a masking policy on every column whose name suggests PHI / PII so non-clinician roles see hashed or redacted values.
- Fix command: `CREATE MASKING POLICY phi_redact AS (val STRING) RETURNS STRING -> CASE WHEN IS_ROLE_IN_SESSION('CLINICIAN_RO') THEN val ELSE 'REDACTED' END; ALTER TABLE <table> MODIFY COLUMN PHONE SET MASKING POLICY phi_redact;`

### PHI / PII column without masking policy (high)
- Resource: `TITAN_DEMO.PUBLIC_BAD.MEMBER_ACCOUNT.MEMBER_PII_DOB`
- FID: `SF-C7F4211A`
- Citation: HIPAA 164.502; CIS Snowflake 4.5
- Recommendation: Apply a masking policy on every column whose name suggests PHI / PII so non-clinician roles see hashed or redacted values.
- Fix command: `CREATE MASKING POLICY phi_redact AS (val STRING) RETURNS STRING -> CASE WHEN IS_ROLE_IN_SESSION('CLINICIAN_RO') THEN val ELSE 'REDACTED' END; ALTER TABLE <table> MODIFY COLUMN MEMBER_PII_DOB SET MASKING POLICY phi_redact;`

### PHI / PII column without masking policy (high)
- Resource: `TITAN_DEMO.PUBLIC_BAD.PATIENT_PHI.PATIENT_ID`
- FID: `SF-419BC036`
- Citation: HIPAA 164.502; CIS Snowflake 4.5
- Recommendation: Apply a masking policy on every column whose name suggests PHI / PII so non-clinician roles see hashed or redacted values.
- Fix command: `CREATE MASKING POLICY phi_redact AS (val STRING) RETURNS STRING -> CASE WHEN IS_ROLE_IN_SESSION('CLINICIAN_RO') THEN val ELSE 'REDACTED' END; ALTER TABLE <table> MODIFY COLUMN PATIENT_ID SET MASKING POLICY phi_redact;`

### PHI / PII column without masking policy (high)
- Resource: `TITAN_DEMO.PUBLIC_BAD.MEMBER_ACCOUNT.MEMBER_PII_SSN`
- FID: `SF-DE0028EF`
- Citation: HIPAA 164.502; CIS Snowflake 4.5
- Recommendation: Apply a masking policy on every column whose name suggests PHI / PII so non-clinician roles see hashed or redacted values.
- Fix command: `CREATE MASKING POLICY phi_redact AS (val STRING) RETURNS STRING -> CASE WHEN IS_ROLE_IN_SESSION('CLINICIAN_RO') THEN val ELSE 'REDACTED' END; ALTER TABLE <table> MODIFY COLUMN MEMBER_PII_SSN SET MASKING POLICY phi_redact;`

### PHI / PII column without masking policy (high)
- Resource: `TITAN_DEMO.PUBLIC_BAD.PATIENT_PHI.MRN`
- FID: `SF-94EFEC7D`
- Citation: HIPAA 164.502; CIS Snowflake 4.5
- Recommendation: Apply a masking policy on every column whose name suggests PHI / PII so non-clinician roles see hashed or redacted values.
- Fix command: `CREATE MASKING POLICY phi_redact AS (val STRING) RETURNS STRING -> CASE WHEN IS_ROLE_IN_SESSION('CLINICIAN_RO') THEN val ELSE 'REDACTED' END; ALTER TABLE <table> MODIFY COLUMN MRN SET MASKING POLICY phi_redact;`

### External stage without server-side encryption (high)
- Resource: `TITAN_DEMO.PUBLIC_BAD.BAD_EXT_STAGE`
- FID: `SF-854AD08E`
- Citation: HIPAA 164.312(a)(2)(iv); CIS Snowflake 4.2
- Recommendation: Configure server-side encryption (AWS-KMS or Azure-KV or GCS-CMEK) on every external stage carrying regulated data.
- Fix command: `CREATE OR REPLACE STAGE TITAN_DEMO.PUBLIC_BAD.BAD_EXT_STAGE URL='s3://titan-demo-fake-bucket/' STORAGE_INTEGRATION=<si> ENCRYPTION=(TYPE='AWS_SSE_KMS' KMS_KEY_ID='<arn>');`
