Secrets in Kubernetes and HashiCorp Vault

Secrets in Kubernetes and HashiCorp Vault

Deeptiman Pattnaik's photo
Deeptiman Pattnaik
·Sep 30, 2020·

12 min read

Subscribe to my newsletter and never miss my upcoming articles

In this article, I will try to explain the features that Kubernetes provides to store sensitive data, credentials, auth token as Secret that will run under a Pod. Also, we will see a more robust approach to store Secrets using HashiCorp Vault.

Kubernetes Secrets

In application development, sensitive data storage is a critical operation. A single key or credential leak can bridge an entire database system in a network. So, Kubernetes provide flexibility where we can store a small size of data in different format like in a file system, environmental variable, and mount them into a volume. The Secrets will be mounted to a Pod to be accessible.

Secrets as Environmental Variables

The secrets can be mounted as an env variable and in a Pod definition, each container will contain a secret key that can be accessed from env[].valueFrom.secretKeyRef.

  • Create Secret literals using kubectl
$ kubectl create secret generic mongosecret — from-literal=’username=demoadmin’ — from-literal=’password=demopwd123'

Distribute Credentials Securely Using Secrets This page shows how to securely inject sensitive data, such as passwords and encryption keys, into Pods. Before you…kubernetes.io

  • Deploy Secret as Environment variable in Pod
spec:
containers:
- name: go-cache-kubernetes-container-poc
  image: deeptiman1991/go-cache-kubernetes-v1:1.0.0
env:
- name: SECRET_USERNAME
    valueFrom:
      secretKeyRef:
        name: mongosecret
        key: username
- name: SECRET_PASSWORD
    valueFrom:
      secretKeyRef:
        name: mongosecret
        key: password

So, under a container, multiple env can be created. In this Pod deployment, we have created two Secrets as ‘SECRET_USERNAME’ and ‘SECRET_PASSWORD’.

If we get into the Pod shell

$ kubectl exec -it <<pod-name>> — /bin/sh

# echo $SECRET_USERNAME
# demoadmin
# echo $SECRET_PASSWORD
# demopwd123

Potential Risk using Kubernetes Secrets

There are many different possibilities of risk involved with using Kubernetes Secrets if the Pods are not configured properly.

  • In a shared environment, if the administrator creates secrets in the cluster and may be possible for unauthorized access to the environment variable by the malicious actor.

  • Avoid writing environmental variables into the logs as they are widely visible in the plain text.

  • In a large scale cloud infrastructure, there is a higher chance of misconfiguration of microservices, containers can easily create security vulnerabilities to gain access to the container images to read envs.

  • Creating various levels of access policy among containers, pods are highly essential as every node in Kubernetes environment talk to each other that give all access to file systems, database cluster, and many other exposed endpoints.

  • Frequent security assessment and audit of each container has to be an essential practice for the network administrator.

A robust approach with HashiCorp Vault

The *HashiCorp Vault* provides a variety of pluggable component architecture that store secrets with access-controls, policies, token management, and key sharing encryption algorithms. The access control to sensitive data can be changed dynamically on lease or Time to Live (TTL).

Vault Seal/Unseal

The initial status of the vault is sealed and cannot decrypt any data stored in the physical storage. Vault follows the *Shamir Key Sharing Algorithm* that creates multiple pieces of the master key. So, the vault requires a master key to unlock the encryption key to decrypt the data that is stored inside the vault.

$ export VAULT_ADDR=[http://127.0.0.1:8200](http://127.0.0.1:8200)
$ vault operator init

   Unseal Key 1: SVJHjpSU/1Y3I5LqHJM5oQ+WCyQ52KJSb6/4939phE97
   Unseal Key 2: cPBI2gDQX7o3igJwml34fo1wN7mM0WZO++fW5Al0Vc3J
   Unseal Key 3: pUhQ5HsnBvaCOtjRNdNo5d6FMw9iWKN0/UZTAeyM11kB
   Unseal Key 4: yTR7BKgEkMG+hSClBu9yrx13sLMioXukTJsONUrQClWY
   Unseal Key 5: prDHpyCzyDAu2g1MvG81ammS1cgqV8pQCQ+WZvb55zpu

Initial Root Token: s.su8bzw3WALaNfGCWVdrhALdK

Deploy Vault Up to this point, you interacted with the "dev" server, which automatically unseals Vault, sets up in-memory storage…learn.hashicorp.com

The initialization of the vault creates 5 key shares and a threshold of 3 keys to unseal the vault. These unseal keys are only visible in the local environment but in the real scenario, these keys won’t be visible altogether, and also they will be encrypted using several tools like Keybase and *HashiCorp’s PGP*.

$ vault operator unseal
Unseal Key (will be hidden):
 Key             Value
 ---             -----
 Seal Type       shamir
 Initialized     true
 Sealed          false
 Total Shares    1
 Threshold       1
 Version         1.5.2
 Cluster Name    vault-cluster-29ef6044
 Cluster ID      00081a9e-4f31-3902-4b8c-3b047fefad34
 HA Enabled      true
 HA Cluster      [https://vault-0.vault-internal:8201](https://vault-0.vault-internal:8201)
 HA Mode         active

 The administrator can also login with root token.

$ vault login s.su8bzw3WALaNfGCWVdrhALdK

Create Static Secret with Vault using Minikube

We will create a sample static secret using Vault under a *minikube* environment similar to the environmental variable secret using Kubernetes.

  • Install Consul Helm Chart

HashiCorp provides a *Consul Helm chart that provides a configured Consul to run under a Vault Dev Server Mode*.

Add HashiCorp Helm repository

$ helm repo add hashicorp [https://helm.releases.hashicorp.com](https://helm.releases.hashicorp.com)
 “hashicorp” has been added to your repositories

Vault Installation to Minikube via Helm Running Vault on Kubernetes is generally the same as running it anywhere else. Kubernetes, as a container orchestration…learn.hashicorp.com

  • Deploy Consul Client and Server Pods
$ cat helm-consul-values-yaml
global:
  datacenter: vault-kubernetes-guide

client:
  enabled: true

server:
  replicas: 1
  bootstrapExpect: 1
  disruptionBudget:
    maxUnavailable: 0
$ helm install consul hashicorp/consul  values helm-consul-values.yaml
 NAME: consul
 LAST DEPLOYED: Tue Sep 29 23:26:53 2020
 NAMESPACE: default
 STATUS: deployed
 REVISION: 1
 NOTES:
 Thank you for installing HashiCorp Consul!

$ kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
consul-consul-ffqnh      1/1     Running   0          5m46s
consul-consul-server-0   1/1     Running   0          5m45s

Both Client and Server Pods deployed successfully.

  • Install Vault Helm Chart

The Vault Helm Chart will run in *high-availability* mode and will create a file storage backend.

$ cat helm-vault-values.yaml
server:
  affinity: ""
  ha:
    enabled: true
$ helm install vault hashicorp/vault  values helm-vault-values.yaml 
 NAME: vault
 LAST DEPLOYED: Tue Sep 29 23:43:38 2020
 NAMESPACE: default
 STATUS: deployed
 REVISION: 1
 TEST SUITE: None
 NOTES:
 Thank you for installing HashiCorp Vault!

$ kubectl get pods
 NAME                                  READY STATUS   RESTARTS AGE
 consul-consul-ffqnh                   1/1 Running           0 18m
 consul-consul-server-0                1/1 Running           0 18m
 vault-0                               0/1 Running           0 95s
 vault-1                               0/1 Running           0 93s
 vault-2                               0/1 ContainerCreating 0 92s
 vault-agent-injector-857cdd9594-xq8cv 0/1 ContainerCreating 0 95s

This installation will create Vault Pods and Vault Agent but they are not ready as the status shows (0/1) because the Vault seal status is true.

$ kubectl exec -it vault-0 -- vault status
 Key                 Value
                   -
 Seal Type           shamir
 Initialized         false
 Sealed              true
 Total Shares        0
 Threshold           0
 Unseal Progress     0/0
 Unseal Nonce        n/a
 Version             n/a
 HA Enabled          true
 command terminated with exit code 2

Unseal the Vault

Initialize the Vault with -key-shares=5 and -key-threshold=3

$ kubectl exec -it vault-0 -- vault operator init -key-shares=5 -key-threshold=3 -format=json > vault-keys.json
$ cat vault-keys.json
{
    "unseal_keys_b64": [
      "SMY/5QwJkqc4bHAWiEg0bA5h50M+5kkkE4q6iHP14rG/",
      "0oO5su7BJ7uiAFfX0lnB9Omb8ZkWU8/CN6gPb5YqNbec",
      "PK0EY++Y/zL5OgeHMlwA3dC7wn8gF6nsDDHMLBOD/NvD",
      "5alKgqaa4y3BkeqPzwodHMQ9nE8PI/QsD+2h419AYKVB",
      "dUHpwUY7TKkzT9j9VzvcsyeJsSUBXmxV89iVR0jowMXa"
    ],
    "unseal_keys_hex": [
      "48c63fe50c0992a7386c70168848346c0e61e7433ee64924138aba8873f5e2b1bf",
      "d283b9b2eec127bba20057d7d259c1f4e99bf1991653cfc237a80f6f962a35b79c",
      "3cad0463ef98ff32f93a0787325c00ddd0bbc27f2017a9ec0c31cc2c1383fcdbc3",
      "e5a94a82a69ae32dc191ea8fcf0a1d1cc43d9c4f0f23f42c0feda1e35f4060a541",
      "7541e9c1463b4ca9334fd8fd573bdcb32789b125015e6c55f3d8954748e8c0c5da"
    ],
    "unseal_shares": 5,
    "unseal_threshold": 3,
    "recovery_keys_b64": [],
    "recovery_keys_hex": [],
    "recovery_keys_shares": 5,
    "recovery_keys_threshold": 3,
    "root_token": "s.4XLyZOkSzGynYL0GDCCTruJ7"
}

Now Unseal the vault-0 with the unseal keys. We need to enter at-least 3 unseal keys to change the seal status false.

$ kubectl exec -it vault-0 -- /bin/sh
$ vault operator unseal
 Unseal Key (will be hidden): SMY/5QwJkqc4bHAWiEg0bA5h50M+5kkkE4q6iHP14rG/
 Key                Value
 ---                -----
 Seal Type          shamir
 Initialized        true
 Sealed             true
 Total Shares       5
 Threshold          3
 Unseal Progress    1/3
 Unseal Nonce       db5bf091-4695-9238-61e2-66ae08e97b8e
 Version            1.5.2
 HA Enabled         true
$ vault operator unseal
  Unseal Key (will be hidden): 0oO5su7BJ7uiAFfX0lnB9Omb8ZkWU8/CN6gPb5YqNbec
 Key                Value
 ---                -----
 Seal Type          shamir
 Initialized        true
 Sealed             true
 Total Shares       5
 Threshold          3
 Unseal Progress    2/3
 Unseal Nonce       db5bf091-4695-9238-61e2-66ae08e97b8e
 Version            1.5.2
 HA Enabled         true
$ vault operator unseal
 Unseal Key (will be hidden): PK0EY++Y/zL5OgeHMlwA3dC7wn8gF6nsDDHMLBOD/NvD
 Key                    Value
 ---                    -----
 Seal Type              shamir
 Initialized            true
 Sealed                 false
 Total Shares           5
 Threshold              3
 Version                1.5.2
 Cluster Name           vault-cluster-ea4ff059
 Cluster ID             34e1ad16-6aca-5085-3442-0acf00a3ebbd
 HA Enabled             true
 HA Cluster             n/a
 HA Mode                standby
 Active Node Address    <none>

Now vault-0 is unseal, similar will follow for vault-1, vault-2.

$ kubectl get pods
 NAME                                  READY STATUS  RESTARTS AGE
 consul-consul-ffqnh                   1/1   Running 0        38m
 consul-consul-server-0                1/1   Running 0        38m
 vault-0                               1/1   Running 0        22m
 vault-1                               1/1   Running 0        22m
 vault-2                               1/1   Running 0        22m
 vault-agent-injector-857cdd9594-xq8cv 1/1   Running 0        22m

All Vault Pods and Vault Agents are now running.

Vault Web UI

Vault Web Interface can be accessible at http://localhost:8200/ui from the web browser, so please follow the below command for port-forwarding at 8200. $ kubectl port-forward vault-0 8200:8200 Forwarding from 127.0.0.1:8200 -&gt; 8200 Forwarding from [::1]:8200 -&gt; 8200

Vault Sign in — Use root token to authenticateVault Sign in — Use root token to authenticate

  • Set Secret in Vault

Now, we can proceed to create a secret in Vault at the path secret/webapp/config. The secrets will be stored as key-value pairs in the Vault secret engine and login into the Vault via root token is required to enable the key-value secret engine.

$ kubectl exec -it vault-0 — /bin/sh
$ vault login
  Token (will be hidden): s.4XLyZOkSzGynYL0GDCCTruJ7
  Success! You are now authenticated. The token information displayed below
  is already stored in the token helper. You do NOT need to run "vault login"
  again. Future Vault requests will automatically use this token.

  Key                  Value
  ---                  -----
  token                s.4XLyZOkSzGynYL0GDCCTruJ7
  token_accessor       wkHbTPmh5pnxdbKQNwbT7b1L
  token_duration       ∞
  token_renewable      false
  token_policies       ["root"]
  identity_policies    []
  policies             ["root"]
$ vault secrets enable -path=secret kv-v2
  Success! Enabled the kv-v2 secrets engine at: secret/

Create Secret at path secret/webapp/config

$ vault kv put secret/webapp/config username=”demoadmin” password=”demopwd123"
 Key               Value
                 -
 created_time      2020–09–29T18:45:21.598063156Z
 deletion_time     n/a
 destroyed         false
 version           1
$ vault kv get secret/webapp/config
 ====== Metadata ======
 Key              Value
 ---              -----
 created_time     2020-09-29T18:45:21.598063156Z
 deletion_time    n/a
 destroyed        false
 version          1

====== Data ======
 Key         Value
 ---         -----
 password    demopwd123
 username    demoadmin

The static secret as username and password is created at Vault secret engine.

Vault Secret DashboardVault Secret Dashboard

Configure Vault with Authentication

Vault will authenticate web applications via *JWT token with limited access to read secrets. The [Kubernetes Service Account](kubernetes.io/docs/tasks/configure-pod-cont..) authentication method will provide a token to the clients. Vault will authenticate web applications via JWT token with limited access to read secrets. The Kubernetes Service Account* authentication method will provide a token to the clients.

$ kubectl exec -it vault-0 — /bin/sh
$ vault auth enable kubernetes
Success! Enabled kubernetes auth method at: kubernetes/

Vault Installation to Minikube via Helm Running Vault on Kubernetes is generally the same as running it anywhere else. Kubernetes, as a container orchestration…learn.hashicorp.com

Configure the Kubernetes authentication with Service Account Token

$ vault write auth/kubernetes/config \
 token_reviewer_jwt=”$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)” \
 kubernetes_host=”[https://$KUBERNETES_PORT_443_TCP_ADDR:443](https://$KUBERNETES_PORT_443_TCP_ADDR:443)" \
 kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt 
 Success! Data written to: auth/kubernetes/config

This will configure the token_reviewer_jwt and kubernetes_ca_cert that will mount with containers during the creation in Kubernetes.

Grant Read Access Policy

The secret path secret/webapp/config requires few policy access agreements that will enable clients to read secrets from the path.

$ vault policy write webapp — <<EOF
 pathsecret/data/webapp/config” {
 capabilities = [“read”]
 }
 EOF
 Success! Uploaded policy: webapp 

 Additional role-based control requires to apply this policy in the authentication engine.

$ vault write auth/kubernetes/role/webapp \
 bound_service_account_names=vault \
 bound_service_account_namespaces=default \
 policies=webapp \
 ttl=24h
 Success! Data written to: auth/kubernetes/role/webapp

The authentication token remains alive for 24 hours.

Verify Vault Setup from minikube dashboard

Type the following command to navigate to the Kubernetes dashboard in the browser.

$ minikube dashboard

Vault WorkloadsVault Workloads

Vault Container Server DataVault Container Server Data

Vault Seal EventsVault Seal Events

Vault Stores Service Account Token in Kubernetes SecretsVault Stores Service Account Token in Kubernetes Secrets

Read Vault Secrets from Web Application

As we have completed all the steps to create secrets, enable authentication in Vault, configuring read access policy, So now we can apply Deployments in Kubernetes that will mount the VAULT_ADDR, JWT_PATH, and SERVICE_PORT as an env into a container.

$ cat go-cache-poc-app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: go-cache-kubernetes-app-poc
  labels:
    app: go-cache-kubernetes-app-poc
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: go-cache-kubernetes-app-poc
  template:
    metadata:      
      creationTimestamp: null
      labels:
        app: go-cache-kubernetes-app-poc
    spec:
      serviceAccountName: vault
      containers:
      - name: go-cache-kubernetes-container-poc
        image: deeptiman1991/go-cache-kubernetes-v1:1.0.0
        imagePullPolicy: Always
        env:
        - name: VAULT_ADDR
          value: "http://vault:8200"
        - name: JWT_PATH
          value: "/var/run/secrets/kubernetes.io/serviceaccount/token"
        - name: SERVICE_PORT
          value: "8080"
        ports:
        - containerPort: 5000          
      hostname: go-cache-kubernetes-app-poc
      restartPolicy: Always
      volumes:
      - name: go-cache-kubernetes-pvc-v1-poc
        persistentVolumeClaim:
          claimName: go-cache-kubernetes-pvc-v1-poc
status: {}
$ kubectl apply -f go-cache-poc-app.yaml

Vault Envs[VAULT_ADDR, JWT_PATH & SERVICE_PORT] mounted into the Web App Pod deploymentVault Envs[VAULT_ADDR, JWT_PATH & SERVICE_PORT] mounted into the Web App Pod deployment

Go Application Code

type Vault struct {
  Auth Auth
}
type Auth struct {
  Client_Token string
}    

type VaultData struct {
      Data Data
}

type Data struct {
     Data SecretData
}

type SecretData struct {
      Username string
      Password string
}


//This function is the implementation of the Vault request to read the secrets from Vault. 
//GetCredFromVault  
func GetCredFromVault() (*SecretData, error) {

  VAULT_URL := os.Getenv("VAULT_ADDR") + "/v1/"
  VAULT_AUTH_LOGIN  := "auth/kubernetes/login"
  VAULT_SECRET_DATA := "secret/data/webapp/config"
  VAULT_ROLE        := "webapp"

  JWT_TOKEN, err := ioutil.ReadFile(os.Getenv("JWT_PATH"))
  if err != nil {
    e.log.Error("Unable to read JWT File", "error", err.Error())
    return nil, err
  }

  e.log.Info("VAULT_URL", "Prod", VAULT_URL)
  e.log.Info("Vault", "Auth URL", VAULT_URL+VAULT_AUTH_LOGIN)

//Vault Request - 1: [Retrieve Client token from Vault]

  requestBody1 := strings.NewReader(`
    {
      "role": "` + VAULT_ROLE + `",
      "jwt": "` + string(JWT_TOKEN) + `"      
    }
  `)
  res1, err := http.NewRequest("POST", VAULT_URL+VAULT_AUTH_LOGIN, requestBody1)
  if err != nil {
    e.log.Error("Unable to set Request", "error", err.Error())
    return nil, err
  }
  res1.Header.Set("Content-Type", "application/json")

  resp1, err := http.DefaultClient.Do(res1)
  if err != nil {
     e.log.Error("Unable to fetch Vault Client Token", "error", err.Error())
  }
  defer resp1.Body.Close()
  data, _ := ioutil.ReadAll(resp1.Body)

  var vault Vault
  json.Unmarshal(data, &vault)

  e.log.Info("Vault", "Auth Response", string(data))
  e.log.Info("Vault", "Secret URL", VAULT_URL+VAULT_SECRET_DATA)


//Vault Request - 2: [Retrieve Secret Data from Vault]

  res2, err := http.NewRequest("GET", VAULT_URL+VAULT_SECRET_DATA, nil)
  if err != nil {
     e.log.Error("Unable to make Get request for Vault Data", "error", err.Error())
     return nil, err
  }
  res2.Header.Set("Content-Type", "application/json")
  res2.Header.Set("X-Vault-Token", vault.Auth.Client_Token)
  resp2, err := http.DefaultClient.Do(res2)
  if err != nil {
     e.log.Error("Unable to fetch Vault Data", "error", err.Error())
  }
  defer resp2.Body.Close()
  vaultData, err := ioutil.ReadAll(resp2.Body)
  if err != nil {
     e.log.Error("Unable to read Vault Data", "error", err.Error())
     return nil, err
  }

  var vData VaultData
  json.Unmarshal(vaultData, &vData)
  e.log.Info("Vault", "Response Secret Data", string(vaultData))

  return &vData.Data.Data, nil
}
  • The first request will retrieve the client_token using the Service Account Token(JWT).

  • In the second request, the client_token will be used as the “X-Vault-Token” header to send a Get request that will retrieve the secret from Vault.

  • Vault HTTP Request to receive client_token

    API: http://localhost:8200/v1/auth/kubernetes/login Method: POST

Request Body:

{
  "role": "webapp",
  "jwt": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ik5TTWZPRDl3M1g2dWtEQXp2STcwVk1SLUNfeVhsdF85UzY5b0JsOVB2bFEifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InZhdWx0LXRva2VuLXJtdHRkIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6InZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiNzQzODI4NWUtZjg1Ny00N2I3LWJlMTctODY0NjU1ZjFmYzg3Iiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRlZmF1bHQ6dmF1bHQifQ.W0HXdOD80I_Z3TBpNtdR_0M4xX_Q9XsjusK-8L5XaEH80gynbFg5H2LaYnUXied56Y4VDG0WAJzhzPb_ZV_QWoIkUtSvKP1SoLU52uTTexI73kVmlaeSzZj2ksQOgLLSJUtaCU-wHZBNotQpYBg51X5RqEzOctDwIK4t5pzckQNslWH92d70yXE_Y7-J0oFeqDDcAbZUYw3CAZ107NEsrJqp1iYId2sFeh3G7prfbxW_WmxRoNbOEulrpqap8lIyc1ypeUEZBXD-xU8alWs0crg6CZTyaqmQusNynxjxfGb_DQ1ddzjyC3KneqQ9CH7XvrZMcVcjvrnmRpwF89q0Kg"      
}

Response:

{
    "request_id": "f315c427-b2eb-676a-79d0-22ce9b34434c",
    "lease_id": "",
    "renewable": false,
    "lease_duration": 0,
    "data": null,
    "wrap_info": null,
    "warnings": null,
    "auth": {
        "client_token": "s.pKglUecLzREWuEpIsaFbt1fu",
        "accessor": "GIeVblWL7JfmgJWuZgBZL0n7",
        "policies": [
            "default",
            "webapp"
        ],
        "token_policies": [
            "default",
            "webapp"
        ],
        "metadata": {
            "role": "webapp",
            "service_account_name": "vault",
            "service_account_namespace": "default",
            "service_account_secret_name": "vault-token-rmttd",
            "service_account_uid": "7438285e-f857-47b7-be17-864655f1fc87"
        },
        "lease_duration": 86400,
        "renewable": true,
        "entity_id": "c73092ba-98a8-7870-023c-5a51c0c1ccd1",
        "token_type": "service",
        "orphan": true
    }
}
  1. Vault HTTP Request to read the secret

    API: http://localhost:8200/v1/secret/data/webapp/config Method: Get Headers X-Vault-Token: <<client_token_received_from_vault_request_1>>

Response:

{
    "request_id": "77987812-d21e-2a41-deea-bf86580501e9",
    "lease_id": "",
    "renewable": false,
    "lease_duration": 0,
    "data": {
        "data": {
            "password": "demopwd123",
            "username": "demoadmin"
        },
        "metadata": {
            "created_time": "2020-09-29T18:45:21.598063156Z",
            "deletion_time": "",
            "destroyed": false,
            "version": 1
        }
    },
    "wrap_info": null,
    "warnings": null,
    "auth": null
}

So, this is the high-level practical implementation of HashiCorp Vault and comparison with the Secrets management in Kubernetes. I hope the article may have provided you the knowledge regarding the potential benefits of using HashiCorp Vault to store sensitive information over Kubernetes Secret management.

Please also check the project on Kubernetes at my Github.

I hope you find this article useful :)

Thanks

 
Share this