Kubernetes auth best practices and advice

Dear community, we’ve been hard at work setting up vault to integrate with Kubernetes but we have a few problems and would need the experience of the forum to steer us in the right direction.

We have a Kubernetes environment with multiple namespaces with many apps in each. How would you set up the environment to secure what each pod has access to?

For example, if we have the following

vault write auth/kubernetes/role/role01 \
  bound_service_account_names="vault-auth" \
  bound_service_account_namespaces="test" \
  policies=“pol01"

vault write auth/kubernetes/role/role02 \
  bound_service_account_names="vault-auth" \
  bound_service_account_namespaces="test" \
  policies=“pol02"

And authenticate as follows

curl -s --request POST --data '{"jwt": "'"$KUBE_TOKEN"'", "role": "role01"}' ${VAULT_ADDR}/v1/auth/vault/login|jq -r .auth.client_token

What would stop me from changing the file from role01 to role02? Would I not be able to get access to credentials meant for pol02 and this across pods or even namespaces?

We then thought we could create a different service account and authentication per namespace or even per pod

vault auth enable -path=test-myapp01 kubernetes
vault auth tune -description='kubernetes authentication for myapp01 in namespace test' test-myapp01

But is vault meant to be used in this way or are we miss using the authentication layer?

Last but not least, are we using the best authentication for the job? What advantages would we have with appRole for example? What do you recommend? We currently run 80 or so pods across 15 namespaces and we aspire to reach nirvana when we get a working Gitops. :slight_smile:

Thanks!

You can enable authentication from any namespace and set access in the policy according to the namespace:

    vault write auth/kubernetes/role/role01 \
      bound_service_account_names="vault-auth" \
      bound_service_account_namespaces="*" \
      policies=“pol01"

    policy:
    path "sys/mounts" { capabilities = ["read"] }

    path "secret/data/k8s/{{identity.entity.aliases.auth_kubernetes_***.metadata.service_account_namespace}}/*" {
      capabilities = ["read"]
    }

Hi @stempher,

Thank you for your answer. I think I wasn’t very clear. What I meant was this.

If authentication using the Kubernetes method, then the pod should authenticate the following way:

curl -s --request POST --data '{"jwt": "'"$KUBE_TOKEN"'", "role": "role01"}' ${VAULT_ADDR}/v1/auth/vault/login|jq -r .auth.client_token

If that auth/vault/role has two roles role01 and role02. What would stop the pod from running the above and changing the role to role02?

curl -s --request POST --data '{"jwt": "'"$KUBE_TOKEN"'", "role": "role02"}' ${VAULT_ADDR}/v1/auth/vault/login|jq -r .auth.client_token

Is there a way to prevent access to other roles when using the same serviceAccount?

How do you secure your passwords?

  • 1 serviceAccount for all namespaces and a way I do not yet know of to segregate access to passwords
  • 1 serviceAccount per namespace with the same segregation as above
  • 1 serviceAccount per pod and a role per pod restricting all other access from that pod.

I think I am missing a critical part of how segregation and access to passwords occurs.

Thanks.

Isolation is possible only at the namespace level. There is only one role per cluster. The service account in each namespace will be the same, but will have different tokens. During k8s auth, the Vault itself learns from which namespace the request came and assigns the necessary policy.

1 Like

Thank you for your answer. It seems the Kubernetes authentication method might not be suited for us.

We will reevaluate the authentication methods starting with appRole.

Thanks again for taking the time to answer.

What is your usage scenario? Perhaps it will turn out to implement with a k8s auth)

We use namespaces to logically group together pods that a part of a workflow. This doesn’t mean that the pods in the same namespace should be able to access passwords from other pods.

If we have pods in a namespace, we would want that no other pod have access to the policy other than the policies granted to it.

If a pod has access to database credentials and only that pod should have access to those credentials, then no other pod should have access to those credentials. Within the same namespace or any other namespace.

So if I understand well, eatch auth can have multiple roles and each role multiple policies. How can we be sure that a role is tied to a specific pod and only that pod?

In such a scheme, it is better to use a different auth method, for example approle. Or revise the way namespaces are organized)