How to Audit Access in Snowflake

Galaxy Glossary

How do I audit data access in Snowflake using ACCESS_HISTORY?

Audit Access lets you trace who queried which tables, columns, and rows in Snowflake for security and compliance.

Sign up for the latest in SQL knowledge from the Galaxy Team!
Welcome to the Galaxy, Guardian!
Oops! Something went wrong while submitting the form.

Description

What is Access History in Snowflake?

Access History is a system view that records every successful query and the exact objects, columns, and masking policies it touched. It is the foundation for auditing who saw what.

How do I audit data access in Snowflake?

Run SELECT statements against the SNOWFLAKE.ACCOUNT_USAGE.ACCESS_HISTORY or ORGANIZATION_USAGE.ACCESS_HISTORY views.Filter by object name, user, or time range to pinpoint activity.

Example: Who read Customers.email last week?

Use a WHERE clause on OBJECT_NAME, COLUMN_NAME, and QUERY_START_TIME to isolate reads of sensitive columns.

How can I join Access History with query text?

Join ACCESS_HISTORY to QUERY_HISTORY on QUERY_ID to see the full SQL that touched your data.

Which roles can query Access History?

Only ACCOUNTADMIN and ORGADMIN have default rights.Grant the MONITOR USAGE global privilege to custom roles that need audit visibility.

Best practices for reliable audits

Store audit extracts in a secure database, schedule daily exports, and keep at least 90 days of data.Use masking policies and row access policies to reduce exposure.

Tip: Automate alerts for suspicious activity

Write tasks that scan ACCESS_HISTORY for unexpected access—e.g., a sales role querying the Products.stock column—and send alerts via email or Slack.

How long is Access History retained?

ACCOUNT_USAGE keeps 365 days; ORGANIZATION_USAGE keeps 365 days for Enterprise Edition and above. Export data if you need longer retention.

.

Why How to Audit Access in Snowflake is important

How to Audit Access in Snowflake Example Usage


-- Detect who viewed high-value customer emails in the last 7 days
SELECT ah.user_name,
       qh.query_text,
       ah.query_start_time
FROM snowflake.account_usage.access_history   AS ah
JOIN snowflake.account_usage.query_history    AS qh
  ON ah.query_id = qh.query_id
WHERE ah.object_name = 'CUSTOMERS'
  AND ah.column_name  = 'EMAIL'
  AND ah.query_start_time >= DATEADD('day', -7, CURRENT_TIMESTAMP());

How to Audit Access in Snowflake Syntax


-- Basic access audit
SELECT *
FROM snowflake.account_usage.access_history;

-- Filter by object and date
SELECT query_id,
       user_name,
       object_name,
       column_name,
       direct_objects_accessed,
       query_start_time
FROM snowflake.account_usage.access_history
WHERE object_name = 'CUSTOMERS'
  AND column_name = 'EMAIL'
  AND query_start_time >= DATEADD('day', -7, CURRENT_TIMESTAMP());

-- Join with query text
SELECT ah.user_name,
       qh.query_text,
       ah.query_start_time
FROM snowflake.account_usage.access_history AS ah
JOIN snowflake.account_usage.query_history AS qh
  ON ah.query_id = qh.query_id
WHERE ah.object_name = 'ORDERS'

Common Mistakes

Frequently Asked Questions (FAQs)

Is ACCESS_HISTORY available in all Snowflake editions?

Yes, but Standard Edition retains only 7 days; Enterprise and above keep 365 days.

Can I see failed queries?

No. ACCESS_HISTORY logs only successful queries. Use LOGIN_HISTORY and QUERY_HISTORY for failures.

How do I retain audit data longer than 365 days?

Create a scheduled task that copies ACCESS_HISTORY into a long-term storage table or external stage.

Want to learn about other SQL terms?

Trusted by top engineers on high-velocity teams
Aryeo Logo
Assort Health
Curri
Rubie
BauHealth Logo
Truvideo Logo
Welcome to the Galaxy, Guardian!
Oops! Something went wrong while submitting the form.