Mounting secrets via CSI driver¶
Overview¶
This is a guide on how to mount secrets to your pods using the Secrets Store CSI Driver for HashiCorp Vault. For overview on installation and configuration process of the CSI Driver, refer to this guide.
Prerequisites¶
- Kubernetes cluster
- Vault installed and running (This guide assumes external installation)
- Vault CSI Driver installed and configured see this guide
- Kubernetes authentication method setup in Vault see this guide
Installation¶
Step 1. Create a secret via Vault UI¶
- Open desired Secret Engine (in this case it's a
kvstore), you should see a list of secrets, like this:
- Click on
Create secretbutton, fill in the form with desired key-value pairs and clickSave, for example:
- You should now see your secret in the UI. Note the API path as you will need it later (the overview page may vary depending on the secret engine you're using):

- Create a policy that will allow your application to access the secret:

- Go to
Access->Authentication Methodsand click on your kubernetes auth method, you should see list of related roles like this:
- Click on
Create Rolebutton, fill in the form with desired values, remember to set policy in the Tokens section. ClickSave, for example:
Step 2. Create a Kubernetes Mount & deploy a pod¶
Note
For the sake of the guide we will be deploying a simple "hello world" webapp container written in Go, from jweissig/app:0.0.1 image.
- Create a Kubernetes SecretProviderClass object:
Where:
apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: vault-database spec: provider: vault parameters: vaultAddress: "https://192.168.88.212" vaultSkipTLSVerify: "true" roleName: "webapp-example" objects: | - objectName: "db-password" secretPath: "secret/data/webapp-example" secretKey: "password" vaultAddressis the address of your Vault servervaultSkipTLSVerifyis a boolean flag that tells the driver to skip TLS verification (Not recommended for production, the CA certificate should be mounted inside the provider pods, however for the sake of completeness of this guide we will assume that the certificate is not present)roleNameis the name of the role you created in the previous stepobjectsis a list of objects that you want to mount, where:objectNameis the name of the object that will be mounted in the KubernetessecretPathis the path to the secret in the VaultsecretKeyis the key from the key-value pair from Vault that will be mounted under this objectName
Additional parameters can be found in the official documentation.
-
Create a Kubernetes ServiceAccount object:
Make sure the name maches the one you've specified previously in the Vault role -
Create a Kubernetes Pod object, tied to the previously created ServiceAccount:
apiVersion: v1 kind: Pod metadata: name: webapp spec: serviceAccountName: vault-auth containers: - image: jweissig/app:0.0.1 name: webapp volumeMounts: - name: secrets-store-inline mountPath: "/mnt/secrets-store" readOnly: true volumes: - name: secrets-store-inline csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: "vault-database" - After deploying the pod make sure your secret is mounted correctly. If anything went wrong the pod will be raising warnings in the kubernetes event log.
Step 3. [Recommended] Mount as a Kubernetes Secret¶
If you want to use the secret across multiple pods, you can also mount it directly as a kuberntes secret.
To do thise you need to modify the SecretProviderClass object, as follows:
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: vault-database
spec:
provider: vault
secretObjects:
- data:
- key: password
objectName: db-password
secretName: dbpass
type: Opaque
parameters:
vaultAddress: "https://192.168.88.212"
vaultSkipTLSVerify: "true"
roleName: "webapp-example"
objects: |
- objectName: "db-password"
secretPath: "secret/data/webapp-example"
secretKey: "password"
kind: Pod
apiVersion: v1
metadata:
name: webapp
spec:
serviceAccountName: webapp-sa
containers:
- image: jweissig/app:0.0.1
name: webapp
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: dbpass
key: password
volumeMounts:
- name: secrets-store-inline
mountPath: "/mnt/secrets-store"
readOnly: true
volumes:
- name: secrets-store-inline
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: "vault-database"