snowflake-user
The snowflake-user rotator enables you to rotate RSA keypairs for a Snowflake database user in your Environment. It automatically manages the key rotation process, ensuring that two keys remain valid at any point in time, which allows for seamless credential rotation without disrupting service availability. (See rotation concepts).
How Key Rotation Works
When the snowflake-user rotator is executed:
- It connects to Snowflake using the provided login credentials.
- It generates a new 2048-bit RSA keypair.
- If a previous keypair exists in the state, it sets the user’s
RSA_PUBLIC_KEY_2to the previous public key. - It sets the user’s
RSA_PUBLIC_KEYto the new public key. - The new private key is stored securely in the environment state.
This two-key approach ensures that applications have time to update to the new key before the old one is completely removed, providing a smooth transition during rotation.
Configuring Snowflake for Key Rotation
Step 1: Create the Target User
Create the Snowflake user whose keys will be rotated:
CREATE USER ESC_ROTATION_DEMO_USER
DEFAULT_ROLE = 'PUBLIC'
TYPE = SERVICE;
Step 2: Create a Rotator Role
Create a role that has permission to alter the target user:
CREATE ROLE ESC_ROTATOR;
GRANT OWNERSHIP ON USER ESC_ROTATION_DEMO_USER TO ROLE ESC_ROTATOR;
Step 3: Create a Rotation Service User
Create a service user that will perform the rotation:
CREATE USER ESC_ROTATION_SERVICE_USER
DEFAULT_ROLE = 'ESC_ROTATOR'
TYPE = SERVICE;
GRANT ROLE ESC_ROTATOR TO USER ESC_ROTATION_SERVICE_USER;
The rotation service user should have minimal permissions, only enough to alter the target user.
Step 4: Set Up OIDC for the Rotation Service User
Follow the OIDC setup steps in the snowflake-login documentation to allow Pulumi ESC to authenticate as the rotation service user.
CREATE SECURITY INTEGRATION pulumi_oidc
TYPE = EXTERNAL_OAUTH
ENABLED = TRUE
EXTERNAL_OAUTH_TYPE = CUSTOM
EXTERNAL_OAUTH_ISSUER = 'https://api.pulumi.com/oidc'
EXTERNAL_OAUTH_JWS_KEYS_URL = 'https://api.pulumi.com/oidc/.well-known/jwks'
EXTERNAL_OAUTH_TOKEN_USER_MAPPING_CLAIM = 'snowflake_user'
EXTERNAL_OAUTH_SNOWFLAKE_USER_MAPPING_ATTRIBUTE = 'login_name'
EXTERNAL_OAUTH_AUDIENCE_LIST = ('snowflake:<pulumi-org>')
EXTERNAL_OAUTH_ALLOWED_ROLES_LIST = ('ESC_ROTATOR')
EXTERNAL_OAUTH_ANY_ROLE_MODE = 'ENABLE';
Replace <pulumi-org> with your Pulumi organization name.
Step 5: Managing credentials
Set up an environment with Snowflake login credentials for the rotation service user:
# my-org/logins/snowflake
values:
snowflake:
account: myorganization-account
login:
fn::open::snowflake-login:
oidc:
account: myorganization-account
user: ESC_ROTATION_SERVICE_USER
role: ESC_ROTATOR
Step 6: Rotated environment
Then, create a separate environment for your rotated credentials:
# my-org/rotators/snowflake-keyrotator
values:
user:
fn::rotate::snowflake-user:
inputs:
login: ${environments.logins.snowflake.snowflake.login}
targetUser: ESC_ROTATION_DEMO_USER
If you have existing keys you want ESC to keep track of, you can optionally provide an initial state:
# my-org/rotators/snowflake-keyrotator
values:
user:
fn::rotate::snowflake-user:
inputs:
login: ${environments.logins.snowflake.snowflake.login}
targetUser: ESC_ROTATION_DEMO_USER
state:
account: myorganization-account
privateKey:
fn::secret: |
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQE...
-----END PRIVATE KEY-----
createdAt: "2025-01-01T12:00:00Z"
Alternative: authenticating with a private key
Instead of an OIDC token from the snowflake-login provider, the login can authenticate directly with a key-pair by supplying a privateKey. Provide account, user, and exactly one of privateKey or token:
# my-org/rotators/snowflake-keyrotator
values:
user:
fn::rotate::snowflake-user:
inputs:
login:
account: myorganization-account
user: ESC_ROTATION_SERVICE_USER
privateKey:
fn::secret: |
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQE...
-----END PRIVATE KEY-----
targetUser: ESC_ROTATION_DEMO_USER
Validation
Perform a manual rotation on the environment to provision a new private key. If successful, should see output similar to the following when opening the environment:
{
"user": {
"account": "myorganization-account",
"user": "ESC_ROTATION_DEMO_USER",
"privateKey": "[secret]",
"rotatedAt": "2025-04-24T10:00:00Z"
}
}
Schema reference
Reference schemas last updated on 2026-07-11, synced automatically from the Pulumi Cloud ESC API.
Inputs
loginobject requiredThe credentials used to perform rotation.- ↳
accountstring requiredSnowflake account identifier. - ↳
userstring requiredManaging user to connect as. This user must have permission to alter the target user. - Exactly one of — option 1
- ↳
privateKeystring requiredPrivate key in PEM format. - Exactly one of — option 2
- ↳
tokenstring requiredOAuth token (output of snowflake-login provider). targetUserstring requiredThe user to rotate credentials for.
State
accountstring requiredSnowflake account identifiercreatedAtstring requiredWhen the keypair was generated, in RFC3339 format.privateKeystring requiredThe private key in PEM format.
Outputs
accountstring requiredSnowflake account identifierprivateKeystring requiredPrivate key in PEM format.rotatedAtstring requiredWhen the keypair was generated, in RFC3339 format.userstring requiredThe rotated user.
Troubleshooting
| Symptom | Likely cause | Resolution |
|---|---|---|
| Rotation fails to authenticate to Snowflake | The OIDC security integration may be misconfigured, or the rotation service user may lack access. | Verify the EXTERNAL_OAUTH security integration values (issuer, JWKS URL, audience, allowed roles) and confirm the service user maps to the expected login_name. See snowflake-login. |
| Rotation fails with a permissions error | The rotator role may not be able to alter the target user. | Confirm the rotator role can alter the target user, following the grants in Configuring Snowflake for Key Rotation. |
| Applications fail to authenticate after a rotation | Applications may still be using the rotated-out public key (RSA_PUBLIC_KEY_2). | Update applications to the current private key; the previous key remains valid as RSA_PUBLIC_KEY_2 until the next rotation. |
Related
- Rotators - How credential rotation works in Pulumi ESC
- snowflake-login - Authenticate with Snowflake via OIDC
- Rotators reference - Catalog of all ESC rotators