Skip to content

ci(snowflake): switch driver and integration tests to key-pair auth - #11963

Merged
bsod90 merged 2 commits into
masterfrom
maxim/snowflake-drivers-tests-key-pair
Sep 22, 2026
Merged

bsod90 merged 2 commits into
masterfrom
maxim/snowflake-drivers-tests-key-pair

Conversation

@bsod90

@bsod90 bsod90 commented Sep 22, 2026

Copy link
Copy Markdown
Member

Summary

On 2026-09-22 Snowflake started enforcing MFA on the Snowflake test user (account lxb31104), which a CI user cannot complete. Every password-based Snowflake job now fails with:

OperationFailedError: Multi-factor authentication is required for this account. Log in to Snowsight to enroll.

Confirmed on current PR runs:

  • drivers-tests.yml: 10 of the 11 Snowflake legs fail. Only snowflake-encrypted-pk passes, which proves the existing key pair still authenticates.
  • push.yml: integration (*, snowflake, *) fails.

Change

The encrypted key pair the snowflake-encrypted-pk leg already uses becomes the default auth. It comes from the existing DRIVERS_TESTS_CUBEJS_DB_SNOWFLAKE_PRIVATE_KEY / _PASS secrets, so no secret changes are needed.

  • cubejs-testing-drivers/fixtures/snowflake.json: the base env uses SNOWFLAKE_JWT + the private key instead of CUBEJS_DB_PASS.
  • .github/actions/integration/snowflake.sh + push.yml: the same for the driver integration and smoke tests.
  • cubejs-testing/src/REQUIRED_ENV_VARS.ts: the Snowflake smoke harness requires CUBEJS_DB_SNOWFLAKE_PRIVATE_KEY instead of CUBEJS_DB_PASS. The smoke test sets SNOWFLAKE_JWT itself, and the passphrase stays optional, since only encrypted keys need it.
  • drivers-tests.yml: drops the now-unused password env and the snowflake-encrypted-pk leg, together with its test file, snapshot and scripts. The base config is that same encrypted key pair now, so the leg re-ran the identical suite.

After merge, the DRIVERS_TESTS_CUBEJS_DB_SNOWFLAKE_PASS repo secret is unused and can be deleted.

Test plan

  • drivers-tests Snowflake legs green on this PR
  • push.yml integration (snowflake) green on this PR

🤖 Generated with Claude Code

Snowflake now enforces MFA on the test user, so every password-based
Snowflake job fails with 'Multi-factor authentication is required'. The
encrypted key pair the snowflake-encrypted-pk leg already uses still
authenticates, so make it the default for the drivers suites and the
push.yml integration/smoke tests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@bsod90
bsod90 requested a review from a team as a code owner September 22, 2026 21:39
@github-actions github-actions Bot added the javascript Pull requests that update Javascript code label Sep 22, 2026
@claude

claude Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Claude finished @bsod90's task in 3m 15s —— View job


Approve with nits — 0 blocking, 2 low

Full review
  • Read diff and changed files
  • Check other Snowflake CI paths for leftover password usage
  • Verify driver env-var handling (authenticator, private key)
  • Check REQUIRED_ENV_VARS forwarding into the smoke harness
  • Resolve stale threads / post findings

Verdict

The fix is correct and complete for the MFA breakage. Wiring checks out end to end:

  • .github/workflows/push.yml:526-527 exports DRIVERS_TESTS_SNOWFLAKE_CUBEJS_DB_PRIVATE_KEY{,_PASS}, which is exactly what .github/actions/integration/snowflake.sh:14-15 reads — names match.
  • packages/cubejs-testing-drivers/fixtures/snowflake.json:108-110 uses DRIVERS_TESTS_CUBEJS_DB_SNOWFLAKE_PRIVATE_KEY{,_PASS}, still exported by drivers-tests.yml:430-431.
  • DRIVERS_TESTS_CUBEJS_DB_SNOWFLAKE_PASS has no remaining references anywhere in the repo — the removal at drivers-tests.yml:430 leaves nothing dangling. (Worth deleting the now-unused repo secret separately.)
  • The unquoted export VAR=$OTHER in snowflake.sh is safe for the multi-line PEM: assignment context does no word splitting.
  • The driver decrypts the encrypted PEM itself before handing it to the SDK (SnowflakeDriver.ts:206-227), so SNOWFLAKE_JWT + PRIVATE_KEY + PRIVATE_KEY_PASS is the right trio.
  • birdbox.ts:581 still injects CUBEJS_DB_PASS: 'test' into the smoke-test child env (the Postgres-container default branch), so a stray password now reaches the Snowflake SDK alongside the JWT authenticator. Not a regression risk: the pre-existing encrypted-pk leg already ran JWT on top of the base password and passed, which is what the PR description reports.

Findings

# Sev Where What
1 low fixtures/snowflake.json:108 encrypted-pk override is now identical to the base env — the snowflake-encrypted-pk leg re-runs the full suite for zero extra coverage. Drop it, or repoint it at CUBEJS_DB_SNOWFLAKE_PRIVATE_KEY_PATH, which CI otherwise never exercises.
2 low REQUIRED_ENV_VARS.ts:20-22 CUBEJS_DB_SNOWFLAKE_AUTHENTICATOR is a constant, not a cli-supplied secret, and _PRIVATE_KEY_PASS only matters for encrypted keys — requiring it hard-fails smoke:snowflake for anyone with an unencrypted PEM.

Both posted inline.

Review threads

No prior threads — the listing returned 0, so nothing to resolve or re-affirm.

· [branch `maxim/snowflake-drivers-tests-key-pair`](https://github.com/cube-js/cube/tree/maxim/snowflake-drivers-tests-key-pair)

Comment thread packages/cubejs-testing-drivers/fixtures/snowflake.json
Comment thread packages/cubejs-testing/src/REQUIRED_ENV_VARS.ts Outdated
@codecov

codecov Bot commented Sep 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 61.42%. Comparing base (3222ec0) to head (3f98e75).
⚠️ Report is 3 commits behind head on master.

❗ There is a different number of reports uploaded between BASE (3222ec0) and HEAD (3f98e75). Click for more details.

HEAD has 1 upload less than BASE
Flag BASE (3222ec0) HEAD (3f98e75)
cubesql 1 0
Additional details and impacted files
@@             Coverage Diff             @@
##           master   #11963       +/-   ##
===========================================
- Coverage   80.52%   61.42%   -19.10%     
===========================================
  Files         508      247      -261     
  Lines      107359    19834    -87525     
  Branches     4043     4046        +3     
===========================================
- Hits        86450    12184    -74266     
+ Misses      20337     7076    -13261     
- Partials      572      574        +2     
Flag Coverage Δ
cube-backend 61.42% <ø> (+0.19%) ⬆️
cubesql ?

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

The base Snowflake env is key-pair now, so snowflake-encrypted-pk re-ran
the same suite for no extra coverage. The smoke harness now requires only
the private key; the authenticator is a constant set by the test, and the
passphrase is only needed for encrypted keys.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@claude

claude Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Claude finished @bsod90's task in 2m 52s —— View job


Review: no blocking issues — 0 findings this round (2 prior threads resolved)

Details
  • Read the PR diff and the changed files in full
  • Trace the key-pair env through the driver, the birdbox harness and both CI entry points
  • Check for leftover references to the dropped snowflake-encrypted-pk leg and the retired password secret
  • Resolve stale threads from earlier rounds / dedupe new findings
  • Post review

What I verified

export CUBEJS_DB_SNOWFLAKE_PRIVATE_KEY=$DRIVERS_TESTS_SNOWFLAKE_CUBEJS_DB_PRIVATE_KEY at .github/actions/integration/snowflake.sh:12 is unquoted, but it is an assignment argument to a declaration command, so bash applies no word splitting — the multi-line PEM survives intact. Not a bug.

packages/cubejs-testing/src/REQUIRED_ENV_VARS.ts:20 lists only the private key, not the passphrase. In LOCAL mode — the default for smoke:snowflake, and there is no birdbox-fixtures/snowflake.yml, so docker mode is not reachable for this type — startBirdBoxFromCli spreads ...process.env (packages/cubejs-testing/src/birdbox.ts:563), so CUBEJS_DB_SNOWFLAKE_PRIVATE_KEY_PASS exported by the shell script still reaches the server. Requiring it would instead break local runs with an unencrypted PEM, since SnowflakeDriver.ts:208-215 only reads the passphrase inside the BEGIN ENCRYPTED PRIVATE KEY branch. The narrowing in 3f98e75 is right.

No references to encrypted-pk remain anywhere in the tree, and DRIVERS_TESTS_CUBEJS_DB_SNOWFLAKE_PASS is gone from every workflow, script and fixture — the matrix entry, the npm script, the test file, the 23k-line duplicate snapshot and the update-all-snapshots-local chain were all removed together. The -full suites and SnowflakeDriver.test.ts build their driver from env, so they pick up the new auth without change.

Non-blocking observation

Snowflake CI now has a single point of failure: every leg authenticates with the one key pair behind DRIVERS_TESTS_CUBEJS_DB_SNOWFLAKE_PRIVATE_KEY, with no password path left as fallback. That is the intended trade (password auth is dead under the MFA policy), but it is worth a calendar reminder before the key rotates — the failure mode is all 11 legs red at once.

Review threads

The listing returned 2 of my own threads. Both resolved, none re-affirmed:

  • PRRT_kwDOCOH19M6k7ekh — duplicate encrypted-pk override in fixtures/snowflake.json; the override and its matrix leg are gone.
  • PRRT_kwDOCOH19M6k7ex8 — required-env-var list in REQUIRED_ENV_VARS.ts; addressed in 3f98e75.
· branch [`maxim/snowflake-drivers-tests-key-pair`](https://github.com/cube-js/cube/tree/maxim/snowflake-drivers-tests-key-pair)

@bsod90
bsod90 merged commit 928e492 into master Sep 22, 2026
159 of 164 checks passed
@bsod90
bsod90 deleted the maxim/snowflake-drivers-tests-key-pair branch September 22, 2026 23:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

javascript Pull requests that update Javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant