Kubernetes secrets engine
Note: This engine can use external X.509 certificates as part of TLS or signature validation. Verifying signatures against X.509 certificates that use SHA-1 is deprecated and is no longer usable without a workaround starting in Vault 1.12. See the deprecation FAQ for more information.
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 and Kubernetes RBAC documentation.
Note: We do not recommend using tokens created by the Kubernetes Secrets Engine to authenticate with the Vault Kubernetes Auth Method. 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.
By default, Vault will connect to Kubernetes using its own service account. If using the standard Helm chart, this service account is created automatically by default and named after the Helm release (often
vault
, but this can be configured via the Helm valueserver.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 Kubernetes 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:
Similarly, you can create a more permissive cluster role with full permissions to manage tokens, service accounts, bindings, and roles.
Create this role in Kubernetes (e.g., with
kubectl apply -f
).Moreover, if you want to use label selection to configure the namespaces on which a role can act, you will need to grant Vault permissions to read namespaces.
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.
Note: Protect the Vault service account, especially if you use broader permissions for it, as it is essentially a cluster administrator account.
Create a role binding to bind the role to Vault's service account and grant Vault permission to manage tokens.
For more information on Kubernetes roles, service accounts, bindings, and tokens, visit the Kubernetes RBAC documentation.
If Vault will not be automatically managing roles or service accounts (see 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.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:You can create these objects with
kubectl apply -f
.Enable the Kubernetes Secrets Engine:
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.Configure the mount point. An empty config is allowed.
Configuration options are available as specified in the API docs.
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:
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.
You can use the service account token above (eyJHbG...
) with any Kubernetes API request that
its service account is authorized for (through role bindings).
When the lease expires, you can verify that the token has been revoked.
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.
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).
You can verify the token's TTL by decoding the JWT token and extracting the iat
(issued at) and exp
(expiration time) claims.
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.
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 Kubernetes prevents privilege escalation.
You can read more in the
Kubernetes RBAC documentation.
You can then get credentials with the automatically generated service account.
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.
You can then get credentials in the same way as before.
API
The Kubernetes Secrets Engine has a full HTTP API. Please see the Kubernetes Secrets Engine API docs for more details.