Skip to main content

External Secrets

External Secrets Operator (ESO) is a Kubernetes operator designed to integrate with various external secret management systems such as AWS Secrets Manager, HashiCorp Vault, Google Secrets Manager, Azure Key Vault, IBM Cloud Secrets Manager, and CyberArk Conjur, among others. This operator retrieves information from external APIs and injects the values into Kubernetes Secrets automatically.

Availability

External Secrets is available as an optional service for NKE. It can be deployed on an existing NKE cluster using Cockpit or Nine Self Service API.

Overview

ESO consists of custom API resources: ExternalSecret, SecretStore, and ClusterSecretStore, which offer a user-friendly abstraction for managing and synchronizing secrets through external APIs. The SecretStore references a collection of key/value pairs, which may correspond to different external APIs like an Azure KeyVault instance or an AWS Secrets Manager in a specific AWS account and region. An ExternalSecret defines the data to be fetched and also serves as a blueprint for creating Kubernetes Secrets. The resource model can be visualized as follows:

SecretStore

The SecretStore resource aims to distinguish between authentication/access concern and the actual secrets and configurations needed for workloads. The ExternalSecret defines what data to retrieve, while the SecretStore specifies how to access that data. The SecretStore contains references to credentials required to access the external API. This resource is namespaced.

apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: secretstore-sample
spec:
provider:
aws:
service: SecretsManager
region: eu-central-2
auth:
secretRef:
accessKeyIDSecretRef:
name: awssm-secret
key: access-key
secretAccessKeySecretRef:
name: awssm-secret
key: secret-access-key

ExternalSecret

An ExternalSecret specifies the data to be fetched and includes a reference to a SecretStore, which knows how to access the data. The controller uses the ExternalSecret as a blueprint to create the Kubernetes Secret.

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: example
spec:
refreshInterval: 1h
secretStoreRef:
name: secretstore-sample
kind: SecretStore
target:
name: secret-to-be-created
creationPolicy: Owner
data:
- secretKey: secret-key-to-be-managed
remoteRef:
key: mymap
property: foo
# Or use `dataFrom` to have all key properties automatically mapped to the k8s secret.
dataFrom:
- extract:
key: mymap

ClusterSecretStore

The ClusterSecretStore is a cluster-wide SecretStore that can be referenced from any namespace. It acts as a central gateway to the secret provider for the entire cluster.

Usage

Implementation details and the range of supported features vary based on the selected backend provider. For a comprehensive list of currently supported providers, an overview of feature support across different providers, and advanced examples, please refer to the Stability and Support documentation.

Hashicorp Vault Provider Example

External Secrets Operator integrates with HashiCorp Vault for secret management. The KV Secrets Engine is the only one supported by this provider.

First, create a SecretStore with a vault backend. For the sake of simplicity we'll use a static token root:

apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: vault-backend
spec:
provider:
vault:
server: "http://my.vault.server:8200"
path: "secret"
# Version is the Vault KV secret engine version.
# This can be either "v1" or "v2", defaults to "v2"
version: "v2"
auth:
# points to a secret that contains a vault token
# https://www.vaultproject.io/docs/auth/token
tokenSecretRef:
name: "vault-token"
key: "token"
---
apiVersion: v1
kind: Secret
metadata:
name: vault-token
data:
token: cm9vdA== # "root"
note

In case of a ClusterSecretStore, Be sure to provide namespace for tokenSecretRef with the namespace of the secret that we just created.

Then create a simple k/v pair at path secret/foo:

vault kv put secret/foo my-value=s3cr3t

You can check the kv version using the command below and check the Options column, it should show [version:2]:

vault secrets list -detailed

If you are using version: 1, just remember to update your SecretStore manifest appropriately

Now create a ExternalSecret that uses the above SecretStore:

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: vault-example
spec:
refreshInterval: "15s"
secretStoreRef:
name: vault-backend
kind: SecretStore
target:
name: example-sync
data:
- secretKey: foobar
remoteRef:
key: foo
property: my-value

---
# will create a secret with:
kind: Secret
metadata:
name: example-sync
data:
foobar: czNjcjN0

For additional HashiCorp Vault examples and advanced usage instructions, please refer to the official provider documentation.