Add usage documentation for new Kubernetes Secrets Engine (#15527)
Add usage documentation for new Kubernetes Secrets Engine Co-authored-by: Tom Proctor <tomhjp@users.noreply.github.com> Co-authored-by: Theron Voran <tvoran@users.noreply.github.com>
This commit is contained in:
parent
ae106058b8
commit
644345b1cc
|
@ -0,0 +1,3 @@
|
|||
```release-note:improvement
|
||||
website/docs: Add usage documentation for Kubernetes Secrets Engine
|
||||
```
|
|
@ -0,0 +1,343 @@
|
|||
---
|
||||
layout: docs
|
||||
page_title: Kubernetes - Secrets Engines
|
||||
description: >-
|
||||
The Kubernetes secrets engine for Vault generates Kubernetes service account
|
||||
tokens, service accounts, role bindings, and roles dynamically.
|
||||
---
|
||||
|
||||
# Kubernetes Secrets Engine
|
||||
|
||||
The Kubernetes Secrets Engine for Vault generates Kubernetes service account tokens, and
|
||||
optionally service accounts, role bindings, and roles. The created service account tokens have
|
||||
a configurable TTL and any objects created are automatically deleted when the Vault lease expires.
|
||||
|
||||
For each lease, Vault will create a service account token attached to the
|
||||
defined service account. The service account token is returned to the caller.
|
||||
|
||||
To learn more about service accounts in Kubernetes, visit the
|
||||
[Kubernetes service account](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/)
|
||||
and [Kubernetes RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/)
|
||||
documentation.
|
||||
|
||||
~> **Note:** We do not recommend using tokens created by the Kubernetes Secrets Engine to
|
||||
authenticate with the [Vault Kuberenetes Auth Method](/docs/auth/kubernetes). This will
|
||||
generate many unique identities in Vault that will be hard to manage.
|
||||
|
||||
## Setup
|
||||
|
||||
The Kubernetes Secrets Engine must be configured in advance before it
|
||||
can perform its functions. These steps are usually completed by an operator or configuration
|
||||
management tool.
|
||||
|
||||
1. By default, Vault will connect to Kubernetes using its own service account.
|
||||
If using the [standard Helm chart](https://github.com/hashicorp/vault-helm), this service account
|
||||
is created automatically by default and named after the Helm release (often `vault`, but this can be
|
||||
configured via the Helm value `server.serviceAccount.name`).
|
||||
|
||||
It's necessary to ensure that the service account Vault uses will have permissions to manage
|
||||
service account tokens, and optionally manage service accounts, roles, and role bindings. These
|
||||
permissions can be managed using a Kuberentes role or cluster role. The role is attached to the
|
||||
Vault service account with a role binding or cluster role binding.
|
||||
|
||||
For example, a minimal cluster role to create service account tokens is:
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: k8s-minimal-secrets-abilities
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["serviceaccounts/token"]
|
||||
verbs: ["create"]
|
||||
```
|
||||
|
||||
Similarly, you can create a more permissive cluster role with full permissions to manage tokens,
|
||||
service accounts, bindings, and roles.
|
||||
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: k8s-full-secrets-abilities
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["serviceaccounts", "serviceaccounts/token"]
|
||||
verbs: ["create", "update", "delete"]
|
||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
||||
resources: ["rolebindings", "clusterrolebindings"]
|
||||
verbs: ["create", "update", "delete"]
|
||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
||||
resources: ["roles", "clusterroles"]
|
||||
verbs: ["bind", "escalate", "create", "update", "delete"]
|
||||
```
|
||||
|
||||
Create this role in Kubernetes (e.g., with `kubectl apply -f`).
|
||||
|
||||
~> **Note:** Getting the right permissions for Vault will require some trial and error most
|
||||
likely since Kubernetes has strict protections against privilege escalation. You can read more
|
||||
in the
|
||||
[Kubernetes RBAC documentation](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#privilege-escalation-prevention-and-bootstrapping).
|
||||
|
||||
~> **Note:** Protect the Vault service account, especially if you use broader permissions for it,
|
||||
as it is essentially a cluster administrator account.
|
||||
|
||||
1. Create a role binding to bind the role to Vault's service account and grant Vault permission
|
||||
to manage tokens.
|
||||
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: vault-token-creator-binding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: k8s-minimal-secrets-abilities
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: vault
|
||||
namespace: vault
|
||||
```
|
||||
|
||||
For more information on Kubernetes roles, service accounts, bindings, and tokens, visit the
|
||||
[Kubernetes RBAC documentation](https://kubernetes.io/docs/reference/access-authn-authz/rbac/).
|
||||
|
||||
1. If Vault will not be automatically managing roles or service accounts (see
|
||||
[Automatically Managing Roles and Service Accounts](#automatically-managing-roles-and-service-accounts)),
|
||||
then you will need to set up a service account that Vault will issue tokens for.
|
||||
|
||||
~> **Note**: It is highly recommended that the service account that Vault issues tokens for
|
||||
is **NOT** the same service account that Vault itself uses.
|
||||
|
||||
The examples we will use will under the namespace `test`, which you can create if it does not
|
||||
already exist.
|
||||
|
||||
```shell-session
|
||||
$ kubectl create namespace test
|
||||
namespace/test created
|
||||
```
|
||||
|
||||
Here is a simple set up of a service account, role, and role binding in the Kubernetes `test`
|
||||
namespace with basic permissions we will use for this document:
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: test-service-account-with-generated-token
|
||||
namespace: test
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: test-role-list-pods
|
||||
namespace: test
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["pods"]
|
||||
verbs: ["list"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: test-role-abilities
|
||||
namespace: test
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: test-role-list-pods
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: test-service-account-with-generated-token
|
||||
namespace: test
|
||||
```
|
||||
|
||||
You can create these objects with `kubectl apply -f`.
|
||||
|
||||
1. Enable the Kubernetes Secrets Engine:
|
||||
|
||||
```shell-session
|
||||
$ vault secrets enable kubernetes
|
||||
Success! Enabled the kubernetes Secrets Engine at: kubernetes/
|
||||
```
|
||||
|
||||
By default, the secrets engine will mount at the same name as the engine, i.e.,
|
||||
`kubernetes/` here. This can be changed by passing the `-path` argument when enabling.
|
||||
|
||||
1. Configure the mount point. An empty config is allowed.
|
||||
|
||||
```shell-session
|
||||
$ vault write -f kubernetes/config
|
||||
```
|
||||
|
||||
Configuration options are available as specified in the
|
||||
[API docs](/api-docs/secret/kubernetes).
|
||||
|
||||
1. You can now configure Kubernetes Secrets Engine to create a Vault role (**not** the same as a
|
||||
Kubernetes role) that can generate service account tokens for the given service account:
|
||||
|
||||
```shell-session
|
||||
$ vault write kubernetes/roles/my-role \
|
||||
allowed_kubernetes_namespaces="*" \
|
||||
service_account_name="test-service-account-with-generated-token" \
|
||||
token_default_ttl="10m"
|
||||
```
|
||||
|
||||
## Generating Credentials
|
||||
|
||||
After a user has authenticated to Vault and has sufficient permissions, a write to the
|
||||
`creds` endpoint for the Vault role will generate and return a new service account token.
|
||||
|
||||
```shell-session
|
||||
$ vault write kubernetes/creds/my-role \
|
||||
kubernetes_namespace=test
|
||||
|
||||
Key Value
|
||||
–-- -----
|
||||
lease_id kubernetes/creds/my-role/31d771a6-...
|
||||
lease_duration 10m0s
|
||||
lease_renwable false
|
||||
service_account_name test-service-account-with-generated-token
|
||||
service_account_namespace test
|
||||
service_account_token eyJHbGci0iJSUzI1NiIsImtpZCI6ImlrUEE...
|
||||
```
|
||||
|
||||
You can use the service account token above (`eyJHbG...`) with any Kubernetes API request that
|
||||
its service account is authorized for (through role bindings).
|
||||
|
||||
```shell-session
|
||||
$ curl -sk $(kubectl config view --minify -o 'jsonpath={.clusters[].cluster.server}')/api/v1/namespaces/test/pods \
|
||||
--header "Authorization: Bearer eyJHbGci0iJSUzI1Ni..."
|
||||
{
|
||||
"kind": "PodList",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"resourceVersion": "1624"
|
||||
},
|
||||
"items": []
|
||||
}
|
||||
```
|
||||
|
||||
When the lease expires, you can verify that the token has been revoked.
|
||||
```shell-session
|
||||
$ curl -sk $(kubectl config view --minify -o 'jsonpath={.clusters[].cluster.server}')/api/v1/namespaces/test/pods \
|
||||
--header "Authorization: Bearer eyJHbGci0iJSUzI1Ni..."
|
||||
{
|
||||
"kind": "Status",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {},
|
||||
"status": "Failure",
|
||||
"message": "Unauthorized",
|
||||
"reason": "Unauthorized",
|
||||
"code": 401
|
||||
}
|
||||
```
|
||||
|
||||
## TTL
|
||||
|
||||
Kubernetes service account tokens have a time-to-live (TTL). When a token expires it is
|
||||
automatically revoked.
|
||||
|
||||
You can set a default (`token_default_ttl`) and a maximum TTL (`token_max_ttl`) when
|
||||
creating or tuning the Vault role.
|
||||
|
||||
```shell-session
|
||||
$ vault write kubernetes/roles/my-role \
|
||||
allowed_kubernetes_namespaces="*" \
|
||||
service_account_name="new-service-account-with-generated-token" \
|
||||
token_default_ttl="10m" \
|
||||
token_max_ttl="2h"
|
||||
```
|
||||
|
||||
You can also set a TTL (`ttl`) when you generate the token from the credentials endpoint.
|
||||
The TTL of the token will be given the default if not specified (and cannot exceed the
|
||||
maximum TTL of the role, if present).
|
||||
|
||||
```shell-session
|
||||
$ vault write kubernetes/creds/my-role \
|
||||
kubernetes_namespace=test \
|
||||
ttl=20m
|
||||
|
||||
Key Value
|
||||
–-- -----
|
||||
lease_id kubernetes/creds/my-role/31d771a6-...
|
||||
lease_duration 20m0s
|
||||
lease_renwable false
|
||||
service_account_name new-service-account-with-generated-token
|
||||
service_account_namespace test
|
||||
service_account_token eyJHbGci0iJSUzI1NiIsImtpZCI6ImlrUEE...
|
||||
```
|
||||
|
||||
|
||||
You can verify the token's TTL by decoding the JWT token and extracting the `iat`
|
||||
(issued at) and `exp` (expiration time) claims.
|
||||
|
||||
```shell-session
|
||||
$ echo 'eyJhbGc...' | cut -d'.' -f2 | base64 -d | jq -r '.iat,.exp|todate'
|
||||
2022-05-20T17:14:50Z
|
||||
2022-05-20T17:34:50Z
|
||||
```
|
||||
|
||||
## Automatically Managing Roles and Service Accounts
|
||||
|
||||
When configuring the Vault role, you can pass in parameters to specify that you want to
|
||||
automatically generate the Kubernetes service account and role binding,
|
||||
and optionally generate the Kubernetes role itself.
|
||||
|
||||
If you want to configure the Vault role to use a pre-existing Kubernetes role, but generate
|
||||
the service account and role binding automatically, you can set the `kubernetes_role_name`
|
||||
parameter.
|
||||
|
||||
```shell-session
|
||||
$ vault write kubernetes/roles/auto-managed-sa-role \
|
||||
allowed_kubernetes_namespaces="test" \
|
||||
kubernetes_role_name="test-role-list-pods"
|
||||
```
|
||||
|
||||
~> **Note**: Vault's service account will also need access to the resources it is granting
|
||||
access to. This can be done for the examples above with `kubectl -n test create rolebinding --role test-role-list-pods --serviceaccount=vault:vault vault-test-role-abilities`.
|
||||
This is how Kuberentes prevents privilege escalation.
|
||||
You can read more in the
|
||||
[Kubernetes RBAC documentation](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#privilege-escalation-prevention-and-bootstrapping).
|
||||
|
||||
You can then get credentials with the automatically generated service account.
|
||||
```shell-session
|
||||
$ vault write kubernetes/creds/auto-managed-sa-role \
|
||||
kubernetes_namespace=test
|
||||
Key Value
|
||||
--- -----
|
||||
lease_id kubernetes/creds/auto-managed-sa-role/cujRLYjKZUMQk6dkHBGGWm67
|
||||
lease_duration 768h
|
||||
lease_renewable false
|
||||
service_account_name v-token-auto-man-1653001548-5z6hrgsxnmzncxejztml4arz
|
||||
service_account_namespace test
|
||||
service_account_token eyJHbGci0iJSUzI1Ni...
|
||||
```
|
||||
|
||||
Furthermore, Vault can also automatically create the role in addition to the service account and
|
||||
role binding by specifying the `generated_role_rules` parameter, which accepts a set of JSON or YAML
|
||||
rules for the generated role.
|
||||
|
||||
```shell-session
|
||||
$ vault write kubernetes/roles/auto-managed-sa-and-role \
|
||||
allowed_kubernetes_namespaces="test" \
|
||||
generated_role_rules='{"rules":[{"apiGroups":[""],"resources":["pods"],"verbs":["list"]}]}'
|
||||
```
|
||||
You can then get credentials in the same way as before.
|
||||
```shell-session
|
||||
$ vault write kubernetes/creds/auto-managed-sa-and-role \
|
||||
kubernetes_namespace=test
|
||||
Key Value
|
||||
--- -----
|
||||
lease_id kubernetes/creds/auto-managed-sa-and-role/pehLtegoTP8vCkcaQozUqOHf
|
||||
lease_duration 768h
|
||||
lease_renewable false
|
||||
service_account_name v-token-auto-man-1653002096-4imxf3ytjh5hbyro9s1oqdo3
|
||||
service_account_namespace test
|
||||
service_account_token eyJHbGci0iJSUzI1Ni...
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
The Kubernetes Secrets Engine has a full HTTP API. Please see the
|
||||
[Kubernetes Secrets Engine API docs](/api-docs/secret/kubernetes) for more details.
|
|
@ -1056,6 +1056,10 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Kubernetes",
|
||||
"path": "secrets/kubernetes"
|
||||
},
|
||||
{
|
||||
"title": "Identity",
|
||||
"routes": [
|
||||
|
|
Loading…
Reference in New Issue