Search code examples
kubernetesamazon-eksvault

Extract Only Secret Values with EKS + Vault CSI Provider


I am using the Vault CSI Provider with EKS to load secrets stored in Vault KV into my deployment as a JSON file. Here are the relevant configurations:

SecretProviderClass configuration:

apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: CENSORED-secret-provider-class
  namespace: CENSORED
spec:
  parameters:
    objects: |
      - objectName: "CENSORED"
        secretPath: "CENSORED"
        secretKey: ""
        template: |
          {
            "BotToken": "{{ .data.BotToken }}",
            "Mongo": {
              "db": "{{ .data.Mongo.db }}",
              "host": "{{ .data.Mongo.host }}",
              "password": "{{ .data.Mongo.password }}",
              "port": {{ .data.Mongo.port }},
              "username": "{{ .data.Mongo.username }}"
            }
          }
    roleName: CENSORED
    vaultAddress: CENSORED
  provider: vault

Secret stored in Vault KV:

/ $ vault kv get CENSORED
====== Data ======
Key         Value
---         -----
BotToken    CENSORED
Mongo       map[db:CENSORED host:CENSORED password:CENSORED port:CENSORED username:CENSORED]

Deployment.yaml:

          volumeMounts:
            - name: secret
              mountPath: CENSORED
              readOnly: true
      volumes:
      - name: secret
        csi:
          driver: secrets-store.csi.k8s.io
          readOnly: true
          volumeAttributes:
            secretProviderClass: "CENSORED"
            secretKey: ""

My Situation: I am trying to use Vault CSI Provider to load secrets stored in Vault KV into my deployment.yaml. The service expects the secret in the form of an ENV.json file.

While I have successfully loaded the secrets from Vault KV, I am encountering an issue where additional fields (like request_id, lease_id, etc.) are added to the JSON, making it difficult for me to access the desired data.

This is how the secret looks after being loaded:

AS-IS:

/CENSORED # cat CENSORED.json 
{
  "request_id": "...",
  "lease_id": "",
  "lease_duration": 2764800,
  "renewable": false,
  "data": {
    "BotToken": "...",
    "Mongo": {
      "db": "...",
      "host": "...",
      "password": "...",
      "port": ...,
      "username": "..."
    }
  }
}

I want to extract only the values under the data field and remove the extra fields like request_id, lease_id, etc., so that the output looks like this:

TO-BE:

/CENSORED # cat CENSORED.json 
{
  "BotToken": "...",
  "Mongo": {
    "db": "...",
    "host": "...",
    "password": "...",
    "port": ...,
    "username": "..."
  }
}

Question: How can I modify my setup so that only the contents under the data field are included in the JSON file, without the additional metadata like request_id and lease_id?


Solution

  • when you set the secretKey: "", it will have the metadata. The only solution is to copy all the needed data (AS json object) to a new key (let's say Appinfo in the same path) and retrieve that key:

    vault kv put YOUR_PATH_IN_VAULT -<<EOF
    {
      "Appinfo": {
        "BotToken": "...",
        "Mongo": {
          "db": "...",
          "host": "...",
          "password": "...",
          "port": "...",
          "username": "..."
        }
      }
    }
    EOF
    

    and then in your SecretProviderClass configuration:

    apiVersion: secrets-store.csi.x-k8s.io/v1
    kind: SecretProviderClass
    metadata:
      name: CENSORED-secret-provider-class
      namespace: CENSORED
    spec:
      parameters:
        objects: |
          - objectName: "CENSORED"
            secretPath: "CENSORED"
            secretKey: "Appinfo"
        roleName: CENSORED
        vaultAddress: CENSORED
      provider: vault