PlainID Snowflake Policy Orchestration
Technical documentation for implementing Policy Orchestration Points (POPs) for Snowflake Data Cloud environments using PlainID's SaaS Authorization Management.
Snowflake Requirements: Enterprise Edition or higher (required for Row Access Policies and Dynamic Data Masking)
System Overview
PlainID's Snowflake integration leverages Policy Orchestration to centralize Snowflake's access controls through a unified Policy-Based Access Control (PBAC) framework. The Policy Orchestration Point (POP) enables enterprises to discover, manage, and enforce data access policies across their Snowflake environments.
Core Components Architecture
End-to-End Authorization Flow
Key Capabilities
- Policy Discovery: Automatic discovery of existing Snowflake row access policies, masking policies, tag-based policies, and role structures
- Centralized Management: Single pane of glass for managing data access across multiple Snowflake accounts and warehouses
- Bi-directional Sync: Policies created in PlainID are deployed and enforced in Snowflake
- Visual Policy Mapping: Graphical representation of complex access policies
- Audit & Compliance: Complete visibility and audit trail of all policy changes
- Tag-Based Governance: Support for Snowflake's tag-based security policies for metadata-driven access control
Policy Orchestration Point (POP) Architecture
SaaS Authorization Management Pattern
Policy Administration
PAP + Policy Store
Orchestration Layer
Discover & Deploy
Native Policies
Row Access & Masking
POP Components
| Component | Function | Location |
|---|---|---|
| Policy Orchestration Service | Manages bi-directional sync between PlainID and Snowflake | PlainID Cloud |
| Discovery Engine | Scans and maps Snowflake objects and policies | POP Service |
| Policy Translator | Converts between PlainID policies and Snowflake native policies | POP Service |
| Deployment Engine | Applies policy changes to Snowflake environments | POP Service |
Snowflake Policy Orchestration Point
Integration Overview
The Snowflake POP enables PlainID to discover, manage, and deploy authorization policies using Snowflake's native security features.
Discovered Objects
# Objects automatically discovered during POP initialization: DATABASES ├── Schemas ├── Tables │ ├── Columns (with data types) │ └── Row Access Policies ├── Views │ ├── Columns │ └── Access Policies ├── External Functions └── Warehouses SECURITY OBJECTS ├── Roles (System & Custom) ├── Users ├── Masking Policies │ ├── Standard Masking Policies │ └── Tag-Based Masking Policies ├── Row Access Policies ├── Network Policies └── Tags (for Tag-Based Security) METADATA ├── Tags ├── Classifications ├── Policy Associations └── Data Lineage
Policy Translation
PlainID policies are automatically translated to Snowflake native constructs:
| PlainID Policy Type | Snowflake Implementation | Example |
|---|---|---|
| Row-Level Security | ROW ACCESS POLICY | region = current_user_region() |
| Column Masking | MASKING POLICY | CASE WHEN role IN ('ANALYST') THEN val ELSE '***' END |
| Dynamic Groups | Role Hierarchies + Policies | Mapped to Snowflake role structures with IS_ROLE_IN_SESSION() |
| Attribute-Based Access | Context Functions + Policies | current_role(), current_user(), current_account() |
| Tag-Based Policies | TAG + MASKING/ROW ACCESS POLICY | SYSTEM$GET_TAG_ON_CURRENT_COLUMN('tag_name') |
Tag-Based Security Policies
PlainID POP also discovers and manages Snowflake's tag-based security policies, enabling centralized governance through metadata tagging:
# Example: Tag-Based Masking Policy Discovery
-- Snowflake Tag-Based Policy
CREATE TAG pii_classification;
CREATE MASKING POLICY tag_based_pii_mask AS (val STRING)
RETURNS STRING ->
CASE
WHEN SYSTEM$GET_TAG_ON_CURRENT_COLUMN('pii_classification') = 'SENSITIVE'
AND CURRENT_ROLE() NOT IN ('DATA_STEWARD')
THEN '***MASKED***'
ELSE val
END;
-- Apply tag to columns
ALTER TABLE customer_data MODIFY COLUMN ssn SET TAG pii_classification = 'SENSITIVE';
ALTER TAG pii_classification SET MASKING POLICY tag_based_pii_mask;
Policy Evaluation Order
- Row Access Policies are evaluated first - Filters which rows the user can see
- Masking Policies are evaluated second - Masks sensitive data in the returned rows
- If a column has both a direct masking policy and a tag-based masking policy, the direct policy takes precedence
Learn & Manage Modes
Learn Mode (Discovery)
Initial integration phase where PlainID discovers and maps existing Snowflake policies without making changes.
Learn Mode Activities:
- Discovers all Snowflake databases, schemas, tables, and views
- Maps existing row access policies and masking policies
- Identifies role hierarchies and user assignments
- Translates Snowflake policies to PlainID policy representation
- Generates Policy Map visualization
- Creates audit reports of current access patterns
// Example: Discovered Snowflake Policy
CREATE ROW ACCESS POLICY sales_region_policy
AS (region_column VARCHAR)
RETURNS BOOLEAN ->
EXISTS (
SELECT 1 FROM sales_managers
WHERE manager_id = CURRENT_USER()
AND region = region_column
);
// Applied to table using:
ALTER TABLE sales_data
SET ROW ACCESS POLICY sales_region_policy ON (region);
// Translated to PlainID Policy Structure
{
"policyName": "sales_region_policy",
"type": "row_filter",
"condition": {
"type": "exists",
"source": "sales_managers",
"match": {
"manager_id": "${user.id}",
"region": "${row.region_column}"
}
}
}
Snowflake POP Setup
Prerequisites
- Snowflake Account with ACCOUNTADMIN or SECURITYADMIN privileges
- Snowflake Enterprise Edition or higher (required for Row Access Policies and Dynamic Data Masking)
- Service Account for PlainID integration
- PlainID Platform access with Orchestration Workspace enabled
- Active Snowflake warehouse for discovery operations
Step 1: Create Snowflake Service Account
-- Create PlainID integration role CREATE ROLE PLAINID_ORCHESTRATOR; -- Grant necessary privileges GRANT USAGE ON WAREHOUSE COMPUTE_WH TO ROLE PLAINID_ORCHESTRATOR; GRANT USAGE ON ALL DATABASES IN ACCOUNT TO ROLE PLAINID_ORCHESTRATOR; GRANT USAGE ON ALL SCHEMAS IN DATABASE TO ROLE PLAINID_ORCHESTRATOR; GRANT SELECT ON ALL TABLES IN SCHEMA TO ROLE PLAINID_ORCHESTRATOR; GRANT SELECT ON ALL VIEWS IN SCHEMA TO ROLE PLAINID_ORCHESTRATOR; -- Grant policy management privileges -- Option 1: Grant on specific schemas GRANT CREATE ROW ACCESS POLICY ON SCHEMA PUBLIC TO ROLE PLAINID_ORCHESTRATOR; GRANT CREATE MASKING POLICY ON SCHEMA PUBLIC TO ROLE PLAINID_ORCHESTRATOR; -- Option 2: Grant on all schemas in database (recommended) GRANT CREATE ROW ACCESS POLICY ON ALL SCHEMAS IN DATABASE TO ROLE PLAINID_ORCHESTRATOR; GRANT CREATE MASKING POLICY ON ALL SCHEMAS IN DATABASE TO ROLE PLAINID_ORCHESTRATOR; -- Grant apply privileges at account level GRANT APPLY ROW ACCESS POLICY ON ACCOUNT TO ROLE PLAINID_ORCHESTRATOR; GRANT APPLY MASKING POLICY ON ACCOUNT TO ROLE PLAINID_ORCHESTRATOR; -- Create service user CREATE USER PLAINID_SERVICE_USER PASSWORD = 'secure_password' DEFAULT_ROLE = PLAINID_ORCHESTRATOR; GRANT ROLE PLAINID_ORCHESTRATOR TO USER PLAINID_SERVICE_USER;
Step 2: Configure POP in PlainID
- Navigate to Orchestration Workspace
- Click Add Policy Orchestration Point
- Select Snowflake from vendor list
- Configure connection settings:
{
"displayName": "Snowflake Production POP",
"connectionSettings": {
"account": "mycompany.snowflakecomputing.com",
"warehouse": "COMPUTE_WH",
"database": "PRODUCTION",
"authenticationType": "password",
"username": "PLAINID_SERVICE_USER",
"password": "${ENCRYPTED_PASSWORD}"
},
"discoveryScope": {
"databases": ["PRODUCTION", "ANALYTICS"],
"schemas": ["PUBLIC", "SENSITIVE", "REPORTS"],
"includeMaskingPolicies": true,
"includeRowAccessPolicies": true,
"includeRoles": true
},
"syncSettings": {
"mode": "learn", // Always start with "learn" mode for initial discovery
"syncInterval": "hourly",
"conflictResolution": "plainid_wins" // Options: "plainid_wins", "snowflake_wins", "manual"
}
}
Step 3: Test Connection
-- Verify service account permissions in Snowflake SHOW GRANTS TO ROLE PLAINID_ORCHESTRATOR; SHOW GRANTS TO USER PLAINID_SERVICE_USER; -- Test warehouse access USE WAREHOUSE COMPUTE_WH; SELECT CURRENT_WAREHOUSE(), CURRENT_USER(), CURRENT_ROLE();
Discovery Process
Automatic Discovery Flow
When a Snowflake POP is created, PlainID automatically initiates a discovery process:
Query Snowflake
metadata
Create PlainID
objects
Convert policies to
PBAC format
Show in Orchestration
Workspace
Discovered Elements Mapping
| Snowflake Object | PlainID Mapping | Workspace |
|---|---|---|
| Database.Schema.Table | Asset Type | Authorization Workspace |
| Columns | Asset Attributes | Authorization Workspace |
| Roles | Dynamic Groups | Identity Workspace |
| Users | Identities | Identity Workspace |
| Row Access Policies | Filter Policies | Orchestration Workspace |
| Masking Policies | Masking Policies | Orchestration Workspace |
Manual Discovery Trigger
# Trigger discovery manually from Orchestration Workspace
1. Navigate to Snowflake POP card
2. Click three dots menu (⋮)
3. Select "Discover Now"
4. Monitor progress in Activity Log
# Discovery API endpoint (for automation)
POST /api/v1/orchestration/pop/{popId}/discover
{
"scope": "full", // or "incremental"
"notify": true
}
Policy Resolution Pattern
How POP Uses Policy Resolution
While POPs primarily manage native vendor policies, they utilize PlainID's Policy Resolution API for complex data access scenarios.
Resolution Request (Snowflake Context)
{
"identity": {
"type": "user",
"id": "snowflake_user@company.com",
"attributes": {
"department": "Finance",
"clearance_level": 2,
"region": "US_EAST"
}
},
"scope": {
"name": "snowflake-production"
},
"assetType": {
"type": "table",
"database": "ANALYTICS",
"schema": "SALES",
"table": "REVENUE_DATA"
},
"action": "SELECT",
"context": {
"warehouse": "COMPUTE_WH",
"role": "ANALYST",
"session_id": "sf_session_12345"
}
}
Resolution Response
{
"decision": "PERMIT",
"nativePolicies": {
"rowAccessPolicy": {
"name": "finance_region_policy",
"sql": "region IN ('US_EAST', 'US_CENTRAL')"
},
"maskingPolicies": [
{
"column": "ssn",
"policy": "pii_mask_policy",
"function": "REGEXP_REPLACE(val, '[0-9]', 'X')"
},
{
"column": "salary",
"policy": "salary_mask_policy",
"function": "CASE WHEN current_role() = 'HR' THEN val ELSE 0 END"
}
]
},
"deploymentInstructions": {
"applyRowPolicy": "ALTER TABLE analytics.sales.revenue_data SET ROW ACCESS POLICY finance_region_policy ON (region)",
"applyMaskingPolicies": [
"ALTER TABLE analytics.sales.revenue_data MODIFY COLUMN ssn SET MASKING POLICY pii_mask_policy",
"ALTER TABLE analytics.sales.revenue_data MODIFY COLUMN salary SET MASKING POLICY salary_mask_policy"
]
}
}
Orchestration Workspace
Workspace Overview
The Orchestration Workspace provides centralized visibility and management for all Snowflake policies.
Vendor Policies Tab
Lists all discovered and managed Snowflake policies:
- Native Snowflake row access policies
- Masking policies with their conditions
- Policy creation/modification timestamps
- Deployment status (synced/pending/conflict)
Objects Tab
Displays discovered Snowflake objects:
- Databases and schemas hierarchy
- Tables and views with column details
- Warehouses and their configurations
- Object relationships and dependencies
Policy Map Visualization
Graphical representation showing:
- Identity-to-resource access paths
- Policy application flow
- Effective permissions visualization
- Access pattern analysis
Policy Reconciliation
Side-by-side comparison of:
- PlainID policies vs Snowflake native policies
- Pending changes awaiting deployment
- Conflict detection and resolution
- Drift analysis between environments
Monitoring & Auditing
POP Activity Monitoring
Example of activity log entry for policy deployment:
# Activity Log Entry Example
{
"timestamp": "2024-12-15T10:30:00Z",
"popId": "snowflake-prod-pop",
"action": "POLICY_DEPLOYED",
"details": {
"policyName": "revenue_access_policy",
"targetObject": "ANALYTICS.SALES.REVENUE",
"deploymentStatus": "SUCCESS",
"changedBy": "admin@company.com",
"approvedBy": "security_team",
"snowflakeResponse": {
"status": "APPLIED",
"affectedRows": 1500000
}
}
}
Audit Capabilities
- Policy Changes: Complete history of all policy modifications
- Discovery Events: Log of all discovery runs and findings
- Deployment History: Record of all policy deployments to Snowflake
- Access Patterns: Analysis of who accessed what data when
- Compliance Reports: Automated compliance reporting for auditors
Troubleshooting
IP Allowlisting for PlainID Services
In case customer is restricting access via network policies they should allowlist the following IPs:
| Region | IP Addresses |
|---|---|
| US region | 3.139.229.73 3.21.70.3 3.141.133.162 |
| EU region | 18.203.129.39 52.208.224.64 54.220.132.102 |
| CA region | 99.79.30.66 35.182.160.92 15.156.98.158 |
Common Issues and Resolutions
| Issue | Symptoms | Resolution |
|---|---|---|
| Discovery Incomplete | Some Snowflake objects not appearing in PlainID | Check service account permissions; ensure USAGE grants on all schemas |
| Policy Deployment Fails | Policies created in PlainID not applying to Snowflake | Verify APPLY POLICY privileges; check for conflicting native policies |
| Sync Conflicts | Discrepancies between PlainID and Snowflake policies | Use Reconciliation view; set conflict resolution strategy |
| Performance Issues | Slow discovery or deployment | Optimize discovery scope; use incremental discovery mode |
| Connection Timeouts | Test connection fails | Check network policies; verify warehouse is running |
| Policy Syntax Errors | "Cannot ADD policy" error when setting policies | Use SET instead of ADD: ALTER TABLE ... SET ROW ACCESS POLICY ... |
Debug Mode
# Enable debug logging for POP
{
"popId": "snowflake-prod-pop",
"settings": {
"logging": {
"level": "DEBUG",
"includeSnowflakeQueries": true,
"logPolicyTranslations": true,
"capturePerformanceMetrics": true
}
}
}
Pattern: Policy Orchestration Point (POP) for SaaS Authorization Management
Snowflake Features: Row Access Policies, Dynamic Data Masking, Tag-Based Security (Enterprise Edition+)
Support: For production deployments, contact PlainID Technical Support for detailed implementation guidance.