pulumi / pulumi-vault

A Vault Pulumi resource package, providing multi-language access to HashiCorp Vault
Apache License 2.0
25 stars 5 forks source link

Allow passing `credential_type="rsa_private_key"` when creating snowflake secrets engine role #180

Open breathe opened 2 years ago

breathe commented 2 years ago

Hello!

Issue details

The snowflake secrets engine supports configuration options for creating rsa based authentication which cannot be specified when creating a pulumi_vault.database.SecretBackendRole.

In particular, in order to provision users with rsa_private_key auth rather than password auth, the role needs to be created with credential_type="rsa_private_key" -- without specifying that parameter the secrets engine doesn't pass an appropriate value for the {{public_key}} template parameter when rendering the creation statements.

Here's a python example to demonstrate: I'd like to provision a role that uses the snowflake-secrets engine to create a dynamic user with a generated-by-vault RSA_PUBLIC_KEY. The commented out PASSWORD creation statement below works, but the example that uses RSA_PUBLIC_KEY does not.

    vault_role = pulumi_vault.database.SecretBackendRole(
        f"{resource_name}-query-log-service-role",
        name=role,
        backend=snowflake_integration.path,
        db_name=snowflake_authorization.name,
        # be careful when reading this -- {{ }} vars are expanded by vault
        # vars like {role} should be string replaced in python
        # (don't use .format() or f"" strings as those _will_ remove the extra brace!
        creation_statements=[
            # want this but can't use {{public_key}} without specifying credential_type and can't specify credential_type anywhere...
            "CREATE USER \"{{name}}\" RSA_PUBLIC_KEY='{{public_key}}' DAYS_TO_EXPIRY = {{expiration}} DEFAULT_ROLE={role};  GRANT ROLE {role} TO USER \"{{name}}\";"
            .replace("{role}", role)
            # "CREATE USER \"{{name}}\" PASSWORD='{{password}}' DAYS_TO_EXPIRY = {{expiration}} DEFAULT_ROLE={snowflake_role};  GRANT ROLE {snowflake_role} TO USER \"{{name}}\";"
            # .replace("{snowflake_role}", snowflake_role)
        ],
        default_ttl=3600,
        max_ttl=3600,
    )

Provisioning as above will succeed but then attempting to read creds from the role fails with

ncohen@m1-max-toast ~/f/o/i/a/secrets (main)> vault read dev_us_snowflake/creds/SOME_SERVICE
Error reading dev_us_snowflake/creds/SOME_SERVICE: Error making API request.

URL: GET https://vault.faunadb.net/v1/dev_us_snowflake/creds/SOME_SERVICE
Code: 500. Errors:

* 1 error occurred:
    * 003065 (42601): SQL execution error:
New public key rejected by current policy. Reason: 'Invalid public key'

I believe this fails because there is no valid value for {{pubkey}} being supplied by the secrets engine -- I believe this value is only supplied by the secrets engine when credential_type="rsa_private_key" is specified to create the role.

Provisioning the role manually like this works as expected:

vault write dev_us_snowflake/roles/SOME_SERVICE \
                                                          db_name=snowflake-connection \
                                                          creation_statements="CREATE USER \"{{name}}\" RSA_PUBLIC_KEY='{{public_key}}'
                                                        DAYS_TO_EXPIRY = {{expiration}} DEFAULT_ROLE=SOME_SERVICE_DEV;
                                                        GRANT ROLE SOME_SERVICE_DEV TO USER \"{{name}}\";" \
                                                          credential_type="rsa_private_key" \
                                                          credential_config=key_bits=2048 \
                                                          default_ttl="1h" \
                                                          max_ttl="1h" \
                                                          credential_config=format="pkcs8"

If there's a workaround for this that I'm not aware of - I'd greatly appreciate someone pointing me that way. Otherwise it would be huge if the pulumi api grew support for specifying values for these arguments -- the set that I'm aware of being

pubkey

~As far as I can tell -- its also not possible to provision static roles from pulumi -- as these require specifying rotation_period and username which I don't think can be done from pulumi.~ edit: nvm for this last observation. I believe SecretBackendStaticRole already supports the static role case -- its just not present in the version of pulumi_vault that I am using. But I am not seeing anything in newer versions of pulumi_vault that would support rsa credential creation (?)

Affected area/feature

Terraform Bridge/related to the Hashicorp Vault with Snowflake Secrets Engine

lblackstone commented 2 years ago

As far as I can tell, this argument isn't available in the upstream terraform-vault provider. You could open an enhancement request upstream, and pulumi_vault would also get the requested support if it's added there. Otherwise, it's unlikely that we'll be able to add this feature to pulumi_vault in the near future.