Vault Unaware

The Vault Unaware method uses the Vault Agent Injector to attach a sidecar container to a given pod. The sidecar handles all authentication with Vault, retrieves the specified secrets, and mounts them on a shared filesystem to make them available to all containers in the pod. The applications running in the pod can access these secrets as files.

Prerequisites

  • Configure and enable the Kubernetes Auth Method before configuring the Vault Unaware method.

  • Ensure a policy and role exists for the Application’s service account to access the ‘secret’ path secret engine, and a secret actually exists in this secret engine.

  1. Set environment variables on controller-0.

    $ ROOT_TOKEN=$(kubectl exec -n vault sva-vault-manager-0 -- cat /mnt/data/cluster_keys.json | grep -oP --color=never '(?<="root_token":")[^"]*')
    
    $ SA_CA_CERT=$(kubectl exec -n vault sva-vault-0 -- awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' /var/run/secrets/kubernetes.io/serviceaccount/ca.crt)
    
    $ TOKEN_JWT=$(kubectl exec -n vault sva-vault-0 -- cat /var/run/secrets/kubernetes.io/serviceaccount/token)
    
    $ KUBERNETES_PORT_443_TCP_ADDR=$(kubectl exec -n vault sva-vault-0 -- sh -c 'echo $KUBERNETES_PORT_443_TCP_ADDR')
    
    $ echo $(kubectl get secrets -n vault vault-ca -o jsonpath='{.data.tls\.crt}') | base64 --decode > /home/sysadmin/vault_ca.pem
    
  2. Create the policy.

    $ curl --cacert /home/sysadmin/vault_ca.pem --header "X-Vault-Token:$ROOT_TOKEN" -H "Content-Type: application/json" --request PUT -d '{"policy":"path \"secret/basic-secret/*\" {capabilities = [\"read\"]}"}' https://sva-vault.vault.svc.cluster.local:8200/v1/sys/policy/basic-secret-policy
    
  3. Create the role with policy and namespace.

    $ curl --cacert /home/sysadmin/vault_ca.pem --header "X-Vault-Token:$ROOT_TOKEN" --request POST --data '{ "bound_service_account_names": "basic-secret", "bound_service_account_namespaces": "default",  "policies": "basic-secret-policy",  "max_ttl": "1800000"}' https://sva-vault.vault.svc.cluster.local:8200/v1/auth/kubernetes/role/basic-secret-role
    
  4. Create the secret.

    $ curl --cacert /home/sysadmin/vault_ca.pem --header "X-Vault-Token:$ROOT_TOKEN" -H "Content-Type: application/json" -X POST -d '{"username":"pvtest","password":"Li69nux*"}' https://sva-vault.vault.svc.cluster.local:8200/v1/secret/basic-secret/helloworld
    
  5. Verify the secret.

    $ curl --cacert /home/sysadmin/vault_ca.pem --header "X-Vault-Token:$ROOT_TOKEN" https://sva-vault.vault.svc.cluster.local:8200/v1/secret/basic-secret/helloworld
    

Procedure

  1. Copy the Vault certs to the default namespace.

    $ kubectl get secret vault-server-tls --namespace=vault --export -o yaml | kubectl apply --namespace=default -f-
    
  2. Use the following vault-injector.yaml file to create a test namespace, an example Vault-Unaware deployment, ‘basic-secret’, with vault annotations for creating the Vault Agent Injector sidecar container:

    cat <<EOF >> vault-injector.yaml
    apiVersion: v1
    kind: Namespace
    metadata:
      name: test
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: basic-secret
      namespace: test
      labels:
        app: basic-secret
    spec:
      selector:
        matchLabels:
          app: basic-secret
      replicas: 1
      template:
        metadata:
          annotations:
            vault.hashicorp.com/agent-inject: "true"
            vault.hashicorp.com/tls-skip-verify: "true"
            vault.hashicorp.com/agent-inject-secret-helloworld: "secret/basic-secret/helloworld"
            vault.hashicorp.com/agent-inject-template-helloworld: |
              {{- with secret "secret/basic-secret/helloworld" -}}
              {
                "username" : "{{ .Data.username }}",
                "password" : "{{ .Data.password }}"
              }
              {{- end }}
            vault.hashicorp.com/role: "basic-secret-role"
          labels:
            app: basic-secret
        spec:
          serviceAccountName: basic-secret
          containers:
          - name: app
            image: jweissig/app:0.0.1
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: basic-secret
      labels:
        app: basic-secret
    EOF
    
  3. Apply the application and verify the pod is running.

    $ kubectl create -f helloworld.yaml
    
  4. Verify secrets are injected into the pod.

    $ kubectl exec -n pvtest basic-secret-55d6c9bb6f-4whbp -- cat /vault/secrets/helloworld