Skip to content

Akeyless

Akeyless Secrets Management Platform

External Secrets Operator integrates with the Akeyless Secrets Management Platform.

Create Secret Store

SecretStore resource specifies how to access Akeyless. This resource is namespaced.

NOTE: Make sure the Akeyless provider is listed in the Kind=SecretStore. If you use a customer fragment, define the value of akeylessGWApiURL as the URL of your Akeyless Gateway in the following format: https://your.akeyless.gw:8080/v2.

Akeyelss provide several Authentication Methods:

Authentication with Kubernetes

Options for obtaining Kubernetes credentials include:

  1. Using a service account jwt referenced in serviceAccountRef
  2. Using the jwt from a Kind=Secret referenced by the secretRef
  3. Using transient credentials from the mounted service account token within the external-secrets operator

Create the Akeyless Secret Store Provider with Kubernetes Auth-Method

apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: akeyless-secret-store
spec:
  provider:
    akeyless:
      # URL of your akeyless API
      akeylessGWApiURL: "https://api.akeyless.io"
      authSecretRef:
        kubernetesAuth:
          accessID: "p-XXXXXX"
          k8sConfName: "my-conf-name"

          # Optional service account field containing the name
          # of a kubernetes ServiceAccount
          serviceAccountRef:
            name: "my-sa"

          # Optional secret field containing a Kubernetes ServiceAccount JWT
          # used for authenticating with Akeyless
          secretRef:
            name: "my-secret"
            key: "token"

NOTE: In case of a ClusterSecretStore, Be sure to provide namespace for serviceAccountRef and secretRef according to the namespaces where the secrets reside.

Authentication With Cloud-Identity or Api-Access-Key

Akeyless providers require an access-id, access-type and access-Type-param To set your SecretStore with an authentication method from Akeyless.

The supported auth-methods and their parameters are:

accessType accessTypeParam
aws_iam -
gcp The gcp audience
azure_ad azure object id (optional)
api_key The access key.
k8s The k8s configuration name

For more information see Akeyless Authentication Methods

Creating an Akeyless Credentials Secret

Create a secret containing your credentials using the following example as a guide:

apiVersion: v1
kind: Secret
metadata:
  name: akeyless-secret-creds
type: Opaque
stringData:
  accessId: "p-XXXX"
  accessType:  # gcp/azure_ad/api_key/k8s/aws_iam
  accessTypeParam:  # optional: can be one of the following: gcp-audience/azure-obj-id/access-key/k8s-conf-name

Create the Akeyless Secret Store Provider with the Credentials Secret

apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: akeyless-secret-store
spec:
  provider:
    akeyless:
      # URL of your akeyless API
      akeylessGWApiURL: "https://api.akeyless.io"
      authSecretRef:
        secretRef:
          accessID:
            name: akeyless-secret-creds
            key: accessId
          accessType:
            name: akeyless-secret-creds
            key: accessType
          accessTypeParam:
            name: akeyless-secret-creds
            key: accessTypeParam

NOTE: In case of a ClusterSecretStore, be sure to provide namespace for accessID, accessType and accessTypeParam according to the namespaces where the secrets reside.

Create the Akeyless Secret Store With CAs for TLS handshake

....
spec:
  provider:
    akeyless:
      akeylessGWApiURL: "https://your.akeyless.gw:8080/v2"

      # Optional caBundle - PEM/base64 encoded CA certificate
      caBundle: "<base64 encoded cabundle>"
      # Optional caProvider:
      # Instead of caBundle you can also specify a caProvider
      # this will retrieve the cert from a Secret or ConfigMap
      caProvider:
        type: "Secret/ConfigMap" # Can be Secret or ConfigMap
        name: "<name of secret or configmap>"
        key: "<key inside secret>"
        # namespace is mandatory for ClusterSecretStore and not relevant for SecretStore
        namespace: "my-cert-secret-namespace"
  ....

Creating an external secret

To get a secret from Akeyless and create it as a secret on the Kubernetes cluster, a Kind=ExternalSecret is needed.

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: database-credentials
spec:
  refreshInterval: 1h

  secretStoreRef:
    kind: SecretStore
    name: akeyless-secret-store # Must match SecretStore on the cluster

  target:
    name: database-credentials # Name for the secret to be created on the cluster
    creationPolicy: Owner

  data:
    - secretKey: username # Key given to the secret to be created on the cluster
      remoteRef:
        key: db-username  # Full path of the secret on Akeyless
    - secretKey: password # Key given to the secret to be created on the cluster
      remoteRef:
        key: db-password  # Full path of the secret on Akeyless

Using DataFrom

DataFrom can be used to get a secret as a JSON string and attempt to parse it.

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: database-credentials
spec:
  refreshInterval: 1h

  secretStoreRef:
    kind: SecretStore
    name: akeyless-secret-store # Must match SecretStore on the cluster

  target:
    name: database-credentials-json # Name for the secret to be created on the cluster
    creationPolicy: Owner

  # for json formatted secrets: each key in the json will be used as the secret key in the SECRET k8s target object
  dataFrom:
  - extract:
      key: database-credentials # Full path of the secret on Akeyless

Getting the Kubernetes Secret

The operator will fetch the secret and inject it as a Kind=Secret.

kubectl get secret database-credentials -o jsonpath='{.data.db-password}' | base64 -d
kubectl get secret database-credentials-json -o jsonpath='{.data}'

Pushing a secret

To push a secret from Kubernetes cluster and create it as a secret to Akeyless, a Kind=PushSecret resource is needed.

apiVersion: external-secrets.io/v1alpha1 kind: PushSecret metadata: name: push-secret spec: refreshInterval: 5s updatePolicy: Replace deletionPolicy: Delete secretStoreRefs: - name: akeyless-secret-store kind: SecretStore selector: secret: name: k8s-created-secret data: - match: remoteRef: remoteKey: eso-created/my-secret

Then when you create a matching secret as follows:

kubectl create secret generic --from-literal=cache-pass=mypassword k8s-created-secret

Then it will create a secret in akeyless eso-created/my-secret with value {"cache-pass":"mypassword"}