Secrets

Secrets management is achieved using External Secrets Operatorarrow-up-right. This not only allows for consistant interface and management of secrets from multiple sources, but also allows for the periodic syncing and updating of secrets.

In order to use the External Secrets Operator, there are some concepts to understand.

  • ClusterSecretStore

  • SecretStore

  • ExternalSecret

ClusterSecretStore

This is a type of secret store that exposes the secrets inside to enable the usage across a kubernetes cluster. Resources that are exposed in this way should be treated with extreme caution and should only be used for secrets that are truly shared across a cluster. Use with caution.

With the below cluster secret store (called cluster-secret-store), all that is required to use secrets that are in the Key Vault is to reference the secret store as you would with a standard SecretStore

chevron-rightAzure Key Vault ClusterSecretStore Examplehashtag
apiVersion: v1
kind: ServiceAccount
metadata:
  name: {{ .Values.externalSecrets.serviceAccountName }}
  annotations: {}
---
apiVersion: v1
kind: Secret
metadata:
  name: external-secrets-managed-identity
data:
  clientId: "{{b64enc .Values.externalSecrets.clientId }}"
  tenantId: "{{b64enc .Values.externalSecrets.tenantId }}"
---
apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
  name: cluster-secret-store
spec:
  provider:
    azurekv:
      environmentType: PublicCloud
      authType: WorkloadIdentity
      vaultUrl: {{ .Values.externalSecrets.vaultUrl }}
      serviceAccountRef:
        name: {{ .Values.externalSecrets.serviceAccountName }}
      authSecretRef:
        clientId:
          name: external-dns-secrets-managed-identity
          key: clientId
        tenantId:
          name: external-dns-secrets-managed-identity
          key: tenantId

SecretStore

The SecretStore resource and the ClusterSecretStore are almost identitcal. The distinction is that a SecretStore is confined to the namespace that it is created in. This should be the default type of SecretStore that is created to limit exposure of secrets to more applications than is necessary.

chevron-rightAzure Key Vault SecretStore Examplehashtag
apiVersion: v1
kind: ServiceAccount
metadata:
  name: {{ .Values.externalSecrets.serviceAccountName }}
  annotations: {}
---
apiVersion: v1
kind: Secret
metadata:
  name: external-secrets-managed-identity
data:
  clientId: "{{b64enc .Values.externalSecrets.clientId }}"
  tenantId: "{{b64enc .Values.externalSecrets.tenantId }}"
---
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: secret-store
spec:
  provider:
    azurekv:
      environmentType: PublicCloud
      authType: WorkloadIdentity
      vaultUrl: {{ .Values.externalSecrets.vaultUrl }}
      serviceAccountRef:
        name: {{ .Values.externalSecrets.serviceAccountName }}
      authSecretRef:
        clientId:
          name: external-dns-secrets-managed-identity
          key: clientId
        tenantId:
          name: external-dns-secrets-managed-identity
          key: tenantId

ExternalSecret

So far we have only described setting up the "plumbing" required to get secrets into a namespace. This is where the ExternalSecret resource will be used. We use it to define what secrets we want to pull from the backend, how often we want those secrets to sync and what template should be used to create the kubernetes secret.

It is important to note that each ExternalSecret resource has a 1:1 mapping with a kubernetes secret object that it will create, manage and keep updated.

The ExternalSecret resource resource has several ways to create the secret. The most basic form of this is Key/Value. In the below exmple, a kubernetes secret called external-secrets (taken from the spec.target.name field) would be created with a singular key/value inside called token (taken from the spec.data[0].secretKey field). The spec.data[0].remoteRef.key field specifies which secret this is in the SecretStore that was created with the helm in the SecretStore definition above.

chevron-rightKey/Value ExternalSecret examplehashtag

Many services require configuration to be in other formats like json. This means that we usually have to do some templating to get everthing created correctly. An example of this can be seen when configuring a kubernetes secret for External DNS, as it requires a json object to be constructed.

If we assume that this can use the same SecretStore as we have specified above, then we can specify the template using the template engine built into ExternalSecrets. As you can see the secrets within the helm file below are referenced with "{{ `{{ .secretName }}` }}". Normally you only reference a secret with {{ .secretName }}, but the extra encapsulation is required to stop helm trying to replace the value during it's templating

chevron-rightJson Template ExternalSecret Examplehashtag

Last updated

Was this helpful?