Skip to content

HashiCorp Vault

HCP Vault

Hashicorp Vault

External Secrets Operator integrates with HashiCorp Vault for secret management. Vault itself implements lots of different secret engines, as of now we only support the KV Secrets Engine.

Example

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

apiVersion: external-secrets.io/v1alpha1
kind: SecretStore
metadata:
  name: vault-backend
spec:
  provider:
    vault:
      server: "http://my.vault.server:8200"
      path: "secret"
      version: "v2"
      auth:
        # points to a secret that contains a vault token
        # https://www.vaultproject.io/docs/auth/token
        tokenSecretRef:
          name: "vault-token"
          namespace: "default"
          key: "token"
---
apiVersion: v1
kind: Secret
metadata:
  name: vault-token
data:
  token: cm9vdA== # "root"

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

vault kv put secret/foo my-value=s3cr3t

Now create a ExternalSecret that uses the above SecretStore:

apiVersion: external-secrets.io/v1alpha1
kind: ExternalSecret
metadata:
  name: vault-example
spec:
  refreshInterval: "15s"
  secretStoreRef:
    name: vault-backend
    kind: ClusterSecretStore
  target:
    name: example-sync
  data:
  - secretKey: foobar
    remoteRef:
      key: secret/foo
      property: my-value
---
# will create a secret with:
kind: Secret
metadata:
  name: example-sync
data:
  foobar: czNjcjN0

Limitations

Vault supports only simple key/value pairs - nested objects are not supported. Hence specifying gjson properties like other providers support it is not supported.

Authentication

We support three different modes for authentication: token-based, appRole and kubernetes-native, each one comes with it's own trade-offs. Depending on the authentication method you need to adapt your environment.

Token-based authentication

A static token is stored in a Kind=Secret and is used to authenticate with vault.

apiVersion: external-secrets.io/v1alpha1
kind: SecretStore
metadata:
  name: vault-backend
  namespace: example
spec:
  provider:
    vault:
      server: "https://vault.acme.org"
      path: "secret"
      version: "v2"
      auth:
        # points to a secret that contains a vault token
        # https://www.vaultproject.io/docs/auth/token
        tokenSecretRef:
          name: "my-secret"
          namespace: "secret-admin"
          key: "vault-token"

AppRole authentication example

AppRole authentication reads the secret id from a Kind=Secret and uses the specified roleId to aquire a temporary token to fetch secrets.

apiVersion: external-secrets.io/v1alpha1
kind: SecretStore
metadata:
  name: vault-backend
  namespace: example
spec:
  provider:
    vault:
      server: "https://vault.acme.org"
      path: "secret"
      version: "v2"
      auth:
        # VaultAppRole authenticates with Vault using the
        # App Role auth mechanism
        # https://www.vaultproject.io/docs/auth/approle
        appRole:
          # Path where the App Role authentication backend is mounted
          path: "approle"
          # RoleID configured in the App Role authentication backend
          roleId: "db02de05-fa39-4855-059b-67221c5c2f63"
          # Reference to a key in a K8 Secret that contains the App Role SecretId
          secretRef:
            name: "my-secret"
            namespace: "secret-admin"
            key: "secret-id"

Kubernetes authentication

Kubernetes-native authentication has three options of optaining credentials for vault:

  1. by using a service account jwt referenced in serviceAccountRef
  2. by using the jwt from a Kind=Secret referenced by the secretRef
  3. by using transient credentials from the mounted service account token within the external-secrets operator
apiVersion: external-secrets.io/v1alpha1
kind: SecretStore
metadata:
  name: vault-backend
  namespace: example
spec:
  provider:
    vault:
      server: "https://vault.acme.org"
      path: "secret"
      version: "v2"
      auth:
        # Authenticate against Vault using a Kubernetes ServiceAccount
        # token stored in a Secret.
        # https://www.vaultproject.io/docs/auth/kubernetes
        kubernetes:
          # Path where the Kubernetes authentication backend is mounted in Vault
          mountPath: "kubernetes"
          # A required field containing the Vault Role to assume.
          role: "demo"
          # Optional service account field containing the name
          # of a kubernetes ServiceAccount
          serviceAccountRef:
            name: "my-sa"
            namespace: "secret-admin"
          # Optional secret field containing a Kubernetes ServiceAccount JWT
          #  used for authenticating with Vault
          secretRef:
            name: "my-secret"
            namespace: "secret-admin"
            key: "vault"

LDAP authentication

LDAP authentication uses username/password pair to get an access token. Username is stored directly in a Kind=SecretStore or Kind=ClusterSecretStore resource, password is stored in a Kind=Secret referenced by the secretRef.

apiVersion: external-secrets.io/v1alpha1
kind: SecretStore
metadata:
  name: vault-backend
  namespace: example
spec:
  provider:
    vault:
      server: "https://vault.acme.org"
      path: "secret"
      version: "v2"
      auth:
        # VaultLdap authenticates with Vault using the LDAP auth mechanism
        # https://www.vaultproject.io/docs/auth/ldap
        ldap:
          # LDAP username
          username: "username"
          secretRef:
            name: "my-secret"
            namespace: "secret-admin"
            key: "ldap-password"

JWT/OIDC authentication

JWT/OIDC uses a JWT token stored in a Kind=Secret and referenced by the secretRef. Optionally a role field can be defined in a Kind=SecretStore or Kind=ClusterSecretStore resource.

apiVersion: external-secrets.io/v1alpha1
kind: SecretStore
metadata:
  name: vault-backend
  namespace: example
spec:
  provider:
    vault:
      server: "https://vault.acme.org"
      path: "secret"
      version: "v2"
      auth:
        # VaultJwt authenticates with Vault using the JWT/OIDC auth mechanism
        # https://www.vaultproject.io/docs/auth/jwt
        jwt:
          # JWT role configured in a Vault server, optional.
          role: "vault-jwt-role"
          secretRef:
            name: "my-secret"
            namespace: "secret-admin"
            key: "jwt-token"