<< Back to all Blogs
Go Secretless: Snowflake OIDC with GitHub Actions

Go Secretless: Snowflake OIDC with GitHub Actions

Ben Dang

It's been four months since Snowflake released Workload Identity Federation (WIF) in August 2025, enabling secure, secretless authentication for applications and services. So if you're still using passwords or key-pairs for your CI/CD pipelines, it's time to upgrade. Here's how to set up OIDC with GitHub Actions as a modern, secure way to authenticate.

Why OIDC over traditional credentials?

Before diving into the technical details, here's a refresher on why this matters.

ApproachCredential LifecycleRiskRotation Burden
Passwords/Key-pairsLong-lived, stored in secretsFull access if revokedManual rotation required
OIDCShort-lived, never storedExpires quickly, scope-limitedNone as tokens are ephemeral

With OIDC, GitHub Actions requests a short-lived token at runtime. Snowflake validates this token against the issuer (GitHub), and if the claims match, authentication succeeds. No secrets to leak, rotate or manage.

A reminder on least privilege

Using ACCOUNTADMIN for any workflow is obviously an egregious example, but it illustrates the importance of least privilege.

Aspect❌ ACCOUNTADMIN✅ Custom Role
PermissionsFull control over your entire Snowflake accountOnly the specific permissions needed
Security RiskA compromised workflow could drop databases, users, or access billingBlast radius is limited to the granted scope
PrincipleViolates least privilege principleFollows security best practices
AuditabilityAudit logs are harder to interpretClear accountability for actions

Step 1: Create a least-privilege role

Before creating service users, define roles scoped to each environment's database. This ensures your CI/CD pipelines can only affect their intended environment. The below example creates a test OIDC role and user which can never touch prod.

CREATE ROLE TEST_CICD_ROLE;
GRANT CREATE SCHEMA ON DATABASE TEST_DATABASE TO ROLE TEST_CICD_ROLE;

Step 2: Create a Snowflake service user

Create a service user with a workload identity tied to your repository. The SUBJECT must match our GitHub repository and environment exactly (this is case-sensitive).

For a GitHub organisation called MechRock, a repository named snowflake-infrastructure and a GitHub environment called test:

CREATE USER TEST_SVC_INFRA_GITHUB
	DEFAULT_ROLE = TEST_CICD_ROLE
	TYPE = SERVICE
	COMMENT = 'GitHub Actions service user for TEST infrastructure deployments'
	WORKLOAD_IDENTITY = (
	 TYPE = OIDC
	 ISSUER = 'https://token.actions.githubusercontent.com'
	 SUBJECT = 'repo:MechRock/snowflake-infrastructure:environment:test'
);

-- Don't forget to grant the role to the user!
GRANT ROLE TEST_CICD_ROLE TO USER TEST_SVC_INFRA_GITHUB;

Step 3: Configure a GitHub Actions workflow

Deploy the following workflow to validate your Snowflake OIDC authentication. The id-token: write permission is required for GitHub to issue the OIDC token, and the environment: test must match the subject claim you configured in Snowflake.

name: Snowflake OIDC
on: workflow_dispatch

permissions:
 id-token: write
 contents: read

jobs:
 oidc-job:
   runs-on: ubuntu-latest
   environment: test
   steps:
     - name: Set up Snowflake CLI
       uses: snowflakedb/snowflake-cli-action@v2.0
       with:
         use-oidc: true
         cli-version: "3.14.0"
     - name: test connection
       env:
         SNOWFLAKE_ACCOUNT: A1234567890-MECHROCK
       run: snow connection test -x

Trigger the workflow manually to confirm everything is wired up correctly. If authentication fails, verify that your SUBJECT claim matches exactly and that the GitHub environment exists.

Bonus Step: Using schemachange with OIDC

Once Snowflake OIDC is working, you can integrate it with database migration tools like schemachange.

Here's a complete workflow that verifies schemachange directory on push to main:

name: schemachange Deploy
on:
 workflow_dispatch:
 push:
   branches:
     - main

permissions:
 id-token: write
 contents: read

jobs:
 schemachange-deploy:
   runs-on: ubuntu-latest
   environment: test
   env:
     SNOWFLAKE_ACCOUNT: A1234567890-MECHROCK

   steps:
     - uses: actions/checkout@v5

     - name: Setup Snowflake CLI for OIDC
       uses: snowflakedb/snowflake-cli-action@v2.0
       with:
         use-oidc: true
         cli-version: "3.14.0"

     - name: setup Python
       uses: actions/setup-python@v6
       with:
         python-version: 3.13

     - run: pip install schemachange

     - name: Schemachange verify
       run: schemachange verify --schemachange-root-folder deploy

Remember to

  • Always use a least-privilege custom role, never ACCOUNTADMIN
  • Match your SUBJECT claim exactly to your repository and environment (it's case-sensitive!)
  • Leverage GitHub environment protection rules for additional security

This pattern extends beyond simple deployments. Once you've got OIDC working, consider applying it to dbt, Terraform, or any tool that integrates with the Snowflake CLI.

Wrapping up

With Workload Identity Federation, you've eliminated long-lived credentials from your CI/CD pipeline. No more rotating keys, no more secrets sprawl. You now have a more secure, auditable, ephemeral authentication.

If you're looking to empower your data stack, consider dbt Projects on Snowflake - check out Maciej Tarsa's blog here for more info.

Feel free to reach out to Mechanical Rock for anything data related!