2017-09-19 14:27:26 +00:00
|
|
|
|
---
|
2020-01-18 00:18:09 +00:00
|
|
|
|
layout: docs
|
|
|
|
|
page_title: Kubernetes - Auth Methods
|
2017-09-19 14:27:26 +00:00
|
|
|
|
description: |-
|
2017-09-20 20:47:13 +00:00
|
|
|
|
The Kubernetes auth method allows automated authentication of Kubernetes
|
2017-09-29 15:52:42 +00:00
|
|
|
|
Service Accounts.
|
2017-09-19 14:27:26 +00:00
|
|
|
|
---
|
|
|
|
|
|
2017-09-20 20:47:13 +00:00
|
|
|
|
# Kubernetes Auth Method
|
2017-09-19 14:27:26 +00:00
|
|
|
|
|
2017-09-20 20:47:13 +00:00
|
|
|
|
The `kubernetes` auth method can be used to authenticate with Vault using a
|
2017-09-19 14:27:26 +00:00
|
|
|
|
Kubernetes Service Account Token. This method of authentication makes it easy to
|
2017-09-20 20:47:13 +00:00
|
|
|
|
introduce a Vault token into a Kubernetes Pod.
|
2017-09-19 14:27:26 +00:00
|
|
|
|
|
2021-12-08 18:20:24 +00:00
|
|
|
|
You can also use a Kubernetes Service Account Token to [log in via JWT auth][k8s-jwt-auth].
|
|
|
|
|
See the section on [How to work with short-lived Kubernetes tokens][short-lived-tokens]
|
|
|
|
|
for a summary of why you might want to use JWT auth instead and how it compares to
|
|
|
|
|
Kubernetes auth.
|
|
|
|
|
|
|
|
|
|
-> **Note:** If you are upgrading to Kubernetes v1.21+, ensure the config option
|
|
|
|
|
`disable_iss_validation` is set to true. Assuming the default mount path, you
|
|
|
|
|
can check with `vault read -field disable_iss_validation auth/kubernetes/config`.
|
2022-02-19 00:43:18 +00:00
|
|
|
|
See [Kubernetes 1.21](#kubernetes-1-21) below for more details.
|
2021-12-08 18:20:24 +00:00
|
|
|
|
|
2017-09-19 14:27:26 +00:00
|
|
|
|
## Authentication
|
|
|
|
|
|
2017-09-20 20:47:13 +00:00
|
|
|
|
### Via the CLI
|
2017-09-19 14:27:26 +00:00
|
|
|
|
|
2017-09-20 20:47:13 +00:00
|
|
|
|
The default path is `/kubernetes`. If this auth method was enabled at a
|
|
|
|
|
different path, specify `-path=/my-path` in the CLI.
|
2017-09-19 14:27:26 +00:00
|
|
|
|
|
2020-05-21 17:18:17 +00:00
|
|
|
|
```shell-session
|
2017-09-20 20:47:13 +00:00
|
|
|
|
$ vault write auth/kubernetes/login role=demo jwt=...
|
|
|
|
|
```
|
2017-09-19 14:27:26 +00:00
|
|
|
|
|
2017-09-20 20:47:13 +00:00
|
|
|
|
### Via the API
|
2017-09-19 14:27:26 +00:00
|
|
|
|
|
2017-09-20 20:47:13 +00:00
|
|
|
|
The default endpoint is `auth/kubernetes/login`. If this auth method was enabled
|
|
|
|
|
at a different path, use that value instead of `kubernetes`.
|
2017-09-19 14:27:26 +00:00
|
|
|
|
|
2020-05-21 17:18:17 +00:00
|
|
|
|
```shell-session
|
2017-09-20 20:47:13 +00:00
|
|
|
|
$ curl \
|
|
|
|
|
--request POST \
|
2020-11-16 23:45:12 +00:00
|
|
|
|
--data '{"jwt": "<your service account jwt>", "role": "demo"}' \
|
2018-03-23 15:41:51 +00:00
|
|
|
|
http://127.0.0.1:8200/v1/auth/kubernetes/login
|
2017-09-19 14:27:26 +00:00
|
|
|
|
```
|
|
|
|
|
|
2017-09-20 20:47:13 +00:00
|
|
|
|
The response will contain a token at `auth.client_token`:
|
2017-09-19 14:27:26 +00:00
|
|
|
|
|
2017-09-20 20:47:13 +00:00
|
|
|
|
```json
|
2017-09-19 14:27:26 +00:00
|
|
|
|
{
|
2017-09-20 20:47:13 +00:00
|
|
|
|
"auth": {
|
|
|
|
|
"client_token": "38fe9691-e623-7238-f618-c94d4e7bc674",
|
|
|
|
|
"accessor": "78e87a38-84ed-2692-538f-ca8b9f400ab3",
|
2020-01-18 00:18:09 +00:00
|
|
|
|
"policies": ["default"],
|
2017-09-20 20:47:13 +00:00
|
|
|
|
"metadata": {
|
2018-05-01 22:04:53 +00:00
|
|
|
|
"role": "demo",
|
2017-09-20 20:47:13 +00:00
|
|
|
|
"service_account_name": "vault-auth",
|
|
|
|
|
"service_account_namespace": "default",
|
|
|
|
|
"service_account_secret_name": "vault-auth-token-pd21c",
|
|
|
|
|
"service_account_uid": "aa9aa8ff-98d0-11e7-9bb7-0800276d99bf"
|
|
|
|
|
},
|
|
|
|
|
"lease_duration": 2764800,
|
|
|
|
|
"renewable": true
|
|
|
|
|
}
|
2017-09-19 14:27:26 +00:00
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Configuration
|
|
|
|
|
|
2017-09-20 20:47:13 +00:00
|
|
|
|
Auth methods must be configured in advance before users or machines can
|
|
|
|
|
authenticate. These steps are usually completed by an operator or configuration
|
|
|
|
|
management tool.
|
2017-09-19 14:27:26 +00:00
|
|
|
|
|
2021-12-08 18:20:24 +00:00
|
|
|
|
1. Enable the Kubernetes auth method:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
vault auth enable kubernetes
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
1. Use the `/config` endpoint to configure Vault to talk to Kubernetes. Use
|
|
|
|
|
`kubectl cluster-info` to validate the Kubernetes host address and TCP port.
|
|
|
|
|
For the list of available configuration options, please see the
|
2022-03-18 01:14:48 +00:00
|
|
|
|
[API documentation](/api-docs/auth/kubernetes).
|
2021-12-08 18:20:24 +00:00
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
vault write auth/kubernetes/config \
|
|
|
|
|
token_reviewer_jwt="<your reviewer service account JWT>" \
|
|
|
|
|
kubernetes_host=https://192.168.99.100:<your TCP port or blank for 443> \
|
|
|
|
|
kubernetes_ca_cert=@ca.crt
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
!> **Note:** The pattern Vault uses to authenticate Pods depends on sharing
|
|
|
|
|
the JWT token over the network. Given the [security model of
|
|
|
|
|
Vault](/docs/internals/security), this is allowable because Vault is
|
|
|
|
|
part of the trusted compute base. In general, Kubernetes applications should
|
|
|
|
|
**not** share this JWT with other applications, as it allows API calls to be
|
|
|
|
|
made on behalf of the Pod and can result in unintended access being granted
|
|
|
|
|
to 3rd parties.
|
|
|
|
|
|
|
|
|
|
1. Create a named role:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
vault write auth/kubernetes/role/demo \
|
|
|
|
|
bound_service_account_names=vault-auth \
|
|
|
|
|
bound_service_account_namespaces=default \
|
|
|
|
|
policies=default \
|
|
|
|
|
ttl=1h
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
This role authorizes the "vault-auth" service account in the default
|
|
|
|
|
namespace and it gives it the default policy.
|
|
|
|
|
|
|
|
|
|
For the complete list of configuration options, please see the [API
|
2022-03-18 01:14:48 +00:00
|
|
|
|
documentation](/api-docs/auth/kubernetes).
|
2021-12-08 18:20:24 +00:00
|
|
|
|
|
|
|
|
|
## Kubernetes 1.21
|
|
|
|
|
|
|
|
|
|
Starting in version [1.21][k8s-1.21-changelog], the Kubernetes
|
|
|
|
|
`BoundServiceAccountTokenVolume` feature defaults to enabled. This changes the
|
|
|
|
|
JWT token mounted into containers by default in two ways that are important for
|
|
|
|
|
Kubernetes auth:
|
|
|
|
|
|
|
|
|
|
* It has an expiry time and is bound to the lifetime of the pod and service account.
|
|
|
|
|
* The value of the JWT's `"iss"` claim depends on the cluster's configuration.
|
|
|
|
|
|
|
|
|
|
The changes to token lifetime are important when configuring the
|
2022-01-15 03:55:15 +00:00
|
|
|
|
[`token_reviewer_jwt`](/api-docs/auth/kubernetes#token_reviewer_jwt) option.
|
|
|
|
|
If a short-lived token is used,
|
2021-12-08 18:20:24 +00:00
|
|
|
|
Kubernetes will revoke it as soon as the pod or service account are deleted, or
|
|
|
|
|
if the expiry time passes, and Vault will no longer be able to use the
|
|
|
|
|
`TokenReview` API. See [How to work with short-lived Kubernetes tokens][short-lived-tokens]
|
|
|
|
|
below for details on handling this change.
|
|
|
|
|
|
|
|
|
|
In response to the issuer changes, Kubernetes auth has been updated in Vault
|
|
|
|
|
1.9.0 to not validate the issuer by default. The Kubernetes API does the same
|
|
|
|
|
validation when reviewing tokens, so enabling issuer validation on the Vault
|
|
|
|
|
side is duplicated work. Without disabling Vault's issuer validation, it is not
|
|
|
|
|
possible for a single Kubernetes auth configuration to work for default mounted
|
|
|
|
|
pod tokens with both Kubernetes 1.20 and 1.21. Note that auth mounts created
|
|
|
|
|
before Vault 1.9 will maintain the old default, and you will need to explicitly
|
|
|
|
|
set `disable_iss_validation=true` before upgrading Kubernetes to 1.21. See
|
|
|
|
|
[Discovering the service account `issuer`](#discovering-the-service-account-issuer)
|
|
|
|
|
below for guidance if you wish to enable issuer validation in Vault.
|
|
|
|
|
|
|
|
|
|
[k8s-1.21-changelog]: https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.21.md#api-change-2
|
|
|
|
|
[short-lived-tokens]: #how-to-work-with-short-lived-kubernetes-tokens
|
|
|
|
|
|
|
|
|
|
### How to work with short-lived Kubernetes tokens
|
|
|
|
|
|
|
|
|
|
There are a few different ways to configure auth for Kubernetes pods when
|
|
|
|
|
default mounted pod tokens are short-lived, each with their own tradeoffs. This
|
|
|
|
|
table summarizes the options, each of which is explained in more detail below.
|
|
|
|
|
|
|
|
|
|
| Option | All tokens are short-lived | Can revoke tokens early | Other considerations |
|
|
|
|
|
| ------------------------------------ | -------------------------- | ----------------------- | -------------------- |
|
2022-01-31 23:16:01 +00:00
|
|
|
|
| Use local token as reviewer JWT | Yes | Yes | Requires Vault (1.9.3+) to be deployed on the Kubernetes cluster |
|
2021-12-08 18:20:24 +00:00
|
|
|
|
| Use client JWT as reviewer JWT | Yes | Yes | Operational overhead |
|
|
|
|
|
| Use long-lived token as reviewer JWT | No | Yes | |
|
|
|
|
|
| Use JWT auth instead | Yes | No | |
|
|
|
|
|
|
|
|
|
|
-> **Note:** By default, Kubernetes currently extends the lifetime of admission
|
|
|
|
|
injected service account tokens to a year to help smooth the transition to
|
|
|
|
|
short-lived tokens. If you would like to disable this, set
|
|
|
|
|
[--service-account-extend-token-expiration=false][k8s-extended-tokens] for
|
|
|
|
|
`kube-apiserver` or specify your own `serviceAccountToken` volume mount. See
|
|
|
|
|
[here](/docs/auth/jwt/oidc_providers#specifying-ttl-and-audience) for an example.
|
|
|
|
|
|
|
|
|
|
[k8s-extended-tokens]: https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/#options
|
|
|
|
|
|
2022-01-15 03:55:15 +00:00
|
|
|
|
#### Use local service account token as the reviewer JWT
|
|
|
|
|
|
|
|
|
|
When running Vault in a Kubernetes pod the recommended option is to use the pod's local
|
|
|
|
|
service account token. Vault will periodically re-read the file to support
|
|
|
|
|
short-lived tokens. To use the local token and CA certificate, omit
|
|
|
|
|
`token_reviewer_jwt` and `kubernetes_ca_cert` when configuring the auth method.
|
|
|
|
|
Vault will attempt to load them from `token` and `ca.crt` respectively inside
|
|
|
|
|
the default mount folder `/var/run/secrets/kubernetes.io/serviceaccount/`.
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
vault write auth/kubernetes/config \
|
2022-02-09 19:16:33 +00:00
|
|
|
|
kubernetes_host=https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT
|
2022-01-15 03:55:15 +00:00
|
|
|
|
```
|
|
|
|
|
|
2022-01-31 23:16:01 +00:00
|
|
|
|
!> **Note:** Requires Vault 1.9.3+. In earlier versions the service account
|
2022-01-15 03:55:15 +00:00
|
|
|
|
token and CA certificate is read once and stored in Vault storage.
|
|
|
|
|
When the service account token expires or is revoked, Vault will no longer be
|
|
|
|
|
able to use the `TokenReview` API and client authentication will fail.
|
|
|
|
|
|
2021-12-08 18:20:24 +00:00
|
|
|
|
#### Use the Vault client's JWT as the reviewer JWT
|
|
|
|
|
|
|
|
|
|
When configuring Kubernetes auth, you can omit the `token_reviewer_jwt`, and Vault
|
|
|
|
|
will use the Vault client's JWT as its own auth token when communicating with
|
|
|
|
|
the Kubernetes `TokenReview` API. If Vault is running in Kubernetes, you also need
|
|
|
|
|
to set `disable_local_ca_jwt=true`.
|
|
|
|
|
|
|
|
|
|
This means Vault does not store any JWTs and allows you to use short-lived tokens
|
|
|
|
|
everywhere but adds some operational overhead to maintain the cluster role
|
|
|
|
|
bindings on the set of service accounts you want to be able to authenticate with
|
|
|
|
|
Vault. Each client of Vault would need the `system:auth-delegator` ClusterRole:
|
2017-09-19 14:27:26 +00:00
|
|
|
|
|
2021-12-08 18:20:24 +00:00
|
|
|
|
```bash
|
|
|
|
|
kubectl create clusterrolebinding vault-client-auth-delegator \
|
|
|
|
|
--clusterrole=system:auth-delegator \
|
|
|
|
|
--group=group1 \
|
|
|
|
|
--serviceaccount=default:svcaccount1 \
|
|
|
|
|
...
|
|
|
|
|
```
|
2017-09-19 14:27:26 +00:00
|
|
|
|
|
2021-12-08 18:20:24 +00:00
|
|
|
|
#### Continue using long-lived tokens
|
2017-09-19 14:27:26 +00:00
|
|
|
|
|
2022-01-31 23:16:01 +00:00
|
|
|
|
You can create a long-lived secret using the instructions [here][k8s-create-secret]
|
|
|
|
|
and use that as the `token_reviewer_jwt`. In this example, the `vault` service
|
|
|
|
|
account would need the `system:auth-delegator` ClusterRole:
|
2017-09-19 14:27:26 +00:00
|
|
|
|
|
2021-12-08 18:20:24 +00:00
|
|
|
|
```bash
|
2022-01-31 23:16:01 +00:00
|
|
|
|
kubectl apply -f - <<EOF
|
|
|
|
|
apiVersion: v1
|
|
|
|
|
kind: Secret
|
|
|
|
|
metadata:
|
|
|
|
|
name: vault-k8s-auth-secret
|
|
|
|
|
annotations:
|
|
|
|
|
kubernetes.io/service-account.name: vault
|
|
|
|
|
type: kubernetes.io/service-account-token
|
|
|
|
|
EOF
|
2021-12-08 18:20:24 +00:00
|
|
|
|
```
|
|
|
|
|
|
2022-01-31 23:16:01 +00:00
|
|
|
|
Using this maintains previous workflows but does not benefit from the improved
|
|
|
|
|
security posture of short-lived tokens.
|
|
|
|
|
|
|
|
|
|
[k8s-create-secret]: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#manually-create-a-service-account-api-token
|
2019-06-18 19:36:51 +00:00
|
|
|
|
|
2021-12-08 18:20:24 +00:00
|
|
|
|
#### Use JWT auth
|
2017-09-19 14:27:26 +00:00
|
|
|
|
|
2021-12-08 18:20:24 +00:00
|
|
|
|
Kubernetes auth is specialized to use Kubernetes' `TokenReview` API. However, the
|
|
|
|
|
JWT tokens Kubernetes generates can also be verified using Kubernetes as an OIDC
|
|
|
|
|
provider. The JWT auth method documentation has [instructions][k8s-jwt-auth] for
|
|
|
|
|
setting up JWT auth with Kubernetes as the OIDC provider.
|
2017-09-19 14:27:26 +00:00
|
|
|
|
|
2021-12-08 18:20:24 +00:00
|
|
|
|
[k8s-jwt-auth]: /docs/auth/jwt/oidc_providers#kubernetes
|
2017-09-19 14:27:26 +00:00
|
|
|
|
|
2021-12-08 18:20:24 +00:00
|
|
|
|
This solution allows you to use short-lived tokens for all clients and removes
|
|
|
|
|
the need for a reviewer JWT. However, the client tokens cannot be revoked before
|
|
|
|
|
their TTL expires, so it is recommended to keep the TTL short with that
|
|
|
|
|
limitation in mind.
|
2021-09-09 15:39:21 +00:00
|
|
|
|
|
|
|
|
|
### Discovering the service account `issuer`
|
|
|
|
|
|
2021-12-08 18:20:24 +00:00
|
|
|
|
-> **Note:** From Vault 1.9.0, `disable_iss_validation` and `issuer` are deprecated
|
|
|
|
|
and the default for `disable_iss_validation` has changed to `true` for new
|
|
|
|
|
Kubernetes auth mounts. The following section only applies if you have set
|
|
|
|
|
`disable_iss_validation=false` or created your mount before 1.9 with the default
|
|
|
|
|
value, but `disable_iss_validation=true` is the new recommended value for all
|
|
|
|
|
versions of Vault.
|
2021-11-18 23:16:54 +00:00
|
|
|
|
|
2021-09-09 15:39:21 +00:00
|
|
|
|
Kubernetes 1.21+ clusters may require setting the service account
|
|
|
|
|
[`issuer`](/api-docs/auth/kubernetes#issuer) to the same value as
|
|
|
|
|
`kube-apiserver`'s `--service-account-issuer` flag. This is because the service
|
|
|
|
|
account JWTs for these clusters may have an issuer specific to the cluster
|
|
|
|
|
itself, instead of the old default of `kubernetes/serviceaccount`. If you are
|
|
|
|
|
unable to check this value directly, you can run the following and look for the
|
|
|
|
|
`"iss"` field to find the required value:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
kubectl proxy &
|
|
|
|
|
curl --silent http://127.0.0.1:8001/api/v1/namespaces/default/serviceaccounts/default/token \
|
|
|
|
|
-H "Content-Type: application/json" \
|
|
|
|
|
-X POST \
|
|
|
|
|
-d '{"apiVersion": "authentication.k8s.io/v1", "kind": "TokenRequest"}' \
|
|
|
|
|
| jq -r '.status.token' \
|
2021-09-27 19:37:03 +00:00
|
|
|
|
| cut -d . -f2 \
|
2021-09-09 15:39:21 +00:00
|
|
|
|
| base64 -D
|
2021-12-08 18:20:24 +00:00
|
|
|
|
|
|
|
|
|
# Kill the background proxy process when you're done
|
|
|
|
|
kill %%
|
2021-09-09 15:39:21 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Most clusters will also have that information available at the
|
|
|
|
|
`.well-known/openid-configuration` endpoint:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
kubectl proxy &
|
|
|
|
|
curl --silent http://127.0.0.1:8001/.well-known/openid-configuration | jq -r .issuer
|
2021-12-08 18:20:24 +00:00
|
|
|
|
|
|
|
|
|
# Kill the background proxy process when you're done
|
|
|
|
|
kill %%
|
2021-09-09 15:39:21 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
This value is then used when configuring Kubernetes auth, e.g.:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
vault write auth/kubernetes/config \
|
2022-02-09 19:16:33 +00:00
|
|
|
|
kubernetes_host="https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT" \
|
2021-09-09 15:39:21 +00:00
|
|
|
|
issuer="\"test-aks-cluster-dns-d6cbb78e.hcp.uksouth.azmk8s.io\""
|
|
|
|
|
```
|
2017-09-19 14:27:26 +00:00
|
|
|
|
|
|
|
|
|
## Configuring Kubernetes
|
|
|
|
|
|
2017-09-20 20:47:13 +00:00
|
|
|
|
This auth method accesses the [Kubernetes TokenReview API][k8s-tokenreview] to
|
|
|
|
|
validate the provided JWT is still valid. Kubernetes should be running with
|
2021-12-08 18:20:24 +00:00
|
|
|
|
`--service-account-lookup`. This is defaulted to true from Kubernetes 1.7.
|
|
|
|
|
Otherwise deleted tokens in Kubernetes will not be properly revoked and
|
2017-09-20 20:47:13 +00:00
|
|
|
|
will be able to authenticate to this auth method.
|
2017-09-27 21:02:18 +00:00
|
|
|
|
|
2017-09-20 20:47:13 +00:00
|
|
|
|
Service Accounts used in this auth method will need to have access to the
|
2018-12-12 14:23:20 +00:00
|
|
|
|
TokenReview API. If Kubernetes is configured to use RBAC roles, the Service
|
2017-09-20 20:47:13 +00:00
|
|
|
|
Account should be granted permissions to access this API. The following
|
|
|
|
|
example ClusterRoleBinding could be used to grant these permissions:
|
2017-09-19 14:27:26 +00:00
|
|
|
|
|
2017-09-20 20:47:13 +00:00
|
|
|
|
```yaml
|
2017-09-19 14:27:26 +00:00
|
|
|
|
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:
|
2020-01-18 00:18:09 +00:00
|
|
|
|
- kind: ServiceAccount
|
|
|
|
|
name: vault-auth
|
|
|
|
|
namespace: default
|
2017-09-19 14:27:26 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## API
|
|
|
|
|
|
|
|
|
|
The Kubernetes Auth Plugin has a full HTTP API. Please see the
|
2022-03-18 01:14:48 +00:00
|
|
|
|
[API docs](/api-docs/auth/kubernetes) for more details.
|
2017-09-19 14:27:26 +00:00
|
|
|
|
|
2021-12-08 18:20:24 +00:00
|
|
|
|
[k8s-tokenreview]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#tokenreview-v1-authentication-k8s-io
|
2021-10-08 21:57:53 +00:00
|
|
|
|
|
|
|
|
|
## Code Example
|
|
|
|
|
|
|
|
|
|
The following code snippet demonstrates the Kubernetes auth method to authenticate
|
|
|
|
|
with Vault.
|
|
|
|
|
|
|
|
|
|
<CodeTabs heading="kubernetes auth example">
|
|
|
|
|
|
|
|
|
|
<CodeBlockConfig lineNumbers>
|
|
|
|
|
|
|
|
|
|
```go
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"os"
|
|
|
|
|
|
|
|
|
|
vault "github.com/hashicorp/vault/api"
|
2022-03-18 01:14:48 +00:00
|
|
|
|
auth "github.com/hashicorp/vault/api-docs/auth/kubernetes"
|
2021-10-08 21:57:53 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Fetches a key-value secret (kv-v2) after authenticating to Vault with a Kubernetes service account.
|
2021-12-22 17:33:12 +00:00
|
|
|
|
// For a more in-depth setup explanation, please see the relevant readme in the hashicorp/vault-examples repo.
|
2021-10-08 21:57:53 +00:00
|
|
|
|
func getSecretWithKubernetesAuth() (string, error) {
|
2021-11-17 19:52:38 +00:00
|
|
|
|
// If set, the VAULT_ADDR environment variable will be the address that
|
|
|
|
|
// your pod uses to communicate with Vault.
|
2021-10-08 21:57:53 +00:00
|
|
|
|
config := vault.DefaultConfig() // modify for more granular configuration
|
|
|
|
|
|
|
|
|
|
client, err := vault.NewClient(config)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", fmt.Errorf("unable to initialize Vault client: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-17 19:52:38 +00:00
|
|
|
|
// The service-account token will be read from the path where the token's
|
|
|
|
|
// Kubernetes Secret is mounted. By default, Kubernetes will mount it to
|
|
|
|
|
// /var/run/secrets/kubernetes.io/serviceaccount/token, but an administrator
|
|
|
|
|
// may have configured it to be mounted elsewhere.
|
|
|
|
|
// In that case, we'll use the option WithServiceAccountTokenPath to look
|
|
|
|
|
// for the token there.
|
|
|
|
|
k8sAuth, err := auth.NewKubernetesAuth(
|
|
|
|
|
"dev-role-k8s",
|
|
|
|
|
auth.WithServiceAccountTokenPath("path/to/service-account-token"),
|
|
|
|
|
)
|
2021-10-08 21:57:53 +00:00
|
|
|
|
if err != nil {
|
2021-11-17 19:52:38 +00:00
|
|
|
|
return "", fmt.Errorf("unable to initialize Kubernetes auth method: %w", err)
|
2021-10-08 21:57:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-11-17 19:52:38 +00:00
|
|
|
|
authInfo, err := client.Auth().Login(context.TODO(), k8sAuth)
|
2021-10-08 21:57:53 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return "", fmt.Errorf("unable to log in with Kubernetes auth: %w", err)
|
|
|
|
|
}
|
2021-11-17 19:52:38 +00:00
|
|
|
|
if authInfo == nil {
|
|
|
|
|
return "", fmt.Errorf("no auth info was returned after login")
|
2021-10-08 21:57:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// get secret from Vault
|
|
|
|
|
secret, err := client.Logical().Read("kv-v2/data/creds")
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", fmt.Errorf("unable to read secret: %w", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
data, ok := secret.Data["data"].(map[string]interface{})
|
|
|
|
|
if !ok {
|
|
|
|
|
return "", fmt.Errorf("data type assertion failed: %T %#v", secret.Data["data"], secret.Data["data"])
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-17 19:52:38 +00:00
|
|
|
|
// data map can contain more than one key-value pair,
|
|
|
|
|
// in this case we're just grabbing one of them
|
2021-10-08 21:57:53 +00:00
|
|
|
|
key := "password"
|
|
|
|
|
value, ok := data[key].(string)
|
|
|
|
|
if !ok {
|
|
|
|
|
return "", fmt.Errorf("value type assertion failed: %T %#v", data[key], data[key])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return value, nil
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
</CodeBlockConfig>
|
|
|
|
|
|
2021-11-03 17:10:28 +00:00
|
|
|
|
<CodeBlockConfig lineNumbers>
|
|
|
|
|
|
|
|
|
|
```cs
|
|
|
|
|
using System;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using VaultSharp;
|
|
|
|
|
using VaultSharp.V1.AuthMethods;
|
|
|
|
|
using VaultSharp.V1.AuthMethods.Kubernetes;
|
|
|
|
|
using VaultSharp.V1.Commons;
|
|
|
|
|
|
|
|
|
|
namespace Examples
|
|
|
|
|
{
|
2021-12-22 17:33:12 +00:00
|
|
|
|
public class KubernetesAuthExample
|
2021-11-03 17:10:28 +00:00
|
|
|
|
{
|
|
|
|
|
const string DefaultTokenPath = "path/to/service-account-token";
|
|
|
|
|
|
|
|
|
|
// Fetches a key-value secret (kv-v2) after authenticating to Vault with a Kubernetes service account.
|
2021-12-22 17:33:12 +00:00
|
|
|
|
// For a more in-depth setup explanation, please see the relevant readme in the hashicorp/vault-examples repo.
|
2021-11-03 17:10:28 +00:00
|
|
|
|
public string GetSecretWithK8s()
|
|
|
|
|
{
|
|
|
|
|
var vaultAddr = Environment.GetEnvironmentVariable("VAULT_ADDR");
|
|
|
|
|
if(String.IsNullOrEmpty(vaultAddr))
|
|
|
|
|
{
|
|
|
|
|
throw new System.ArgumentNullException("Vault Address");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var roleName = Environment.GetEnvironmentVariable("VAULT_ROLE");
|
|
|
|
|
if(String.IsNullOrEmpty(roleName))
|
|
|
|
|
{
|
|
|
|
|
throw new System.ArgumentNullException("Vault Role Name");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get the path to service account token or fall back on default path
|
|
|
|
|
string pathToToken = String.IsNullOrEmpty(Environment.GetEnvironmentVariable("SA_TOKEN_PATH")) ? DefaultTokenPath : Environment.GetEnvironmentVariable("SA_TOKEN_PATH");
|
2021-12-22 17:33:12 +00:00
|
|
|
|
string jwt = File.ReadAllText(pathToToken);
|
2021-11-03 17:10:28 +00:00
|
|
|
|
|
|
|
|
|
IAuthMethodInfo authMethod = new KubernetesAuthMethodInfo(roleName, jwt);
|
|
|
|
|
var vaultClientSettings = new VaultClientSettings(vaultAddr, authMethod);
|
|
|
|
|
|
2021-12-22 17:33:12 +00:00
|
|
|
|
IVaultClient vaultClient = new VaultClient(vaultClientSettings);
|
2021-11-03 17:10:28 +00:00
|
|
|
|
|
|
|
|
|
// We can retrieve the secret after creating our VaultClient object
|
|
|
|
|
Secret<SecretData> kv2Secret = null;
|
|
|
|
|
kv2Secret = vaultClient.V1.Secrets.KeyValue.V2.ReadSecretAsync(path: "/creds").Result;
|
2021-12-22 17:33:12 +00:00
|
|
|
|
|
2021-11-03 17:10:28 +00:00
|
|
|
|
var password = kv2Secret.Data.Data["password"];
|
2021-12-22 17:33:12 +00:00
|
|
|
|
|
2021-11-03 17:10:28 +00:00
|
|
|
|
return password.ToString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
</CodeBlockConfig>
|
|
|
|
|
|
2021-10-08 21:57:53 +00:00
|
|
|
|
</CodeTabs>
|