Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Vault Agent for Kubernetes

The final next step is to configure Vault's Kubernetes authentication method.

See https://www.vaultproject.io/docs/auth/kubernetes.html#configuration

See https://learn.hashicorp.com/vault/identity-access-management/vault-agent-k8s

First, configure a ServiceAccount in Kubernetes that Vault will use to authenticate:

Code Block
languagebash
# Create a service account called 'vault-auth'
$ kubectl create serviceaccount vault-auth

# Write a set of permissions for the service account
$ cat vault-auth-service-account.yml
  ---
  apiVersion: rbac.authorization.k8s.io/v1beta1
  kind: ClusterRoleBinding
  metadata:
    name: role-tokenreview-binding
    namespace: default
  roleRef:
    apiGroup: rbac.authorization.k8s.io
    kind: ClusterRole
    name: system:auth-delegator
  subjects:
  - kind: ServiceAccount
    name: vault-auth
    namespace: default

# Update the vault-auth service account with the new permissions
$ kubectl apply --filename vault-auth-service-account.yml

If you are running locally, you will also need to point Vault at your Kubernetes cluster. In the Helm Chart case, this should already be done for you.

Code Block
languagebash
# Set VAULT_SA_NAME to the service account you created earlier
$ export VAULT_SA_NAME=$(kubectl get sa vault-auth -o jsonpath="{.secrets[*]['name']}")

# Set SA_JWT_TOKEN value to the service account JWT used to access the TokenReview API
$ export SA_JWT_TOKEN=$(kubectl get secret $VAULT_SA_NAME -o jsonpath="{.data.token}" | base64 --decode; echo)

# Set SA_CA_CRT to the PEM encoded CA cert used to talk to Kubernetes API
$ export SA_CA_CRT=$(kubectl get secret $VAULT_SA_NAME -o jsonpath="{.data['ca\.crt']}" | base64 --decode; echo)

# Set K8S_HOST to minikube or master IP address
$ export K8S_HOST=$(minikube ip)

Now we are ready to enable the Kubernetes auth method:

Code Block
languagebash
# Enable the Kubernetes auth method at the default path ("auth/kubernetes")
$ vault auth enable kubernetes

# Tell Vault how to communicate with the Kubernetes cluster
$ vault write auth/kubernetes/config \
        token_reviewer_jwt="$SA_JWT_TOKEN" \
        kubernetes_host="https://$K8S_HOST:8443" \
        kubernetes_ca_cert="$SA_CA_CRT"

# Create a role named 'example' to map Kubernetes ServiceAccount to Vault policies and default token TTL
$ vault write auth/kubernetes/role/example \
        bound_service_account_names=vault-auth \
        bound_service_account_namespaces=default \
        policies=myapp-kv-ro \
        ttl=24h

Test That it Works

Run a simple pod:

Code Block
languagebash
$ kubectl run --generator=run-pod/v1 tmp --rm -i --tty --serviceaccount=vault-auth --image alpine:3.7

Once inside the container, install curl  and jq:

Code Block
languagebash
/# apk update
/# apk add curl jq

Verify that you can communicate with the Vault cluster and you should see output similar to the following:

Code Block
languagebash
/# VAULT_ADDR=http://10.0.2.2:8200

/# curl -s $VAULT_ADDR/v1/sys/health | jq
{
  "initialized": true,
  "sealed": false,
  "standby": false,
  "performance_standby": false,
  "replication_performance_mode": "disabled",
  "replication_dr_mode": "disabled",
  "server_time_utc": 1543969628,
  "version": "1.0.0+ent",
  "cluster_name": "vault-cluster-e314942e",
  "cluster_id": "2b4f6213-d58f-0530-cf07-65ea467181f2"
}

NOTE: Be sure to set VAULT_ADDR to where your Vault server is running if it's NOT running locally.

Set KUBE_TOKEN to the service account token value:

Code Block
languagebash
/# KUBE_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
/# echo $KUBE_TOKEN


Now, test the kubernetes auth method to ensure that you can authenticate with Vault:

Code Block
languagebash
/# curl --request POST \
        --data '{"jwt": "'"$KUBE_TOKEN"'", "role": "example"}' \
        $VAULT_ADDR/v1/auth/kubernetes/login | jq
{
  ...
  "auth": {
    "client_token": "s.7cH83AFIdmXXYKsPsSbeESpp",
    "accessor": "8bmYWFW5HtwDHLAoxSiuMZRh",
    "policies": [
      "default",
      "myapp-kv-ro"
    ],
    "token_policies": [
      "default",
      "myapp-kv-ro"
    ],
    "metadata": {
      "role": "example",
      "service_account_name": "vault-auth",
      "service_account_namespace": "default",
      "service_account_secret_name": "vault-auth-token-vqqlp",
      "service_account_uid": "adaca842-f2a7-11e8-831e-080027b85b6a"
    },
    "lease_duration": 86400,
    "renewable": true,
    "entity_id": "2c4624f1-29d6-972a-fb27-729b50dd05e2",
    "token_type": "service"
  }
}

Notice that client_token is successfully generated and myapp-kv-ro policy is attached with the token. The metadata displays that its service account name (service_account_name) is vault-auth.

Vault Agent Auto-Auth

TBD