The Snowflake account URL {account}.snowflakecomputing.com resolves on the public internet by default — anyone with valid credentials can authenticate from anywhere. For most enterprises that is unacceptable. The two-part fix is to require private connectivity at the network layer (so traffic never traverses the public internet) and to attach a network policy that explicitly enumerates which sources may even attempt to authenticate. This page covers the SQL, the resource hierarchy (network rule → network policy → account/user attach), and the integration with AWS PrivateLink, Azure Private Link, and GCP Private Service Connect.
The diagram below shows the request path from a client inside a customer VPC to an authenticated Snowflake session. PrivateLink terminates the public DNS path; the network policy is what actually enforces "this VPCE id may connect" once the request reaches Snowflake's edge.
┌──────────────────────────────────────────────────────────────────────┐
│ CUSTOMER VPC / VNET │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ Snowflake CLI / │ │ BI tool / app │ │
│ │ driver │ │ (Tableau, etc.) │ │
│ └─────────┬────────┘ └─────────┬────────┘ │
│ │ │ │
│ └────────────┬───────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────┐ │
│ │ PrivateLink endpoint │ │
│ │ (VPCE id: vpce-...) │ │
│ └───────────┬────────────┘ │
└──────────────────────────────────────────────────────────────────────┘
│
▼ (private DNS, no public route)
┌──────────────────────────────────────────────────────────────────────┐
│ SNOWFLAKE ACCOUNT BOUNDARY │
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │
│ │ Network Policy │ │ Network Rules │ │ Session Policy │ │
│ │ ALLOWED list │ │ TYPE = AWSVPCEID│ │ idle / abs TTL │ │
│ └─────────┬────────┘ └─────────┬────────┘ └─────────┬────────┘ │
│ └────────────┬────────┴─────────────────────┘ │
│ ▼ │
│ ┌────────────────────────┐ │
│ │ Authenticated session │ │
│ │ (warehouse compute) │ │
│ └────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────┘
A NETWORK RULE is a reusable list of network identifiers — IPV4 CIDRs, AWS VPCE IDs, or Azure Private Link IDs — typed by what the values represent. Network rules replaced the old inline ALLOWED_IP_LIST string on the policy and are the modern primitive.
USE ROLE SECURITYADMIN;
-- 1. Corporate office IPv4 range (egress through corporate NAT)
CREATE OR REPLACE NETWORK RULE corp_office_ipv4
TYPE = IPV4
MODE = INGRESS
VALUE_LIST = ('203.0.113.0/24', '198.51.100.42/32')
COMMENT = 'HQ NAT egress + on-call jump box';
-- 2. AWS PrivateLink VPCE for production data plane
CREATE OR REPLACE NETWORK RULE prod_vpce_aws
TYPE = AWSVPCEID
MODE = INGRESS
VALUE_LIST = ('vpce-0123456789abcdef0', 'vpce-0fedcba9876543210')
COMMENT = 'us-east-1 prod VPC PrivateLink endpoints';
-- 3. Azure Private Link resource IDs
CREATE OR REPLACE NETWORK RULE prod_pl_azure
TYPE = AZURELINKID
MODE = INGRESS
VALUE_LIST = ('sf-pe-/subscriptions/.../resourceGroups/prod/.../privateEndpoints/sf-pe-1');
-- 4. A blocklist for known-bad sources
CREATE OR REPLACE NETWORK RULE deny_sources
TYPE = IPV4
MODE = INGRESS
VALUE_LIST = ('192.0.2.0/24');
A network rule is just a named list. It does nothing on its own — it has to be referenced from a network policy.
A NETWORK POLICY binds one or more network rules into an allow / deny posture, then attaches to the account or to specific users. User-level policies override account-level policies, which is how you punt a single break-glass admin around the corporate firewall without weakening the global policy.
USE ROLE SECURITYADMIN;
CREATE OR REPLACE NETWORK POLICY corp_prod_policy
ALLOWED_NETWORK_RULE_LIST = ('corp_office_ipv4', 'prod_vpce_aws', 'prod_pl_azure')
BLOCKED_NETWORK_RULE_LIST = ('deny_sources')
COMMENT = 'Production policy: corp office + PrivateLink only';
-- Attach to the entire account (most restrictive default)
ALTER ACCOUNT SET NETWORK_POLICY = corp_prod_policy;
-- Punt the break-glass admin to a less restrictive user-level policy
CREATE NETWORK POLICY break_glass_policy
ALLOWED_NETWORK_RULE_LIST = ('corp_office_ipv4');
ALTER USER break_glass_admin SET NETWORK_POLICY = break_glass_policy;
-- Inspect what is currently bound
SHOW NETWORK POLICIES;
DESC NETWORK POLICY corp_prod_policy;
-- Audit who has user-level overrides
SELECT name, network_policy
FROM SNOWFLAKE.ACCOUNT_USAGE.USERS
WHERE network_policy IS NOT NULL
AND deleted_on IS NULL;
Order of evaluation: blocklist wins. If an IP appears in both the allow and deny rule lists, the request is rejected. Account-level BLOCKED rules apply even when a user-level policy says allow.
PrivateLink replaces the public Snowflake URL with a private endpoint that resolves only inside your VPC. The Snowflake side is provisioned by support or by the SYSTEM$AUTHORIZE_PRIVATELINK family of stored procedures; the cloud side is a standard VPC endpoint or Private Endpoint resource.
account.snowflakecomputing.com resolves to the endpoint's private IP. The corresponding network rule type is AWSVPCEID.AZURELINKID, taking the Azure resource ID of the private endpoint.
-- Retrieve the Snowflake-side PrivateLink config to give to your cloud team
SELECT SYSTEM$GET_PRIVATELINK_CONFIG();
-- Self-service authorization of a new VPCE id (AWS)
CALL SYSTEM$AUTHORIZE_PRIVATELINK(
'aws-arn-or-account-id',
'vpce-0aaaa1111bbbb2222c'
);
-- Revoke when an environment is decommissioned
CALL SYSTEM$REVOKE_PRIVATELINK(
'aws-arn-or-account-id',
'vpce-0aaaa1111bbbb2222c'
);
PrivateLink alone does not enforce that only your VPCE may connect — Snowflake's edge still accepts public traffic to that account unless the network policy explicitly excludes the public internet. Always pair PrivateLink with a network policy whose ALLOWED_NETWORK_RULE_LIST contains the VPCE rule and nothing public.
Session policies are a complementary control: they cap how long an authenticated session can live before being forced to re-authenticate. This narrows the window for a stolen session token to be useful.
CREATE OR REPLACE SESSION POLICY analyst_session
SESSION_IDLE_TIMEOUT_MINS = 30
SESSION_UI_IDLE_TIMEOUT_MINS = 15
COMMENT = 'Analysts: 30-min idle, 15-min Snowsight idle';
ALTER ACCOUNT SET SESSION POLICY analyst_session;
-- Stricter policy for service users that should never be idle
CREATE OR REPLACE SESSION POLICY service_session
SESSION_IDLE_TIMEOUT_MINS = 5;
ALTER USER svc_etl_loader SET SESSION POLICY service_session;
ALTER ACCOUNT. A misconfigured account-level policy locks out everyone, including you — recovery requires a Snowflake support ticket.LOGIN_HISTORY.SHOW NETWORK POLICIES output and user-level overrides against the IaC source of truth. The SNOWFLAKE.ACCOUNT_USAGE.NETWORK_POLICIES view gives history.