Passing secrets into vault from helm configs using native-kubernetes-secrets

Hi,

I am using EKS and Vault latest-LTS version (Installed with helm).
I am using postgres as storage backend, and it is working fine. But I don’t want to pass the postgres password in plain text in config.yaml.

I am using below config.yaml file

server:
   extraSecretEnvironmentVars:
     - envName: POSTGRES_PASSWORD
       secretName: postgres-backend
       secretKey: POSTGRES_PASSWORD

   extraEnvironmentVars:
     VAULT_SEAL_TYPE: awskms
     VAULT_AWSKMS_SEAL_KEY_ID: 7e753935-75fa-*******************

   serviceAccount:
     create: true
     annotations: |
       eks.amazonaws.com/role-arn: "arn:aws:iam::412*******:role/vault-auto-unseal"
       meta.helm.sh/release-namespace: default
       meta.helm.sh/release-name: vault
     labels:
       app.kubernetes.io/instance: vault
       app.kubernetes.io/managed-by: Helm
       app.kubernetes.io/name: vault
       helm.sh/chart: vault-0.30.0
   affinity: ""
   ha:
      enabled: true
      raft:
         enabled: true
         setNodeId: true
         config: |
            ui = true
            cluster_name = "vault-postgres-storage"

            storage "postgresql" {
              #connection_url="postgres://postgres:8qYUaQWWg97lOn9HEnY3@******************.us-east-1.rds.amazonaws.com:5432/vaultdb"
              connection_url="postgres://postgres:${POSTGRES_PASSWORD}@**************.us-east-1.rds.amazonaws.com:5432/vaultdb"
              table="vault_kv_store",
              ha_enabled=true,
              ha_table="vault_ha_locks"
              }

            listener "tcp" {
               address = "[::]:8200"
               cluster_address = "[::]:8201"
               tls_disable = "true"
            }
            service_registration "kubernetes" {}
            log_level = "Debug"
            seal "awskms" {
              region     = "us-east-1"
              kms_key_id = "7e753935-75fa-**************"
            }

ui:
  enabled: true
  externalPort: 8200

Also I have created kubernetes-secret

And After helm install I am able to see the actual password from within vault-container

But when I’m using the actual hard-coded password in connection_url, it is able to inject the kubernetes-secret as env inside vault POD.

But when I’m using ${POSTGRES_PASSWORD} in connection_url, rather than hard-coded password it is not working and throwing below error -

Is there anything that I’m doing wrong like passing the things in connection_url or any other issue.

Thanks in advance !

Hi @Bharat-vyas

Looking at how PostgreSQL handles environment variables you may be able to remove the password from the connection string and have it rely on PGPASSWORD in the environment. So only providing the user in the connecting string.

connection_url="postgres://postgres@example.com:5432/vaultdb"

Alternatively, it looks like you can pass the entire PostgreSQL connection url as an environment variable using VAULT_PG_CONNECTION_URL.

  • connection_url (string: <required>) – Specifies the connection string to use to authenticate and connect to PostgreSQL. The connection URL can also be set using the VAULT_PG_CONNECTION_URL environment variable. A full list of supported parameters can be found in the pgx library and PostgreSQL connection string documentation.

Hi @michaelkosir

Thanks a lot, It worked, basically I used the same method that I was using
just used below config:

server:
   extraSecretEnvironmentVars:
     - envName: VAULT_PG_CONNECTION_URL
       secretName: postgres-backend-connection-url
       secretKey: VAULT_PG_CONNECTION_URL

   extraEnvironmentVars:
     VAULT_SEAL_TYPE: awskms
     VAULT_AWSKMS_SEAL_KEY_ID: 7e753935-75fa*************

   serviceAccount:
     create: true
     annotations: |
       eks.amazonaws.com/role-arn: "arn:aws:iam::******:role/vault-auto-unseal"
       meta.helm.sh/release-namespace: default
       meta.helm.sh/release-name: vault
     labels:
       app.kubernetes.io/instance: vault
       app.kubernetes.io/managed-by: Helm
       app.kubernetes.io/name: vault
       helm.sh/chart: vault-0.30.0
   affinity: ""
   ha:
      enabled: true
      raft:
         enabled: true
         setNodeId: true
         config: |
            ui = true
            cluster_name = "vault-postgres-storage"

            storage "postgresql" {
              table="vault_kv_store",
              ha_enabled=true,
              ha_table="vault_ha_locks"
              }

            listener "tcp" {
               address = "[::]:8200"
               cluster_address = "[::]:8201"
               tls_disable = "true"
            }
            service_registration "kubernetes" {}
            log_level = "Debug"
            seal "awskms" {
              region     = "us-east-1"
              kms_key_id = "7e753935-75fa**********"
            }


ui:
  enabled: true
  externalPort: 8200

I passed whole connection_url within the secret, and then refer the secret without providing connection_url in config.

  kubectl create secret generic postgres-backend-connection-url \
  --from-literal=VAULT_PG_CONNECTION_URL='postgres://postgres:************@************.us-east-1.rds.amazonaws.com:5432/vaultdb'

Thanks for the help @michaelkosir !

1 Like

Also if possible can you suggest what should be the best way to provide “kms_key_id” in secure way ?
For now I’m passing it directly but having service account and role attached, so don’t have to provide credentials.

AWS states that the key identifier (kms_key_id) is completely unrelated to the key material associated with the KMS key. Therefore I do not think it is considered sensitive data and can be left in the helm values file.

The way you are defining it through environment variables works, but you could also create a KMS key alias and use the alias instead of the key id.

  • [kms_key_id]: The AWS KMS key ID or ARN to use for encryption and decryption. May also be specified by the VAULT_AWSKMS_SEAL_KEY_ID environment variable. An alias in the format alias/key-alias-name may also be used here.

The most important thing is not exposing any AWS credentials, but as you stated you are using a service account and role as to not hardcode any credentials!

Thanks for the explanation @michaelkosir !