Kubernetes Generic Dynamic Secrets

You can use Akeyless dynamic secrets to generate tokens for Kubernetes service accounts that are used to authenticate to a Kubernetes cluster as an external resource.

Kubernetes service accounts are designed to be used by processes for specific tasks, following the principle of least privilege. Each service account has an associated JWT token, which can be generated by the dynamic secret. The service account and token are authenticated by the Kubernetes API server.

Once you have created a dynamic generic Kubernetes secret using the Akeyless CLI, you can use the token in a kubeconfig file.

If the Akeyless CLI is installed on the same host as the kubectl, this can be done automatically.

Alternatively, you can get the token from the Akeyless CLI, and manually update the kubeconfig file.

Prerequisites

  • A service account with permission to run the Kubernetes API RequestToken command to generate JWT tokens for other service accounts.

  • A service account with the permissions that should be given to clients on a specific Kubernetes namespace.

In the following example, you can see a cluster role with permission to create and get tokens:

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: tokenrequest
rules:
- apiGroups: [""]
  resources:
  - "serviceaccounts/token"
  - "serviceaccounts"
  verbs:
  - "create"
  - "get"

πŸ“˜

Note

When using kubeadm, please make sure to enable the following api flags in the kubeadm-config.yaml file.

apiServer:
  extraArgs:
    service-account-signing-key-file: /etc/kubernetes/pki/sa.key
    service-account-key-file: /etc/kubernetes/pki/sa.pub
    service-account-issuer: api
    service-account-api-audiences: api,vault,factors

Create a Dynamic Generic Kubernetes Secret from the CLI

πŸ‘

Tip

We recommend using dynamic secrets with Targets. It allows saving time on the secrets' configuration for different types of access levels. Where you are not required to provide an inline connection string each time.

To create a dynamic generic Kubernetes secret from the CLI using an existing Kubernetes Target, run the following command:

akeyless gateway-create-producer-k8s \ 
--name <secret name> \
--target-name <Target Name> \
--gateway-url 'https:\\<Your-Akeyless-GW-URL:8000>' \
--k8s-service-account <service account>

Or using an inline connection string:

akeyless gateway-create-producer-k8s \ 
--name <secret name> \
--gateway-url 'https:\\<Your-Akeyless-GW-URL:8000>' \
--k8s-service-account <service account> \
--k8s-cluster-endpoint <Cluster Endpoint URL> \
--k8s-cluster-ca-cert <Base64-encoded cluster CA certificate> \
--k8s-cluster-token ${TOKEN}

Where:

  • name: A unique name of the dynamic secret. The name can include the path to the virtual folder where you want to create the new dynamic secret, using slash / separators. If the folder does not exist, it will be created together with the dynamic secret.

  • target-name: A name of the target that enables connection to the Kubernetes cluster. The name can include the path to the virtual folder where this target resides.

  • gateway-url: Akeyless Gateway URL.

  • k8s-service-account: The Kubernetes service account from which to extract the token.

Inline connection strings

If you don't have a configured Kubernetes Targets yet, you can use the command with your K8s Cluster connection strings:

  • k8s-cluster-endpoint: The URL of the cluster.

  • k8s-cluster-ca-cert: The base-64 encoded CA cluster certificate.

  • k8s-cluster-token: A JWT authentication token authorized to create service account tokens.

You can find the complete list of parameters for this command in the CLI Reference - Akeyless Producers section.

Use a Dynamic Generic Kubernetes Secret with the Akeyless CLI

If the Akeyless CLI is installed on the same host as the kubectl, you can define a kubeconfig file to automatically run the get-dynamic-secret-value command and fetch new access tokens as required.

Create the following kubeconfig file to run the get-dynamic-secret-value command and fetch new access tokens:

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: <base 64 encoding of the cluster certificate>
    server: <cluster DNS/IP address>
  name: <cluster name>
contexts:
- context:
    cluster: <cluster name>
    user: <user name>
  name: <cluster context name>
current-context: <cluster context name>
kind: Config
preferences: {}
users:
- name: <user name>
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      args:
        - get-dynamic-secret-value
        - --name
        - <dynamic secret item name>
        - --profile
        - <some profile> 
      command: /usr/local/bin/akeyless

Use a Dynamic Generic Kubernetes Secret with the Akeyless CLI running on a different host

If the Akeyless CLI is installed on a different host as the kubectl, you can get a service account token from Akeyless separately, and then manually update the kubeconfig file that uses the token.

  1. Create the following kubeconfig file:
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: <base 64 encoding of the cluster certificate>
    server: <cluster DNS/IP address>
  name: <cluster name>
contexts:
- context:
    cluster: <cluster name>
    user: <user name>
  name: <cluster context name>
current-context: <cluster context name>
kind: Config
preferences: {}
users:
- name: <some user name>
  user:
    token: < Dynamic Secret Value goes here >

To get the dynamic generic Kubernetes secret value from the CLI, you should run the following command:

akeyless get-dynamic-secret-value --name <Path to the dynamic secret>

Then you need to replace < Dynamic Secret Value goes here > with the response token exactly as you received it.

πŸ‘

Tip

To start working with dynamic secrets from the Akeyless Console, you need to configure the Gateway URL thus enabling communication between the Akeyless SaaS and the Akeyless Gateway.

To create and fetch dynamic secrets directly from the Akeyless Gateway, you can use the Gateway Configuration Manager.

Example: Kubernetes Dashboard

Let's see an example of how you could use dynamic generic Kubernetes secrets to get a token for the Kubernetes Dashboard.

In this example, the token-request-sa service account has permission to create tokens for existing service accounts on the kubernetes-dashboard namespace:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: token-request-sa
  namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: tokenrequest-dash
rules:
- apiGroups: [""]
  resources:
  - "serviceaccounts/token"
  - "serviceaccounts"
  verbs:
  - "create"
  - "get"
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: tokenrequest-dash
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: tokenrequest-dash
subjects:
- kind: ServiceAccount
  name: token-request-sa
  namespace: kubernetes-dashboard
  1. Extract the service account token (secret) name by running:
TOKENNAME=`kubectl -n kubernetes-dashboard get serviceaccount/token-request-sa -o jsonpath='{.secrets[0].name}'`
  1. Extract the service account token by running:
TOKEN=`kubectl -n kubernetes-dashboard get secret $TOKENNAME -o jsonpath='{.data.token}'| base64 --decode`
  1. Create a Kubernetes generic dynamic secret called k8s-dashboard-producer by running:
akeyless gateway-create-producer-k8s -n k8s-dashboard-producer \
--k8s-cluster-endpoint <cluster DNS/IP address> \
--k8s-cluster-ca-cert <base 64 encoding of the cluster certificate> \
--k8s-namespace kubernetes-dashboard \
--k8s-service-account kubernetes-dashboard \
--k8s-cluster-token ${TOKEN}
  1. Get the k8s-dashboard-producer dynamic secret value by running:
akeyless get-dynamic-secret-value -n k8s-dashboard-producer | jq .

The output is:

{
  "apiVersion": "client.authentication.k8s.io/v1beta1",
  "clusterCACertificate": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJkekNDQVIyZ0F3SUJBZ0lCQURBS0JnZ3Foa2pPUFFRREFqQWpNU0V3SHdZRFZRUUREQmhyTTNNdGMyVnkKZG1WeUxXTmhRREUyTWpNek1UZzBPRFV3SGhjTk1qRXdOakV3TURrME9EQTFXaGNOTXpFd05qQTRNRGswT0RBMQpXakFqTVNFd0h3WURWUVFEREJock0zTXRjMlZ5ZG1WeUxXTmhRREUyTWpNek1UZzBPRFV3V1RBVEJnY3Foa2pPClBRSUJCZ2dxaGtqT1BRTUJCd05DQUFUTEZqVXZIRFg0YmhzMm9TS0Vkb1Y1R2dsQVRPUkpYVDBzYmhCVSs2VzEKUm52dEFwWVZlVDlQa1crUnJXL0VKcS9lZEpNYUFzZGFIcEtxM2FHZTFNbGJvMEl3UURBT0JnTlZIUThCQWY4RQpCQU1DQXFRd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVWhXTGwzU1N5UGVHVlRRVlh6UkszClV5RnF4S0l3Q2dZSUtvWkl6ajBFQXdJRFNBQXdSUUloQUkwd2MwcUUwck9YZVN2VzN5d1RFc1BHWVUrVHZkVTIKbVFEYUtIN3BvSGJVQWlCbWtoQTNZejZhQkpmTmU0c09Eb1RKK2lGTElwSndvb3FPZjhGZWYvdnJSdz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K",
  "clusterEndpoint": "https://0.0.0.0:56155",
  "clusterName": "k8s-native-cluster",
  "clusterUsername": "k8s-native-cluster",
  "kind": "ExecCredential",
  "status": {
    "token": "eyJhbGciOiJSUzI1NiIsImtpZCI6InNmMmZhbXgyRC1KT1pzUTBSVll0RFMzQjk1dGJXV19sRnd0b3FhYnBBRTgifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiLCJrM3MiXSwiZXhwIjoxNjI0MTg4MTY5LCJpYXQiOjE2MjQxODQ1NjksImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsInNlcnZpY2VhY2NvdW50Ijp7Im5hbWUiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsInVpZCI6IjI5MGU4M2IwLTc1MTItNDZiOC1hYWIxLWViN2IxOTIxNmY2NyJ9fSwibmJmIjoxNjI0MTg0NTY5LCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZXJuZXRlcy1kYXNoYm9hcmQ6a3ViZXJuZXRlcy1kYXNoYm9hcmQifQ.oflUcXwzFF2Kcyi45_SNrdGmAk_2abqAz0nE7AyUU_-W2-l7ZxPovtM2pfcfHm_dmW9wCDxM3zK4Zh39ruWnvjqIB_uxWQGAtQnU3TBlHSY2knQdZ7lNop-ylvQMdh4rTNf07BM_zKoKVh1w1__nE-esghwOe6mtRuKIy3Xj5Ijk2aamx3DFbFcyizHyZVst_PSbm1fdxdSLFzBy0vXmI8-Lx-KbJsUM5yO2MGmEk-oX28YCG0hgF0NkPbyjyEtIPBrRKbbdyo8lM_dGQ5Hk7D1P5Vo56f14oKUHRJDdzyd-jFSH_dtxD0FxazuNPlmuE9lRdJzeSgvuGp6S-MsksQ"
  }
}
  1. Copy the token value, and use it for the Kubernetes Dashboard.
17901790

Did this page help you?