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:
- Using a service account jwt referenced in serviceAccountRef
- Using the jwt from a Kind=Secret referenced by the secretRef
- 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"}
