Snowflake

⚠️

The Snowflake source requires a Pro plan subscription in RunReveal.

The Snowflake source collects audit and activity logs from your Snowflake account via the SNOWFLAKE.ACCOUNT_USAGE views. A single source instance polls three views automatically:

  • Login History — authentication events including successful and failed login attempts, MFA usage, and client information.
  • Query History — every query executed in your account, including the SQL text, execution status, user, role, warehouse, and performance metrics.
  • Access History — data access patterns showing which objects (tables, views, columns) were read or modified by each query, plus any policies evaluated.

All three views use the same OAuth credentials, so no additional configuration is needed beyond the standard setup below.

Query History and Access History are available on all Snowflake editions. However, ACCESS_HISTORY requires Snowflake Enterprise Edition or higher. If your account does not support it, RunReveal will continue collecting login and query history without interruption.

Setup

Step 1: Whitelist RunReveal IP addresses (if required)

If your Snowflake account has IP allowlisting enabled, you’ll need to whitelist RunReveal’s outbound IP addresses before the integration can connect. See Network Connectivity and IP Whitelisting for the IP addresses to add to your Snowflake network policy allowlist.

Step 2: Start RunReveal source creation

  1. Navigate to the RunReveal UI and go to the source creation page.
  2. Select “Snowflake” as your source type.
  3. Provide a descriptive name for your Snowflake source.
  4. Fill in your Snowflake Account Identifier. See the Snowflake docs on Account Identifiers for more information.
  5. Copy the Redirect URL provided near the top of the page — you’ll need this later.

Step 3: Create a new Snowflake role

  1. Log into Snowflake and open a worksheet.
  2. Execute the following commands:
    CREATE ROLE runreveal_role;
    GRANT IMPORTED PRIVILEGES ON DATABASE SNOWFLAKE TO ROLE runreveal_role;
    GRANT USAGE ON WAREHOUSE COMPUTE_WH TO ROLE runreveal_role;

Note: You may use a different role name here, but be sure to use the same role in later commands, and change the default role on the Source settings page in RunReveal.

Step 4: Create a service user in Snowflake

This is the account you’ll use to authenticate with Snowflake during the OAuth flow when adding the source.

  1. You can create the user through the Snowflake UI, or with a SQL statement like this:

    CREATE USER svc_runreveal
      PASSWORD = 'abc123_Be57P@Ssw0rd_Ev3r'
      DEFAULT_ROLE = runreveal_role
      DEFAULT_WAREHOUSE = COMPUTE_WH;
  2. Then grant the custom role you created earlier to this service user:

    GRANT ROLE runreveal_role TO USER svc_runreveal;

Step 5: Create a “Security Integration” in Snowflake

From a Snowflake worksheet, execute the following command — substitute the Redirect URL you copied earlier for the OAUTH_REDIRECT_URI value.

CREATE SECURITY INTEGRATION RUNREVEAL
  TYPE = OAUTH
  OAUTH_CLIENT = CUSTOM
  OAUTH_CLIENT_TYPE = 'CONFIDENTIAL'
  OAUTH_REDIRECT_URI = 'https://www-api.runreveal.com/sources/snowflake/auth/cb/<YOUR_UNIQUE_IDENTIFIER_HERE>'
  OAUTH_ISSUE_REFRESH_TOKENS = TRUE
  ENABLED = TRUE
  PRE_AUTHORIZED_ROLES_LIST = ('RUNREVEAL_ROLE')
  OAUTH_ALLOW_NON_TLS_REDIRECT_URI = FALSE
  COMMENT = 'This is the OAuth integration that allows RunReveal to retrieve audit logs from Snowflake';

See also Snowflake docs on “CREATE SECURITY INTEGRATION (Snowflake OAuth)“

Step 6: Collect the OAuth details for the new integration

You’ll need to supply the OAuth Client ID and Client Secret to RunReveal so it can connect to Snowflake.

Run the following commands from your Snowflake worksheet.

  1. For the Client ID:

    SELECT get_path(parse_json(SELECT SYSTEM$SHOW_OAUTH_CLIENT_SECRETS( 'RUNREVEAL' )),
                    'OAUTH_CLIENT_ID');
  2. For the Client Secret:

    SELECT get_path(parse_json(SELECT SYSTEM$SHOW_OAUTH_CLIENT_SECRETS( 'RUNREVEAL' )),
                    'OAUTH_CLIENT_SECRET');

Copy each of these strings without the quotes.

Step 7: Complete the source creation in RunReveal

  1. Return to the page you opened earlier on RunReveal and fill in the remaining values: Client ID and Client Secret. Make sure your Account Identifier is filled in, and that the Snowflake role matches the one you used in the above steps.
  2. Click Connect
  3. You will be sent to a Snowflake login page — log in with the username and password of the service user you created earlier (ex: svc_runreveal).

Verify It’s Working

Once added, the source logs should begin flowing within a few minutes. Login history events appear first (up to 2-hour latency from Snowflake), followed by query history (up to 1 hour) and access history (up to 3 hours).

You can validate that logs are flowing by running the following SQL query:

SELECT * FROM runreveal.logs WHERE sourceType = 'snowflake' LIMIT 10

To check each event type specifically, use the serviceName field:

-- Login events
SELECT * FROM runreveal.logs
WHERE sourceType = 'snowflake' AND serviceName = 'login_history'
LIMIT 5
 
-- Query history events
SELECT * FROM runreveal.logs
WHERE sourceType = 'snowflake' AND serviceName = 'query_history'
LIMIT 5
 
-- Access history events
SELECT * FROM runreveal.logs
WHERE sourceType = 'snowflake' AND serviceName = 'access_history'
LIMIT 5

What’s Collected

Login History

Sourced from SNOWFLAKE.ACCOUNT_USAGE.LOGIN_HISTORY. Captures every authentication attempt to your Snowflake account, including:

  • User identity and client IP address
  • Authentication factors (password, MFA, SSO)
  • Success or failure status with error codes
  • Client type and version (Snowflake UI, JDBC driver, SnowSQL, etc.)

Query History

Sourced from SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY. Captures every query executed in your account, including:

  • Full SQL query text
  • Database, schema, and warehouse context
  • User and role that executed the query
  • Execution status, error codes, and performance metrics (elapsed time, bytes scanned, rows produced)
  • Query tags for custom attribution

Access History

Sourced from SNOWFLAKE.ACCOUNT_USAGE.ACCESS_HISTORY. Tracks which data objects each query touched, including:

  • Direct and base objects accessed (tables, views, columns)
  • Objects modified (inserts, updates, DDL changes)
  • Policies evaluated during query execution (masking, row access)

Access History requires Snowflake Enterprise Edition or higher. If your account does not support it, this view is automatically skipped and the other two views continue to be polled.

Schema

The following columns are exposed for this source. RunReveal applies schema normalization across all sources, ensuring uniform field names and data types for cross-source queries and reusable detection logic.

Table: snowflake_logs
ColumnType
workspaceIDString
sourceIDString
sourceTypeString
sourceTTLUInt32
receivedAtDateTime
idString
eventTimeDateTime
eventNameString
eventIDString
srcIPString
srcASCountryCodeString
srcASNumberUInt32
srcASOrganizationString
srcCityString
srcConnectionTypeString
srcISPString
srcLatitudeFloat64
srcLongitudeFloat64
srcUserTypeString
dstIPString
dstASCountryCodeString
dstASNumberUInt32
dstASOrganizationString
dstCityString
ColumnType
dstConnectionTypeString
dstISPString
dstLatitudeFloat64
dstLongitudeFloat64
dstUserTypeString
actorMap(String, String)
tagsMap(String, String)
resourcesArray(String)
serviceNameString
enrichmentsArray(Tuple(data Map(String, String), name String, provider String, type String, value String))
readOnlyBool
rawLogString
snowflakeReportedClientTypeString
snowflakeReportedClientVersionString
snowflakeFirstAuthenticationFactorString
snowflakeSecondAuthenticationFactorString
snowflakeIsSuccessString
snowflakeErrorCodeInt32
snowflakeErrorMessageString
snowflakeRelatedEventIDInt32
snowflakeConnectionString
snowflakeClientPrivateLinkIDString
snowflakeFirstAuthenticationFactorIDString
snowflakeSecondAuthenticationFactorIDString

All three event types (login history, query history, and access history) are stored in this table. Use the serviceName field to distinguish between them:

  • Login events (serviceName = 'login_history'): eventName is the event type from Snowflake (e.g., LOGIN).
  • Query history events (serviceName = 'query_history'): eventName is the query type (SELECT, INSERT, CREATE_TABLE, etc.). Additional details are available in the tags map (e.g., tags['role_name'], tags['warehouse_name'], tags['execution_status'], tags['bytes_scanned']).
  • Access history events (serviceName = 'access_history'): eventName is ACCESS. The resources array contains the objects accessed and modified as "objectDomain - objectName" entries. The tags map includes tags['has_modifications'] to indicate whether data was changed.

Troubleshooting

Invalid Client

If you see this source error:

failed to get oauth token using refresh token: oauth2: "invalid_client"

it indicates trouble with the OAuth integration in Snowflake. Check that the Client ID and Client Secret you entered in RunReveal match the values from Snowflake.

If you get the error “Invalid consent request” when attempting to log into Snowflake as part of the OAuth flow in adding the source to RunReveal, check the following:

  • make sure you’re logging in with the correct service user credentials
  • make sure that user has been granted the correct role. (This will be runreveal_role if you followed the instructions above.)
  • make sure that role is mentioned in the CREATE SECURITY INTEGRATION statement you issued as part of the setup.

no refresh token available

If you see the source error no refresh token available, make sure you included OAUTH_ISSUE_REFRESH_TOKENS = TRUE when creating the integration.

User's configured default role 'OTHER_ROLE' is not granted to this user.

If you see this source error, be sure you’ve granted the correct role (usually runreveal_role) to the service user, and that you logged in with that service user during the OAuth flow.

'SNOWFLAKE.ACCOUNT_USAGE' does not exist or not authorized

If you see this source error, double check the runreveal_role (or other role, if you specified a different one in the Source setup page) was created properly, and that the role was granted to the service user.

you must specify the warehouse....

If you see this source error

snowflake API returned status code 422: Unable to run the command. You must specify the warehouse to use by either setting the warehouse field in the body of the request or by setting the DEFAULT_NAMESPACE property for the current user.

make sure to set DEFAULT_WAREHOUSE when creating the service user.

Query History falling behind on high-volume accounts

RunReveal polls up to 2,000 query history events per cycle. Snowflake accounts that execute more than roughly 2,000 queries per minute may see the query history lag behind. If you notice growing delays in query history events, contact support to discuss tuning options.

Query History or Access History not appearing

If you only see login events but not query or access history events:

  • Query History: Events have up to 1-hour latency in Snowflake. Wait at least 1 hour after setup before investigating.
  • Access History: Events have up to 3-hour latency. This view also requires Snowflake Enterprise Edition or higher. Check your Snowflake edition if access history events never appear.
  • Verify the service user’s role has IMPORTED PRIVILEGES ON DATABASE SNOWFLAKE granted, which provides access to all ACCOUNT_USAGE views.