Skip to content

[Fix] Snowflake connection fails when users configure encrypted private keys - #1664

Draft
roomote-roomote[bot] wants to merge 1 commit into
developfrom
fix/snowflake-encrypted-key-auth-0y2b4zqpikgir
Draft

[Fix] Snowflake connection fails when users configure encrypted private keys#1664
roomote-roomote[bot] wants to merge 1 commit into
developfrom
fix/snowflake-encrypted-key-auth-0y2b4zqpikgir

Conversation

@roomote-roomote

Copy link
Copy Markdown
Contributor

​Opened on behalf of @mrubens. Follow up by mentioning @roomote-roomote, in the web UI, or in Slack.

What changed

  • decrypts encrypted PKCS8 private keys in API memory with Node crypto and passes Snowflake SDK a normalized unencrypted PKCS8 key
  • accepts only RSA keys with a modulus of at least 2048 bits while preserving existing password-only authentication
  • replaces crypto and connection failures with credential-safe errors and masks the passphrase field in Settings
  • adds operator guidance for secure key generation, staged rotation, runtime verification, and old-credential revocation

Why this change was made

Snowflake SDK does not apply privateKeyPass to inline private keys, so encrypted PKCS8 credentials could be saved but failed when a task connected. Roomote must decrypt and validate the key before invoking the SDK without persisting or exposing the normalized key.

Impact

Encrypted and unencrypted PKCS8 RSA keys now reach Snowflake SDK in its supported inline form. Password-only stored connections continue to work when no private key exists.

Security-sensitive behavior is covered with generated encrypted RSA and EC keys, wrong-passphrase rejection, minimum key-size enforcement, SDK option assertions, and error-redaction assertions. The focused API suite passes 13 tests; the broader API MCP suite passes 256 tests; web integration settings pass 69 tests; SDK and worker proxy suites pass 36 and 40 tests. API/web typechecks, lint:fast, check-types:fast, knip, and docs validation also pass.

A live external Snowflake login was not run because this environment has no Snowflake credentials. Production acceptance still requires a controlled JWT smoke test against the target Snowflake account.

Security considerations

  • decrypted key material exists only in API process memory and is never persisted
  • Snowflake SDK receives no passphrase or password on the key-pair path
  • malformed keys, incorrect passphrases, unsupported key types, weak keys, and SDK connection failures return generic messages without crypto details or credential content
  • the passphrase input is password-masked; private-key and passphrase fields remain blank when editing an existing connection

Cutover instructions

  1. Deploy this API change before installing an encrypted key in Roomote.
  2. Generate a dedicated encrypted RSA key on a secure operator machine and install its public key in Snowflake's unused RSA_PUBLIC_KEY_2 rotation slot.
  3. Verify the Snowflake public-key fingerprint, then enter the encrypted PKCS8 private key and passphrase in Settings > Integrations > Snowflake.
  4. Run a controlled Roomote task using list_databases, list_schemas, and execute_sql with SELECT CURRENT_USER(), CURRENT_ROLE(), CURRENT_WAREHOUSE(); confirm one authorized read and the intended role restrictions.
  5. Check Roomote API logs and Snowflake login history for a successful JWT login and absence of credential material.
  6. After an observation window, revoke the old password, programmatic access token, or prior public-key slot and verify a fresh task still connects.

@roomote-community

roomote-community Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

No code issues found. See task

Reviewed dc37b4f

Comment on lines +451 to +455
const { privateKey: shortPrivateKey } = generateKeyPairSync('rsa', {
modulusLength: 1024,
privateKeyEncoding: { type: 'pkcs8', format: 'pem' },
publicKeyEncoding: { type: 'spki', format: 'pem' },
});
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.

2 participants