Skip to content

CORE-742: switch Snowflake CI auth from password to private key#2224

Merged
haritamar merged 3 commits intomasterfrom
core-742-snowflake-private-key-auth
May 5, 2026
Merged

CORE-742: switch Snowflake CI auth from password to private key#2224
haritamar merged 3 commits intomasterfrom
core-742-snowflake-private-key-auth

Conversation

@devin-ai-integration
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot commented May 5, 2026

Summary

Migrates the Snowflake CI target in tests/profiles/profiles.yml.j2 from password-based auth to key-pair authentication.

  • password: …private_key: … (with optional private_key_passphrase)
  • _yaml_inline in generate_profiles.py now safely renders multi-line strings (e.g. PEM private keys) as a double-quoted YAML scalar with escaped newlines, so the rendered profiles.yml stays parseable when the secret is provided as a PEM string.
  • Single-line base64-encoded DER keys also continue to render correctly as plain scalars.
  • The <<: *snowflake anchor used by the inner elementary profile inherits the new private_key field automatically.

Companion PR (must merge together): elementary-data/dbt-data-reliability — see Linear ticket CORE-742.

Required coordinated changes (outside this PR)

The CI_WAREHOUSE_SECRETS GitHub Actions secret (a base64-encoded JSON blob, see generate_profiles.py) needs:

  • Remove key: snowflake_password
  • Add key: snowflake_private_key — Snowflake user's private key (PEM or base64-encoded DER). Multi-line PEM is supported.
  • Optional: snowflake_private_key_passphrase — only if the key is encrypted.

On Snowflake side:

  • Generate an RSA key pair for the CI service user.
  • ALTER USER <ci_user> SET RSA_PUBLIC_KEY = '<public_key_pem_without_headers>';
  • (Optional) you can keep the password set during transition and only remove it after this PR merges, so existing runs aren't broken.

generate_profiles.py uses StrictUndefined when secrets are loaded — so if snowflake_private_key is missing from the secret blob, the Snowflake CI job will fail fast with a clear error rather than producing an unauthenticated profile.

Review & Testing Checklist for Human

  • Update CI_WAREHOUSE_SECRETS in this repo's GitHub Actions secrets (add snowflake_private_key, remove snowflake_password) before merging — otherwise the next Snowflake CI run will fail.
  • Configure the matching RSA_PUBLIC_KEY on the Snowflake CI user.
  • Trigger Test warehouse platform workflow for warehouse-type: snowflake from this branch and verify dbt debug -t snowflake and the integration tests pass.
  • Verify the companion elementary-data/dbt-data-reliability PR is merged in lockstep so both repos' Snowflake CI stays green.

Notes

Locally rendered the template with both PEM (multi-line) and base64 (single-line) inputs and confirmed the resulting YAML is parseable by yaml.safe_load_all and contains private_key (and optionally private_key_passphrase) on the snowflake target with no leftover password field. Both the outer elementary_tests profile and the inner elementary profile (which inherits via <<: *snowflake) are correctly updated.

Link to Devin session: https://app.devin.ai/sessions/c6321f52b3274f499dd305e96c8ed73b
Requested by: @haritamar

Summary by CodeRabbit

  • New Features

    • Added key-pair authentication support for Snowflake cloud target configuration.
    • Added conditional inclusion of private key passphrases for Snowflake authentication.
  • Bug Fixes

    • Improved YAML output: multi-line and plain string values are now emitted as inline double-quoted scalars for more consistent formatting.

The 'snowflake' target in profiles.yml.j2 now uses key-pair authentication
(private_key, with optional private_key_passphrase) instead of password.

generate_profiles.py's _yaml_inline filter is updated to safely render
multi-line strings (e.g. PEM private keys) as a double-quoted YAML scalar
with escaped newlines, so the rendered profiles.yml stays parseable inline.

The CI_WAREHOUSE_SECRETS GitHub Actions secret needs a coordinated update:
- remove key 'snowflake_password'
- add key 'snowflake_private_key' (PEM or base64-encoded DER)
- optional 'snowflake_private_key_passphrase' for encrypted keys

The CI service user's RSA_PUBLIC_KEY must also be configured in Snowflake.

Co-Authored-By: Itamar Hartstein <haritamar@gmail.com>
@linear
Copy link
Copy Markdown

linear Bot commented May 5, 2026

@devin-ai-integration
Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 5, 2026

Warning

Rate limit exceeded

@devin-ai-integration[bot] has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 6 minutes and 55 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e9e5ab17-f467-428d-acb4-6ae99720b034

📥 Commits

Reviewing files that changed from the base of the PR and between 33d70b4 and 88f8715.

📒 Files selected for processing (1)
  • tests/profiles/generate_profiles.py
📝 Walkthrough

Walkthrough

The PR changes YAML inline serialization to explicitly serialize Python str values as double-quoted YAML scalars and updates the Snowflake profile template to use private_key (with optional private_key_passphrase) instead of password.

Changes

YAML Serialization and Snowflake Profile

Layer / File(s) Summary
Data Shape / Template inputs
tests/profiles/profiles.yml.j2, tests/profiles/generate_profiles.py
Templates and helper operate on the same profile input variables; Snowflake authentication variables switch from snowflake_password to snowflake_private_key and optional snowflake_private_key_passphrase.
YAML Helper
tests/profiles/generate_profiles.py
_yaml_inline adds an isinstance(value, str) branch that returns yaml.dump(value, default_flow_style=True, default_style='"').strip() to emit inline double-quoted YAML scalars for strings; existing Undefined and compact dict handling remain. Docstring updated.
Profile Template Update
tests/profiles/profiles.yml.j2
Snowflake target YAML no longer emits password; it emits private_key from snowflake_private_key and conditionally emits private_key_passphrase when snowflake_private_key_passphrase is defined. Existing role, database, warehouse, schema, and threads fields retained.
Tests / Fixtures / Docs
tests/profiles/* (implicit)
Test/profile fixtures that render templates will reflect the new string serialization and Snowflake auth fields (changes localized to template and helper).

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 I nibble quotes around each string,
Inline and tidy — hear them sing!
Keys and passphrases snugly kept,
Passwords retired, quietly swept.
Hoppity hops, the profiles pass — hooray!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title clearly summarizes the main change: switching Snowflake CI authentication from password-based to private key-based authentication, which is the primary objective of the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch core-742-snowflake-private-key-auth

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

👋 @devin-ai-integration[bot]
Thank you for raising your pull request.
Please make sure to add tests and document all user-facing changes.
You can do this by editing the docs files in this pull request.

devin-ai-integration Bot and others added 2 commits May 5, 2026 13:47
…back)

Quoting only multi-line strings still allowed single-line string secrets
like 'true', 'null', or '123' to be emitted unquoted and mis-parsed as
booleans/None/integers when the rendered profiles.yml is loaded by dbt.

Always quote string values for safety; non-string values (Undefined,
dict, etc.) keep their previous behavior.

Co-Authored-By: Itamar Hartstein <haritamar@gmail.com>
The previous change to always quote string values broke YAML type coercion
for fields like redshift_port that come in as JSON strings but need to be
rendered as bare YAML scalars so the dbt adapter parses them as integers.

Revert to the original behavior: only multi-line strings (e.g. PEM private
keys) are double-quoted with escaped newlines; single-line strings pass
through unchanged so port/host/etc. continue to type-coerce correctly.

Co-Authored-By: Itamar Hartstein <haritamar@gmail.com>
@haritamar haritamar merged commit 9b843d1 into master May 5, 2026
24 of 28 checks passed
@haritamar haritamar deleted the core-742-snowflake-private-key-auth branch May 5, 2026 15:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant