Skip to content

Add support for Kubernetes authentication#116

Closed
ruuda wants to merge 19 commits intochannable:masterfrom
ruuda:auth-kubernetes
Closed

Add support for Kubernetes authentication#116
ruuda wants to merge 19 commits intochannable:masterfrom
ruuda:auth-kubernetes

Conversation

@ruuda
Copy link
Contributor

@ruuda ruuda commented Nov 15, 2021

Background

Currently, Vaultenv requires you to have a Vault token. When used in Kubernetes, typically this Vault token is not available directly. Instead, Kubernetes mounts a file into /var/run/secrets that contains a Kubernetes service account token, and you can then use this token with the Vault Kubernetes authentication endpoint to obtain the Vault token. This authentication method also requires specifying a role.

Changes

Add a new option, --kubernetes-role, which is an alternative to --vault-token. If --kubernetes-role is supplied, Vaultenv will read the Kubernetes token from /var/run/secrets/kubernetes.io/serviceaccount/token, authenticate to Vault with that token and the given role, and that produces a token which Vaultenv will use for subsequent requests.

Testing

This feature is inherently complex: it requires a Kubernetes cluster, which is already a very complex piece of software that consists of multiple moving parts. On top of that it requires a Vault server, and then Vault needs to be configured to use Kubernetes. I wrote a Python script to test Vaultenv with Kubernetes authentication, and eventually I got it working on my machine with Minikube, but it is not fully automated, and likely the test will not work out of the box in other environments. Making this run on CI would be quite an effort and this is not my goal right now.

In addition to this semi-manual testing, I will be testing this against a production Kubernetes cluster before marking this pull request as ready for review.

Alternatives

Apparently, newer versions of Kubernetes can act as an OIDC provider, and Vault supports OIDC authentication as well. OIDC authentication is useful outside of Kubernetes. So maybe this approach of using Kubernetes authentication in Vault is already obsolete. Still, it’s a good way to explore what alternative authentication methods can look like, and I think the work in this PR will make it easier to add OIDC support in the future.

ruuda added 19 commits October 13, 2021 16:48
This is to prepare for Kubernetes support. To authenticate with a
Kubernetes service account, we need to make one additional request that
then returns the X-Vault-Token. My plan is to check for AuthKubernetes
before we start retrieving secrets, and to switch it back to
AuthVaultToken once the token has been obtained, so most of the logic
does not need to change.

For now, this only adds the CLI options for this, but trying to use it
would crash.
It makes more sense to me to first verify that we can even parse the
secrets file, before we start making requests to Vault.
This reads the Kubernetes jwt from /var/run, and uses Vault's Kubernetes
authentication to obtain a short-lived token.
This is a bit of a trade-off between safety and debuggability. If the
response could not be parsed, but still contained a secret, this might
log secrets to stdout, and they might end up in places where secrets are
not supposed to go. But on the other hand, the error message that some
json failed to parse, is not very useful if you can't see what the json
what that we tried to parse, and if it fails, it is likely a programming
or configuration error, and the response will not contain secrets.
It works now! \o/

    kubectl logs vaultenv-test-pod
    Host:                  host.minikube.internal
    Port:                  8200
    Addr:                  http://host.minikube.internal:8200
    Authentication method: Kubernetes service account, role: vaultenv-test-role
    Secret file:           /lib/test.secrets
    Command:               /bin/env
    Arguments:             []
    Use TLS:               False
    Validate certs:        True
    Inherit env:           True
    Inherit env blacklist: []
    Base delay:            40
    Retry attempts:        9
    Log-level:             Info
    Use PATH:              True
    Concurrent requests:   8
    DATA_TESTAPP_CONFIG_USERNAME=vaultenvtestuser
    DATA_TESTAPP_CONFIG_PASSWORD=hunter2
Finally it can test what it was supposed to test!
Copy link
Contributor

@Riscky Riscky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work!
I don't have any specific comments, but I do have a general question: since we want to add more authentication methods later (Github auth to be specific), can you move the Kubernetes specific logic in Main.hs to a separate file?

@Riscky
Copy link
Contributor

Riscky commented Jun 13, 2022

This has been merged via #122

@Riscky Riscky closed this Jun 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants