External Secret Operator
External Secrets Operator (ESO)
External Secrets Operator (ESO) is a Kubernetes (K8s) operator that integrates with external secret management systems like Akeyless. The operator reads information from Akeyless APIs and automatically injects the values into a K8s Secret. More information can be found under Akeyless official provider.
The goal of the ESO is to synchronize secrets from Akeyless into K8s. ESO is a collection of custom API resources - ExternalSecret
, SecretStore
, and ClusterSecretStore
that provide a user-friendly abstraction for the external API that stores and manages the lifecycle of the secrets for you.
The ESO runs within your K8s cluster as a deployment
resource. It utilizes CustomResourceDefinitions
to configure access to secret providers through SecretStore
resources and manages K8s secret resources with ExternalSecret
resources.
Prerequisites
- Helm
K8s v1.16
and above (users that are still runningK8s v1.15
or below should upgrade to a supported version before installing external-secrets).
Installing with Helm
External Secrets Official Git: https://github.com/external-secrets/external-secrets
helm repo add external-secrets https://charts.external-secrets.io
helm install external-secrets external-secrets/external-secrets # -n external-secrets --create-namespace
SecretStore
The idea behind the SecretStore
resource is to separate concerns of authentication/access and the actual Secret and configuration needed for workloads. The ExternalSecret
specifies what to fetch, and the SecretStore
specifies how to access it. This resource is namespaced.
Authentication methods:
Akeyless providers require an accessId
, accessType
, and accessTypeParam
To set your SecretStore
with an authentication method from Akeyless, create a secret item on your cluster that contains the following settings:
apiVersion: v1
kind: Secret
metadata:
name: akeyless-secret-creds
type: Opaque
stringData:
accessId: "p-XXXX"
accessType: # k8s/aws_iam/gcp/azure_ad/api_key
accessTypeParam: # replace by the appropriate value for: <k8s-conf-name>/<gcp-audience>/<azure-obj-id>/<access-key>
Note
Ensure that an Access Role is defined in Akeyless for the credentials you specify and that the Access Role is associated with an Authentication Method that allows access to the required secret.
If you define the value of
accessType
as api_key, define the value ofaccessTypeParam
as your access key.
Create the secret item for authentication:
kubectl apply -f akeylesscreds.yaml
Alternatively, you can explicitly specify the secret details as described in the K8sSecretStore example below:
Create the Akeyless SecretStore Provider:
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
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
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.
Create the Secret Store:
kubectl apply -f secretstore.yaml
Creating an External Secret:
To fetch a secret from Akeyless and store it as a K8s secret on your cluster, a Kind=ExternalSecret
is required.
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: akeyless-external-secret-example
spec:
refreshInterval: 1h
secretStoreRef:
kind: SecretStore
name: akeyless-secret-store # Must match SecretStore on the cluster
target:
name: akeyless-secret-to-create # Name for the secret to be created on the cluster
creationPolicy: Owner
data:
- secretKey: secretKey # Key given to the secret to be created on the cluster
remoteRef:
key: /path/to/your/secret # Full path of the secret on Akeyless
Create the ExternalSecret item:
kubectl apply -f externalsecret.yaml
Getting the K8s secret:
kubectl get secret akeyless-secret-to-create -o jsonpath='{.data.secretKey}' | base64 -d
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: akeyless-external-secret-example-json
spec:
refreshInterval: 1h
secretStoreRef:
kind: SecretStore
name: akeyless-secret-store # Must match SecretStore on the cluster
target:
name: akeyless-secret-to-create-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: /path/to/your/secret/keyname # Full path of the secret on Akeyless
Getting the K8s secret:
kubectl get secret akeyless-secret-to-create-json -o jsonpath='{.data}'
Tutorial
Check out our tutorial video on Sync Secrets to K8s with External Secrets Operator (ESO).
Updated about 24 hours ago