Skip to main content

Snowflake Data Lake + GCS Integration with Program Access Token (PAT) Authentication

Written by Openbridge Support

This guide walks you through connecting your Snowflake warehouse to Openbridge using a Programmatic Access Token (PAT) with Google Cloud Storage (GCS) as the staging area. PAT authentication is simpler than OAuth — there is no recurring token refresh or manual re-authentication. You generate a token, provide it to Openbridge, and it remains valid until it expires. Token lifetime is controlled by your authentication policy; this guide configures a maximum of 365 days. When the token approaches expiration, you generate a new one.

Prerequisites

Before you begin, make sure you have:

  • An active Snowflake account with ACCOUNTADMIN privileges

  • A Google Cloud account with permissions to create GCS buckets and manage service accounts

Openbridge handles the rest automatically once your destination is configured.


Step 1: Create Your GCS Bucket

Openbridge uses a GCS bucket as a staging area to load data into Snowflake.

  1. In the Google Cloud Console, navigate to Cloud Storage > Buckets.

  2. Click Create.

  3. Enter a globally unique bucket name (e.g., openbridge-snowflake-staging).

  4. Choose a location type and region that aligns with your Snowflake account region.

  5. Leave other settings at their defaults and click Create.

Important: Note your bucket name exactly — you will need it in the next step. Bucket names are case-sensitive.


Step 2: Run the Openbridge Setup Script

Open a Snowflake worksheet and log in as ACCOUNTADMIN. Copy and customize the script below by replacing the placeholder variables at the top.

Variables to Customize

Variable

Description

Format

db_name

Name for the Openbridge database

UPPERCASE

schema_name

Name for the schema

UPPERCASE

user_name

Username for the Openbridge service account

UPPERCASE

role_name

Name for the Openbridge role

UPPERCASE

stage_name

Name for the external stage

UPPERCASE

warehouse_name

Name for the warehouse

UPPERCASE

warehouse_type

Warehouse type

UPPERCASE

warehouse_size

Warehouse size

UPPERCASE

gcs_bucket_name

Your GCS bucket name

Exact casing

Setup Script

-- ============================================
-- SET THESE VARIABLES BEFORE RUNNING
-- ============================================
SET db_name = 'OPENBRIDGE';
SET schema_name = 'OPENBRIDGE_SCHEMA';
SET user_name = 'OPENBRIDGE_USER';
SET role_name = 'OPENBRIDGE_ROLE';
SET stage_name = 'OPENBRIDGE_STAGE';
SET warehouse_name = 'OPENBRIDGE_WH';
SET warehouse_type = 'STANDARD';
SET warehouse_size = 'XSMALL';
SET gcs_bucket_name = 'your-bucket-name';

SET default_ns = $db_name || '.' || $schema_name;
SET gcs_url = 'gcs://' || $gcs_bucket_name || '/';

-- ============================================
-- CREATE ROLE
-- ============================================
USE ROLE ACCOUNTADMIN;
CREATE ROLE IF NOT EXISTS IDENTIFIER($role_name);

-- Grant the role to your current user (for testing purposes)
SET current_username = CURRENT_USER();
GRANT ROLE IDENTIFIER($role_name) TO USER IDENTIFIER($current_username);

-- ============================================
-- CREATE WAREHOUSE
-- ============================================
CREATE WAREHOUSE IF NOT EXISTS IDENTIFIER($warehouse_name)
WAREHOUSE_SIZE = $warehouse_size
WAREHOUSE_TYPE = $warehouse_type
AUTO_SUSPEND = 60
AUTO_RESUME = TRUE
INITIALLY_SUSPENDED = TRUE;

GRANT USAGE ON WAREHOUSE IDENTIFIER($warehouse_name) TO ROLE IDENTIFIER($role_name);

-- ============================================
-- CREATE DATABASE AND SCHEMA
-- ============================================
CREATE DATABASE IF NOT EXISTS IDENTIFIER($db_name);
GRANT USAGE ON DATABASE IDENTIFIER($db_name) TO ROLE IDENTIFIER($role_name);

USE DATABASE IDENTIFIER($db_name);
CREATE SCHEMA IF NOT EXISTS IDENTIFIER($schema_name);

GRANT ALL PRIVILEGES ON SCHEMA IDENTIFIER($schema_name) TO ROLE IDENTIFIER($role_name);
GRANT CREATE TABLE, CREATE VIEW, CREATE STAGE, CREATE FILE FORMAT ON SCHEMA IDENTIFIER($schema_name) TO ROLE IDENTIFIER($role_name);
USE SCHEMA IDENTIFIER($default_ns);

-- ============================================
-- CREATE USER
-- Service users cannot have passwords — authentication
-- is handled exclusively via the PAT created in Step 5.
-- ============================================
CREATE USER IF NOT EXISTS IDENTIFIER($user_name)
TYPE = SERVICE
DEFAULT_ROLE = $role_name
DEFAULT_WAREHOUSE = $warehouse_name
DEFAULT_NAMESPACE = $default_ns;

GRANT ROLE IDENTIFIER($role_name) TO USER IDENTIFIER($user_name);

-- ============================================
-- CREATE GCS STORAGE INTEGRATION AND STAGE
-- (STORAGE_ALLOWED_LOCATIONS and URL do not support
-- session variable substitution)
-- ============================================
DECLARE
gcs_uri VARCHAR DEFAULT $gcs_url;
stage VARCHAR DEFAULT $stage_name;
sql_str VARCHAR;
BEGIN
sql_str := 'CREATE OR REPLACE STORAGE INTEGRATION openbridge_gcs TYPE = EXTERNAL_STAGE STORAGE_PROVIDER = ''GCS'' ENABLED = TRUE STORAGE_ALLOWED_LOCATIONS = (''' || :gcs_uri || ''')';
EXECUTE IMMEDIATE :sql_str;
sql_str := 'CREATE STAGE IF NOT EXISTS ' || :stage || ' STORAGE_INTEGRATION = openbridge_gcs URL = ''' || :gcs_uri || ''' FILE_FORMAT = (TYPE = ''PARQUET'')';
EXECUTE IMMEDIATE :sql_str;
END;

GRANT ALL PRIVILEGES ON STAGE IDENTIFIER($stage_name) TO ROLE IDENTIFIER($role_name);
GRANT USAGE ON INTEGRATION openbridge_gcs TO ROLE IDENTIFIER($role_name);

-- ============================================
-- CREATE NETWORK POLICY
-- ============================================
USE ROLE ACCOUNTADMIN;

-- These are the Openbridge production IP addresses.
-- Current IPs: https://docs.openbridge.com/en/articles/11822520-snowflake-warehouse-with-oauth-authentication
-- If these IPs ever change, update the network rule:
-- ALTER NETWORK RULE openbridge_network_rule
-- SET VALUE_LIST = ('NEW_IP_1/32', 'NEW_IP_2/32');
CREATE NETWORK RULE IF NOT EXISTS openbridge_network_rule
TYPE = IPV4
MODE = INGRESS
VALUE_LIST = ('52.2.68.68/32', '52.54.227.22/32');

CREATE NETWORK POLICY IF NOT EXISTS openbridge_network_policy
ALLOWED_NETWORK_RULE_LIST = ('openbridge_network_rule');

ALTER USER IDENTIFIER($user_name)
SET NETWORK_POLICY = openbridge_network_policy;

-- ============================================
-- CREATE AUTHENTICATION POLICY FOR PAT
-- ============================================
CREATE AUTHENTICATION POLICY IF NOT EXISTS openbridge_pat_policy
PAT_POLICY = (
NETWORK_POLICY_EVALUATION = ENFORCED_REQUIRED,
MAX_EXPIRY_IN_DAYS = 365
);

ALTER USER IDENTIFIER($user_name)
SET AUTHENTICATION POLICY openbridge_pat_policy;

-- ============================================
-- GRANT PAT MANAGEMENT TO OPENBRIDGE ROLE
-- ============================================
GRANT MODIFY PROGRAMMATIC AUTHENTICATION METHODS ON USER IDENTIFIER($user_name)
TO ROLE IDENTIFIER($role_name);

-- Test 1: Create a table
CREATE OR REPLACE TABLE test_table (
id INT AUTOINCREMENT PRIMARY KEY,
name STRING,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP()
);

-- Test 2: Insert data into the table
INSERT INTO test_table (name) VALUES
('Alice'),
('Bob'),
('Charlie');

-- Test 3: Query data from the table
SELECT * FROM test_table;

-- Test 4: Update data in the table
UPDATE test_table
SET name = 'Alice Updated'
WHERE name = 'Alice';

-- Test 5: Delete data from the table
DELETE FROM test_table
WHERE name = 'Bob';

-- Test 6: Drop the table
DROP TABLE test_table;

🛈

Need full ownership? The script above grants usage and specific privileges, which is safe for shared databases. If this is a dedicated Openbridge database and you want the Openbridge role to have full control, replace the database/schema grants with:

GRANT OWNERSHIP ON DATABASE IDENTIFIER($db_name) TO ROLE IDENTIFIER($role_name);
GRANT OWNERSHIP ON SCHEMA IDENTIFIER($schema_name) TO ROLE IDENTIFIER($role_name);

GRANT OWNERSHIP transfers full control of the database and schema to the Openbridge role, which can revoke access for other roles. Only use it for a dedicated Openbridge database.


Step 3: Grant Snowflake Access to Your GCS Bucket

The storage integration created in Step 2 generates a Google Cloud service account that Snowflake uses to access your bucket. You need to grant this service account the required permissions.

3a: Retrieve the Snowflake Service Account

Run the following in your Snowflake worksheet:

DESC STORAGE INTEGRATION openbridge_gcs;

From the output, copy the value of STORAGE_GCP_SERVICE_ACCOUNT. It will look something like:

xxxxxxxx@gcpuscentral1-1abc.iam.gserviceaccount.com

3b: Create a Custom IAM Role for Snowflake

Snowflake requires specific GCS permissions — not a broad admin role. Create a custom IAM role with only the permissions Snowflake needs.

  1. In the Google Cloud Console, navigate to IAM & Admin > Roles.

  2. Click Create Role.

  3. Enter a title (e.g., Snowflake Storage Access) and an ID (e.g., snowflakeStorageAccess).

  4. Click Add Permissions and add the following:

Permission

Purpose

storage.buckets.get

Transfer cost calculation

storage.objects.create

Write staged data to the bucket

storage.objects.delete

Remove staged files after loading

storage.objects.get

Read staged data from the bucket

storage.objects.list

List objects in the bucket

  1. Click Create.

🛈

Reference: These are the exact permissions specified in the Snowflake documentation for GCS configuration. They cover both data loading and unloading, which is what Openbridge needs for staging.

3c: Grant the Custom Role to the Snowflake Service Account

  1. Navigate to Cloud Storage > Buckets.

  2. Select your bucket.

  3. Click the Permissions tab.

  4. Click Grant Access.

  5. In the New principals field, paste the STORAGE_GCP_SERVICE_ACCOUNT value from Step 3a.

  6. In the Role dropdown, select Custom > Snowflake Storage Access (the role you created in Step 3b).

  7. Click Save.

If you ever recreate the storage integration in Snowflake, it will generate a new service account. You would need to repeat this step with the new service account.


Step 4: Create an Openbridge GCS Service Account

Openbridge needs its own Google Cloud service account to access your GCS bucket for data transfers. This is separate from Snowflake's service account.

  1. In the Google Cloud Console, navigate to IAM & Admin > Service Accounts.

  2. Click Create Service Account.

  3. Enter a name such as openbridge-snowflake-access and click Create and Continue.

  4. Under Grant this service account access to project, assign the custom Snowflake Storage Access role you created in Step 3b.

  5. Click Continue, then Done.

  6. Open the newly created service account from the list.

  7. Go to the Keys tab.

  8. Click Add Key > Create new key.

  9. Select JSON and click Create.

  10. Save the downloaded JSON key file — you will upload it when configuring your Openbridge destination in Step 7.

Important: This JSON file allows Openbridge to access your GCS bucket when transferring data via Snowflake. Store it securely and do not share it.


Step 5: Generate a Programmatic Access Token

The setup script in Step 2 granted PAT management privileges to your Openbridge role. Switch to that role and generate the token.

Replace <YOUR_ROLE_NAME> and <YOUR_USER_NAME> below with the values you set in Step 2:

USE ROLE <YOUR_ROLE_NAME>;

ALTER USER <YOUR_USER_NAME>
ADD PROGRAMMATIC ACCESS TOKEN openbridge_pat
DAYS_TO_EXPIRY = 365
ROLE_RESTRICTION = <YOUR_ROLE_NAME>;

For example, if you used the default values from Step 2:

USE ROLE OPENBRIDGE_ROLE;

ALTER USER OPENBRIDGE_USER
ADD PROGRAMMATIC ACCESS TOKEN openbridge_pat
DAYS_TO_EXPIRY = 365
ROLE_RESTRICTION = OPENBRIDGE_ROLE;

Important: This command returns the token only once. Copy and save it in a secure location immediately. You will not be able to retrieve it again.


Step 6: Find Your Snowflake Account Identifier

  1. Log in to your Snowflake account.

  2. Click the account selector in the bottom-left corner.

  3. Hover over your account and click the link icon to copy your Account Identifier.

Your Account Identifier should be in the format ORGNAME-ACCOUNTNAME (e.g., MYORG-MYACCOUNT).

If you are unsure of your Account Identifier, run the following in a Snowflake worksheet:

SELECT CURRENT_ORGANIZATION_NAME() || '-' || CURRENT_ACCOUNT_NAME();

Use the result as your Account Identifier.


Step 7: Configure Your Destination in Openbridge

  1. In the Openbridge app, navigate to your Snowflake destination settings.

  2. Enter the following details:

Field

Value

Account Identifier

From Step 6

Username

The user_name value from Step 2 (e.g., OPENBRIDGE_USER)

Programmatic Access Token

The token from Step 5

Database

The db_name value from Step 2 (e.g., OPENBRIDGE)

Schema

The schema_name value from Step 2 (e.g., OPENBRIDGE_SCHEMA)

Warehouse

The warehouse_name value from Step 2 (e.g., OPENBRIDGE_WH)

Stage

The stage_name value from Step 2 (e.g., OPENBRIDGE_STAGE)

Role

The role_name value from Step 2 (e.g., OPENBRIDGE_ROLE)

GCS Bucket

Your GCS bucket name

GCS Service Account Key

The JSON key file from Step 4

  1. Save the destination.


Token Renewal

Your Programmatic Access Token expires based on the DAYS_TO_EXPIRY value set during generation (up to 365 days). Before it expires, revoke the old token, generate a new one, and update it in your Openbridge destination settings.

Check token expiration

SHOW PROGRAMMATIC ACCESS TOKENS FOR USER <YOUR_USER_NAME>;

Revoke the expiring token

ALTER USER <YOUR_USER_NAME>
REMOVE PROGRAMMATIC ACCESS TOKEN openbridge_pat;

Generate a new token

ALTER USER <YOUR_USER_NAME>
ADD PROGRAMMATIC ACCESS TOKEN openbridge_pat
DAYS_TO_EXPIRY = 365
ROLE_RESTRICTION = <YOUR_ROLE_NAME>;

Important: This command returns the token only once. Copy and save it immediately.


Update Openbridge

Edit your destination in the Openbridge app and replace the token. All other fields are prepopulated.

Replace <YOUR_USER_NAME> and <YOUR_ROLE_NAME> with the values from Step 2 (e.g., OPENBRIDGE_USER, OPENBRIDGE_ROLE).


Troubleshooting

"Authentication policy does not allow programmatic access tokens"

If your account has an existing authentication policy that restricts authentication methods, you need to add PAT as an allowed method:

ALTER AUTHENTICATION POLICY your_existing_policy
SET AUTHENTICATION_METHODS = ('OAUTH', 'PASSWORD', 'PROGRAMMATIC_ACCESS_TOKEN');

"Network policy required"

The authentication policy requires a network policy. Verify the network policy from Step 2 was created and applied to the user successfully:

DESCRIBE USER OPENBRIDGE_USER;

Look for NETWORK_POLICY in the output. If empty, re-run the network policy section from Step 2.

Token is not working after policy change

If an admin changed the MAX_EXPIRY_IN_DAYS to a value shorter than your token's remaining lifetime, the token is automatically invalidated. Generate a new token with Step 5.

Snowflake cannot access your GCS bucket

If Snowflake fails to access your GCS bucket after completing all steps:

  1. Verify the STORAGE_GCP_SERVICE_ACCOUNT from DESC STORAGE INTEGRATION openbridge_gcs matches the principal granted access on your bucket.

  2. Confirm the service account has the custom Snowflake Storage Access role (from Step 3b) on the bucket.

  3. Check that the bucket name in the storage integration matches your actual GCS bucket name exactly (case-sensitive).

Did this answer your question?