Data Platform Governance in Snowflake: RBAC, Lineage, and Access Control at Scale

Srikar Mandava

Snowflake RBAC Management with Streamlit

1. Executive Summary

As Snowflake platforms scale, governance becomes essential not only for security, but for data trust, compliance, and operational stability.

Many teams implement basic RBAC and consider governance complete. This approach leads to:

  • Uncontrolled access that compounds over time with team growth
  • Inconsistent data definitions across reporting teams
  • Undetected exposure of sensitive data due to missing masking policies
  • Privilege drift as role assignments diverge between environments

A production-grade governance model ensures:

  • Controlled and auditable access using role hierarchies and future grants
  • Automated enforcement of policies not manual, not optional
  • Protection of sensitive data using object tagging and dynamic masking
  • Traceability of data usage within the realistic scope of Snowflake's metadata

2. Background

Snowflake provides powerful native governance primitives that, when systematically implemented, form a complete enterprise governance layer:

  • Role-Based Access Control (RBAC) with hierarchical role inheritance
  • Object tagging and classification (Snowflake Horizon)
  • Dynamic data masking policies (column-level)
  • Row access policies (row-level security)
  • Access history and audit metadata in ACCOUNT_USAGE schema
  • FUTURE GRANTS for scalable privilege management

However, these primitives must be implemented systematically and automated via Infrastructure-as-Code. Without automation, governance becomes inconsistent and impossible to audit.


3. Problem

3.1 Symptoms

In poorly governed Snowflake environments:

  • Analysts directly query RAW tables, bypassing data quality layers
  • Metrics differ across teams due to no enforced curated layer
  • Access permissions are overly broad and accumulate over time
  • Sensitive data is exposed because masking policies are not applied
  • Role assignments drift between dev, staging, and production environments
  • Service accounts have excessive privileges with no rotation policy

3.2 Impact

  • Loss of data trust and conflicting business metrics
  • Security and compliance risk regulatory exposure in finance/healthcare
  • Audit failures no traceable chain of data access
  • Operational inefficiency due to duplicated logic and inconsistent definitions
  • Hidden cost increases from uncontrolled warehouse usage

4. Requirements & Assumptions

A production-grade governance model must:

  • Enforce RBAC consistently using automation and IaC
  • Separate access by data layers (RAW / STAGING / CURATED / CONSUMPTION)
  • Classify and tag sensitive data using Snowflake object tags
  • Apply dynamic masking and row-level security at query time
  • Provide lineage visibility within realistic scope (see Section 6.5 for limitations)
  • Enable auditability and proactive monitoring with alerting
  • Handle schema evolution safely new columns inherit tag-based policies
  • Prevent role drift via version-controlled IaC (Terraform or SchemaChange)
  • Govern service accounts separately from human users

5. Recommended Architecture

5.1 High-Level Flow

Snowflake Governance High-Level Flow

5.2 Governance Architecture Model

A governed Snowflake platform should follow a structured access model:

Snowflake Governance Architecture Model

A governed Snowflake platform should include the following layers working together:

  • Users assigned to roles via version-controlled IaC
  • Roles controlling access to schemas and tables with FUTURE GRANTS
  • Object tagging for classification (PII, sensitivity level, data domain)
  • Masking and row access policies enforced transparently at query time
  • Monitoring and audit layer using Snowflake ACCOUNT_USAGE + external SIEM
  • Automation layer (Terraform / CI-CD) for drift-free governance enforcement

5.3 Access Boundaries by Layer

  • RAW — restricted to pipeline/service roles only. No human access.
  • STAGING — data engineers performing transformation only
  • CURATED — business consumption layer for analysts (with masking enforced)
  • CONSUMPTION — governed views with row-level and column-level controls

6. Implementation

6.1 RBAC Implementation (Concrete)

RBAC must be implemented using explicit SQL grants.


-- Create roles
CREATE ROLE IF NOT EXISTS data_engineer;
CREATE ROLE IF NOT EXISTS analyst;
-- Grant schema access
GRANT USAGE ON SCHEMA curated TO ROLE analyst;
GRANT SELECT ON ALL TABLES IN SCHEMA curated TO ROLE analyst;
-- CRITICAL: Future grants prevent privilege drift
GRANT SELECT ON FUTURE TABLES IN SCHEMA curated TO ROLE analyst;
-- Assign role to user
GRANT ROLE analyst TO USER user_1;

Why FUTURE GRANTS matter

Without FUTURE GRANTS, every new table added to a schema requires a manual grant. At scale, this leads to privilege drift where new objects are inaccessible or accessible to unintended roles. Always pair GRANT ON ALL with GRANT ON FUTURE.

6.2 Role Hierarchy Design

Roles should be hierarchical to simplify management:

  • SYSADMIN → full control
  • DATA_ENGINEER → pipeline + RAW access
  • ANALYST → CURATED access only

This avoids duplication and enforces consistency.

6.3 Service Account Governance

Service accounts are the highest-risk vector in a Snowflake platform. They have broad access and are often over-permissioned.


-- Dedicated pipeline role — no human access
CREATE ROLE IF NOT EXISTS pipeline_role;
GRANT USAGE ON SCHEMA raw TO ROLE pipeline_role;
GRANT INSERT, UPDATE ON ALL TABLES IN SCHEMA raw TO ROLE pipeline_role;
GRANT INSERT ON FUTURE TABLES IN SCHEMA raw TO ROLE pipeline_role;
-- Key principles:
-- 1. Never grant pipeline_role to human users
-- 2. Rotate credentials on a defined schedule (e.g. 90 days)
-- 3. Monitor service account activity separately from human access
-- 4. Use key-pair authentication, not password-based auth

6.4 Data Ownership & Contracts

Ownership must be enforced, not just documented. A plain metadata table is insufficient — it provides no enforcement.

  • Implement ownership via CI/CD validation — fail pipeline if owner is undefined
  • Use dbt tests or Great Expectations as data contracts
  • Tag datasets with owner metadata using Snowflake object tags
  • SLA breaches should trigger automated alerts, not manual review

-- Tag-based ownership (machine-readable, not just a table)
CREATE TAG data_owner;
CREATE TAG data_domain;
ALTER TABLE curated.orders
  SET TAG data_owner = 'analytics-team',
           data_domain = 'commerce';

6.5 Data Lineage

Important Limitation — Read Before Implementing

Snowflake's object_dependencies view tracks object relationships (which views reference which tables).

It does NOT provide column-level lineage or full transformation lineage across dbt/pipeline code.

Claiming 'full lineage' from object_dependencies alone is inaccurate and will fail audit scrutiny

What Snowflake metadata provides:


-- Object-level dependency tracking
SELECT *
FROM snowflake.account_usage.object_dependencies
WHERE referenced_object_name = 'ORDERS';
-- Access history: who accessed what and when
SELECT user_name, object_name, query_start_time
FROM snowflake.account_usage.access_history
WHERE object_name = 'ORDERS'
ORDER BY query_start_time DESC;

Production lineage approach — combine layers:

  • Snowflake access_history for user-level access tracking
  • dbt lineage graph for transformation-level column lineage
  • OpenLineage / Marquez for pipeline-to-warehouse lineage events
  • External catalog tools (Atlan, Alation) if enterprise lineage catalog is required

6.6 Protecting Sensitive Data

Step 1: Tag Sensitive Columns


-- Create classification tags
CREATE TAG PII_TYPE;
CREATE TAG SENSITIVITY_LEVEL;
-- Apply to sensitive columns
ALTER TABLE curated.customers
  MODIFY COLUMN email
  SET TAG PII_TYPE = 'EMAIL', SENSITIVITY_LEVEL = 'HIGH';
ALTER TABLE curated.customers
  MODIFY COLUMN phone
  SET TAG PII_TYPE = 'PHONE', SENSITIVITY_LEVEL = 'HIGH';

Step 2: Apply Dynamic Masking Policy


-- Role-based unmasking: only SYSADMIN sees real values
CREATE OR REPLACE MASKING POLICY email_mask
AS (val STRING) RETURNS STRING ->
  CASE
    WHEN CURRENT_ROLE() IN ('SYSADMIN', 'DATA_COMPLIANCE_OFFICER')
      THEN val
    WHEN CURRENT_ROLE() IN ('DATA_ENGINEER')
      THEN CONCAT(LEFT(val, 2), '***@***.com')
    ELSE '***MASKED***'
  END;
-- Apply to column
ALTER TABLE curated.customers
  MODIFY COLUMN email
  SET MASKING POLICY email_mask;

Schema Evolution & Masking

When a new sensitive column is added, masking policies do NOT auto-apply unless the column is tagged.

Best practice: use tag-based masking policies so any column tagged PII_TYPE automatically inherits the correct masking policy without manual intervention.

Step 3: Row-Level Security


-- Restrict rows by region based on role context
CREATE OR REPLACE ROW ACCESS POLICY region_policy
AS (region STRING) RETURNS BOOLEAN ->
  CURRENT_ROLE() = 'SYSADMIN'
  OR EXISTS (
    SELECT 1 FROM access_control.user_regions ur
    WHERE ur.user_name = CURRENT_USER()
    AND ur.allowed_region = region
  );
ALTER TABLE curated.sales
  ADD ROW ACCESS POLICY region_policy ON (region);

6.7 Infrastructure-as-Code for Governance

Manual RBAC management is not production-grade. Role assignments must be version-controlled to prevent drift between environments.


# Terraform example — Snowflake RBAC as code
resource "snowflake_role" "analyst" {
  name = "ANALYST"
}
resource "snowflake_grant_privileges_to_role" "analyst_curated" {
  role_name  = snowflake_role.analyst.name
  privileges = ["SELECT"]
  on_schema_object {
    object_type = "TABLE"
    object_name = "CURATED.ORDERS"
  }
}
# All changes go through Git PR → CI validation → apply
# Drift detection: terraform plan in CI detects unauthorized manual grants

6.8 Schema Evolution Handling

Schema evolution is a governance risk that is almost always overlooked.

  • New columns added to sensitive tables must be evaluated for PII classification
  • CI/CD pipeline should scan ALTER TABLE statements and flag untagged columns
  • Use tag-based masking policies to auto-enforce masking on newly tagged columns
  • dbt schema tests should fail builds when expected columns are missing or renamed

-- Tag-based masking: auto-applies to any column with this tag
-- No per-column policy assignment needed after initial setup
ALTER TAG PII_TYPE SET MASKING POLICY email_mask USING (STRING);
-- Now any column tagged PII_TYPE = 'EMAIL' automatically uses email_mask

7. Validation & Testing

Governance validation must be automated — manual checks do not scale.

  • Test role permissions: verify analyst cannot SELECT from RAW
  • Validate masking: confirm masked output for non-privileged roles
  • Verify tagged columns have active masking policies
  • Detect schema changes: CI scan on dbt schema YAML changes
  • Row access policy tests: validate per-user row visibility

-- Test: analyst should NOT be able to access raw
-- Run this check in CI using a test service account with analyst role
USE ROLE analyst;
SELECT COUNT(*) FROM raw.events;  -- should fail with insufficient privileges
-- Test: masking is active for analyst role
USE ROLE analyst;
SELECT email FROM curated.customers LIMIT 1;
-- expected: '***MASKED***'

Integrate all governance tests into CI/CD. A failing governance test should block deployment — not just generate a warning.


8. Security & Access

A strong governance model ensures:

  • Controlled access — least-privilege enforced at role and object level
  • Auditability — every access query is logged in ACCOUNT_USAGE.ACCESS_HISTORY
  • Compliance readiness — masking and row policies satisfy GDPR, HIPAA, SOC 2 requirements

Additionally, these are non-negotiable in production:

  • Service accounts must use key-pair authentication, not password-based
  • Credentials and key pairs must be rotated on a defined schedule
  • Network policies should restrict Snowflake access to known IP ranges
  • MFA must be enforced for all human users

9. Performance & Cost Considerations

Corrected Claim

Governance does NOT automatically improve query performance.

Masking policies, row access policies, and secure views add query-time overhead.

The correct framing: governance enables controlled access patterns that prevent runaway queries and unplanned cost spikes.

Cost governance approach:

  • Separate warehouses per workload type: ETL, BI, ingestion, ad-hoc
  • Apply resource monitors with credit thresholds and auto-suspend
  • Tag queries with workload labels for cost attribution
  • Monitor warehouse utilization weekly — right-size before scaling up

-- Resource monitor: alert at 80%, suspend at 100%
CREATE RESOURCE MONITOR governance_monitor
  WITH CREDIT_QUOTA = 100
  TRIGGERS
    ON 80 PERCENT DO NOTIFY
    ON 100 PERCENT DO SUSPEND;
ALTER WAREHOUSE bi_warehouse
  SET RESOURCE_MONITOR = governance_monitor

10. Operations & Monitoring

Monitoring must be proactive — not ad-hoc queries run after an incident.

Access Monitoring


-- Top access patterns by user and object
SELECT user_name, object_name, COUNT(*) AS access_count
FROM snowflake.account_usage.access_history
WHERE query_start_time >= DATEADD('day', -7, CURRENT_TIMESTAMP())
GROUP BY user_name, object_name
ORDER BY access_count DESC;

Key Signals to Monitor

  • Access to sensitive/tagged data by unexpected roles
  • Sudden spikes in query volume or bytes scanned
  • New role assignments not made through IaC PR process
  • Service account access outside of scheduled pipeline windows
  • Failed login attempts or MFA bypasses

Production Monitoring Setup

  • Snowflake Tasks + Alerts for threshold-based notifications
  • Export ACCOUNT_USAGE data to SIEM (Splunk, Datadog, Elastic)
  • Set up Snowflake data quality monitors on curated layer
  • Create a governance dashboard tracking policy coverage %

-- Example: alert on sensitive data access by non-privileged roles
CREATE ALERT sensitive_access_alert
  WAREHOUSE = monitoring_wh
  SCHEDULE = '60 MINUTES'
  IF (EXISTS (
    SELECT 1 FROM snowflake.account_usage.access_history ah
    JOIN snowflake.account_usage.columns c
      ON ah.object_name = c.table_name
    WHERE c.column_name IN ('EMAIL','SSN','PHONE')
    AND ah.user_name NOT IN (SELECT user_name FROM access_control.privileged_users)
    AND ah.query_start_time >= DATEADD('hour', -1, CURRENT_TIMESTAMP())
  ))
  THEN CALL SYSTEM$SEND_EMAIL(...);

11. Common Pitfalls

  • Treating RBAC as complete governance — it is the foundation, not the ceiling
  • Allowing direct RAW access for any human user or analyst
  • Assuming Snowflake provides full column-level lineage out of the box
  • Applying masking policies manually per column — use tag-based masking for scale
  • Manual role management without IaC — leads to privilege drift
  • Ignoring schema evolution — new sensitive columns escape governance policies
  • Not governing service accounts separately from human users
  • Treating the data ownership table as enforcement — it is documentation only without CI/CD integration

12. Variations / Use Cases

  • Multi-team enterprise platforms — enforce domain-level isolation via role hierarchy
  • Regulated industries (finance, healthcare) — masking + row access + audit for HIPAA/SOX
  • Data-sharing environments — Snowflake Secure Data Sharing with governance policies applied before sharing
  • Cross-domain analytics platforms — object tags enforce domain ownership across shared datasets

13. Next Steps

Prioritized implementation order for a team starting from scratch:

  • Define RBAC roles and hierarchy — implement via Terraform from day one
  • Apply FUTURE GRANTS across all schemas to prevent privilege drift
  • Implement object tagging and classification for sensitive columns
  • Apply dynamic masking policies — use tag-based masking for auto-scale
  • Establish data ownership model via CI/CD validation and tags
  • Introduce monitoring, alerting, and SIEM integration
  • Add row access policies for multi-tenant or regulated datasets
  • Implement schema evolution detection in CI/CD pipeline

13.1 Governance Maturity Model (Differentiator)

Organizations typically evolve through four governance maturity levels. The goal is Level 4 — automated, enforceable, and continuous.

Level Stage Capabilities Status
1 No Governance Open access, no RBAC, no visibility Risky
2 Basic RBAC Role-based access, manual grants Partial
3 RBAC + Masking + Lineage Tagging, masking policies, audit queries Functional
4 Automated Governance IaC, CI/CD, contracts, SIEM, cost governance Production

14. Conclusion

Governance is a foundational component of any Snowflake data platform not an afterthought.

Without the following, systems become insecure, unreliable, and unauditable:

  • Automated enforcement via IaC and CI/CD
  • Honest lineage visibility that combines Snowflake metadata with transformation tools
  • Tag-based masking that handles schema evolution automatically
  • Service account governance as a first-class concern

About Boolean Data
Systems

Boolean Data Systems is a Snowflake Premier Partner that implements solutions on cloud platforms. We help enterprises make better business decisions with data and solve real-world business analytics and data challenges.

Global
Head Quarters

USA - Atlanta
3970 Old Milton Parkway,
Suite #200, Alpharetta, GA 30005
Ph. : 770-410-7770
Fax : 855-414-2865

Boolean Data is SOC 2 Type 1 compliant
All rights reserved – Boolean Data Systems