Securing Snowflake with Network Access Policies
At Canvas, we believe data warehouses exist to democratize access to data. Fivetran brings the data from every application your team uses. dbt transforms data from the format your machines prefer to a format humans can understand. Finally, Canvas brings the data to your people.
Serving everyone is the purpose of a data warehouse. Unfortunately, this makes security a greater challenge. Typically, you won’t be able to get away with placing your warehouse behind a private VPC as you might with your application database. Many of your data tools and some of your human users will need the ability to access your warehouse from the public internet.
This makes Snowflake’s network policies an essential layer of your security posture. Network policies tell Snowflake to only allow a user access from an enumerated list of IP addresses; traffic from all other sources is blocked.
This prevents an adversary from even attempting to brute force a user’s password unless they can first determine and gain control of the IP address. Because Snowflake only allows access via SSL, spoofing the IP address on network packets is very difficult for an attacker. And even if they could, they would not be able to receive the response (your data) unless they could also compromise the routing back to an IP address they own.
In this post I’ll describe:
- How you can add network policies to your Snowflake users for both your data apps and your human users.
- How you can enforce that all users have a network policy by default.
- How you can monitor your network policy posture in a tool like Canvas.
Creating and attaching network policies
Network policies can be created through the UI or via SQL; we use the latter here. To create the policy we need the list of IP addresses to whitelist. These are typically called Fixed IPs or Static IPs; for most applications, a Google search will turn up the addresses you need.
Let’s say we’d created a user
CANVAS_USER for use by Canvas from the IPs listed here. We then run the commands:
CREATE NETWORK POLICY CANVAS ALLOWED_IP_LIST = ('22.214.171.124', '126.96.36.199', '188.8.131.52'); ALTER USER CANVAS_USER SET NETWORK_POLICY = CANVAS;
Now, if you attempt to log into the Snowflake console with the user’s credentials you’ll be rejected:
Dealing with human users is trickier. Unless you’re paying for a fixed IP address, the address assigned to your home or office could change anytime (known as a dynamic IP address). And you often want your users to be able to connect to your warehouse from anywhere, not just the home or office.
The state-of-the-art here is to use PrivateLink to connect Snowflake to your cloud environment like AWS or Azure. Then, use DirectConnect to connect your users directly to the private cloud. In this configuration your Snowflake instance only need allow access from the internal network.
Unfortunately, this is quite difficult to set up. An easier solution that still provides many of the security benefits is to use a VPN product like NordVPN or Perimeter81 that can assign you a fixed IP address that you can whitelist. Then your users would log in to this VPN (hopefully using an additional layer of device-level security!) before logging in to your Snowflake instance. In this configuration you whitelist the static IP provided by the service as above.
Enforcing that users have network policies
Snowflake does not provide a way to require that users have a network policy set, in the way that you can set minimum password strength. To enforce that going forward all users have a network policy applied, the best pattern I’ve found is to set an account-level policy that is very restrictive. User-level network policies take precedence over account-level policies; so, to “enable” the user, the creator will have to assign a policy to that user.
Monitoring network policies
If you already have many users without network policies, or want ongoing monitoring of your user’s network policies, you need to be able to list all your users’ policies in one place.
Snowflake does not provide a UI or even a simple command that can list the network policies for every user. User network policies can only be viewed individually using the following command:
SHOW PARAMETERS like 'NETWORK_POLICY' for user "[username]";
The procedure below creates a
SNOWFLAKE_METRICS.NETWORK_POLICIES in the current database containing every user and its assigned network policy. This is a modified version of this script provided by the Snowflake community team:
Now I can bring this table into my favorite BI tool (Canvas!) to start visualizing my policy enforcement:
From here you can begin clicking into the different network policies and filtering your policies table to better understand your instance’s access control, or set up alerts for when users of a certain age still have no network policy.
No single security measure can ever be foolproof, but each additional security layer makes compromising the entire system exponentially more difficult. IP whitelisting aligns with the Zero Trust maxim of “Deny all, permit by exception”. This simple change will greatly reduce the vulnerable surface area of your Snowflake instance.
If you’d like to learn more about setting up a dashboard for monitoring user access - or if you’d like us to just set up your entire warehouse for you - please drop me a line!