> Spinning
← All 50 Days
Day 22 of 50
D2: Account & Governance Week 4
DAY 22

Snowflake Network Policies + Logging & Tracing with Event Tables

Today closes sub-objective 2.1 with two paired perimeter topics: network policies (who connects from where) and event-table logging (what code did once inside). One practice-doc question is wired in verbatim (Q17, session policies); the other four target network rules, precedence, IPv6 status, and event-table defaults.

📘

Today’s Concept

Micro-Concept 1: Network Policies, the Perimeter Object

A network policy is a Snowflake object that restricts which IP addresses can connect to an account or a specific user. Without one, any client anywhere on the public internet can attempt to log in. Authentication is still required, but the front door is open to the whole world.

The object itself is account-scoped and has two list-shaped properties for the legacy form: ALLOWED_IP_LIST and BLOCKED_IP_LIST. IP addresses are specified in CIDR notation. 192.168.1.0/24 covers the 256-address range starting at 192.168.1.0.

Three rules about these legacy properties matter for the exam.

ALLOWED_IP_LIST supports IPv4 only. IPv6 addresses cannot be placed in this list.
→ If BLOCKED_IP_LIST and ALLOWED_IP_LIST overlap, the block wins. Blocks are evaluated first.
→ An empty ALLOWED_IP_LIST combined with the property being specified means no IPv4 addresses can connect. That is a common self-lockout.

The role requirement is one of the most-tested facts in this area. SECURITYADMIN or higher creates network policies, or any custom role granted the global CREATE NETWORK POLICY privilege. SYSADMIN cannot. That distinction was the Day 19 lab failure step and is the documented answer to Practice doc Q32.

Micro-Concept 2: Network Rules, the Newer Building Block

Snowflake now recommends network rules in conjunction with network policies, rather than the inline ALLOWED_IP_LIST and BLOCKED_IP_LIST properties. A network rule is its own schema-level object. The policy then references it via ALLOWED_NETWORK_RULE_LIST or BLOCKED_NETWORK_RULE_LIST.

Network rules have two properties the exam writes around: TYPE and MODE.

TYPE valueWhat it identifiesNotes
IPV4IPv4 addresses or CIDR rangesThe standard case. Protects Snowflake service and internal stages.
IPV6IPv6 addresses or CIDR rangesPreview, AWS eu-west-1 only. Requires ENABLE_IPV6_NETWORK_RULES = TRUE. INGRESS only. Does NOT protect internal stages.
AWSVPCEIDAWS PrivateLink VPC endpoint IDsFor PrivateLink ingress.
AZURELINKIDAzure private endpoint LinkIDsFor Azure Private Link ingress.
GCPPSCIDGCP Private Service Connect IDsFor GCP PSC ingress.
HOST_PORTExternal hostnames (and ports)For external access integrations, EGRESS mode.

The MODE is either INGRESS (incoming traffic, the default network-policy use case) or EGRESS (outgoing traffic, used by external access integrations). A third mode, INTERNAL_STAGE, restricts incoming traffic to the account’s internal stages. IPv6 rules support INGRESS only.

IPv4 and IPv6 network rules in the same policy evaluate independently. A request that arrives on IPv6 is checked against IPv6 rules. If the policy has no IPv6 rules, the IPv6 request is checked against IPv4 rules and will almost certainly fail. In a dual-stack environment you write rules for both address families.

Micro-Concept 3: Account-Level Versus User-Level (User Wins)

A network policy can be attached to the account or to a specific user. The account-level policy applies to every user by default. The user-level policy applies only to that one user. When both exist for the same user, the user-level policy takes precedence. The account-level policy is then ignored for that user.

The mental model that holds up across the exam: each user evaluates exactly one network policy at login. Snowflake looks for a user-level policy first. If one is set, the account-level policy does not apply.

That precedence is the source of two common production patterns. A locked-down account policy plus a permissive user-level policy on a single service account lets that account skip the global allow-list. A locked-down user-level policy on one administrator, with no account-level policy, restricts only that one user.

Attach via ALTER ACCOUNT SET NETWORK_POLICY = my_policy or ALTER USER alice SET NETWORK_POLICY = my_policy. Detach via UNSET NETWORK_POLICY on the same target.

Micro-Concept 4: The Lockout Escape Hatch

The most common production accident with network policies is self-lockout. An admin attaches a restrictive policy to their own account from the office, then tries to connect from a different network. The new IP is not in the allow list. The new login is refused.

Snowflake provides one escape route. The user property MINS_TO_BYPASS_NETWORK_POLICY temporarily disables policy enforcement for a user for a number of minutes. It is visible via DESCRIBE USER but only Snowflake Support can set it. Customers cannot.

That property is the documented break-glass mechanism. One piece of advice repeats across Snowflake training material. Never apply a restrictive network policy to your own admin account first. Test on a low-privilege test user, observe the block, then graduate to wider rollout. In production projects I have worked on, this discipline catches around half of the would-be lockouts before they happen.

Micro-Concept 5: Session Policies, an Adjacent Family

Network policies are not the only policy controlling who is connected. Session policies control how long an idle session can sit before requiring re-authentication. They are a sub-objective 2.1 item too and share the same account-or-user attachment model, with the same user-wins precedence.

The exam fact that anchors them is in the verbatim practice question Q1 below. The SESSION_IDLE_TIMEOUT_MINS parameter has a minimum of 5 minutes. Below that, the policy is rejected at creation.

The maximum, in current docs, is 1440 minutes (24 hours). Older practice banks still list 240 minutes as the ceiling. Memorize 5 minutes as the minimum. For the maximum, take whatever the question prints as correct unless it is below 240.

Session policies have a second timeout property: SESSION_UI_IDLE_TIMEOUT_MINS for Snowsight specifically, in addition to SESSION_IDLE_TIMEOUT_MINS for programmatic clients. A newer pair, SESSION_MAX_LIFESPAN_MINS and SESSION_UI_MAX_LIFESPAN_MINS, ends the session after a fixed duration regardless of activity. Maximum lifespan is configurable up to 30 days.

Session policies require Enterprise Edition or higher. Without a policy, the default idle timeout is 4 hours for programmatic sessions. For Snowsight, the default is 4 hours or 18 hours depending on whether the account opted into BCR-2139.

Micro-Concept 6: Event Tables, Where Logs and Traces Land

Sub-objective 2.1 explicitly lists “Logging and tracing.” The mechanism is the event table. An event table is a Snowflake-managed table with a fixed schema. It captures three kinds of telemetry data from your code: log messages, trace events (spans), and metrics.

Since BCR-1598 (June 2024), Snowflake provides a default event table at SNOWFLAKE.TELEMETRY.EVENTS. If no other event table is associated with the account, that one is active. A predefined view SNOWFLAKE.TELEMETRY.EVENTS_VIEW sits on top of it. Most accounts do not need to create a custom event table at all.

When you do want a custom event table, the DDL is straightforward.

SQL
-- One-time setup, run as ACCOUNTADMIN
CREATE DATABASE telemetry_db;
CREATE SCHEMA telemetry_db.events;
CREATE EVENT TABLE telemetry_db.events.app_events;

-- Make it the active event table for the account
ALTER ACCOUNT SET EVENT_TABLE = telemetry_db.events.app_events;

The columns of an event table are predefined. You do not specify them in the DDL. They include TIMESTAMP, RECORD_TYPE (LOG, SPAN, or SPAN_EVENT), RECORD (severity for logs, name for traces), RECORD_ATTRIBUTES, RESOURCE_ATTRIBUTES, and a value column. The schema is the same whether you use the default event table or a custom one.

One account-level fact matters here. Each Snowflake account has one active event table at a time. You can have many event tables created, but only one is set as the EVENT_TABLE on the account at any given moment. Telemetry from a specific database can be routed to a different event table by setting EVENT_TABLE at the database level. The more-specific scope wins.

Micro-Concept 7: Telemetry Levels Control What Is Actually Captured

Creating the event table and pointing the account at it is not enough. By default, no telemetry data is collected. You also have to set telemetry levels. These are parameters that act as filters: only events at the configured level or more severe are written to the event table.

ParameterWhat it controlsLevels (most → least verbose)
LOG_LEVELLogs from procedures and UDFs (logging APIs)TRACE → DEBUG → INFO → WARN → ERROR → FATAL → OFF
TRACE_LEVELTrace events (spans) from procedures and UDFsALWAYS → ON_EVENT → OFF
METRIC_LEVELMetrics dataALL or NONE
LOG_EVENT_LEVELSystem log events (Snowpipe, tasks, dynamic tables, Iceberg refresh, tag activity)Same levels as LOG_LEVEL

The default for all of these is OFF. Setting LOG_LEVEL = WARN means WARN, ERROR, and FATAL are captured. INFO and DEBUG are not. The verbosity cascade is one of the more catch-out details on the exam.

Telemetry levels can be set at multiple scopes. The precedence is most-specific wins, mirroring the parameter rule from Day 6.

Session overrides object. Object (a procedure or UDF) overrides schema. Schema overrides database. Database overrides account. The hierarchy is on the exam in the same shape as Day 6.

From inside a Snowflake Scripting stored procedure, you emit a log line with SYSTEM$LOG('info', 'My message'). The corresponding language-specific APIs exist for Python, Java, Scala, and JavaScript. The data lands in the active event table when the relevant level allows it.

Cheat Sheet

TopicWhat to rememberExam keyword
Network policy roleSECURITYADMIN or higher creates them. NOT SYSADMIN“SECURITYADMIN”
PrecedenceUser-level network policy wins over account-level“User policy wins”
ALLOWED_IP_LISTIPv4 only. CIDR notation. Use network rules for IPv6“IPv4 only”
IPv6 statusPreview, AWS eu-west-1 only. Needs ENABLE_IPV6_NETWORK_RULES = TRUE. INGRESS only. Does not protect internal stages“IPv6 preview”
Lockout bypassMINS_TO_BYPASS_NETWORK_POLICY is set ONLY by Snowflake Support. Customers cannot“Support sets”
Network rules vs policiesRules are reusable building blocks. Policies reference them via ALLOWED_NETWORK_RULE_LIST“Network rule TYPE”
Session policy minimumSESSION_IDLE_TIMEOUT_MINS minimum is 5 minutes“5-minute minimum”
Session policy editionEnterprise+ required“Enterprise+”
Default event tableSNOWFLAKE.TELEMETRY.EVENTS, active by default since BCR-1598“TELEMETRY.EVENTS”
Telemetry defaultDefault LOG_LEVEL and TRACE_LEVEL are OFF. No data captured until you set them“OFF by default”
Level cascadeMost-specific scope wins: session > object > schema > database > account“Most-specific wins”
Event table sourcesStored procedures and UDFs (SQL, Python, Java, Scala, JavaScript), plus system events from Snowpipe / tasks / dynamic tables / Iceberg / tags“UDFs and procedures”
🎯

Exam Tip

🎯 Exam Tip

Three traps appear in different forms on this material. Read each carefully.

Trap 1: “SYSADMIN creates network policies.” FALSE. The role for network policies is SECURITYADMIN (or higher, or a custom role with the global CREATE NETWORK POLICY privilege). Day 19 already flagged this; the exam re-tests it inside scenario questions where SYSADMIN sounds like the operationally correct answer. It is not.

Trap 2: “Account-level policy overrides user-level policy.” FALSE. The user-level policy wins. If a question hands you both and asks which applies to a specific user, pick the user-level one. This is the same most-specific-wins pattern as parameter precedence (Day 6) and telemetry levels (today). When you see two scopes, take the smaller scope.

Trap 3: “Once you create an event table, logs start flowing.” FALSE. The event table is the storage location. Telemetry levels (LOG_LEVEL, TRACE_LEVEL) are the on switch. Default for both is OFF. The exam writes a scenario around this. The setup looks complete, but the event table stays empty. The answer is always “set the level on the relevant scope.” Warehouse size, edition, and event-table schema are distractors.

🛠️

Hands-On Lab

Type: LAB (guided)  |  Time: ~25 minutes  |  Credits: <0.2  |  Prerequisite: Snowflake trial on Enterprise edition, lab_xs warehouse from Day 1. Run as ACCOUNTADMIN unless a step says otherwise.
1

Inspect the existing perimeter. Before creating anything, see what is already in place.

SQL
USE ROLE ACCOUNTADMIN;
USE WAREHOUSE lab_xs;

SHOW NETWORK POLICIES;
SHOW PARAMETERS LIKE 'NETWORK_POLICY' IN ACCOUNT;

-- See your current IP as Snowflake sees it
SELECT CURRENT_IP_ADDRESS();
👀 Observe: On a fresh trial, SHOW NETWORK POLICIES returns no rows. The account parameter NETWORK_POLICY is empty. Anyone with valid credentials can connect from anywhere. CURRENT_IP_ADDRESS() returns the IP Snowflake observed. Note this value. It is what you would want to include in your own allow-list later.
2

Build a network policy from network rules. This is the current best-practice pattern. We will not attach it to the account yet.

SQL
CREATE DATABASE IF NOT EXISTS day22_lab;
CREATE SCHEMA IF NOT EXISTS day22_lab.security;
USE SCHEMA day22_lab.security;

-- An allow rule for a fictional office range
CREATE NETWORK RULE allow_office_ipv4
  TYPE = IPV4
  MODE = INGRESS
  VALUE_LIST = ('192.168.10.0/24', '10.0.0.0/16')
  COMMENT = 'Day 22 lab: example office subnet';

-- A block rule for one rogue address
CREATE NETWORK RULE block_one_ipv4
  TYPE = IPV4
  MODE = INGRESS
  VALUE_LIST = ('203.0.113.99')
  COMMENT = 'Day 22 lab: example blocked host';

-- Compose the policy from the two rules
CREATE NETWORK POLICY day22_policy
  ALLOWED_NETWORK_RULE_LIST = ('day22_lab.security.allow_office_ipv4')
  BLOCKED_NETWORK_RULE_LIST = ('day22_lab.security.block_one_ipv4')
  COMMENT = 'Day 22 lab policy. Do not attach to account.';

DESCRIBE NETWORK POLICY day22_policy;
SHOW NETWORK RULES IN SCHEMA day22_lab.security;
👀 Observe: The policy lists the rules by fully-qualified name. DESCRIBE NETWORK POLICY returns one row per rule plus any inline IP lists. Notice we did NOT execute ALTER ACCOUNT SET NETWORK_POLICY = day22_policy. If we did, with CURRENT_IP_ADDRESS() not in the allow list, the next connection attempt would fail. Only Snowflake Support can release a self-lockout via MINS_TO_BYPASS_NETWORK_POLICY.
3

Prove the SYSADMIN trap. This is the second-favorite Domain 2 trap (after edition boundaries).

SQL
-- Switch to SYSADMIN and try to create a new policy
USE ROLE SYSADMIN;

CREATE NETWORK POLICY sysadmin_attempt
  ALLOWED_IP_LIST = ('203.0.113.10');
-- Expected: error.
-- "Insufficient privileges to operate on account"

-- Back to ACCOUNTADMIN to continue
USE ROLE ACCOUNTADMIN;
👀 Observe: SYSADMIN cannot create network policies. It owns warehouses and databases, not security perimeter objects. The same statement run as SECURITYADMIN succeeds. This is exactly the COF-C03 Q32 pattern from the practice bank. Day 19 lab proved the same point; today proves it again because the exam keeps testing it.
4

Create a session policy and observe the 5-minute floor.

SQL
USE SCHEMA day22_lab.security;

-- Try below the minimum (this WILL fail)
CREATE SESSION POLICY too_short
  SESSION_IDLE_TIMEOUT_MINS = 2;
-- Expected: error. "value must be >= 5"

-- Valid policy at the minimum
CREATE SESSION POLICY day22_session
  SESSION_IDLE_TIMEOUT_MINS = 5
  SESSION_UI_IDLE_TIMEOUT_MINS = 5
  COMMENT = 'Day 22 lab: 5-minute idle on both surfaces';

SHOW SESSION POLICIES;
DESCRIBE SESSION POLICY day22_session;
👀 Observe: The 2-minute attempt fails outright. Snowflake enforces the 5-minute floor at DDL time. That floor is the verbatim answer to today’s Practice Q1. SESSION_IDLE_TIMEOUT_MINS is for programmatic clients (drivers, CLI). SESSION_UI_IDLE_TIMEOUT_MINS is for Snowsight. They can hold different values. We are not attaching this policy to the account either, to avoid forcing a re-login mid-lab.
5

Inspect the default event table. Since BCR-1598, you do not need to create one.

SQL
SHOW PARAMETERS LIKE 'EVENT_TABLE' IN ACCOUNT;
SHOW PARAMETERS LIKE 'LOG_LEVEL' IN ACCOUNT;
SHOW PARAMETERS LIKE 'TRACE_LEVEL' IN ACCOUNT;

-- The default event table and its view
SHOW EVENT TABLES IN SCHEMA SNOWFLAKE.TELEMETRY;
SELECT COUNT(*) AS rows_in_default_event_table
  FROM SNOWFLAKE.TELEMETRY.EVENTS;
👀 Observe: The EVENT_TABLE parameter may be empty or already point at SNOWFLAKE.TELEMETRY.EVENTS. LOG_LEVEL and TRACE_LEVEL show OFF by default at the account scope. The default event table exists but is empty until you both set a level and run code that emits telemetry. This is the source of the “event table is empty” support ticket the exam writes scenarios around.
6

Turn on logging and emit a message.

SQL
-- Set the level on the account (account scope, easiest demo)
ALTER ACCOUNT SET LOG_LEVEL = INFO;

-- A tiny SQL stored procedure that emits a log line
CREATE OR REPLACE PROCEDURE day22_lab.security.say_hello()
  RETURNS STRING
  LANGUAGE SQL
AS
$$
BEGIN
  SYSTEM$LOG('info', 'Day 22 lab: hello from say_hello()');
  RETURN 'ok';
END;
$$;

CALL day22_lab.security.say_hello();

-- Wait ~1 minute for the event to appear, then query
SELECT TIMESTAMP, RECORD_TYPE, RECORD, RECORD_ATTRIBUTES, VALUE
  FROM SNOWFLAKE.TELEMETRY.EVENTS
  WHERE RECORD:severity_text::STRING = 'INFO'
    AND TIMESTAMP > DATEADD('minute', -5, CURRENT_TIMESTAMP())
  ORDER BY TIMESTAMP DESC
  LIMIT 5;
👀 Observe: Telemetry has a small ingestion delay. Wait a minute, then re-query. You should see the “Day 22 lab: hello” message land in the event table with RECORD_TYPE = 'LOG'. If nothing appears, the most likely cause is the level. Re-check SHOW PARAMETERS LIKE 'LOG_LEVEL' at every relevant scope. In training sessions I have run, the level is the first thing people forget to set after creating the event table.
7

Cleanup. Drop everything created today.

SQL
USE ROLE ACCOUNTADMIN;

-- Reset the account log level so the default event table goes quiet
ALTER ACCOUNT SET LOG_LEVEL = OFF;

-- Drop the policies, rules, procedure, and lab database
DROP PROCEDURE IF EXISTS day22_lab.security.say_hello();
DROP SESSION POLICY IF EXISTS day22_lab.security.day22_session;
DROP NETWORK POLICY  IF EXISTS day22_policy;
DROP NETWORK RULE    IF EXISTS day22_lab.security.allow_office_ipv4;
DROP NETWORK RULE    IF EXISTS day22_lab.security.block_one_ipv4;
DROP DATABASE        IF EXISTS day22_lab;

-- Verify lab_xs is still around for tomorrow
SHOW WAREHOUSES LIKE 'LAB_XS';
👀 Observe: Dropping the policy does not drop the rules; rules are independent schema objects. The DROP DATABASE catches the rules and the procedure together. lab_xs stays for tomorrow’s masking and row-access policy lab. The day10_orders table is not touched today.
❄️

Snowflake Documentation

🔗

External References

Practice Questions

Options:

A. 2 minutes
B. 5 minutes
C. 10 minutes
D. 15 minutes

✅ Answer: B

Why B: The SESSION_IDLE_TIMEOUT_MINS parameter on a session policy has a documented minimum of 5 minutes. The DDL fails at parse time if a lower value is supplied. Today’s lab Step 4 demonstrates this with the 2-minute attempt.

Why not A: 2 minutes is below the floor and is the most common distractor. The exam picks this because it sounds like a natural “tightly secured” value.

Why not C, D: Both are valid timeout values but neither is the minimum. The question asks for the floor, not a typical setting.

Options:

A. Both policies are evaluated. Both must allow the IP for the login to succeed
B. The account-level policy is evaluated. User-level is ignored when an account-level policy exists
C. The user-level policy is evaluated. The account-level policy is not applied to this user
D. Whichever policy was created most recently takes precedence

✅ Answer: C

Why C: When both an account-level and a user-level network policy exist, the user-level policy wins for that specific user. Only one network policy is evaluated per login. This is the same most-specific-scope-wins pattern that runs through Snowflake’s other policy and parameter systems.

Why not A: Network policies are not evaluated in conjunction. They do not intersect or union. Pick one of the wrong-direction answers and you can lock yourself out.

Why not B: This is the opposite of the real precedence. It catches candidates who assume the broader scope dominates the narrower one.

Why not D: Creation time has no role in policy precedence. Pure distractor.

Options:

A. Add both IPv4 and IPv6 addresses to ALLOWED_IP_LIST on the network policy
B. Create separate network rules for each address family. Reference both in ALLOWED_NETWORK_RULE_LIST. Enable the ENABLE_IPV6_NETWORK_RULES account parameter
C. Snowflake does not support IPv6 connections under any configuration
D. Set ALLOWED_IP_LIST for IPv4 and ALLOWED_NETWORK_RULE_LIST for IPv6, with no other configuration

✅ Answer: B

Why B: ALLOWED_IP_LIST is IPv4 only. IPv6 requires network rules with TYPE = IPV6, the ENABLE_IPV6_NETWORK_RULES = TRUE account parameter, and is currently in preview on AWS eu-west-1. IPv4 and IPv6 rules evaluate independently, so a dual-stack deployment needs both.

Why not A: ALLOWED_IP_LIST rejects IPv6 entries. The DDL fails. This is the easiest trap because the property name does not advertise the IPv4 limitation.

Why not C: IPv6 is supported via network rules in the relevant preview region. “Not supported under any configuration” is too absolute.

Why not D: Missing the ENABLE_IPV6_NETWORK_RULES parameter means the IPv6 rule has no effect even after creation. Half-configuration is still configuration drift.

Options:

A. The event table needs to be on a separate warehouse
B. The LOG_LEVEL parameter is set to OFF at every relevant scope
C. SYSTEM$LOG only works for Python stored procedures
D. Stored procedures cannot emit log events. Only UDFs can

✅ Answer: B

Why B: Creating an event table is not enough. Snowflake also requires a telemetry level to be set so that emitted events are actually captured. The default for LOG_LEVEL at the account scope is OFF. With OFF at every scope (session, object, schema, database, account), no log message is written even when handler code calls SYSTEM$LOG. Set LOG_LEVEL to INFO or another non-OFF value at the appropriate scope.

Why not A: Event tables do not use a warehouse. Telemetry data ingestion is handled by Snowflake. Warehouse association is not a concept here.

Why not C: SYSTEM$LOG works for Snowflake Scripting and other handler languages. Language-specific APIs exist for Python, Java, Scala, and JavaScript.

Why not D: Both stored procedures and UDFs (and UDTFs) can emit log and trace events. The asymmetry in this option is invented.

Options:

A. An account can have multiple active event tables receiving telemetry at the same time
B. SNOWFLAKE.TELEMETRY.EVENTS is the default event table activated for an account that has no other event table associated
C. When LOG_LEVEL is set to WARN, log messages at WARN, ERROR, and FATAL levels are captured
D. Telemetry levels can only be set at the account scope. Object-level overrides are not supported
E. Event tables collect log and trace data, but not metrics

✅ Answer: B and C

Why B: Since BCR-1598 (June 2024), Snowflake provides SNOWFLAKE.TELEMETRY.EVENTS as a built-in default event table. If no other event table is set as the account’s active event table, this default is used. A predefined view EVENTS_VIEW in the same schema queries it.

Why C: Telemetry levels follow a severity hierarchy. Setting LOG_LEVEL = WARN captures WARN and everything more severe, which is WARN, ERROR, and FATAL. Less severe levels (INFO, DEBUG, TRACE) are dropped.

Why not A: An account has only one active event table at a time, set via ALTER ACCOUNT SET EVENT_TABLE. Object-level EVENT_TABLE parameters can route telemetry from specific objects to a different event table, but the account itself has one active table.

Why not D: Telemetry levels can be set at session, object, schema, database, and account scopes. Most-specific scope wins. Re-read Day 6 if missed.

Why not E: Event tables collect logs, traces (spans), and metrics. The METRIC_LEVEL parameter controls metrics capture.

📝 Recap

Today you learned: Network policies restrict which IPs can connect to an account or a specific user. SECURITYADMIN or higher creates them. User-level wins over account-level. ALLOWED_IP_LIST is IPv4 only. For IPv6, you use network rules with TYPE = IPV6 plus the ENABLE_IPV6_NETWORK_RULES account parameter, currently in preview on AWS eu-west-1. Self-lockouts can only be cleared by Snowflake Support via MINS_TO_BYPASS_NETWORK_POLICY.

Session policies sit next to network policies and follow the same attachment model. The minimum idle timeout is 5 minutes, Enterprise+ required.

Logging and tracing run through event tables. SNOWFLAKE.TELEMETRY.EVENTS is the default event table since BCR-1598 in June 2024. The catch is that LOG_LEVEL and TRACE_LEVEL default to OFF. Until you set them at the right scope, nothing is captured. The level cascade is the same most-specific-wins rule from Day 6 parameters.

Tomorrow (Day 23): Data Masking, Row Access Policies, and Privacy Policies. Three distinct sub-objective 2.2 policy types, all Enterprise+, all column-or-row level controls on what queriers actually see in result sets. The C03 outline lists them separately, and the exam tests them as separate features.

Abhay Krishnan

Abhay Krishnan

Senior Data & AI Consultant
Connect on LinkedIn

With over five years of data engineering experience at EY and Infosys, Abhay Krishnan specializes in building scalable data pipelines and cloud warehousing solutions. He is a certified SnowPro Core professional, alongside credentials in AWS and Azure. Abhay created this 50-day track to solve a problem he faced firsthand: the lack of a structured, free resource for Snowflake certification prep. Follow him on LinkedIn for more data engineering insights.