diff --git a/main/404.html b/main/404.html old mode 100755 new mode 100644 diff --git a/main/api/clusterexternalsecret/index.html b/main/api/clusterexternalsecret/index.html old mode 100755 new mode 100644 diff --git a/main/api/clustersecretstore/index.html b/main/api/clustersecretstore/index.html old mode 100755 new mode 100644 diff --git a/main/api/components/index.html b/main/api/components/index.html old mode 100755 new mode 100644 diff --git a/main/api/controller-options/index.html b/main/api/controller-options/index.html old mode 100755 new mode 100644 diff --git a/main/api/externalsecret/index.html b/main/api/externalsecret/index.html old mode 100755 new mode 100644 diff --git a/main/api/generator/acr/index.html b/main/api/generator/acr/index.html old mode 100755 new mode 100644 diff --git a/main/api/generator/ecr/index.html b/main/api/generator/ecr/index.html old mode 100755 new mode 100644 diff --git a/main/api/generator/fake/index.html b/main/api/generator/fake/index.html old mode 100755 new mode 100644 diff --git a/main/api/generator/gcr/index.html b/main/api/generator/gcr/index.html old mode 100755 new mode 100644 diff --git a/main/api/generator/index.html b/main/api/generator/index.html old mode 100755 new mode 100644 diff --git a/main/api/generator/password/index.html b/main/api/generator/password/index.html old mode 100755 new mode 100644 diff --git a/main/api/generator/vault/index.html b/main/api/generator/vault/index.html old mode 100755 new mode 100644 diff --git a/main/api/generator/webhook/index.html b/main/api/generator/webhook/index.html old mode 100755 new mode 100644 diff --git a/main/api/metrics/index.html b/main/api/metrics/index.html old mode 100755 new mode 100644 diff --git a/main/api/pushsecret/index.html b/main/api/pushsecret/index.html old mode 100755 new mode 100644 diff --git a/main/api/secretstore/index.html b/main/api/secretstore/index.html old mode 100755 new mode 100644 diff --git a/main/api/spec/index.html b/main/api/spec/index.html old mode 100755 new mode 100644 diff --git a/main/artifacthub-repo.yml b/main/artifacthub-repo.yml old mode 100755 new mode 100644 diff --git a/main/assets/images/favicon.png b/main/assets/images/favicon.png old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/bundle.dd8806f2.min.js b/main/assets/javascripts/bundle.dd8806f2.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/bundle.dd8806f2.min.js.map b/main/assets/javascripts/bundle.dd8806f2.min.js.map old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.ar.min.js b/main/assets/javascripts/lunr/min/lunr.ar.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.da.min.js b/main/assets/javascripts/lunr/min/lunr.da.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.de.min.js b/main/assets/javascripts/lunr/min/lunr.de.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.du.min.js b/main/assets/javascripts/lunr/min/lunr.du.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.el.min.js b/main/assets/javascripts/lunr/min/lunr.el.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.es.min.js b/main/assets/javascripts/lunr/min/lunr.es.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.fi.min.js b/main/assets/javascripts/lunr/min/lunr.fi.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.fr.min.js b/main/assets/javascripts/lunr/min/lunr.fr.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.he.min.js b/main/assets/javascripts/lunr/min/lunr.he.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.hi.min.js b/main/assets/javascripts/lunr/min/lunr.hi.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.hu.min.js b/main/assets/javascripts/lunr/min/lunr.hu.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.hy.min.js b/main/assets/javascripts/lunr/min/lunr.hy.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.it.min.js b/main/assets/javascripts/lunr/min/lunr.it.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.ja.min.js b/main/assets/javascripts/lunr/min/lunr.ja.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.jp.min.js b/main/assets/javascripts/lunr/min/lunr.jp.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.kn.min.js b/main/assets/javascripts/lunr/min/lunr.kn.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.ko.min.js b/main/assets/javascripts/lunr/min/lunr.ko.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.multi.min.js b/main/assets/javascripts/lunr/min/lunr.multi.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.nl.min.js b/main/assets/javascripts/lunr/min/lunr.nl.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.no.min.js b/main/assets/javascripts/lunr/min/lunr.no.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.pt.min.js b/main/assets/javascripts/lunr/min/lunr.pt.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.ro.min.js b/main/assets/javascripts/lunr/min/lunr.ro.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.ru.min.js b/main/assets/javascripts/lunr/min/lunr.ru.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.sa.min.js b/main/assets/javascripts/lunr/min/lunr.sa.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.stemmer.support.min.js b/main/assets/javascripts/lunr/min/lunr.stemmer.support.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.sv.min.js b/main/assets/javascripts/lunr/min/lunr.sv.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.ta.min.js b/main/assets/javascripts/lunr/min/lunr.ta.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.te.min.js b/main/assets/javascripts/lunr/min/lunr.te.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.th.min.js b/main/assets/javascripts/lunr/min/lunr.th.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.tr.min.js b/main/assets/javascripts/lunr/min/lunr.tr.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.vi.min.js b/main/assets/javascripts/lunr/min/lunr.vi.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/min/lunr.zh.min.js b/main/assets/javascripts/lunr/min/lunr.zh.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/tinyseg.js b/main/assets/javascripts/lunr/tinyseg.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/lunr/wordcut.js b/main/assets/javascripts/lunr/wordcut.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/workers/search.b8dbb3d2.min.js b/main/assets/javascripts/workers/search.b8dbb3d2.min.js old mode 100755 new mode 100644 diff --git a/main/assets/javascripts/workers/search.b8dbb3d2.min.js.map b/main/assets/javascripts/workers/search.b8dbb3d2.min.js.map old mode 100755 new mode 100644 diff --git a/main/assets/stylesheets/main.66ac8b77.min.css b/main/assets/stylesheets/main.66ac8b77.min.css old mode 100755 new mode 100644 diff --git a/main/assets/stylesheets/main.66ac8b77.min.css.map b/main/assets/stylesheets/main.66ac8b77.min.css.map old mode 100755 new mode 100644 diff --git a/main/assets/stylesheets/palette.06af60db.min.css b/main/assets/stylesheets/palette.06af60db.min.css old mode 100755 new mode 100644 diff --git a/main/assets/stylesheets/palette.06af60db.min.css.map b/main/assets/stylesheets/palette.06af60db.min.css.map old mode 100755 new mode 100644 diff --git a/main/contributing/coc/index.html b/main/contributing/coc/index.html old mode 100755 new mode 100644 diff --git a/main/contributing/devguide/index.html b/main/contributing/devguide/index.html old mode 100755 new mode 100644 diff --git a/main/contributing/process/index.html b/main/contributing/process/index.html old mode 100755 new mode 100644 diff --git a/main/contributing/release/index.html b/main/contributing/release/index.html old mode 100755 new mode 100644 diff --git a/main/contributing/roadmap/index.html b/main/contributing/roadmap/index.html old mode 100755 new mode 100644 diff --git a/main/eso-blogs/index.html b/main/eso-blogs/index.html old mode 100755 new mode 100644 diff --git a/main/eso-demos/index.html b/main/eso-demos/index.html old mode 100755 new mode 100644 diff --git a/main/eso-talks/index.html b/main/eso-talks/index.html old mode 100755 new mode 100644 diff --git a/main/examples/anchore-engine-credentials/index.html b/main/examples/anchore-engine-credentials/index.html old mode 100755 new mode 100644 diff --git a/main/examples/bitwarden/index.html b/main/examples/bitwarden/index.html old mode 100755 new mode 100644 index 075921033c1..c98c618a965 --- a/main/examples/bitwarden/index.html +++ b/main/examples/bitwarden/index.html @@ -2652,9 +2652,9 @@
Bitwarden is an integrated open source password management solution for individuals, teams, and business organizations.
-To make external-secret compatible with BitWarden, we need:
+To make external-secrets compatible with Bitwarden, we need:
bw serve
When you create a new external-secret object, -External-Secret Webhook provider will do a query to the Bitwarden CLI pod, -which is synced with the BitWarden server.
+When you create a new external-secret object, the External Secrets webhook provider will query the Bitwarden CLI pod that is synced with the Bitwarden server.
ghcr.io/charlesthomas/bitwarden-cli:2023.12.1
or build your own.ghcr.io/charlesthomas/bitwarden-cli:2023.12.1
or build your own.Here an example of Dockerfile use to build this image: +
Here is an example of a Dockerfile used to build the image:
FROM debian:sid
ENV BW_CLI_VERSION=2023.12.1
@@ -3997,7 +3993,7 @@ Requirements
CMD ["/entrypoint.sh"]
And the content of entrypoint.sh
+
And the content of entrypoint.sh
:
#!/bin/bash
set -e
@@ -4011,7 +4007,7 @@ Requirements
echo 'Running `bw server` on port 8087'
bw serve --hostname 0.0.0.0 #--disable-origin-protection
apiVersion: v1
data:
BW_HOST: ...
@@ -4134,11 +4130,11 @@ Deploy Bitwarden CLI container
app.kubernetes.io/name: external-secrets
--NOTE: Deploying a network policy is recommended since, there is no authentication to query the BitWarden CLI, which means that your secrets are exposed.
-NOTE: In this example the Liveness probe is quering /sync to ensure that the BitWarden CLI is able to connect to the server and also to sync secrets. (The secret sync is only every 2 minutes in this example)
+NOTE: Deploying a network policy is recommended since there is no authentication to query the Bitwarden CLI, which means that your secrets are exposed.
+NOTE: In this example the Liveness probe is querying /sync to ensure that the Bitwarden CLI is able to connect to the server and is also synchronised. (The secret sync is only every 2 minutes in this example)
Here the two ClusterSecretStore to deploy
+There are four possible (Cluster)SecretStores to deploy, each can access different types of fields from an item in the Bitwarden vault. It is not required to deploy them all.
---
apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
@@ -4174,27 +4170,49 @@ Deploy ClusterSecretStore (Or
url: "http://bitwarden-cli:8087/object/item/{{ .remoteRef.key }}"
result:
jsonPath: "$.data.notes"
+---
+apiVersion: external-secrets.io/v1beta1
+kind: ClusterSecretStore
+metadata:
+ name: bitwarden-attachments
+spec:
+ provider:
+ webhook:
+ url: "http://bitwarden-cli:8087/object/attachment/{{ .remoteRef.property }}?itemid={{ .remoteRef.key }}"
+ result: {}
(Cluster)SecretStores:
+bitwarden-login
: Use to get the username
or password
fieldsbitwarden-fields
: Use to get custom fieldsbitwarden-notes
: Use to get notesbitwarden-attachments
: Use to get attachmentsremoteRef:
+key
: ID of a secret, which can be found in the URL itemId
parameter:
+ https://myvault.com/#/vault?type=login&itemId=........-....-....-....-............
s
property
: Name of the field to access
username
or the password
of a secret, you have to use bitwarden-login
bitwarden-fields
bitwarden-notes
key
is the ID of a secret, which can be find in the URL with the itemId
value:
- https://myvault.com/#/vault?itemId=........-....-....-....-............
property
is the name of the field:username
for the username of a secret (bitwarden-login
SecretStore)password
for the password of a secret (bitwarden-login
SecretStore)name_of_the_custom_field
for any custom field (bitwarden-fields
SecretStore)id_or_name_of_the_attachment
for any attachment (bitwarden-attachment
, SecretStore)apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
- name: my-db-secrets
+ name: my-secrets
namespace: default
spec:
target:
- name: my-db-secrets
+ name: my-secrets
deletionPolicy: Delete
template:
type: Opaque
@@ -4211,6 +4229,8 @@ How to use it ?
postgresql://{{ .username }}:{{ .password }}@my-postgresql:5432/mydb
service_account_key: |-
{{ .service_account_key }}
+ ssh_pub_key: |-
+ {{ .ssh_pub_key }}
data:
- secretKey: username
sourceRef:
@@ -4251,6 +4271,14 @@ How to use it ?
kind: ClusterSecretStore # or SecretStore
remoteRef:
key: service_account_key
+ - secretKey: ssh_pub_key
+ sourceRef:
+ storeRef:
+ name: bitwarden-attachments
+ kind: ClusterSecretStore # or SecretStore
+ remoteRef:
+ key: aaaabbbb-cccc-dddd-eeee-000011112222
+ property: id_rsa.pub
For more information, please see this issue
This will generate a valid dockerconfigjson secret for you to use!
You can get the final value with:
-kubectl get secret secret-to-be-created -n <namespace> -o jsonpath="{.data\.dockerconfigjson}" | base64 -d
+kubectl get secret secret-to-be-created -n <namespace> -o jsonpath="{.data.\.dockerconfigjson}" | base64 -d
Alternately, if you only have the container registry name and password value, you can take advantage of the advanced ExternalSecret templating functions to create the secret:
apiVersion: external-secrets.io/v1beta1
diff --git a/main/guides/controller-class/index.html b/main/guides/controller-class/index.html
old mode 100755
new mode 100644
diff --git a/main/guides/datafrom-rewrite/index.html b/main/guides/datafrom-rewrite/index.html
old mode 100755
new mode 100644
diff --git a/main/guides/decoding-strategy/index.html b/main/guides/decoding-strategy/index.html
old mode 100755
new mode 100644
diff --git a/main/guides/disable-cluster-features/index.html b/main/guides/disable-cluster-features/index.html
old mode 100755
new mode 100644
diff --git a/main/guides/generator/index.html b/main/guides/generator/index.html
old mode 100755
new mode 100644
diff --git a/main/guides/getallsecrets/index.html b/main/guides/getallsecrets/index.html
old mode 100755
new mode 100644
diff --git a/main/guides/introduction/index.html b/main/guides/introduction/index.html
old mode 100755
new mode 100644
diff --git a/main/guides/multi-tenancy/index.html b/main/guides/multi-tenancy/index.html
old mode 100755
new mode 100644
diff --git a/main/guides/ownership-deletion-policy/index.html b/main/guides/ownership-deletion-policy/index.html
old mode 100755
new mode 100644
diff --git a/main/guides/pushsecrets/index.html b/main/guides/pushsecrets/index.html
old mode 100755
new mode 100644
diff --git a/main/guides/security-best-practices/index.html b/main/guides/security-best-practices/index.html
old mode 100755
new mode 100644
diff --git a/main/guides/templating-v1/index.html b/main/guides/templating-v1/index.html
old mode 100755
new mode 100644
diff --git a/main/guides/templating/index.html b/main/guides/templating/index.html
old mode 100755
new mode 100644
diff --git a/main/guides/threat-model/index.html b/main/guides/threat-model/index.html
old mode 100755
new mode 100644
diff --git a/main/guides/using-latest-image/index.html b/main/guides/using-latest-image/index.html
old mode 100755
new mode 100644
diff --git a/main/guides/v1beta1/index.html b/main/guides/v1beta1/index.html
old mode 100755
new mode 100644
diff --git a/main/index.html b/main/index.html
old mode 100755
new mode 100644
diff --git a/main/introduction/deprecation-policy/index.html b/main/introduction/deprecation-policy/index.html
old mode 100755
new mode 100644
diff --git a/main/introduction/faq/index.html b/main/introduction/faq/index.html
old mode 100755
new mode 100644
diff --git a/main/introduction/getting-started/index.html b/main/introduction/getting-started/index.html
old mode 100755
new mode 100644
diff --git a/main/introduction/overview/index.html b/main/introduction/overview/index.html
old mode 100755
new mode 100644
diff --git a/main/introduction/stability-support/index.html b/main/introduction/stability-support/index.html
old mode 100755
new mode 100644
diff --git a/main/pictures/cloak-provider-header.png b/main/pictures/cloak-provider-header.png
old mode 100755
new mode 100644
diff --git a/main/pictures/cs_logo.png b/main/pictures/cs_logo.png
old mode 100755
new mode 100644
diff --git a/main/pictures/diagrams-cluster-external-secrets.png b/main/pictures/diagrams-cluster-external-secrets.png
old mode 100755
new mode 100644
diff --git a/main/pictures/diagrams-component-overview.png b/main/pictures/diagrams-component-overview.png
old mode 100755
new mode 100644
diff --git a/main/pictures/diagrams-high-level-cluster-detail.png b/main/pictures/diagrams-high-level-cluster-detail.png
old mode 100755
new mode 100644
diff --git a/main/pictures/diagrams-high-level-ns-detail.png b/main/pictures/diagrams-high-level-ns-detail.png
old mode 100755
new mode 100644
diff --git a/main/pictures/diagrams-high-level-simple.png b/main/pictures/diagrams-high-level-simple.png
old mode 100755
new mode 100644
diff --git a/main/pictures/diagrams-multi-tenancy-managed-store.png b/main/pictures/diagrams-multi-tenancy-managed-store.png
old mode 100755
new mode 100644
diff --git a/main/pictures/diagrams-multi-tenancy-self-service.png b/main/pictures/diagrams-multi-tenancy-self-service.png
old mode 100755
new mode 100644
diff --git a/main/pictures/diagrams-multi-tenancy-shared.png b/main/pictures/diagrams-multi-tenancy-shared.png
old mode 100755
new mode 100644
diff --git a/main/pictures/diagrams-provider-aws-auth-pod-identity.png b/main/pictures/diagrams-provider-aws-auth-pod-identity.png
old mode 100755
new mode 100644
diff --git a/main/pictures/diagrams-provider-aws-auth-secret-ref.png b/main/pictures/diagrams-provider-aws-auth-secret-ref.png
old mode 100755
new mode 100644
diff --git a/main/pictures/diagrams-provider-aws-auth-service-account.png b/main/pictures/diagrams-provider-aws-auth-service-account.png
old mode 100755
new mode 100644
diff --git a/main/pictures/diagrams-provider-aws-ssm-parameter-store.png b/main/pictures/diagrams-provider-aws-ssm-parameter-store.png
old mode 100755
new mode 100644
diff --git a/main/pictures/diagrams-provider-vault.png b/main/pictures/diagrams-provider-vault.png
old mode 100755
new mode 100644
diff --git a/main/pictures/diagrams-pushsecret-backup.png b/main/pictures/diagrams-pushsecret-backup.png
old mode 100755
new mode 100644
diff --git a/main/pictures/diagrams-pushsecret-basic.png b/main/pictures/diagrams-pushsecret-basic.png
old mode 100755
new mode 100644
diff --git a/main/pictures/diagrams-resource-mapping.png b/main/pictures/diagrams-resource-mapping.png
old mode 100755
new mode 100644
diff --git a/main/pictures/diagrams.drawio b/main/pictures/diagrams.drawio
old mode 100755
new mode 100644
diff --git a/main/pictures/doppler-create-service-token.jpg b/main/pictures/doppler-create-service-token.jpg
old mode 100755
new mode 100644
diff --git a/main/pictures/doppler-download.png b/main/pictures/doppler-download.png
old mode 100755
new mode 100644
diff --git a/main/pictures/doppler-fetch-all.png b/main/pictures/doppler-fetch-all.png
old mode 100755
new mode 100644
diff --git a/main/pictures/doppler-fetch.png b/main/pictures/doppler-fetch.png
old mode 100755
new mode 100644
diff --git a/main/pictures/doppler-filter.png b/main/pictures/doppler-filter.png
old mode 100755
new mode 100644
diff --git a/main/pictures/doppler-get-db-url-secret.jpg b/main/pictures/doppler-get-db-url-secret.jpg
old mode 100755
new mode 100644
diff --git a/main/pictures/doppler-json.png b/main/pictures/doppler-json.png
old mode 100755
new mode 100644
diff --git a/main/pictures/doppler-name-transformer.png b/main/pictures/doppler-name-transformer.png
old mode 100755
new mode 100644
diff --git a/main/pictures/doppler-provider-header.jpg b/main/pictures/doppler-provider-header.jpg
old mode 100755
new mode 100644
diff --git a/main/pictures/doppler-service-tokens.png b/main/pictures/doppler-service-tokens.png
old mode 100755
new mode 100644
diff --git a/main/pictures/eso-az-kv-aws-sm.png b/main/pictures/eso-az-kv-aws-sm.png
old mode 100755
new mode 100644
diff --git a/main/pictures/eso-az-kv-azure-kv.png b/main/pictures/eso-az-kv-azure-kv.png
old mode 100755
new mode 100644
diff --git a/main/pictures/eso-dashboard-1.png b/main/pictures/eso-dashboard-1.png
old mode 100755
new mode 100644
diff --git a/main/pictures/eso-dashboard-2.png b/main/pictures/eso-dashboard-2.png
old mode 100755
new mode 100644
diff --git a/main/pictures/eso-round-logo.svg b/main/pictures/eso-round-logo.svg
old mode 100755
new mode 100644
diff --git a/main/pictures/eso-threat-model-TLS Bootstrap.drawio.png b/main/pictures/eso-threat-model-TLS Bootstrap.drawio.png
old mode 100755
new mode 100644
diff --git a/main/pictures/eso-threat-model-overview.drawio.png b/main/pictures/eso-threat-model-overview.drawio.png
old mode 100755
new mode 100644
diff --git a/main/pictures/eso-threat-model.drawio b/main/pictures/eso-threat-model.drawio
old mode 100755
new mode 100644
diff --git a/main/pictures/form3_logo.png b/main/pictures/form3_logo.png
old mode 100755
new mode 100644
diff --git a/main/pictures/godaddy_logo.png b/main/pictures/godaddy_logo.png
old mode 100755
new mode 100644
diff --git a/main/pictures/onboardbase-api-key.png b/main/pictures/onboardbase-api-key.png
old mode 100755
new mode 100644
diff --git a/main/pictures/onboardbase-create-api-key.png b/main/pictures/onboardbase-create-api-key.png
old mode 100755
new mode 100644
diff --git a/main/pictures/onboardbase-provider.png b/main/pictures/onboardbase-provider.png
old mode 100755
new mode 100644
diff --git a/main/pictures/pento_logo.png b/main/pictures/pento_logo.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_1password_create_document.png b/main/pictures/screenshot_1password_create_document.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_1password_create_password.png b/main/pictures/screenshot_1password_create_password.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_1password_password_field.png b/main/pictures/screenshot_1password_password_field.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_API_key.png b/main/pictures/screenshot_API_key.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_api_keys_create.png b/main/pictures/screenshot_api_keys_create.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_api_keys_create_button.png b/main/pictures/screenshot_api_keys_create_button.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_api_keys_create_successful.png b/main/pictures/screenshot_api_keys_create_successful.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_api_keys_iam.png b/main/pictures/screenshot_api_keys_iam.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_api_keys_iam_left.png b/main/pictures/screenshot_api_keys_iam_left.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_container_auth_create_1.png b/main/pictures/screenshot_container_auth_create_1.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_container_auth_create_2.png b/main/pictures/screenshot_container_auth_create_2.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_container_auth_create_3.png b/main/pictures/screenshot_container_auth_create_3.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_container_auth_create_button.png b/main/pictures/screenshot_container_auth_create_button.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_container_auth_create_group.png b/main/pictures/screenshot_container_auth_create_group.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_container_auth_create_group_1.png b/main/pictures/screenshot_container_auth_create_group_1.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_container_auth_create_group_2.png b/main/pictures/screenshot_container_auth_create_group_2.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_container_auth_create_group_3.png b/main/pictures/screenshot_container_auth_create_group_3.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_container_auth_create_group_4.png b/main/pictures/screenshot_container_auth_create_group_4.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_container_auth_create_group_5.png b/main/pictures/screenshot_container_auth_create_group_5.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_container_auth_iam_left.png b/main/pictures/screenshot_container_auth_iam_left.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_docker_config_json_example.png b/main/pictures/screenshot_docker_config_json_example.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_fingerprint.png b/main/pictures/screenshot_fingerprint.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_gitlab_projectID.png b/main/pictures/screenshot_gitlab_projectID.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_gitlab_token.png b/main/pictures/screenshot_gitlab_token.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_gitlab_token_created.png b/main/pictures/screenshot_gitlab_token_created.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_gitops_final_directory_tree.png b/main/pictures/screenshot_gitops_final_directory_tree.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_json_string_gcp_secret_value.png b/main/pictures/screenshot_json_string_gcp_secret_value.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_region.png b/main/pictures/screenshot_region.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_service_url.png b/main/pictures/screenshot_service_url.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_ssh_privkey_example.png b/main/pictures/screenshot_ssh_privkey_example.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_ssl_certificate_p12_example.png b/main/pictures/screenshot_ssl_certificate_p12_example.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_tenancy_OCID.png b/main/pictures/screenshot_tenancy_OCID.png
old mode 100755
new mode 100644
diff --git a/main/pictures/screenshot_user_OCID.png b/main/pictures/screenshot_user_OCID.png
old mode 100755
new mode 100644
diff --git a/main/provider-passworddepot/index.html b/main/provider-passworddepot/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/1password-automation/index.html b/main/provider/1password-automation/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/akeyless/index.html b/main/provider/akeyless/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/alibaba/index.html b/main/provider/alibaba/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/aws-parameter-store/index.html b/main/provider/aws-parameter-store/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/aws-secrets-manager/index.html b/main/provider/aws-secrets-manager/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/azure-key-vault/index.html b/main/provider/azure-key-vault/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/chef/index.html b/main/provider/chef/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/cloak/index.html b/main/provider/cloak/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/conjur/index.html b/main/provider/conjur/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/delinea/index.html b/main/provider/delinea/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/doppler/index.html b/main/provider/doppler/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/fake/index.html b/main/provider/fake/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/fortanix/index.html b/main/provider/fortanix/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/gitlab-variables/index.html b/main/provider/gitlab-variables/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/google-secrets-manager/index.html b/main/provider/google-secrets-manager/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/hashicorp-vault/index.html b/main/provider/hashicorp-vault/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/ibm-secrets-manager/index.html b/main/provider/ibm-secrets-manager/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/keeper-security/index.html b/main/provider/keeper-security/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/kubernetes/index.html b/main/provider/kubernetes/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/onboardbase/index.html b/main/provider/onboardbase/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/oracle-vault/index.html b/main/provider/oracle-vault/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/passbolt/index.html b/main/provider/passbolt/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/pulumi/index.html b/main/provider/pulumi/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/scaleway/index.html b/main/provider/scaleway/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/senhasegura-dsm/index.html b/main/provider/senhasegura-dsm/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/webhook/index.html b/main/provider/webhook/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/yandex-certificate-manager/index.html b/main/provider/yandex-certificate-manager/index.html
old mode 100755
new mode 100644
diff --git a/main/provider/yandex-lockbox/index.html b/main/provider/yandex-lockbox/index.html
old mode 100755
new mode 100644
diff --git a/main/search/search_index.json b/main/search/search_index.json
old mode 100755
new mode 100644
index ff4666b5cae..585e06050b1
--- a/main/search/search_index.json
+++ b/main/search/search_index.json
@@ -1 +1 @@
-{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Introduction","text":"External Secrets Operator is a Kubernetes operator that integrates external secret management systems like AWS Secrets Manager, HashiCorp Vault, Google Secrets Manager, Azure Key Vault, IBM Cloud Secrets Manager, CyberArk Conjur and many more. The operator reads information from external APIs and automatically injects the values into a Kubernetes Secret.
"},{"location":"#what-is-the-goal-of-external-secrets-operator","title":"What is the goal of External Secrets Operator?","text":"The goal of External Secrets Operator is to synchronize secrets from external APIs into Kubernetes. 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.
"},{"location":"#where-to-get-started","title":"Where to get started","text":"To get started, please read through API overview this should give you a high-level overview to understand the API and use-cases. After that please follow one of our guides to get a jump start using the operator. See our getting started guide for installation instructions.
For a complete reference of the API types please refer to our API Reference.
"},{"location":"#how-to-get-involved","title":"How to get involved","text":"This project is driven by its users and contributors, and we welcome everybody to get involved. Join our meetings, open issues or ask questions in Slack. The success of this project depends on your input: No contribution is too small - even opinions matter!
How to get involved:
- Bi-weekly Development Meeting every odd week at 8:00 PM Berlin Time on Wednesday (agenda, jitsi call)
- Kubernetes Slack #external-secrets
- Contributing Process
- Twitter
"},{"location":"#kicked-off-by","title":"Kicked off by","text":""},{"location":"#sponsored-by","title":"Sponsored by","text":""},{"location":"eso-blogs/","title":"ESO Blogs","text":"A list of blogs written by people all over the community. Feel free to let us know if you are writing about ESO at some place! We would be happy to mention you here!
"},{"location":"eso-blogs/#comparing-external-secrets-operator-with-secret-storage-csi-as-kubernetes-external-secrets-is-deprecated","title":"Comparing External Secrets Operator with Secret Storage CSI as Kubernetes External Secrets is Deprecated","text":"@riddle writes about choosing ESO when comparing with Secret Store CSI Driver in their specific use case. They show us the relevant differences between the projects when looking at their scenario and requirements while integrating with ArgoCD. Comparing External Secrets Operator with Secret Storage CSI as Kubernetes External Secrets is Deprecated
"},{"location":"eso-blogs/#tutorial-getting-started-with-external-secrets-operator-on-kubernetes-using-aws-secrets-manager","title":"Tutorial: Getting Started with External Secrets Operator on Kubernetes using AWS Secrets Manager","text":"Puru writes about getting started using ESO with AWS Secrets Manager. He uses illustrations to explain ESO to new users and get's you to quickly start using ESO, as article is easy to follow along. Getting Started with External Secrets Operator on Kubernetes using AWS Secrets Manager
"},{"location":"eso-blogs/#tutorial-how-to-set-external-secrets-with-azure-keyvault","title":"Tutorial: How to Set External-Secrets with Azure KeyVault","text":"Gustavo writes about how to setup ESO with Azure Key Vault and adds an guide on how to make it a bit more secure with OPA (Open Policy Agent). How to Set External-Secrets with Azure KeyVault
"},{"location":"eso-blogs/#tutorial-how-to-set-external-secrets-with-gcp-secret-manager","title":"Tutorial: How to Set External-Secrets with GCP Secret Manager","text":"Gustavo writes about how to setup ESO with GCP Secret Manager. He also shows you how to make a simple multi tenant setup with a ClusterSecretStore. How to Set External-Secrets with GCP Secret Manager
"},{"location":"eso-blogs/#tutorial-how-to-set-external-secrets-with-hashicorp-vault","title":"Tutorial: How to Set External-Secrets with Hashicorp Vault","text":"Gustavo writes about how to setup ESO with Hashicorp Vault. He also shows you how to make this scale with multiple replicas of the operator and leader election enabled to lead balance handling synchronization work. How to Set External-Secrets with Hashicorp Vault
"},{"location":"eso-blogs/#tutorial-how-to-set-external-secrets-with-aws","title":"Tutorial: How to Set External-Secrets with AWS","text":"Gustavo writes about how to setup ESO with AWS Secrets Manager. He also shows you how to limit access and give granular permissions with better policies and roles for your service accounts to use. How to Set External-Secrets with AWS
"},{"location":"eso-blogs/#tutorial-how-to-set-external-secrets-with-ibm-secrets-manager","title":"Tutorial: How to Set External-Secrets with IBM Secrets Manager","text":"In this multi-articles series, Xavier writes about how to setup ESO with IBM Secrets Manager using the web user-interface. Xavier also shares how it is integrated into his pipeline scripts. How to Set External-Secrets with IBM Secrets Manager
"},{"location":"eso-blogs/#kubernetes-hardening-tutorial-part-2-network","title":"Kubernetes Hardening Tutorial Part 2: Network","text":"Tiexin Guo Writes about Kubernetes hardening in this series of blogs. He mentions ESO as one of the convenient options when dealing with secrets in Kubernetes, and how to use it with AWS Secret Manager using AWS credentials. Kubernetes Hardening Tutorial Part 2: Network
"},{"location":"eso-blogs/#tutorial-how-to-manage-secrets-in-openshift-using-vault-and-external-secrets-operator","title":"Tutorial: How to manage secrets in OpenShift using Vault and External Secrets Operator","text":"Balkrishna Pandey published a video tutorial and a blog post on integrating HashiCorp Vault and External Secret Operator (ESO) to manage application secrets on OpenShift Cluster. In this blog, he demonstrates the strength of the ClusterSecretStore
functionality, a cluster scoped SecretStore and is global to the Cluster that all ExternalSecrets
can reference from all namespaces.
"},{"location":"eso-blogs/#tutorial-leverage-aws-secrets-stores-from-eks-fargate-with-external-secrets-operator","title":"Tutorial: Leverage AWS secrets stores from EKS Fargate with External Secrets Operator","text":"In this AWS Containers blog post, Ryan writes about how to leverage External Secret Operator with an EKS Fargate cluster using IAM Roles for Service Accounts (IRSA). This setup supports the requirements of Fargate based workloads. Leverage AWS secrets stores from EKS Fargate with External Secrets Operator
"},{"location":"eso-blogs/#cloud-native-secret-management-with-external-secrets-operator","title":"Cloud Native Secret Management with External Secrets Operator","text":"Emin writes about what problems ESO can solve and how to setup ESO on an Amazon EKS Cluster with integrations for AWS Secrets Manager using IAM Roles for Service Accounts (IRSA). In this blog post, there is also a GitHub repository with example codes for everyone to follow this demonstration.
"},{"location":"eso-blogs/#external-secrets-operator-integration-with-hashicorp-vault","title":"External Secrets Operator Integration with HashiCorp Vault","text":"Emin writes about integration between External Secrets Operator and HashiCorp Vault with a demonstration on installing ESO and Vault on a Kubernetes Cluster and configuration of the permissions and other integration parts.
"},{"location":"eso-blogs/#reversing-the-workflow-with-external-secrets-operators-push-secret-feature","title":"Reversing the Workflow with External Secrets Operator\u2019s Push Secret Feature","text":"Emin writes about the Push Secret feature of ESO and how this new feature reverse the workflow of ESO by pushing Kubernetes secrets to external secret management providers.
"},{"location":"eso-blogs/#gcp-secret-manager-with-self-hosted-kubernetes","title":"GCP Secret Manager with self-hosted Kubernetes","text":"Jacek writes about bringing GCP secrets to on-premises cluster through External Secrets Operator intergration with workload identity.
"},{"location":"eso-demos/","title":"ESO Demos","text":"A list of demos given by people going through simple setups with ESO. Feel free to let us know if you have a demo that you want to include here!
"},{"location":"eso-demos/#manage-kubernetes-secrets-with-external-secrets-operator-on-devops-toolkit","title":"Manage Kubernetes Secrets With External Secrets Operator on DevOps Toolkit","text":"Viktor Farvik shows us how to use ESO with GCP provider and explores a simple workflow with the project.
"},{"location":"eso-demos/#managing-kubernetes-secrets-comparing-external-secrets-operator-and-secrets-store-csi-driver","title":"Managing Kubernetes Secrets: Comparing External Secrets Operator and Secrets Store CSI Driver","text":"Kim Schlesinger and Daniel Hix show us how to install and use both projects, comparing their features and limitations in different situations.
"},{"location":"eso-demos/#gcp-sm-aws-sm-azure-key-vault-demo","title":"GCP SM + AWS SM + Azure Key Vault Demo","text":"This was an old demo going through an old version of ESO. Most of it is still valid, but beware of CRD and breaking change differences.
"},{"location":"eso-demos/#how-to-manage-secrets-in-openshift-using-vault-and-external-secrets-operator","title":"How to manage secrets in OpenShift using Vault and External Secrets Operator","text":"Balkrishna Pandey shows us here how to use ClusterSecretStore and how to integrate ESO with Hashicorp Vault on Openshift.
"},{"location":"eso-demos/#managing-sensitive-data-in-kubernetes-with-sealed-secrets-and-external-secrets-operator-eso","title":"Managing Sensitive Data in Kubernetes with Sealed Secrets and External Secrets Operator (ESO)","text":"Lukonde Mwila demonstrates how ESO works and how to fetch secrets from AWS Secrets Manager into your Kubernetes cluster.
"},{"location":"eso-demos/#external-secrets-operator-a-cloud-native-way-to-manage-your-secrets","title":"External Secrets Operator: A Cloud Native way to manage your secrets","text":"Charl Klein gives an overview of the external secrets project, and a walkthrough of getting ESO up and running with Azure Key Vault
"},{"location":"eso-talks/","title":"ESO Talks","text":"A list of talks given by people at conferences and events. Feel free to let us know if you are talking about ESO at some place! We would be happy to mention you here!
"},{"location":"eso-talks/#kubernetes-community-days-uk","title":"Kubernetes Community Days UK","text":""},{"location":"eso-talks/#cncf-community-groups-canada","title":"CNCF Community Groups Canada","text":""},{"location":"eso-talks/#container-days-hamburg","title":"Container Days Hamburg","text":""},{"location":"eso-talks/#kubernetes-community-days-uk-2022","title":"Kubernetes Community Days UK - 2022","text":""},{"location":"eso-talks/#aws-containers-from-the-couch","title":"AWS Containers from the Couch","text":""},{"location":"eso-talks/#fosdem-23-containers-devroom","title":"FOSDEM '23 (Containers devroom)","text":"FOSDEM '23 (Containers devroom)
"},{"location":"eso-talks/#form3-tech-podcast-building-and-maintaining-external-secrets-operator","title":"Form3 .tech Podcast - Building and maintaining External Secrets Operator","text":"Podcast and Blog
"},{"location":"eso-talks/#enlightning-exploring-external-secrets-operator","title":"\u26a1\ufe0f Enlightning - Exploring External Secrets Operator","text":""},{"location":"eso-talks/#kubecon-eu-23-protecting-your-crown-jewels-with-external-secrets-operator","title":"KubeCon EU '23 - Protecting Your Crown Jewels with External Secrets Operator","text":""},{"location":"provider-passworddepot/","title":"Password Depot","text":"External Secrets Operator integrates with Password Depot API to sync Password Depot to secrets held on the Kubernetes cluster.
"},{"location":"provider-passworddepot/#authentication","title":"Authentication","text":"The API requires a username and password.
apiVersion: v1\nkind: Secret\nmetadata:\n name: password-depot-secret\n labels: \n type: password-depot\ntype: Opaque \nstringData:\n username: the-username-for-password-depot\n password: the secret password\n
"},{"location":"provider-passworddepot/#update-secret-store","title":"Update secret store","text":"Be sure the passworddepot
provider is listed in the Kind=SecretStore
and host and database are set.
apiVersion: external-secrets.io/v1alpha1\nkind: ClusterSecretStore\nmetadata:\n name: external-secrets-store\nspec:\n\n # provider field contains the configuration to access the provider\n # which contains the secret exactly one provider must be configured.\n provider:\n\n passworddepot:\n host: host-of-password-depot # port is 8714 by default\n database: \"password depot database name\"\n auth:\n SecretRef:\n credentials:\n name: password-depot-secret\n namespace: external-secrets\n
"},{"location":"provider-passworddepot/#creating-external-secret","title":"Creating external secret","text":"To sync a Password Depot variable to a secret on the Kubernetes cluster, a Kind=ExternalSecret
is needed.
apiVersion: external-secrets.io/v1alpha1\nkind: ExternalSecret\nmetadata:\n name: passworddepot-external-secret-example\nspec:\n refreshInterval: 1h\n\n secretStoreRef:\n kind: SecretStore\n name: passworddepot-secret-store # Must match SecretStore on the cluster\n\n target:\n name: passworddepot-secret-to-create # Name for the secret to be created on the cluster\n creationPolicy: Owner\n\n data:\n - secretKey: username # Key given to the secret to be created on the cluster\n remoteRef: \n key: Production.mySecret\n property: login # field named in passworddepot\n
"},{"location":"provider-passworddepot/#using-datafrom","title":"Using DataFrom","text":"DataFrom can be used to get a variable as a JSON string and attempt to parse it.
apiVersion: external-secrets.io/v1alpha1\nkind: ExternalSecret\nmetadata:\n name: passworddepot-external-secret-example\nspec:\n refreshInterval: 1h\n\n secretStoreRef:\n kind: SecretStore\n name: passworddepot-secret-store # Must match SecretStore on the cluster\n\n target:\n name: passworddepot-secret-to-create # Name for the secret to be created on the cluster\n creationPolicy: Owner\n\n # each property in the secret will be used as the secret key in the SECRET k8s target object\n dataFrom:\n - key: \"Production.mySecret\" # Key of the secret\n
"},{"location":"provider-passworddepot/#getting-the-kubernetes-secret","title":"Getting the Kubernetes secret","text":"The operator will fetch the project variable and inject it as a Kind=Secret
.
kubectl get secret passworddepot-secret-to-create -o jsonpath='{.data.secretKey}' | base64 -d\n
"},{"location":"spec/","title":"API specification","text":"Packages:
- external-secrets.io/v1beta1
"},{"location":"spec/#external-secrets.io/v1beta1","title":"external-secrets.io/v1beta1","text":"
Package v1beta1 contains resources for external-secrets
Resource Types:
"},{"location":"spec/#external-secrets.io/v1beta1.AWSAuth","title":"AWSAuth","text":" (Appears on: AWSProvider)
AWSAuth tells the controller how to do authentication with aws. Only one of secretRef or jwt can be specified. if none is specified the controller will load credentials using the aws sdk defaults.
Field Description secretRef
AWSAuthSecretRef (Optional) jwt
AWSJWTAuth (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.AWSAuthSecretRef","title":"AWSAuthSecretRef","text":" (Appears on: AWSAuth)
AWSAuthSecretRef holds secret references for AWS credentials both AccessKeyID and SecretAccessKey must be defined in order to properly authenticate.
Field Description accessKeyIDSecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector The AccessKeyID is used for authentication
secretAccessKeySecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector The SecretAccessKey is used for authentication
sessionTokenSecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector The SessionToken used for authentication This must be defined if AccessKeyID and SecretAccessKey are temporary credentials see: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html
"},{"location":"spec/#external-secrets.io/v1beta1.AWSJWTAuth","title":"AWSJWTAuth","text":" (Appears on: AWSAuth)
Authenticate against AWS using service account tokens.
Field Description serviceAccountRef
github.com/external-secrets/external-secrets/apis/meta/v1.ServiceAccountSelector"},{"location":"spec/#external-secrets.io/v1beta1.AWSProvider","title":"AWSProvider","text":" (Appears on: SecretStoreProvider)
AWSProvider configures a store to sync secrets with AWS.
Field Description service
AWSServiceType Service defines which service should be used to fetch the secrets
auth
AWSAuth (Optional) Auth defines the information necessary to authenticate against AWS if not set aws sdk will infer credentials from your environment see: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials
role
string (Optional) Role is a Role ARN which the SecretManager provider will assume
region
string AWS Region to be used for the provider
"},{"location":"spec/#external-secrets.io/v1beta1.AWSServiceType","title":"AWSServiceType (string
alias)","text":" (Appears on: AWSProvider)
AWSServiceType is a enum that defines the service/API that is used to fetch the secrets.
Value Description \"ParameterStore\"
AWSServiceParameterStore is the AWS SystemsManager ParameterStore. see: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html
\"SecretsManager\"
AWSServiceSecretsManager is the AWS SecretsManager. see: https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html
"},{"location":"spec/#external-secrets.io/v1alpha1.AlibabaAuth","title":"AlibabaAuth","text":" (Appears on: AlibabaProvider)
AlibabaAuth contains a secretRef for credentials.
Field Description secretRef
AlibabaAuthSecretRef"},{"location":"spec/#external-secrets.io/v1alpha1.AlibabaAuthSecretRef","title":"AlibabaAuthSecretRef","text":" (Appears on: AlibabaAuth)
AlibabaAuthSecretRef holds secret references for Alibaba credentials.
Field Description accessKeyIDSecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector The AccessKeyID is used for authentication
accessKeySecretSecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector The AccessKeySecret is used for authentication
"},{"location":"spec/#external-secrets.io/v1alpha1.AlibabaProvider","title":"AlibabaProvider","text":" (Appears on: SecretStoreProvider)
AlibabaProvider configures a store to sync secrets using the Alibaba Secret Manager provider.
Field Description auth
AlibabaAuth endpoint
string (Optional) regionID
string Alibaba Region to be used for the provider
"},{"location":"spec/#external-secrets.io/v1alpha1.AzureKVAuth","title":"AzureKVAuth","text":" (Appears on: AkeylessProvider)
Field Description secretRef
AkeylessAuthSecretRef (Optional) Reference to a Secret that contains the details to authenticate with Akeyless.
kubernetesAuth
AkeylessKubernetesAuth (Optional) Kubernetes authenticates with Akeyless by passing the ServiceAccount token stored in the named Secret resource.
"},{"location":"spec/#external-secrets.io/v1beta1.AkeylessAuthSecretRef","title":"AkeylessAuthSecretRef","text":" (Appears on: AkeylessAuth)
AkeylessAuthSecretRef AKEYLESS_ACCESS_TYPE_PARAM: AZURE_OBJ_ID OR GCP_AUDIENCE OR ACCESS_KEY OR KUB_CONFIG_NAME.
Field Description accessID
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector The SecretAccessID is used for authentication
accessType
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector accessTypeParam
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector"},{"location":"spec/#external-secrets.io/v1alpha1.CAProvider","title":"CAProvider","text":" (Appears on: VaultProvider)
Defines a location to fetch the cert for the vault provider from.
Field Description type
CAProviderType The type of provider to use such as \u201cSecret\u201d, or \u201cConfigMap\u201d.
name
string The name of the object located at the provider type.
key
string The key the value inside of the provider type to use, only used with \u201cSecret\u201d type
namespace
string The namespace the Provider type is in.
"},{"location":"spec/#external-secrets.io/v1alpha1.CAProviderType","title":"CAProviderType (string
alias)","text":" (Appears on: CAProvider)
Value Description \"ConfigMap\"
\"Secret\"
"},{"location":"spec/#external-secrets.io/v1alpha1.ClusterSecretStore","title":"ClusterSecretStore","text":" (Appears on: AkeylessAuth)
Authenticate with Kubernetes ServiceAccount token stored.
Field Description accessID
string the Akeyless Kubernetes auth-method access-id
k8sConfName
string Kubernetes-auth configuration name in Akeyless-Gateway
serviceAccountRef
github.com/external-secrets/external-secrets/apis/meta/v1.ServiceAccountSelector (Optional) Optional service account field containing the name of a kubernetes ServiceAccount. If the service account is specified, the service account secret token JWT will be used for authenticating with Akeyless. If the service account selector is not supplied, the secretRef will be used instead.
secretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) Optional secret field containing a Kubernetes ServiceAccount JWT used for authenticating with Akeyless. If a name is specified without a key, token
is the default. If one is not specified, the one bound to the controller will be used.
"},{"location":"spec/#external-secrets.io/v1beta1.AkeylessProvider","title":"AkeylessProvider","text":" (Appears on: SecretStoreProvider)
AkeylessProvider Configures an store to sync secrets using Akeyless KV.
Field Description akeylessGWApiURL
string Akeyless GW API Url from which the secrets to be fetched from.
authSecretRef
AkeylessAuth Auth configures how the operator authenticates with Akeyless.
"},{"location":"spec/#external-secrets.io/v1beta1.AlibabaAuth","title":"AlibabaAuth","text":" (Appears on: AlibabaProvider)
AlibabaAuth contains a secretRef for credentials.
Field Description secretRef
AlibabaAuthSecretRef"},{"location":"spec/#external-secrets.io/v1beta1.AlibabaAuthSecretRef","title":"AlibabaAuthSecretRef","text":" (Appears on: AlibabaAuth)
AlibabaAuthSecretRef holds secret references for Alibaba credentials.
Field Description accessKeyIDSecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector The AccessKeyID is used for authentication
accessKeySecretSecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector The AccessKeySecret is used for authentication
"},{"location":"spec/#external-secrets.io/v1beta1.AlibabaProvider","title":"AlibabaProvider","text":" (Appears on: SecretStoreProvider)
AlibabaProvider configures a store to sync secrets using the Alibaba Secret Manager provider.
Field Description auth
AlibabaAuth endpoint
string (Optional) regionID
string Alibaba Region to be used for the provider
"},{"location":"spec/#external-secrets.io/v1beta1.AzureAuthType","title":"AzureAuthType (string
alias)","text":" (Appears on: AzureKVProvider)
AuthType describes how to authenticate to the Azure Keyvault Only one of the following auth types may be specified. If none of the following auth type is specified, the default one is ServicePrincipal.
Value Description \"ManagedIdentity\"
Using Managed Identity to authenticate. Used with aad-pod-identity installed in the cluster.
\"ServicePrincipal\"
Using service principal to authenticate, which needs a tenantId, a clientId and a clientSecret.
\"WorkloadIdentity\"
Using Workload Identity service accounts to authenticate.
"},{"location":"spec/#external-secrets.io/v1beta1.AzureEnvironmentType","title":"AzureEnvironmentType (string
alias)","text":" (Appears on: AzureKVProvider)
AzureEnvironmentType specifies the Azure cloud environment endpoints to use for connecting and authenticating with Azure. By default it points to the public cloud AAD endpoint. The following endpoints are available, also see here: https://github.com/Azure/go-autorest/blob/main/autorest/azure/environments.go#L152 PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud
Value Description \"ChinaCloud\"
\"GermanCloud\"
\"PublicCloud\"
\"USGovernmentCloud\"
"},{"location":"spec/#external-secrets.io/v1beta1.AzureKVAuth","title":"AzureKVAuth","text":" (Appears on: AzureKVProvider)
Configuration used to authenticate with Azure.
Field Description clientId
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) The Azure clientId of the service principle used for authentication.
clientSecret
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) The Azure ClientSecret of the service principle used for authentication.
"},{"location":"spec/#external-secrets.io/v1beta1.AzureKVProvider","title":"AzureKVProvider","text":" (Appears on: SecretStoreProvider)
Configures an store to sync secrets using Azure KV.
Field Description authType
AzureAuthType (Optional) Auth type defines how to authenticate to the keyvault service. Valid values are: - \u201cServicePrincipal\u201d (default): Using a service principal (tenantId, clientId, clientSecret) - \u201cManagedIdentity\u201d: Using Managed Identity assigned to the pod (see aad-pod-identity)
vaultUrl
string Vault Url from which the secrets to be fetched from.
tenantId
string (Optional) TenantID configures the Azure Tenant to send requests to. Required for ServicePrincipal auth type.
environmentType
AzureEnvironmentType EnvironmentType specifies the Azure cloud environment endpoints to use for connecting and authenticating with Azure. By default it points to the public cloud AAD endpoint. The following endpoints are available, also see here: https://github.com/Azure/go-autorest/blob/main/autorest/azure/environments.go#L152 PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud
authSecretRef
AzureKVAuth (Optional) Auth configures how the operator authenticates with Azure. Required for ServicePrincipal auth type.
serviceAccountRef
github.com/external-secrets/external-secrets/apis/meta/v1.ServiceAccountSelector (Optional) ServiceAccountRef specified the service account that should be used when authenticating with WorkloadIdentity.
identityId
string (Optional) If multiple Managed Identity is assigned to the pod, you can select the one to be used
"},{"location":"spec/#external-secrets.io/v1beta1.CAProvider","title":"CAProvider","text":" (Appears on: KubernetesServer, VaultProvider)
Used to provide custom certificate authority (CA) certificates for a secret store. The CAProvider points to a Secret or ConfigMap resource that contains a PEM-encoded certificate.
Field Description type
CAProviderType The type of provider to use such as \u201cSecret\u201d, or \u201cConfigMap\u201d.
name
string The name of the object located at the provider type.
key
string The key where the CA certificate can be found in the Secret or ConfigMap.
namespace
string (Optional) The namespace the Provider type is in. Can only be defined when used in a ClusterSecretStore.
"},{"location":"spec/#external-secrets.io/v1beta1.CAProviderType","title":"CAProviderType (string
alias)","text":" (Appears on: CAProvider)
Value Description \"ConfigMap\"
\"Secret\"
"},{"location":"spec/#external-secrets.io/v1beta1.CertAuth","title":"CertAuth","text":" (Appears on: KubernetesAuth)
Field Description clientCert
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector clientKey
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector"},{"location":"spec/#external-secrets.io/v1beta1.ClusterExternalSecret","title":"ClusterExternalSecret","text":"
ClusterExternalSecret is the Schema for the clusterexternalsecrets API.
Field Description metadata
Kubernetes meta/v1.ObjectMeta Refer to the Kubernetes API documentation for the fields of the metadata
field. spec
ClusterExternalSecretSpec externalSecretSpec
ExternalSecretSpec The spec for the ExternalSecrets to be created
externalSecretName
string (Optional) The name of the external secrets to be created defaults to the name of the ClusterExternalSecret
namespaceSelector
Kubernetes meta/v1.LabelSelector The labels to select by to find the Namespaces to create the ExternalSecrets in.
refreshTime
Kubernetes meta/v1.Duration The time in which the controller should reconcile it\u2019s objects and recheck namespaces for labels.
status
ClusterExternalSecretStatus"},{"location":"spec/#external-secrets.io/v1beta1.ClusterExternalSecretConditionType","title":"ClusterExternalSecretConditionType (string
alias)","text":" (Appears on: ClusterExternalSecretStatusCondition)
Value Description \"NotReady\"
\"PartiallyReady\"
\"Ready\"
"},{"location":"spec/#external-secrets.io/v1beta1.ClusterExternalSecretNamespaceFailure","title":"ClusterExternalSecretNamespaceFailure","text":" (Appears on: ClusterExternalSecretStatus)
ClusterExternalSecretNamespaceFailure represents a failed namespace deployment and it\u2019s reason.
Field Description namespace
string Namespace is the namespace that failed when trying to apply an ExternalSecret
reason
string (Optional) Reason is why the ExternalSecret failed to apply to the namespace
immutable
bool (Optional) Immutable defines if the final secret will be immutable
"},{"location":"spec/#external-secrets.io/v1beta1.ClusterExternalSecretSpec","title":"ClusterExternalSecretSpec","text":" (Appears on: ClusterExternalSecret)
ClusterExternalSecretSpec defines the desired state of ClusterExternalSecret.
Field Description externalSecretSpec
ExternalSecretSpec The spec for the ExternalSecrets to be created
externalSecretName
string (Optional) The name of the external secrets to be created defaults to the name of the ClusterExternalSecret
namespaceSelector
Kubernetes meta/v1.LabelSelector The labels to select by to find the Namespaces to create the ExternalSecrets in.
refreshTime
Kubernetes meta/v1.Duration The time in which the controller should reconcile it\u2019s objects and recheck namespaces for labels.
"},{"location":"spec/#external-secrets.io/v1beta1.ClusterExternalSecretStatus","title":"ClusterExternalSecretStatus","text":" (Appears on: ClusterExternalSecret)
ClusterExternalSecretStatus defines the observed state of ClusterExternalSecret.
Field Description failedNamespaces
[]ClusterExternalSecretNamespaceFailure (Optional) Failed namespaces are the namespaces that failed to apply an ExternalSecret
provisionedNamespaces
[]string (Optional) ProvisionedNamespaces are the namespaces where the ClusterExternalSecret has secrets
conditions
[]ClusterExternalSecretStatusCondition (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.ClusterExternalSecretStatusCondition","title":"ClusterExternalSecretStatusCondition","text":" (Appears on: ClusterExternalSecretStatus)
Field Description type
ClusterExternalSecretConditionType status
Kubernetes core/v1.ConditionStatus message
string (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.ClusterSecretStore","title":"ClusterSecretStore","text":"
ClusterSecretStore represents a secure external location for storing secrets, which can be referenced as part of storeRef
fields.
Field Description metadata
Kubernetes meta/v1.ObjectMeta Refer to the Kubernetes API documentation for the fields of the metadata
field. spec
SecretStoreSpec controller
string (Optional) Used to select the correct KES controller (think: ingress.ingressClassName) The KES controller is instantiated with a specific controller name and filters ES based on this property
provider
SecretStoreProvider Used to configure the provider. Only one provider may be set
retrySettings
SecretStoreRetrySettings (Optional) Used to configure http retries if failed
refreshInterval
int (Optional) Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
conditions
[]ClusterSecretStoreCondition (Optional) Used to constraint a ClusterSecretStore to specific namespaces. Relevant only to ClusterSecretStore
status
SecretStoreStatus"},{"location":"spec/#external-secrets.io/v1beta1.ClusterSecretStoreCondition","title":"ClusterSecretStoreCondition","text":" (Appears on: SecretStoreSpec)
ClusterSecretStoreCondition describes a condition by which to choose namespaces to process ExternalSecrets in for a ClusterSecretStore instance.
Field Description namespaceSelector
Kubernetes meta/v1.LabelSelector (Optional) Choose namespace using a labelSelector
namespaces
[]string Choose namespaces by name
"},{"location":"spec/#external-secrets.io/v1beta1.DopplerAuth","title":"DopplerAuth","text":" (Appears on: DopplerProvider)
Field Description secretRef
DopplerAuthSecretRef"},{"location":"spec/#external-secrets.io/v1beta1.DopplerAuthSecretRef","title":"DopplerAuthSecretRef","text":" (Appears on: DopplerAuth)
Field Description dopplerToken
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector The DopplerToken is used for authentication. See https://docs.doppler.com/reference/api#authentication for auth token types. The Key attribute defaults to dopplerToken if not specified.
"},{"location":"spec/#external-secrets.io/v1beta1.DopplerProvider","title":"DopplerProvider","text":" (Appears on: SecretStoreProvider)
DopplerProvider configures a store to sync secrets using the Doppler provider. Project and Config are required if not using a Service Token.
Field Description auth
DopplerAuth Auth configures how the Operator authenticates with the Doppler API
project
string (Optional) Doppler project (required if not using a Service Token)
config
string (Optional) Doppler config (required if not using a Service Token)
nameTransformer
string (Optional) Environment variable compatible name transforms that change secret names to a different format
format
string (Optional) Format enables the downloading of secrets as a file (string)
"},{"location":"spec/#external-secrets.io/v1alpha1.OracleAuth","title":"OracleAuth","text":" (Appears on: OracleProvider)
Field Description secretRef
OracleSecretRef SecretRef to pass through sensitive information.
"},{"location":"spec/#external-secrets.io/v1alpha1.OracleProvider","title":"OracleProvider","text":" (Appears on: SecretStoreProvider)
Configures an store to sync secrets using a Oracle Vault backend.
Field Description auth
OracleAuth Auth configures how secret-manager authenticates with the Oracle Vault.
user
string User is an access OCID specific to the account.
tenancy
string projectID is an access token specific to the secret.
region
string projectID is an access token specific to the secret.
"},{"location":"spec/#external-secrets.io/v1alpha1.OracleSecretRef","title":"OracleSecretRef","text":" (Appears on: OracleAuth)
Field Description privatekey
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector The Access Token is used for authentication
fingerprint
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector projectID is an access token specific to the secret.
"},{"location":"spec/#external-secrets.io/v1alpha1.PasswordDepotAuth","title":"PasswordDepotAuth","text":" (Appears on: PasswordDepotProvider)
Field Description SecretRef
PasswordDepotSecretRef"},{"location":"spec/#external-secrets.io/v1alpha1.PasswordDepotProvider","title":"PasswordDepotProvider","text":" (Appears on: SecretStoreProvider)
Configures a store to sync secrets with a Password Depot instance.
Field Description host
string URL configures the Password Depot instance URL.
database
string Database to use as source
auth
PasswordDepotAuth Auth configures how secret-manager authenticates with a Password Depot instance.
"},{"location":"spec/#external-secrets.io/v1alpha1.PasswordDepotSecretRef","title":"PasswordDepotSecretRef","text":" (Appears on: PasswordDepotAuth)
Field Description credentials
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector Username / Password is used for authentication.
"},{"location":"spec/#external-secrets.io/v1alpha1.SecretStore","title":"SecretStore","text":"
ExternalSecret is the Schema for the external-secrets API.
Field Description metadata
Kubernetes meta/v1.ObjectMeta Refer to the Kubernetes API documentation for the fields of the metadata
field. spec
ExternalSecretSpec secretStoreRef
SecretStoreRef (Optional) target
ExternalSecretTarget (Optional) refreshInterval
Kubernetes meta/v1.Duration RefreshInterval is the amount of time before the values are read again from the SecretStore provider Valid time units are \u201cns\u201d, \u201cus\u201d (or \u201c\u00b5s\u201d), \u201cms\u201d, \u201cs\u201d, \u201cm\u201d, \u201ch\u201d May be set to zero to fetch and create it once. Defaults to 1h.
data
[]ExternalSecretData (Optional) Data defines the connection between the Kubernetes Secret keys and the Provider data
dataFrom
[]ExternalSecretDataFromRemoteRef (Optional) DataFrom is used to fetch all properties from a specific Provider data If multiple entries are specified, the Secret keys are merged in the specified order
status
ExternalSecretStatus"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretConditionType","title":"ExternalSecretConditionType (string
alias)","text":" (Appears on: ExternalSecretStatusCondition)
Value Description \"Deleted\"
\"Ready\"
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretConversionStrategy","title":"ExternalSecretConversionStrategy (string
alias)","text":" (Appears on: ExternalSecretDataRemoteRef, ExternalSecretFind)
Value Description \"Default\"
\"Unicode\"
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretCreationPolicy","title":"ExternalSecretCreationPolicy (string
alias)","text":" (Appears on: ExternalSecretTarget)
ExternalSecretCreationPolicy defines rules on how to create the resulting Secret.
Value Description \"Merge\"
Merge does not create the Secret, but merges the data fields to the Secret.
\"None\"
None does not create a Secret (future use with injector).
\"Orphan\"
Orphan creates the Secret and does not set the ownerReference. I.e. it will be orphaned after the deletion of the ExternalSecret.
\"Owner\"
Owner creates the Secret and sets .metadata.ownerReferences to the ExternalSecret resource.
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretData","title":"ExternalSecretData","text":" (Appears on: ExternalSecretSpec)
ExternalSecretData defines the connection between the Kubernetes Secret key (spec.data.) and the Provider data. Field Description secretKey
string
SecretKey defines the key in which the controller stores the value. This is the key in the Kind=Secret
remoteRef
ExternalSecretDataRemoteRef RemoteRef points to the remote secret and defines which secret (version/property/..) to fetch.
sourceRef
SourceRef SourceRef allows you to override the source from which the value will pulled from.
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretDataFromRemoteRef","title":"ExternalSecretDataFromRemoteRef","text":" (Appears on: ExternalSecretSpec)
Field Description extract
ExternalSecretDataRemoteRef (Optional) Used to extract multiple key/value pairs from one secret Note: Extract does not support sourceRef.Generator or sourceRef.GeneratorRef.
find
ExternalSecretFind (Optional) Used to find secrets based on tags or regular expressions Note: Find does not support sourceRef.Generator or sourceRef.GeneratorRef.
rewrite
[]ExternalSecretRewrite (Optional) Used to rewrite secret Keys after getting them from the secret Provider Multiple Rewrite operations can be provided. They are applied in a layered order (first to last)
sourceRef
SourceRef SourceRef points to a store or generator which contains secret values ready to use. Use this in combination with Extract or Find pull values out of a specific SecretStore. When sourceRef points to a generator Extract or Find is not supported. The generator returns a static map of values
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretDataRemoteRef","title":"ExternalSecretDataRemoteRef","text":" (Appears on: ExternalSecretData, ExternalSecretDataFromRemoteRef)
ExternalSecretDataRemoteRef defines Provider data location.
Field Description key
string Key is the key used in the Provider, mandatory
metadataPolicy
ExternalSecretMetadataPolicy (Optional) Policy for fetching tags/labels from provider secrets, possible options are Fetch, None. Defaults to None
property
string (Optional) Used to select a specific property of the Provider value (if a map), if supported
version
string (Optional) Used to select a specific version of the Provider value, if supported
conversionStrategy
ExternalSecretConversionStrategy (Optional) Used to define a conversion Strategy
decodingStrategy
ExternalSecretDecodingStrategy (Optional) Used to define a decoding Strategy
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretDecodingStrategy","title":"ExternalSecretDecodingStrategy (string
alias)","text":" (Appears on: ExternalSecretDataRemoteRef, ExternalSecretFind)
Value Description \"Auto\"
\"Base64\"
\"Base64URL\"
\"None\"
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretDeletionPolicy","title":"ExternalSecretDeletionPolicy (string
alias)","text":" (Appears on: ExternalSecretTarget)
ExternalSecretDeletionPolicy defines rules on how to delete the resulting Secret.
Value Description \"Delete\"
Delete deletes the secret if all provider secrets are deleted. If a secret gets deleted on the provider side and is not accessible anymore this is not considered an error and the ExternalSecret does not go into SecretSyncedError status.
\"Merge\"
Merge removes keys in the secret, but not the secret itself. If a secret gets deleted on the provider side and is not accessible anymore this is not considered an error and the ExternalSecret does not go into SecretSyncedError status.
\"Retain\"
Retain will retain the secret if all provider secrets have been deleted. If a provider secret does not exist the ExternalSecret gets into the SecretSyncedError status.
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretFind","title":"ExternalSecretFind","text":" (Appears on: ExternalSecretDataFromRemoteRef)
Field Description path
string (Optional) A root path to start the find operations.
name
FindName (Optional) Finds secrets based on the name.
tags
map[string]string (Optional) Find secrets based on tags.
conversionStrategy
ExternalSecretConversionStrategy (Optional) Used to define a conversion Strategy
decodingStrategy
ExternalSecretDecodingStrategy (Optional) Used to define a decoding Strategy
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretMetadataPolicy","title":"ExternalSecretMetadataPolicy (string
alias)","text":" (Appears on: ExternalSecretDataRemoteRef)
Value Description \"Fetch\"
\"None\"
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretRewrite","title":"ExternalSecretRewrite","text":" (Appears on: ExternalSecretDataFromRemoteRef)
Field Description regexp
ExternalSecretRewriteRegexp (Optional) Used to rewrite with regular expressions. The resulting key will be the output of a regexp.ReplaceAll operation.
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretRewriteRegexp","title":"ExternalSecretRewriteRegexp","text":" (Appears on: ExternalSecretRewrite)
Field Description source
string Used to define the regular expression of a re.Compiler.
target
string Used to define the target pattern of a ReplaceAll operation.
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretSpec","title":"ExternalSecretSpec","text":" (Appears on: ClusterExternalSecretSpec, ExternalSecret)
ExternalSecretSpec defines the desired state of ExternalSecret.
Field Description secretStoreRef
SecretStoreRef (Optional) target
ExternalSecretTarget (Optional) refreshInterval
Kubernetes meta/v1.Duration RefreshInterval is the amount of time before the values are read again from the SecretStore provider Valid time units are \u201cns\u201d, \u201cus\u201d (or \u201c\u00b5s\u201d), \u201cms\u201d, \u201cs\u201d, \u201cm\u201d, \u201ch\u201d May be set to zero to fetch and create it once. Defaults to 1h.
data
[]ExternalSecretData (Optional) Data defines the connection between the Kubernetes Secret keys and the Provider data
dataFrom
[]ExternalSecretDataFromRemoteRef (Optional) DataFrom is used to fetch all properties from a specific Provider data If multiple entries are specified, the Secret keys are merged in the specified order
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretStatus","title":"ExternalSecretStatus","text":" (Appears on: ExternalSecret)
Field Description refreshTime
Kubernetes meta/v1.Time refreshTime is the time and date the external secret was fetched and the target secret updated
syncedResourceVersion
string SyncedResourceVersion keeps track of the last synced version
conditions
[]ExternalSecretStatusCondition (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretStatusCondition","title":"ExternalSecretStatusCondition","text":" (Appears on: ExternalSecretStatus)
Field Description type
ExternalSecretConditionType status
Kubernetes core/v1.ConditionStatus reason
string (Optional) message
string (Optional) lastTransitionTime
Kubernetes meta/v1.Time (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretTarget","title":"ExternalSecretTarget","text":" (Appears on: ExternalSecretSpec)
ExternalSecretTarget defines the Kubernetes Secret to be created There can be only one target per ExternalSecret.
Field Description name
string (Optional) Name defines the name of the Secret resource to be managed This field is immutable Defaults to the .metadata.name of the ExternalSecret resource
creationPolicy
ExternalSecretCreationPolicy (Optional) CreationPolicy defines rules on how to create the resulting Secret Defaults to \u2018Owner\u2019
deletionPolicy
ExternalSecretDeletionPolicy (Optional) DeletionPolicy defines rules on how to delete the resulting Secret Defaults to \u2018Retain\u2019
template
ExternalSecretTemplate (Optional) Template defines a blueprint for the created Secret resource.
immutable
bool (Optional) Immutable defines if the final secret will be immutable
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretTemplate","title":"ExternalSecretTemplate","text":" (Appears on: ExternalSecretTarget)
ExternalSecretTemplate defines a blueprint for the created Secret resource. we can not use native corev1.Secret, it will have empty ObjectMeta values: https://github.com/kubernetes-sigs/controller-tools/issues/448
Field Description type
Kubernetes core/v1.SecretType (Optional) engineVersion
TemplateEngineVersion metadata
ExternalSecretTemplateMetadata (Optional) data
map[string]string (Optional) templateFrom
[]TemplateFrom (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretTemplateMetadata","title":"ExternalSecretTemplateMetadata","text":" (Appears on: ExternalSecretTemplate)
ExternalSecretTemplateMetadata defines metadata fields for the Secret blueprint.
Field Description annotations
map[string]string (Optional) labels
map[string]string (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretValidator","title":"ExternalSecretValidator","text":""},{"location":"spec/#external-secrets.io/v1beta1.FakeProvider","title":"FakeProvider","text":" (Appears on: SecretStoreProvider)
FakeProvider configures a fake provider that returns static values.
Field Description data
[]FakeProviderData"},{"location":"spec/#external-secrets.io/v1beta1.FakeProviderData","title":"FakeProviderData","text":" (Appears on: FakeProvider)
Field Description key
string value
string valueMap
map[string]string version
string"},{"location":"spec/#external-secrets.io/v1beta1.FindName","title":"FindName","text":" (Appears on: ExternalSecretFind)
Field Description regexp
string (Optional) Finds secrets base
"},{"location":"spec/#external-secrets.io/v1beta1.GCPSMAuth","title":"GCPSMAuth","text":" (Appears on: GCPSMProvider)
Field Description secretRef
GCPSMAuthSecretRef (Optional) workloadIdentity
GCPWorkloadIdentity (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.GCPSMAuthSecretRef","title":"GCPSMAuthSecretRef","text":" (Appears on: GCPSMAuth)
Field Description secretAccessKeySecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) The SecretAccessKey is used for authentication
"},{"location":"spec/#external-secrets.io/v1beta1.GCPSMProvider","title":"GCPSMProvider","text":" (Appears on: SecretStoreProvider)
GCPSMProvider Configures a store to sync secrets using the GCP Secret Manager provider.
Field Description auth
GCPSMAuth (Optional) Auth defines the information necessary to authenticate against GCP
projectID
string ProjectID project where secret is located
"},{"location":"spec/#external-secrets.io/v1beta1.GCPWorkloadIdentity","title":"GCPWorkloadIdentity","text":" (Appears on: GCPSMAuth)
Field Description serviceAccountRef
github.com/external-secrets/external-secrets/apis/meta/v1.ServiceAccountSelector clusterLocation
string clusterName
string clusterProjectID
string"},{"location":"spec/#external-secrets.io/v1beta1.GeneratorRef","title":"GeneratorRef","text":" (Appears on: SourceRef)
GeneratorRef points to a generator custom resource.
Field Description apiVersion
string Specify the apiVersion of the generator resource
kind
string Specify the Kind of the resource, e.g. Password, ACRAccessToken etc.
name
string Specify the name of the generator resource
"},{"location":"spec/#external-secrets.io/v1beta1.GenericStore","title":"GenericStore","text":"
GenericStore is a common interface for interacting with ClusterSecretStore or a namespaced SecretStore.
"},{"location":"spec/#external-secrets.io/v1beta1.GenericStoreValidator","title":"GenericStoreValidator","text":""},{"location":"spec/#external-secrets.io/v1beta1.GitlabAuth","title":"GitlabAuth","text":" (Appears on: GitlabProvider)
Field Description SecretRef
GitlabSecretRef"},{"location":"spec/#external-secrets.io/v1beta1.GitlabProvider","title":"GitlabProvider","text":" (Appears on: SecretStoreProvider)
Configures a store to sync secrets with a GitLab instance.
Field Description url
string URL configures the GitLab instance URL. Defaults to https://gitlab.com/.
auth
GitlabAuth Auth configures how secret-manager authenticates with a GitLab instance.
projectID
string ProjectID specifies a project where secrets are located.
inheritFromGroups
bool InheritFromGroups specifies whether parent groups should be discovered and checked for secrets.
groupIDs
[]string GroupIDs specify, which gitlab groups to pull secrets from. Group secrets are read from left to right followed by the project variables.
environment
string Environment environment_scope of gitlab CI/CD variables (Please see https://docs.gitlab.com/ee/ci/environments/#create-a-static-environment on how to create environments)
"},{"location":"spec/#external-secrets.io/v1beta1.GitlabSecretRef","title":"GitlabSecretRef","text":" (Appears on: GitlabAuth)
Field Description accessToken
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector AccessToken is used for authentication.
"},{"location":"spec/#external-secrets.io/v1beta1.IBMAuth","title":"IBMAuth","text":" (Appears on: IBMProvider)
Field Description secretRef
IBMAuthSecretRef containerAuth
IBMAuthContainerAuth"},{"location":"spec/#external-secrets.io/v1beta1.IBMAuthContainerAuth","title":"IBMAuthContainerAuth","text":" (Appears on: IBMAuth)
IBM Container-based auth with IAM Trusted Profile.
Field Description profile
string the IBM Trusted Profile
tokenLocation
string Location the token is mounted on the pod
iamEndpoint
string"},{"location":"spec/#external-secrets.io/v1beta1.IBMAuthSecretRef","title":"IBMAuthSecretRef","text":" (Appears on: IBMAuth)
Field Description secretApiKeySecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector The SecretAccessKey is used for authentication
"},{"location":"spec/#external-secrets.io/v1beta1.IBMProvider","title":"IBMProvider","text":" (Appears on: SecretStoreProvider)
Configures an store to sync secrets using a IBM Cloud Secrets Manager backend.
Field Description auth
IBMAuth Auth configures how secret-manager authenticates with the IBM secrets manager.
serviceUrl
string ServiceURL is the Endpoint URL that is specific to the Secrets Manager service instance
"},{"location":"spec/#external-secrets.io/v1beta1.KubernetesAuth","title":"KubernetesAuth","text":" (Appears on: KubernetesProvider)
Field Description cert
CertAuth (Optional) has both clientCert and clientKey as secretKeySelector
token
TokenAuth (Optional) use static token to authenticate with
serviceAccount
github.com/external-secrets/external-secrets/apis/meta/v1.ServiceAccountSelector (Optional) points to a service account that should be used for authentication
"},{"location":"spec/#external-secrets.io/v1beta1.KubernetesProvider","title":"KubernetesProvider","text":" (Appears on: SecretStoreProvider)
Configures a store to sync secrets with a Kubernetes instance.
Field Description server
KubernetesServer configures the Kubernetes server Address.
auth
KubernetesAuth Auth configures how secret-manager authenticates with a Kubernetes instance.
remoteNamespace
string (Optional) Remote namespace to fetch the secrets from
"},{"location":"spec/#external-secrets.io/v1beta1.KubernetesServer","title":"KubernetesServer","text":" (Appears on: KubernetesProvider)
Field Description url
string (Optional) configures the Kubernetes server Address.
caBundle
[]byte (Optional) CABundle is a base64-encoded CA certificate
caProvider
CAProvider (Optional) see: https://external-secrets.io/v0.4.1/spec/#external-secrets.io/v1alpha1.CAProvider
"},{"location":"spec/#external-secrets.io/v1beta1.NoSecretError","title":"NoSecretError","text":"
NoSecretError shall be returned when a GetSecret can not find the desired secret. This is used for deletionPolicy.
"},{"location":"spec/#external-secrets.io/v1beta1.OnePasswordAuth","title":"OnePasswordAuth","text":" (Appears on: OnePasswordProvider)
OnePasswordAuth contains a secretRef for credentials.
Field Description secretRef
OnePasswordAuthSecretRef"},{"location":"spec/#external-secrets.io/v1beta1.OnePasswordAuthSecretRef","title":"OnePasswordAuthSecretRef","text":" (Appears on: OnePasswordAuth)
OnePasswordAuthSecretRef holds secret references for 1Password credentials.
Field Description connectTokenSecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector The ConnectToken is used for authentication to a 1Password Connect Server.
"},{"location":"spec/#external-secrets.io/v1beta1.OnePasswordProvider","title":"OnePasswordProvider","text":" (Appears on: SecretStoreProvider)
OnePasswordProvider configures a store to sync secrets using the 1Password Secret Manager provider.
Field Description auth
OnePasswordAuth Auth defines the information necessary to authenticate against OnePassword Connect Server
connectHost
string ConnectHost defines the OnePassword Connect Server to connect to
vaults
map[string]int Vaults defines which OnePassword vaults to search in which order
"},{"location":"spec/#external-secrets.io/v1beta1.OracleAuth","title":"OracleAuth","text":" (Appears on: OracleProvider)
Field Description tenancy
string Tenancy is the tenancy OCID where user is located.
user
string User is an access OCID specific to the account.
secretRef
OracleSecretRef SecretRef to pass through sensitive information.
"},{"location":"spec/#external-secrets.io/v1beta1.OracleProvider","title":"OracleProvider","text":" (Appears on: SecretStoreProvider)
Configures an store to sync secrets using a Oracle Vault backend.
Field Description region
string Region is the region where vault is located.
vault
string Vault is the vault\u2019s OCID of the specific vault where secret is located.
auth
OracleAuth (Optional) Auth configures how secret-manager authenticates with the Oracle Vault. If empty, use the instance principal, otherwise the user credentials specified in Auth.
"},{"location":"spec/#external-secrets.io/v1beta1.OracleSecretRef","title":"OracleSecretRef","text":" (Appears on: OracleAuth)
Field Description privatekey
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector PrivateKey is the user\u2019s API Signing Key in PEM format, used for authentication.
fingerprint
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector Fingerprint is the fingerprint of the API private key.
"},{"location":"spec/#external-secrets.io/v1beta1.Provider","title":"Provider","text":"
Provider is a common interface for interacting with secret backends.
"},{"location":"spec/#external-secrets.io/v1beta1.SecretStore","title":"SecretStore","text":"
SecretStore represents a secure external location for storing secrets, which can be referenced as part of storeRef
fields.
Field Description metadata
Kubernetes meta/v1.ObjectMeta Refer to the Kubernetes API documentation for the fields of the metadata
field. spec
SecretStoreSpec controller
string (Optional) Used to select the correct KES controller (think: ingress.ingressClassName) The KES controller is instantiated with a specific controller name and filters ES based on this property
provider
SecretStoreProvider Used to configure the provider. Only one provider may be set
retrySettings
SecretStoreRetrySettings (Optional) Used to configure http retries if failed
refreshInterval
int (Optional) Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
conditions
[]ClusterSecretStoreCondition (Optional) Used to constraint a ClusterSecretStore to specific namespaces. Relevant only to ClusterSecretStore
status
SecretStoreStatus"},{"location":"spec/#external-secrets.io/v1beta1.SecretStoreConditionType","title":"SecretStoreConditionType (string
alias)","text":" (Appears on: SecretStoreStatusCondition)
Value Description \"Ready\"
"},{"location":"spec/#external-secrets.io/v1beta1.SecretStoreProvider","title":"SecretStoreProvider","text":" (Appears on: SecretStoreSpec)
SecretStoreProvider contains the provider-specific configuration.
Field Description aws
AWSProvider (Optional) AWS configures this store to sync secrets using AWS Secret Manager provider
azurekv
AzureKVProvider (Optional) AzureKV configures this store to sync secrets using Azure Key Vault provider
akeyless
AkeylessProvider (Optional) Akeyless configures this store to sync secrets using Akeyless Vault provider
vault
VaultProvider (Optional) Vault configures this store to sync secrets using Hashi provider
gcpsm
GCPSMProvider (Optional) GCPSM configures this store to sync secrets using Google Cloud Platform Secret Manager provider
oracle
OracleProvider (Optional) Oracle configures this store to sync secrets using Oracle Vault provider
ibm
IBMProvider (Optional) IBM configures this store to sync secrets using IBM Cloud provider
yandexcertificatemanager
YandexCertificateManagerProvider (Optional) YandexCertificateManager configures this store to sync secrets using Yandex Certificate Manager provider
yandexlockbox
YandexLockboxProvider (Optional) YandexLockbox configures this store to sync secrets using Yandex Lockbox provider
gitlab
GitlabProvider (Optional) GitLab configures this store to sync secrets using GitLab Variables provider
alibaba
AlibabaProvider (Optional) Alibaba configures this store to sync secrets using Alibaba Cloud provider
onepassword
OnePasswordProvider (Optional) OnePassword configures this store to sync secrets using the 1Password Cloud provider
webhook
WebhookProvider (Optional) Webhook configures this store to sync secrets using a generic templated webhook
kubernetes
KubernetesProvider (Optional) Kubernetes configures this store to sync secrets using a Kubernetes cluster provider
fake
FakeProvider (Optional) Fake configures a store with static key/value pairs
senhasegura
SenhaseguraProvider (Optional) Senhasegura configures this store to sync secrets using senhasegura provider
doppler
DopplerProvider (Optional) Doppler configures this store to sync secrets using the Doppler provider
"},{"location":"spec/#external-secrets.io/v1beta1.SecretStoreRef","title":"SecretStoreRef","text":" (Appears on: ExternalSecretSpec, SourceRef)
SecretStoreRef defines which SecretStore to fetch the ExternalSecret data.
Field Description name
string Name of the SecretStore resource
kind
string (Optional) Kind of the SecretStore resource (SecretStore or ClusterSecretStore) Defaults to SecretStore
"},{"location":"spec/#external-secrets.io/v1beta1.SecretStoreRetrySettings","title":"SecretStoreRetrySettings","text":" (Appears on: SecretStoreSpec)
Field Description maxRetries
int32 retryInterval
string"},{"location":"spec/#external-secrets.io/v1beta1.SecretStoreSpec","title":"SecretStoreSpec","text":" (Appears on: ClusterSecretStore, SecretStore)
SecretStoreSpec defines the desired state of SecretStore.
Field Description controller
string (Optional) Used to select the correct KES controller (think: ingress.ingressClassName) The KES controller is instantiated with a specific controller name and filters ES based on this property
provider
SecretStoreProvider Used to configure the provider. Only one provider may be set
retrySettings
SecretStoreRetrySettings (Optional) Used to configure http retries if failed
refreshInterval
int (Optional) Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
conditions
[]ClusterSecretStoreCondition (Optional) Used to constraint a ClusterSecretStore to specific namespaces. Relevant only to ClusterSecretStore
"},{"location":"spec/#external-secrets.io/v1beta1.SecretStoreStatus","title":"SecretStoreStatus","text":" (Appears on: ClusterSecretStore, SecretStore)
SecretStoreStatus defines the observed state of the SecretStore.
Field Description conditions
[]SecretStoreStatusCondition (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.SecretStoreStatusCondition","title":"SecretStoreStatusCondition","text":" (Appears on: SecretStoreStatus)
Field Description type
SecretStoreConditionType status
Kubernetes core/v1.ConditionStatus reason
string (Optional) message
string (Optional) lastTransitionTime
Kubernetes meta/v1.Time (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.SecretsClient","title":"SecretsClient","text":"
SecretsClient provides access to secrets.
"},{"location":"spec/#external-secrets.io/v1beta1.SenhaseguraAuth","title":"SenhaseguraAuth","text":" (Appears on: SenhaseguraProvider)
SenhaseguraAuth tells the controller how to do auth in senhasegura.
Field Description clientId
string clientSecretSecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector"},{"location":"spec/#external-secrets.io/v1beta1.SenhaseguraModuleType","title":"SenhaseguraModuleType (string
alias)","text":" (Appears on: SenhaseguraProvider)
SenhaseguraModuleType enum defines senhasegura target module to fetch secrets
Value Description \"DSM\"
SenhaseguraModuleDSM is the senhasegura DevOps Secrets Management module\nsee: https://senhasegura.com/devops\n
"},{"location":"spec/#external-secrets.io/v1beta1.SenhaseguraProvider","title":"SenhaseguraProvider","text":" (Appears on: SecretStoreProvider)
SenhaseguraProvider setup a store to sync secrets with senhasegura.
Field Description url
string URL of senhasegura
module
SenhaseguraModuleType Module defines which senhasegura module should be used to get secrets
auth
SenhaseguraAuth Auth defines parameters to authenticate in senhasegura
ignoreSslCertificate
bool IgnoreSslCertificate defines if SSL certificate must be ignored
"},{"location":"spec/#external-secrets.io/v1beta1.SourceRef","title":"SourceRef","text":" (Appears on: ExternalSecretData, ExternalSecretDataFromRemoteRef)
SourceRef allows you to override the source from which the secret will be pulled from. You can define at maximum one property.
Field Description storeRef
SecretStoreRef (Optional) generatorRef
GeneratorRef (Optional) GeneratorRef points to a generator custom resource in
"},{"location":"spec/#external-secrets.io/v1beta1.TemplateEngineVersion","title":"TemplateEngineVersion (string
alias)","text":" (Appears on: ExternalSecretTemplate)
Value Description \"v1\"
\"v2\"
"},{"location":"spec/#external-secrets.io/v1beta1.TemplateFrom","title":"TemplateFrom","text":" (Appears on: ExternalSecretTemplate)
Field Description configMap
TemplateRef secret
TemplateRef scope
TemplateScope (Optional) target
TemplateTarget (Optional) literal
string (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.TemplateRef","title":"TemplateRef","text":" (Appears on: TemplateFrom)
Field Description name
string items
[]TemplateRefItem"},{"location":"spec/#external-secrets.io/v1beta1.TemplateRefItem","title":"TemplateRefItem","text":" (Appears on: TemplateRef)
Field Description key
string"},{"location":"spec/#external-secrets.io/v1beta1.TemplateScope","title":"TemplateScope (string
alias)","text":" (Appears on: TemplateFrom)
Value Description \"KeysAndValues\"
\"Values\"
"},{"location":"spec/#external-secrets.io/v1beta1.TemplateTarget","title":"TemplateTarget (string
alias)","text":" (Appears on: TemplateFrom)
Value Description \"Annotations\"
\"Data\"
\"Labels\"
\"StringData\"
"},{"location":"spec/#external-secrets.io/v1beta1.TokenAuth","title":"TokenAuth","text":" (Appears on: KubernetesAuth)
Field Description bearerToken
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector"},{"location":"spec/#external-secrets.io/v1beta1.ValidationResult","title":"ValidationResult (byte
alias)","text":"Value Description 2
Error indicates that there is a misconfiguration.
0
Ready indicates that the client is configured correctly and can be used.
1
Unknown indicates that the client can be used but information is missing and it can not be validated.
"},{"location":"spec/#external-secrets.io/v1beta1.VaultAppRole","title":"VaultAppRole","text":" (Appears on: VaultAuth)
VaultAppRole authenticates with Vault using the App Role auth mechanism, with the role and secret stored in a Kubernetes Secret resource.
Field Description path
string Path where the App Role authentication backend is mounted in Vault, e.g: \u201capprole\u201d
roleId
string RoleID configured in the App Role authentication backend when setting up the authentication backend in Vault.
secretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector Reference to a key in a Secret that contains the App Role secret used to authenticate with Vault. The key
field must be specified and denotes which entry within the Secret resource is used as the app role secret.
"},{"location":"spec/#external-secrets.io/v1beta1.VaultAuth","title":"VaultAuth","text":" (Appears on: VaultProvider)
VaultAuth is the configuration used to authenticate with a Vault server. Only one of tokenSecretRef
, appRole
, kubernetes
, ldap
, userPass
, jwt
or cert
can be specified.
Field Description tokenSecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) TokenSecretRef authenticates with Vault by presenting a token.
appRole
VaultAppRole (Optional) AppRole authenticates with Vault using the App Role auth mechanism, with the role and secret stored in a Kubernetes Secret resource.
kubernetes
VaultKubernetesAuth (Optional) Kubernetes authenticates with Vault by passing the ServiceAccount token stored in the named Secret resource to the Vault server.
ldap
VaultLdapAuth (Optional) Ldap authenticates with Vault by passing username/password pair using the LDAP authentication method
userPass
VaultUserPassAuth (Optional) UserPass authenticates with Vault by passing username/password pair using the userPass authentication method
jwt
VaultJwtAuth (Optional) Jwt authenticates with Vault by passing role and JWT token using the JWT/OIDC authentication method
cert
VaultCertAuth (Optional) Cert authenticates with TLS Certificates by passing client certificate, private key and ca certificate Cert authentication method
"},{"location":"spec/#external-secrets.io/v1beta1.VaultCertAuth","title":"VaultCertAuth","text":" (Appears on: VaultAuth)
VaultJwtAuth authenticates with Vault using the JWT/OIDC authentication method, with the role name and token stored in a Kubernetes Secret resource.
Field Description clientCert
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) ClientCert is a certificate to authenticate using the Cert Vault authentication method
secretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector SecretRef to a key in a Secret resource containing client private key to authenticate with Vault using the Cert authentication method
"},{"location":"spec/#external-secrets.io/v1beta1.VaultJwtAuth","title":"VaultJwtAuth","text":" (Appears on: VaultAuth)
VaultJwtAuth authenticates with Vault using the JWT/OIDC authentication method, with the role name and a token stored in a Kubernetes Secret resource or a Kubernetes service account token retrieved via TokenRequest
.
Field Description path
string Path where the JWT authentication backend is mounted in Vault, e.g: \u201cjwt\u201d
role
string (Optional) Role is a JWT role to authenticate using the JWT/OIDC Vault authentication method
secretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) Optional SecretRef that refers to a key in a Secret resource containing JWT token to authenticate with Vault using the JWT/OIDC authentication method.
kubernetesServiceAccountToken
VaultKubernetesServiceAccountTokenAuth (Optional) Optional ServiceAccountToken specifies the Kubernetes service account for which to request a token for with the TokenRequest
API.
"},{"location":"spec/#external-secrets.io/v1beta1.VaultKVStoreVersion","title":"VaultKVStoreVersion (string
alias)","text":" (Appears on: VaultProvider)
Value Description \"v1\"
\"v2\"
"},{"location":"spec/#external-secrets.io/v1beta1.VaultKubernetesAuth","title":"VaultKubernetesAuth","text":" (Appears on: VaultAuth)
Authenticate against Vault using a Kubernetes ServiceAccount token stored in a Secret.
Field Description mountPath
string Path where the Kubernetes authentication backend is mounted in Vault, e.g: \u201ckubernetes\u201d
serviceAccountRef
github.com/external-secrets/external-secrets/apis/meta/v1.ServiceAccountSelector (Optional) Optional service account field containing the name of a kubernetes ServiceAccount. If the service account is specified, the service account secret token JWT will be used for authenticating with Vault. If the service account selector is not supplied, the secretRef will be used instead.
secretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) Optional secret field containing a Kubernetes ServiceAccount JWT used for authenticating with Vault. If a name is specified without a key, token
is the default. If one is not specified, the one bound to the controller will be used.
role
string A required field containing the Vault Role to assume. A Role binds a Kubernetes ServiceAccount with a set of Vault policies.
"},{"location":"spec/#external-secrets.io/v1beta1.VaultKubernetesServiceAccountTokenAuth","title":"VaultKubernetesServiceAccountTokenAuth","text":" (Appears on: VaultJwtAuth)
VaultKubernetesServiceAccountTokenAuth authenticates with Vault using a temporary Kubernetes service account token retrieved by the TokenRequest
API.
Field Description oracle
OracleProvider (Optional) Oracle configures this store to sync secrets using Oracle Vault provider
ibm
github.com/external-secrets/external-secrets/apis/meta/v1.ServiceAccountSelector Service account field containing the name of a kubernetes ServiceAccount.
audiences
[]string (Optional) Optional audiences field that will be used to request a temporary Kubernetes service account token for the service account referenced by serviceAccountRef
. Defaults to a single audience vault
it not specified. Deprecated: use serviceAccountRef.Audiences instead
expirationSeconds
int64 (Optional) Optional expiration time in seconds that will be used to request a temporary Kubernetes service account token for the service account referenced by serviceAccountRef
. Deprecated: this will be removed in the future. Defaults to 10 minutes.
alibaba
AlibabaProvider (Optional) Alibaba configures this store to sync secrets using Alibaba Cloud provider
passworddepot
PasswordDepotProvider (Optional) PasswordDepot configures this store to sync secrets using PasswordDepot provider
"},{"location":"spec/#external-secrets.io/v1beta1.VaultLdapAuth","title":"VaultLdapAuth","text":" (Appears on: VaultAuth)
VaultLdapAuth authenticates with Vault using the LDAP authentication method, with the username and password stored in a Kubernetes Secret resource.
Field Description path
string Path where the LDAP authentication backend is mounted in Vault, e.g: \u201cldap\u201d
username
string Username is a LDAP user name used to authenticate using the LDAP Vault authentication method
secretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector SecretRef to a key in a Secret resource containing password for the LDAP user used to authenticate with Vault using the LDAP authentication method
"},{"location":"spec/#external-secrets.io/v1beta1.VaultUserPassAuth","title":"VaultUserPassAuth","text":" (Appears on: VaultAuth)
VaultUserPassAuth authenticates with Vault using the UserPass authentication method, with the username and password stored in a Kubernetes Secret resource.
Field Description path
string Path where the UserPass authentication backend is mounted in Vault, e.g: \u201cuserpass\u201d
username
string Username is a user name used to authenticate using the UserPass Vault authentication method
secretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector SecretRef to a key in a Secret resource containing password for the user used to authenticate with Vault using the UserPass authentication method
"},{"location":"spec/#external-secrets.io/v1beta1.VaultProvider","title":"VaultProvider","text":" (Appears on: SecretStoreProvider)
Configures an store to sync secrets using a HashiCorp Vault KV backend.
Field Description auth
VaultAuth Auth configures how secret-manager authenticates with the Vault server.
server
string Server is the connection address for the Vault server, e.g: \u201chttps://vault.example.com:8200\u201d.
path
string (Optional) Path is the mount path of the Vault KV backend endpoint, e.g: \u201csecret\u201d. The v2 KV secret engine version specific \u201c/data\u201d path suffix for fetching secrets from Vault is optional and will be appended if not present in specified path.
version
VaultKVStoreVersion Version is the Vault KV secret engine version. This can be either \u201cv1\u201d or \u201cv2\u201d. Version defaults to \u201cv2\u201d.
namespace
string (Optional) Name of the vault namespace. Namespaces is a set of features within Vault Enterprise that allows Vault environments to support Secure Multi-tenancy. e.g: \u201cns1\u201d. More about namespaces can be found here https://www.vaultproject.io/docs/enterprise/namespaces
caBundle
[]byte (Optional) PEM encoded CA bundle used to validate Vault server certificate. Only used if the Server URL is using HTTPS protocol. This parameter is ignored for plain HTTP protocol connection. If not set the system root certificates are used to validate the TLS connection.
caProvider
CAProvider (Optional) The provider for the CA bundle to use to validate Vault server certificate.
readYourWrites
bool (Optional) ReadYourWrites ensures isolated read-after-write semantics by providing discovered cluster replication states in each request. More information about eventual consistency in Vault can be found here https://www.vaultproject.io/docs/enterprise/consistency
forwardInconsistent
bool (Optional) ForwardInconsistent tells Vault to forward read-after-write requests to the Vault leader instead of simply retrying within a loop. This can increase performance if the option is enabled serverside. https://www.vaultproject.io/docs/configuration/replication#allow_forwarding_via_header
"},{"location":"spec/#external-secrets.io/v1beta1.WebhookCAProvider","title":"WebhookCAProvider","text":" (Appears on: WebhookProvider)
Defines a location to fetch the cert for the webhook provider from.
Field Description type
WebhookCAProviderType The type of provider to use such as \u201cSecret\u201d, or \u201cConfigMap\u201d.
name
string The name of the object located at the provider type.
key
string The key the value inside of the provider type to use, only used with \u201cSecret\u201d type
namespace
string (Optional) The namespace the Provider type is in.
"},{"location":"spec/#external-secrets.io/v1beta1.WebhookCAProviderType","title":"WebhookCAProviderType (string
alias)","text":" (Appears on: WebhookCAProvider)
Value Description \"ConfigMap\"
\"Secret\"
"},{"location":"spec/#external-secrets.io/v1beta1.WebhookProvider","title":"WebhookProvider","text":" (Appears on: SecretStoreProvider)
AkeylessProvider Configures an store to sync secrets using Akeyless KV.
Field Description method
string Webhook Method
url
string Webhook url to call
headers
map[string]string (Optional) Headers
body
string (Optional) Body
timeout
Kubernetes meta/v1.Duration (Optional) Timeout
result
WebhookResult Result formatting
secrets
[]WebhookSecret (Optional) Secrets to fill in templates These secrets will be passed to the templating function as key value pairs under the given name
caBundle
[]byte (Optional) PEM encoded CA bundle used to validate webhook server certificate. Only used if the Server URL is using HTTPS protocol. This parameter is ignored for plain HTTP protocol connection. If not set the system root certificates are used to validate the TLS connection.
caProvider
WebhookCAProvider (Optional) The provider for the CA bundle to use to validate webhook server certificate.
"},{"location":"spec/#external-secrets.io/v1beta1.WebhookResult","title":"WebhookResult","text":" (Appears on: WebhookProvider)
Field Description jsonPath
string (Optional) Json path of return value
"},{"location":"spec/#external-secrets.io/v1beta1.WebhookSecret","title":"WebhookSecret","text":" (Appears on: WebhookProvider)
Field Description name
string Name of this secret in templates
secretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector Secret ref to fill in credentials
"},{"location":"spec/#external-secrets.io/v1beta1.YandexCertificateManagerAuth","title":"YandexCertificateManagerAuth","text":" (Appears on: YandexCertificateManagerProvider)
Field Description authorizedKeySecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) The authorized key used for authentication
"},{"location":"spec/#external-secrets.io/v1beta1.YandexCertificateManagerCAProvider","title":"YandexCertificateManagerCAProvider","text":" (Appears on: YandexCertificateManagerProvider)
Field Description certSecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector"},{"location":"spec/#external-secrets.io/v1beta1.YandexCertificateManagerProvider","title":"YandexCertificateManagerProvider","text":" (Appears on: SecretStoreProvider)
YandexCertificateManagerProvider Configures a store to sync secrets using the Yandex Certificate Manager provider.
Field Description apiEndpoint
string (Optional) Yandex.Cloud API endpoint (e.g. \u2018api.cloud.yandex.net:443\u2019)
auth
YandexCertificateManagerAuth Auth defines the information necessary to authenticate against Yandex Certificate Manager
caProvider
YandexCertificateManagerCAProvider (Optional) The provider for the CA bundle to use to validate Yandex.Cloud server certificate.
"},{"location":"spec/#external-secrets.io/v1beta1.YandexLockboxAuth","title":"YandexLockboxAuth","text":" (Appears on: YandexLockboxProvider)
Field Description authorizedKeySecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) The authorized key used for authentication
caProvider
CAProvider (Optional) The provider for the CA bundle to use to validate Vault server certificate.
"},{"location":"spec/#external-secrets.io/v1beta1.YandexLockboxCAProvider","title":"YandexLockboxCAProvider","text":" (Appears on: YandexLockboxProvider)
Field Description certSecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector"},{"location":"spec/#external-secrets.io/v1beta1.YandexLockboxProvider","title":"YandexLockboxProvider","text":" (Appears on: SecretStoreProvider)
YandexLockboxProvider Configures a store to sync secrets using the Yandex Lockbox provider.
Field Description apiEndpoint
string (Optional) Yandex.Cloud API endpoint (e.g. \u2018api.cloud.yandex.net:443\u2019)
auth
YandexLockboxAuth Auth defines the information necessary to authenticate against Yandex Lockbox
caProvider
YandexLockboxCAProvider (Optional) The provider for the CA bundle to use to validate Yandex.Cloud server certificate.
Generated with gen-crd-api-reference-docs
.
"},{"location":"api/clusterexternalsecret/","title":"ClusterExternalSecret","text":"The ClusterExternalSecret
is a cluster scoped resource that can be used to manage ExternalSecret
resources in specific namespaces.
With namespaceSelector
you can select namespaces in which the ExternalSecret should be created. If there is a conflict with an existing resource the controller will error out.
"},{"location":"api/clusterexternalsecret/#example","title":"Example","text":"Below is an example of the ClusterExternalSecret
in use.
apiVersion: external-secrets.io/v1beta1\nkind: ClusterExternalSecret\nmetadata:\n name: \"hello-world\"\nspec:\n # The name to be used on the ExternalSecrets\n externalSecretName: \"hello-world-es\"\n\n # This is a basic label selector to select the namespaces to deploy ExternalSecrets to.\n # you can read more about them here https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#resources-that-support-set-based-requirements\n namespaceSelector:\n matchLabels: \n cool: label\n\n # How often the ClusterExternalSecret should reconcile itself\n # This will decide how often to check and make sure that the ExternalSecrets exist in the matching namespaces\n refreshTime: \"1m\"\n\n # This is the spec of the ExternalSecrets to be created\n # The content of this was taken from our ExternalSecret example\n externalSecretSpec:\n secretStoreRef:\n name: secret-store-name\n kind: SecretStore\n\n refreshInterval: \"1h\"\n target:\n name: my-secret\n creationPolicy: 'Merge'\n template:\n type: kubernetes.io/dockerconfigjson\n\n metadata:\n annotations: {}\n labels: {}\n data:\n config.yml: |\n endpoints:\n - https://{{ .data.user }}:{{ .data.password }}@api.exmaple.com\n templateFrom:\n - configMap:\n name: alertmanager\n items:\n - key: alertmanager.yaml\n data:\n - secretKey: secret-key-to-be-managed\n remoteRef:\n key: provider-key\n version: provider-key-version\n property: provider-key-property\n dataFrom:\n - key: provider-key\n version: provider-key-version\n property: provider-key-property\n\nstatus:\n # This will list any namespaces where the creation of the ExternalSecret failed\n # This will not list any issues with the ExternalSecrets, you will have to check the\n # ExternalSecrets to see any issues with them.\n failedNamespaces:\n - namespace: \"matching-ns-1\"\n # This is one of the possible messages, and likely the most common\n reason: \"external secret already exists in namespace\"\n\n # You can find all matching and successfully deployed namespaces here\n provisionedNamespaces:\n - \"matching-ns-3\"\n - \"matching-ns-2\"\n\n # The condition can be Ready, PartiallyReady, or NotReady \n # PartiallyReady would indicate an error in 1 or more namespaces\n # NotReady would indicate errors in all namespaces meaning all ExternalSecrets resulted in errors\n conditions:\n - type: PartiallyReady\n status: \"True\"\n lastTransitionTime: \"2022-01-12T12:33:02Z\"\n
"},{"location":"api/clustersecretstore/","title":"ClusterSecretStore","text":"The ClusterSecretStore
is a cluster scoped SecretStore that can be referenced by all ExternalSecrets
from all namespaces. Use it to offer a central gateway to your secret backend.
"},{"location":"api/clustersecretstore/#example","title":"Example","text":"For a full list of supported fields see spec or dig into our guides.
apiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\n name: example\nspec:\n # Used to select the correct ESO controller (think: ingress.ingressClassName)\n # The ESO controller is instantiated with a specific controller name\n # and filters ES based on this property\n # Optional\n controller: dev\n\n # provider field contains the configuration to access the provider\n # which contains the secret exactly one provider must be configured.\n provider:\n # (1): AWS Secrets Manager\n # aws configures this store to sync secrets using AWS Secret Manager provider\n aws:\n service: SecretsManager\n # Role is a Role ARN which the SecretManager provider will assume\n role: iam-role\n # AWS Region to be used for the provider\n region: eu-central-1\n # Auth defines the information necessary to authenticate against AWS\n auth:\n # Getting the accessKeyID and secretAccessKey from an already created Kubernetes Secret\n secretRef:\n accessKeyIDSecretRef:\n name: awssm-secret\n key: access-key\n secretAccessKeySecretRef:\n name: awssm-secret\n key: secret-access-key\n # IAM roles for service accounts\n # https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-technical-overview.html\n jwt:\n serviceAccountRef:\n name: my-serviceaccount\n namespace: sa-namespace\n\n vault:\n server: \"https://vault.acme.org\"\n # Path is the mount path of the Vault KV backend endpoint\n # Used as a path prefix for the external secret key\n path: \"secret\"\n # Version is the Vault KV secret engine version.\n # This can be either \"v1\" or \"v2\", defaults to \"v2\"\n version: \"v2\"\n # vault enterprise namespace: https://www.vaultproject.io/docs/enterprise/namespaces\n namespace: \"a-team\"\n # base64 encoded string of certificate\n caBundle: \"...\"\n # Instead of caBundle you can also specify a caProvider\n # this will retrieve the cert from a Secret or ConfigMap\n caProvider:\n # Can be Secret or ConfigMap\n type: \"Secret\"\n # namespace is mandatory for ClusterSecretStore and not relevant for SecretStore\n namespace: \"my-cert-secret-namespace\"\n name: \"my-cert-secret\"\n key: \"cert-key\"\n auth:\n # static token: https://www.vaultproject.io/docs/auth/token\n tokenSecretRef:\n name: \"my-secret\"\n namespace: \"secret-admin\"\n key: \"vault-token\"\n\n # AppRole auth: https://www.vaultproject.io/docs/auth/approle\n appRole:\n path: \"approle\"\n roleId: \"db02de05-fa39-4855-059b-67221c5c2f63\"\n secretRef:\n name: \"my-secret\"\n namespace: \"secret-admin\"\n key: \"vault-token\"\n\n # Kubernetes auth: https://www.vaultproject.io/docs/auth/kubernetes\n kubernetes:\n mountPath: \"kubernetes\"\n role: \"demo\"\n # Optional service account reference\n serviceAccountRef:\n name: \"my-sa\"\n namespace: \"secret-admin\"\n # Optional secret field containing a Kubernetes ServiceAccount JWT\n # used for authenticating with Vault\n secretRef:\n name: \"my-secret\"\n namespace: \"secret-admin\"\n key: \"vault\"\n\n # (2): GCP Secret Manager\n gcpsm:\n # Auth defines the information necessary to authenticate against GCP by getting\n # the credentials from an already created Kubernetes Secret.\n auth:\n secretRef:\n secretAccessKeySecretRef:\n name: gcpsm-secret\n key: secret-access-credentials\n namespace: example\n projectID: myproject\n\n # (3): Kubernetes provider\n kubernetes:\n server:\n url: \"https://myapiserver.tld\"\n caProvider:\n type: Secret\n name: my-cluster-secrets\n namespace: example\n key: ca.crt\n auth:\n serviceAccount:\n name: \"example-sa\"\n namespace: \"example\"\n\n # (4): Oracle provider\n oracle:\n # The vault OCID\n vault: ocid1.vault.oc1.eu-frankfurt-1.aaa1aaaaaaaaa.aaaaaaaaaaaaaa1aaaaaaa111aaaaaaaaaaaaaaaa\n # The vault region\n region: eu-frankfurt-1\n auth:\n # The user OCID\n user: ocid1.user.oc1..aaa1aaaaaaaaa.aaaaaaaaaaaaaa1aaaaaaa111aaaaaaaaaaaaaaaa\n # The tenancy OCID\n tenancy: ocid1.tenancy.oc1..aaa1aaaaaaaaa.aaaaaaaaaaaaaa1aaaaaaa111aaaaaaaaaaaaaaaa\n secretRef:\n privatekey:\n # The secret that contains your privatekey\n name: oci-secret-name\n key: privateKey\n namespace: example-namespace\n fingerprint:\n # The secret that contains your fingerprint\n name: oci-secret-name\n key: fingerprint\n namespace: example-namespace\n\n # (TODO): add more provider examples here\n\n # Conditions about namespaces in which the ClusterSecretStore is usable for ExternalSecrets\n conditions:\n # Options are namespaceSelector, or namespaces\n - namespaceSelector:\n matchLabels:\n my.namespace.io/some-label: \"value\" # Only namespaces with that label will work\n\n - namespaces:\n - \"namespace-a\"\n - \"namespace-b\"\n\n # conditions needs only one of the conditions to meet for the CSS to be usable in the namespace.\n\nstatus:\n # Standard condition schema\n conditions:\n # SecretStore ready condition indicates the given store is in ready\n # state and able to referenced by ExternalSecrets\n # If the `status` of this condition is `False`, ExternalSecret controllers\n # should prevent attempts to fetch secrets\n - type: Ready\n status: \"False\"\n reason: \"ConfigError\"\n message: \"SecretStore validation failed\"\n lastTransitionTime: \"2019-08-12T12:33:02Z\"\n
"},{"location":"api/components/","title":"Components","text":""},{"location":"api/components/#overview","title":"Overview","text":"Exernal Secrets comes with three components: Core Controller
, Webhook
and Cert Controller
.
This is due to the need to implement conversion webhooks in order to convert custom resources between api versions and to provide a ValidatingWebhook for the ExternalSecret
and SecretStore
resources.
These features are optional but highly recommended. You can disable them with helm chart values certController.create=false
and webhook.create=false
.
"},{"location":"api/components/#tls-bootstrap","title":"TLS Bootstrap","text":"Cert-controller is responsible for (1) generating TLS credentials which will be used by the webhook component and (2) injecting the certificate as caBundle
into Kind=CustomResourceDefinition
for conversion webhooks and Kind=ValidatingWebhookConfiguration
for validating admission webhook. The TLS credentials are stored in a Kind=Secret
which is consumed by the webhook.
"},{"location":"api/controller-options/","title":"Controller Options","text":"The external-secrets binary includes three components: core controller
, certcontroller
and webook
.
"},{"location":"api/controller-options/#core-controller-flags","title":"Core Controller Flags","text":"The core controller is invoked without a subcommand and can be configured with the following flags:
Name Type Default Description --client-burst
int uses rest client default (10) Maximum Burst allowed to be passed to rest.Client --client-qps
float32 uses rest client default (5) QPS configuration to be passed to rest.Client --concurrent
int 1 The number of concurrent reconciles. --controller-class
string default The controller is instantiated with a specific controller name and filters ES based on this property --enable-cluster-external-secret-reconciler
boolean true Enables the cluster external secret reconciler. --enable-cluster-store-reconciler
boolean true Enables the cluster store reconciler. --enable-push-secret-reconciler
boolean true Enables the push secret reconciler. --enable-secrets-caching
boolean false Enables the secrets caching for external-secrets pod. --enable-configmaps-caching
boolean false Enables the ConfigMap caching for external-secrets pod. --enable-flood-gate
boolean true Enable flood gate. External secret will be reconciled only if the ClusterStore or Store have an healthy or unknown state. --enable-extended-metric-labels
boolean true Enable recommended kubernetes annotations as labels in metrics. --enable-leader-election
boolean false Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager. --experimental-enable-aws-session-cache
boolean false Enable experimental AWS session cache. External secret will reuse the AWS session without creating a new one on each request. --help
help for external-secrets --loglevel
string info loglevel to use, one of: debug, info, warn, error, dpanic, panic, fatal --metrics-addr
string :8080 The address the metric endpoint binds to. --namespace
string - watch external secrets scoped in the provided namespace only. ClusterSecretStore can be used but only work if it doesn't reference resources from other namespaces --store-requeue-interval
duration 5m0s Default Time duration between reconciling (Cluster)SecretStores"},{"location":"api/controller-options/#cert-controller-flags","title":"Cert Controller Flags","text":"Name Type Default Descripton --crd-requeue-interval
duration 5m0s Time duration between reconciling CRDs for new certs --enable-leader-election
boolean false Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager. --healthz-addr
string :8081 The address the health endpoint binds to. --help
help for certcontroller --loglevel
string info loglevel to use, one of: debug, info, warn, error, dpanic, panic, fatal --metrics-addr
string :8080 The address the metric endpoint binds to. --secret-name
string external-secrets-webhook Secret to store certs for webhook --secret-namespace
string default namespace of the secret to store certs --service-name
string external-secrets-webhook Webhook service name --service-namespace
string default Webhook service namespace"},{"location":"api/controller-options/#webhook-flags","title":"Webhook Flags","text":"Name Type Default Description --cert-dir
string /tmp/k8s-webhook-server/serving-certs path to check for certs --check-interval
duration 5m0s certificate check interval --dns-name
string localhost DNS name to validate certificates with --healthz-addr
string :8081 The address the health endpoint binds to. --help
help for webhook --loglevel
string info loglevel to use, one of: debug, info, warn, error, dpanic, panic, fatal --lookahead-interval
duration 2160h0m0s (90d) certificate check interval --metrics-addr
string :8080 The address the metric endpoint binds to. --port
number 10250 Port number that the webhook server will serve. --tls-ciphers
string comma separated list of tls ciphers allowed. This does not apply to TLS 1.3 as the ciphers are selected automatically. The order of this list does not give preference to the ciphers, the ordering is done automatically. Full lists of available ciphers can be found at https://pkg.go.dev/crypto/tls#pkg-constants. E.g. 'TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256' --tls-min-version
string 1.2 minimum version of TLS supported."},{"location":"api/externalsecret/","title":"ExternalSecret","text":"The ExternalSecret
describes what data should be fetched, how the data should be transformed and saved as a Kind=Secret
:
- tells the operator what secrets should be synced by using
spec.data
to explicitly sync individual keys or use spec.dataFrom
to get all values from the external API. - you can specify how the secret should look like by specifying a
spec.target.template
"},{"location":"api/externalsecret/#template","title":"Template","text":"When the controller reconciles the ExternalSecret
it will use the spec.template
as a blueprint to construct a new Kind=Secret
. You can use golang templates to define the blueprint and use template functions to transform secret values. You can also pull in ConfigMaps
that contain golang-template data using templateFrom
. See advanced templating for details.
"},{"location":"api/externalsecret/#update-behavior","title":"Update Behavior","text":"The Kind=Secret
is updated when:
- the
spec.refreshInterval
has passed and is not 0
- the
ExternalSecret
's labels
or annotations
are changed - the
ExternalSecret
's spec
has been changed
You can trigger a secret refresh by using kubectl or any other kubernetes api client:
kubectl annotate es my-es force-sync=$(date +%s) --overwrite\n
"},{"location":"api/externalsecret/#features","title":"Features","text":"Individual features are described in the Guides section:
- Find many secrets / Extract from structured data
- Templating
- Using Generators
- Secret Ownership and Deletion
- Key Rewriting
- Decoding Strategy
"},{"location":"api/externalsecret/#example","title":"Example","text":"Take a look at an annotated example to understand the design behind the ExternalSecret
.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: \"hello-world\"\n\n # labels and annotations are copied over to the\n # secret that will be created\n labels:\n acme.org/owned-by: \"q-team\"\n annotations:\n acme.org/sha: 1234\n\nspec:\n\n # Optional, SecretStoreRef defines the default SecretStore to use when fetching the secret data.\n secretStoreRef:\n name: aws-store\n kind: SecretStore # or ClusterSecretStore\n\n # RefreshInterval is the amount of time before the values reading again from the SecretStore provider\n # Valid time units are \"ns\", \"us\" (or \"\u00b5s\"), \"ms\", \"s\", \"m\", \"h\" (from time.ParseDuration)\n # May be set to zero to fetch and create it once\n refreshInterval: \"1h\"\n\n # the target describes the secret that shall be created\n # there can only be one target per ExternalSecret\n target:\n\n # The secret name of the resource\n # Defaults to .metadata.name of the ExternalSecret\n # It is immutable\n name: application-config\n\n # Enum with values: 'Owner', 'Merge', or 'None'\n # Default value of 'Owner'\n # Owner creates the secret and sets .metadata.ownerReferences of the resource\n # Merge does not create the secret, but merges in the data fields to the secret\n # None does not create a secret (future use with injector)\n creationPolicy: 'Merge'\n\n # DeletionPolicy defines how/when to delete the Secret in Kubernetes\n # if the provider secret gets deleted.\n # Valid values are Delete, Merge, Retain\n deletionPolicy: \"Retain\"\n\n # Specify a blueprint for the resulting Kind=Secret\n template:\n type: kubernetes.io/dockerconfigjson # or TLS...\n\n metadata:\n annotations: {}\n labels: {}\n\n # Use inline templates to construct your desired config file that contains your secret\n data:\n config.yml: |\n database:\n connection: postgres://{{ .username }}:{{ .password }}@{{ .database_host }}:5432/payments\n\n # Uses an existing template from configmap\n # Secret is fetched, merged and templated within the referenced configMap data\n # It does not update the configmap, it creates a secret with: data[\"alertmanager.yml\"] = ...result...\n templateFrom:\n - configMap:\n name: application-config-tmpl\n items:\n - key: config.yml\n\n # Data defines the connection between the Kubernetes Secret keys and the Provider data\n data:\n - secretKey: username\n remoteRef:\n key: database-credentials\n version: v1\n property: username\n decodingStrategy: None # can be None, Base64, Base64URL or Auto\n\n # define the source of the secret. Can be a SecretStore or a Generator kind\n sourceRef:\n # point to a SecretStore that should be used to fetch a secret.\n # must be defined if no spec.secretStoreRef is defined.\n storeRef:\n name: aws-secretstore\n kind: ClusterSecretStore\n\n # Used to fetch all properties from the Provider key\n # If multiple dataFrom are specified, secrets are merged in the specified order\n # Can be defined using sourceRef.generatorRef or extract / find\n # Both use cases are exemplified below\n dataFrom:\n - sourceRef:\n generatorRef:\n apiVersion: generators.external-secrets.io/v1alpha1\n kind: ECRAuthorizationToken\n name: \"my-ecr\"\n #Or\n dataFrom:\n - extract:\n key: database-credentials\n version: v1\n property: data\n conversionStrategy: Default\n decodingStrategy: Auto\n rewrite:\n - regexp:\n source: \"exp-(.*?)-ression\"\n target: \"rewriting-${1}-with-groups\"\n - find:\n path: path-to-filter\n source: \"exp-(.*?)-ression\"\n target: \"rewriting-${1}-with-groups\"\n name:\n regexp: \".*foobar.*\"\n tags:\n foo: bar\n conversionStrategy: Unicode\n decodingStrategy: Base64\n rewrite:\n - regexp:\n source: \"foo\"\n target: \"bar\"\n\nstatus:\n # refreshTime is the time and date the external secret was fetched and\n # the target secret updated\n refreshTime: \"2019-08-12T12:33:02Z\"\n # Standard condition schema\n conditions:\n # ExternalSecret ready condition indicates the secret is ready for use.\n # This is defined as:\n # - The target secret exists\n # - The target secret has been refreshed within the last refreshInterval\n # - The target secret content is up-to-date based on any target templates\n - type: Ready\n status: \"True\" # False if last refresh was not successful\n reason: \"SecretSynced\"\n message: \"Secret was synced\"\n lastTransitionTime: \"2019-08-12T12:33:02Z\"\n
"},{"location":"api/metrics/","title":"Metrics","text":"The External Secrets Operator exposes its Prometheus metrics in the /metrics
path. To enable it, set the serviceMonitor.enabled
Helm flag to true
.
If you are using a different monitoring tool that also needs a /metrics
endpoint, you can set the metrics.service.enabled
Helm flag to true
. In addition you can also set webhook.metrics.service.enabled
and certController.metrics.service.enabled
to scrape the other components.
The Operator has the controller-runtime metrics inherited from kubebuilder plus some custom metrics with a resource name prefix, such as externalsecret_
.
"},{"location":"api/metrics/#cluster-external-secret-metrics","title":"Cluster External Secret Metrics","text":"Name Type Description clusterexternalsecret_status_condition
Gauge The status condition of a specific Cluster External Secret clusterexternalsecret_reconcile_duration
Gauge The duration time to reconcile the Cluster External Secret"},{"location":"api/metrics/#external-secret-metrics","title":"External Secret Metrics","text":"Name Type Description externalsecret_provider_api_calls_count
Counter Number of API calls made to an upstream secret provider API. The metric provides a provider
, call
and status
labels. externalsecret_sync_calls_total
Counter Total number of the External Secret sync calls externalsecret_sync_calls_error
Counter Total number of the External Secret sync errors externalsecret_status_condition
Gauge The status condition of a specific External Secret externalsecret_reconcile_duration
Gauge The duration time to reconcile the External Secret"},{"location":"api/metrics/#cluster-secret-store-metrics","title":"Cluster Secret Store Metrics","text":"Name Type Description clustersecretstore_status_condition
Gauge The status condition of a specific Cluster Secret Store clustersecretstore_reconcile_duration
Gauge The duration time to reconcile the Cluster Secret Store"},{"location":"api/metrics/#secret-store-metrics","title":"Secret Store Metrics","text":"Name Type Description secretstore_status_condition
Gauge The status condition of a specific Secret Store secretstore_reconcile_duration
Gauge The duration time to reconcile the Secret Store"},{"location":"api/metrics/#controller-runtime-metrics","title":"Controller Runtime Metrics","text":"See the kubebuilder documentation on the default exported metrics by controller-runtime.
"},{"location":"api/metrics/#dashboard","title":"Dashboard","text":"We provide a Grafana Dashboard that gives you an overview of External Secrets Operator:
"},{"location":"api/metrics/#service-level-indicators-and-alerts","title":"Service Level Indicators and Alerts","text":"We find the following Service Level Indicators (SLIs) useful when operating ESO. They should give you a good starting point and hints to develop your own Service Level Objectives (SLOs).
"},{"location":"api/metrics/#webhook-http-status-codes","title":"Webhook HTTP Status Codes","text":"The webhook HTTP status code indicates that a HTTP Request was answered successfully or not. If the Webhook pod is not able to serve the requests properly then that failure may cascade down to the controller or any other user of kube-apiserver
.
SLI Example: request error percentage.
sum(increase(controller_runtime_webhook_requests_total{service=~\"external-secrets.*\",code=\"500\"}[1m]))\n/\nsum(increase(controller_runtime_webhook_requests_total{service=~\"external-secrets.*\"}[1m]))\n
"},{"location":"api/metrics/#webhook-http-request-latency","title":"Webhook HTTP Request Latency","text":"If the webhook server is not able to respond in time then that may cause a timeout at the client. This failure may cascade down to the controller or any other user of kube-apiserver
.
SLI Example: p99 across all webhook requests.
histogram_quantile(0.99,\n sum(rate(controller_runtime_webhook_latency_seconds_bucket{service=~\"external-secrets.*\"}[5m])) by (le)\n)\n
"},{"location":"api/metrics/#controller-workqueue-depth","title":"Controller Workqueue Depth","text":"If the workqueue depth is > 0 for a longer period of time then this is an indicator for the controller not being able to reconcile resources in time. I.e. delivery of secret updates is delayed.
Note: when a controller is restarted, then queue length = total number of resources
. Make sure to measure the time it takes for the controller to fully reconcile all secrets after a restart. In large clusters this may take a while, make sure to define an acceptable timeframe to fully reconcile all resources.
sum(\n workqueue_depth{service=~\"external-secrets.*\"}\n) by (name)\n
"},{"location":"api/metrics/#controller-reconcile-latency","title":"Controller Reconcile Latency","text":"The controller should be able to reconcile resources within a reasonable timeframe. When latency is high secret delivery may impacted.
SLI Example: p99 across all controllers.
histogram_quantile(0.99,\n sum(rate(controller_runtime_reconcile_time_seconds_bucket{service=~\"external-secrets.*\"}[5m])) by (le)\n)\n
"},{"location":"api/metrics/#controller-reconcile-error","title":"Controller Reconcile Error","text":"The controller should be able to reconcile resources without errors. When errors occurr secret delivery may be impacted which could cascade down to the secret consuming applications.
sum(increase(\n controller_runtime_reconcile_total{service=~\"external-secrets.*\",controller=~\"$controller\",result=\"error\"}[1m])\n) by (result)\n
"},{"location":"api/pushsecret/","title":"PushSecret","text":"The PushSecret
is namespaced and it describes what data should be pushed to the secret provider.
- tells the operator what secrets should be pushed by using
spec.selector
. - you can specify what secret keys should be pushed by using
spec.data
. - you can also template the resulting property values using templating.
apiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\n name: pushsecret-example # Customisable\n namespace: default # Same of the SecretStores\nspec:\n updatePolicy: Replace # Policy to overwrite existing secrets in the provider on sync\n deletionPolicy: Delete # the provider' secret will be deleted if the PushSecret is deleted\n refreshInterval: 10s # Refresh interval for which push secret will reconcile\n secretStoreRefs: # A list of secret stores to push secrets to\n - name: aws-parameterstore\n kind: SecretStore\n selector:\n secret:\n name: pokedex-credentials # Source Kubernetes secret to be pushed\n template:\n metadata:\n annotations: { }\n labels: { }\n data:\n best-pokemon: \"{{ .best-pokemon | toString | upper }} is the really best!\"\n # Uses an existing template from configmap\n # Secret is fetched, merged and templated within the referenced configMap data\n # It does not update the configmap, it creates a secret with: data[\"alertmanager.yml\"] = ...result...\n templateFrom:\n - configMap:\n name: application-config-tmpl\n items:\n - key: config.yml\n data:\n - conversionStrategy: None # Also supports the ReverseUnicode strategy\n match:\n secretKey: best-pokemon # Source Kubernetes secret key to be pushed\n remoteRef:\n remoteKey: my-first-parameter # Remote reference (where the secret is going to be pushed)\n
"},{"location":"api/pushsecret/#templating","title":"Templating","text":"When the controller reconciles the PushSecret
it will use the spec.template
as a blueprint to construct a new property. You can use golang templates to define the blueprint and use template functions to transform the defined properties. You can also pull in ConfigMaps
that contain golang-template data using templateFrom
. See advanced templating for details.
"},{"location":"api/secretstore/","title":"SecretStore","text":"The SecretStore
is namespaced and specifies how to access the external API. The SecretStore maps to exactly one instance of an external API.
By design, SecretStores are bound to a namespace and can not reference resources across namespaces. If you want to design cross-namespace SecretStores you must use ClusterSecretStores which do not have this limitation.
"},{"location":"api/secretstore/#example","title":"Example","text":"For a full list of supported fields see spec or dig into our guides.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: example\n namespace: example-ns\nspec:\n\n # Used to select the correct ESO controller (think: ingress.ingressClassName)\n # The ESO controller is instantiated with a specific controller name\n # and filters ES based on this property\n # Optional\n controller: dev\n\n # You can specify retry settings for the http connection\n # these fields allow you to set a maxRetries before failure, and\n # an interval between the retries.\n # Current supported providers: AWS, Hashicorp Vault, IBM\n retrySettings:\n maxRetries: 5\n retryInterval: \"10s\"\n\n # provider field contains the configuration to access the provider\n # which contains the secret exactly one provider must be configured.\n provider:\n\n # (1): AWS Secrets Manager\n # aws configures this store to sync secrets using AWS Secret Manager provider\n aws:\n service: SecretsManager\n # Role is a Role ARN which the SecretManager provider will assume\n role: iam-role\n # AWS Region to be used for the provider\n region: eu-central-1\n # Auth defines the information necessary to authenticate against AWS by\n # getting the accessKeyID and secretAccessKey from an already created Kubernetes Secret\n auth:\n secretRef:\n accessKeyIDSecretRef:\n name: awssm-secret\n key: access-key\n secretAccessKeySecretRef:\n name: awssm-secret\n key: secret-access-key\n\n # (2) Hashicorp Vault\n vault:\n server: \"https://vault.acme.org\"\n # Path is the mount path of the Vault KV backend endpoint\n # Used as a path prefix for the external secret key\n path: \"secret\"\n # Version is the Vault KV secret engine version.\n # This can be either \"v1\" or \"v2\", defaults to \"v2\"\n version: \"v2\"\n # vault enterprise namespace: https://www.vaultproject.io/docs/enterprise/namespaces\n namespace: \"a-team\"\n # base64 encoded string of certificate\n caBundle: \"...\"\n # Instead of caBundle you can also specify a caProvider\n # this will retrieve the cert from a Secret or ConfigMap\n caProvider:\n # Can be Secret or ConfigMap\n type: \"Secret\"\n name: \"my-cert-secret\"\n key: \"cert-key\"\n # client side related TLS communication, when the Vault server requires mutual authentication\n tls:\n clientCert:\n namespace: ...\n name: \"my-cert-secret\"\n key: \"tls.crt\"\n secretRef:\n namespace: ...\n name: \"my-cert-secret\"\n key: \"tls.key\"\n\n auth:\n # static token: https://www.vaultproject.io/docs/auth/token\n tokenSecretRef:\n name: \"my-secret\"\n key: \"vault-token\"\n\n # AppRole auth: https://www.vaultproject.io/docs/auth/approle\n appRole:\n path: \"approle\"\n roleId: \"db02de05-fa39-4855-059b-67221c5c2f63\"\n secretRef:\n name: \"my-secret\"\n key: \"vault-token\"\n\n # Kubernetes auth: https://www.vaultproject.io/docs/auth/kubernetes\n kubernetes:\n mountPath: \"kubernetes\"\n role: \"demo\"\n # Optional service account reference\n serviceAccountRef:\n name: \"my-sa\"\n # Optional secret field containing a Kubernetes ServiceAccount JWT\n # used for authenticating with Vault\n secretRef:\n name: \"my-secret\"\n key: \"vault\"\n\n # TLS certificates auth method: https://developer.hashicorp.com/vault/docs/auth/cert\n cert:\n clientCert:\n namespace: ...\n name: \"my-cert-secret\"\n key: \"tls.crt\"\n secretRef:\n namespace: ...\n name: \"my-cert-secret\"\n key: \"tls.key\"\n\n # (3): GCP Secret Manager\n gcpsm:\n # Auth defines the information necessary to authenticate against GCP by getting\n # the credentials from an already created Kubernetes Secret.\n auth:\n secretRef:\n secretAccessKeySecretRef:\n name: gcpsm-secret\n key: secret-access-credentials\n projectID: myproject\n # (TODO): add more provider examples here\n\nstatus:\n # Standard condition schema\n conditions:\n # SecretStore ready condition indicates the given store is in ready\n # state and able to referenced by ExternalSecrets\n # If the `status` of this condition is `False`, ExternalSecret controllers\n # should prevent attempts to fetch secrets\n - type: Ready\n status: \"False\"\n reason: \"ConfigError\"\n message: \"SecretStore validation failed\"\n lastTransitionTime: \"2019-08-12T12:33:02Z\"\n
"},{"location":"api/spec/","title":"API specification","text":"Packages:
- external-secrets.io/v1beta1
"},{"location":"api/spec/#external-secrets.io/v1beta1","title":"external-secrets.io/v1beta1","text":"
Package v1beta1 contains resources for external-secrets
Resource Types:
"},{"location":"api/spec/#external-secrets.io/v1beta1.AWSAuth","title":"AWSAuth","text":" (Appears on: AWSProvider)
AWSAuth tells the controller how to do authentication with aws. Only one of secretRef or jwt can be specified. if none is specified the controller will load credentials using the aws sdk defaults.
Field Description secretRef
AWSAuthSecretRef (Optional) jwt
AWSJWTAuth (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.AWSAuthSecretRef","title":"AWSAuthSecretRef","text":" (Appears on: AWSAuth)
AWSAuthSecretRef holds secret references for AWS credentials both AccessKeyID and SecretAccessKey must be defined in order to properly authenticate.
Field Description accessKeyIDSecretRef
External Secrets meta/v1.SecretKeySelector The AccessKeyID is used for authentication
secretAccessKeySecretRef
External Secrets meta/v1.SecretKeySelector The SecretAccessKey is used for authentication
sessionTokenSecretRef
External Secrets meta/v1.SecretKeySelector The SessionToken used for authentication This must be defined if AccessKeyID and SecretAccessKey are temporary credentials see: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html
"},{"location":"api/spec/#external-secrets.io/v1beta1.AWSJWTAuth","title":"AWSJWTAuth","text":" (Appears on: AWSAuth)
Authenticate against AWS using service account tokens.
Field Description serviceAccountRef
External Secrets meta/v1.ServiceAccountSelector"},{"location":"api/spec/#external-secrets.io/v1beta1.AWSProvider","title":"AWSProvider","text":" (Appears on: SecretStoreProvider)
AWSProvider configures a store to sync secrets with AWS.
Field Description service
AWSServiceType Service defines which service should be used to fetch the secrets
auth
AWSAuth (Optional) Auth defines the information necessary to authenticate against AWS if not set aws sdk will infer credentials from your environment see: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials
role
string (Optional) Role is a Role ARN which the provider will assume
region
string AWS Region to be used for the provider
additionalRoles
[]string (Optional) AdditionalRoles is a chained list of Role ARNs which the provider will sequentially assume before assuming the Role
externalID
string AWS External ID set on assumed IAM roles
sessionTags
[]*github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1.Tag (Optional) AWS STS assume role session tags
secretsManager
SecretsManager (Optional) SecretsManager defines how the provider behaves when interacting with AWS SecretsManager
transitiveTagKeys
[]*string (Optional) AWS STS assume role transitive session tags. Required when multiple rules are used with the provider
"},{"location":"api/spec/#external-secrets.io/v1beta1.AWSServiceType","title":"AWSServiceType (string
alias)","text":" (Appears on: AWSProvider)
AWSServiceType is a enum that defines the service/API that is used to fetch the secrets.
Value Description \"ParameterStore\"
AWSServiceParameterStore is the AWS SystemsManager ParameterStore service. see: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html
\"SecretsManager\"
AWSServiceSecretsManager is the AWS SecretsManager service. see: https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html
"},{"location":"api/spec/#external-secrets.io/v1beta1.AkeylessAuth","title":"AkeylessAuth","text":" (Appears on: AkeylessProvider)
Field Description secretRef
AkeylessAuthSecretRef (Optional) Reference to a Secret that contains the details to authenticate with Akeyless.
kubernetesAuth
AkeylessKubernetesAuth (Optional) Kubernetes authenticates with Akeyless by passing the ServiceAccount token stored in the named Secret resource.
"},{"location":"api/spec/#external-secrets.io/v1beta1.AkeylessAuthSecretRef","title":"AkeylessAuthSecretRef","text":" (Appears on: AkeylessAuth)
AkeylessAuthSecretRef AKEYLESS_ACCESS_TYPE_PARAM: AZURE_OBJ_ID OR GCP_AUDIENCE OR ACCESS_KEY OR KUB_CONFIG_NAME.
Field Description accessID
External Secrets meta/v1.SecretKeySelector The SecretAccessID is used for authentication
accessType
External Secrets meta/v1.SecretKeySelector accessTypeParam
External Secrets meta/v1.SecretKeySelector"},{"location":"api/spec/#external-secrets.io/v1beta1.AkeylessKubernetesAuth","title":"AkeylessKubernetesAuth","text":" (Appears on: AkeylessAuth)
Authenticate with Kubernetes ServiceAccount token stored.
Field Description accessID
string the Akeyless Kubernetes auth-method access-id
k8sConfName
string Kubernetes-auth configuration name in Akeyless-Gateway
serviceAccountRef
External Secrets meta/v1.ServiceAccountSelector (Optional) Optional service account field containing the name of a kubernetes ServiceAccount. If the service account is specified, the service account secret token JWT will be used for authenticating with Akeyless. If the service account selector is not supplied, the secretRef will be used instead.
secretRef
External Secrets meta/v1.SecretKeySelector (Optional) Optional secret field containing a Kubernetes ServiceAccount JWT used for authenticating with Akeyless. If a name is specified without a key, token
is the default. If one is not specified, the one bound to the controller will be used.
"},{"location":"api/spec/#external-secrets.io/v1beta1.AkeylessProvider","title":"AkeylessProvider","text":" (Appears on: SecretStoreProvider)
AkeylessProvider Configures an store to sync secrets using Akeyless KV.
Field Description akeylessGWApiURL
string Akeyless GW API Url from which the secrets to be fetched from.
authSecretRef
AkeylessAuth Auth configures how the operator authenticates with Akeyless.
caBundle
[]byte (Optional) PEM/base64 encoded CA bundle used to validate Akeyless Gateway certificate. Only used if the AkeylessGWApiURL URL is using HTTPS protocol. If not set the system root certificates are used to validate the TLS connection.
caProvider
CAProvider (Optional) The provider for the CA bundle to use to validate Akeyless Gateway certificate.
"},{"location":"api/spec/#external-secrets.io/v1beta1.AlibabaAuth","title":"AlibabaAuth","text":" (Appears on: AlibabaProvider)
AlibabaAuth contains a secretRef for credentials.
Field Description secretRef
AlibabaAuthSecretRef (Optional) rrsa
AlibabaRRSAAuth (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.AlibabaAuthSecretRef","title":"AlibabaAuthSecretRef","text":" (Appears on: AlibabaAuth)
AlibabaAuthSecretRef holds secret references for Alibaba credentials.
Field Description accessKeyIDSecretRef
External Secrets meta/v1.SecretKeySelector The AccessKeyID is used for authentication
accessKeySecretSecretRef
External Secrets meta/v1.SecretKeySelector The AccessKeySecret is used for authentication
"},{"location":"api/spec/#external-secrets.io/v1beta1.AlibabaProvider","title":"AlibabaProvider","text":" (Appears on: SecretStoreProvider)
AlibabaProvider configures a store to sync secrets using the Alibaba Secret Manager provider.
Field Description auth
AlibabaAuth regionID
string Alibaba Region to be used for the provider
"},{"location":"api/spec/#external-secrets.io/v1beta1.AlibabaRRSAAuth","title":"AlibabaRRSAAuth","text":" (Appears on: AlibabaAuth)
Authenticate against Alibaba using RRSA.
Field Description oidcProviderArn
string oidcTokenFilePath
string roleArn
string sessionName
string"},{"location":"api/spec/#external-secrets.io/v1beta1.AzureAuthType","title":"AzureAuthType (string
alias)","text":" (Appears on: AzureKVProvider)
AuthType describes how to authenticate to the Azure Keyvault Only one of the following auth types may be specified. If none of the following auth type is specified, the default one is ServicePrincipal.
Value Description \"ManagedIdentity\"
Using Managed Identity to authenticate. Used with aad-pod-identity installed in the cluster.
\"ServicePrincipal\"
Using service principal to authenticate, which needs a tenantId, a clientId and a clientSecret.
\"WorkloadIdentity\"
Using Workload Identity service accounts to authenticate.
"},{"location":"api/spec/#external-secrets.io/v1beta1.AzureEnvironmentType","title":"AzureEnvironmentType (string
alias)","text":" (Appears on: AzureKVProvider)
AzureEnvironmentType specifies the Azure cloud environment endpoints to use for connecting and authenticating with Azure. By default it points to the public cloud AAD endpoint. The following endpoints are available, also see here: https://github.com/Azure/go-autorest/blob/main/autorest/azure/environments.go#L152 PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud
Value Description \"ChinaCloud\"
\"GermanCloud\"
\"PublicCloud\"
\"USGovernmentCloud\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.AzureKVAuth","title":"AzureKVAuth","text":" (Appears on: AzureKVProvider)
Configuration used to authenticate with Azure.
Field Description clientId
External Secrets meta/v1.SecretKeySelector (Optional) The Azure clientId of the service principle or managed identity used for authentication.
tenantId
External Secrets meta/v1.SecretKeySelector (Optional) The Azure tenantId of the managed identity used for authentication.
clientSecret
External Secrets meta/v1.SecretKeySelector (Optional) The Azure ClientSecret of the service principle used for authentication.
"},{"location":"api/spec/#external-secrets.io/v1beta1.AzureKVProvider","title":"AzureKVProvider","text":" (Appears on: SecretStoreProvider)
Configures an store to sync secrets using Azure KV.
Field Description authType
AzureAuthType (Optional) Auth type defines how to authenticate to the keyvault service. Valid values are: - \u201cServicePrincipal\u201d (default): Using a service principal (tenantId, clientId, clientSecret) - \u201cManagedIdentity\u201d: Using Managed Identity assigned to the pod (see aad-pod-identity)
vaultUrl
string Vault Url from which the secrets to be fetched from.
tenantId
string (Optional) TenantID configures the Azure Tenant to send requests to. Required for ServicePrincipal auth type. Optional for WorkloadIdentity.
environmentType
AzureEnvironmentType EnvironmentType specifies the Azure cloud environment endpoints to use for connecting and authenticating with Azure. By default it points to the public cloud AAD endpoint. The following endpoints are available, also see here: https://github.com/Azure/go-autorest/blob/main/autorest/azure/environments.go#L152 PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud
authSecretRef
AzureKVAuth (Optional) Auth configures how the operator authenticates with Azure. Required for ServicePrincipal auth type. Optional for WorkloadIdentity.
serviceAccountRef
External Secrets meta/v1.ServiceAccountSelector (Optional) ServiceAccountRef specified the service account that should be used when authenticating with WorkloadIdentity.
identityId
string (Optional) If multiple Managed Identity is assigned to the pod, you can select the one to be used
"},{"location":"api/spec/#external-secrets.io/v1beta1.CAProvider","title":"CAProvider","text":" (Appears on: AkeylessProvider, ConjurProvider, KubernetesServer, VaultProvider)
Used to provide custom certificate authority (CA) certificates for a secret store. The CAProvider points to a Secret or ConfigMap resource that contains a PEM-encoded certificate.
Field Description type
CAProviderType The type of provider to use such as \u201cSecret\u201d, or \u201cConfigMap\u201d.
name
string The name of the object located at the provider type.
key
string The key where the CA certificate can be found in the Secret or ConfigMap.
namespace
string (Optional) The namespace the Provider type is in. Can only be defined when used in a ClusterSecretStore.
"},{"location":"api/spec/#external-secrets.io/v1beta1.CAProviderType","title":"CAProviderType (string
alias)","text":" (Appears on: CAProvider)
Value Description \"ConfigMap\"
\"Secret\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.CertAuth","title":"CertAuth","text":" (Appears on: KubernetesAuth)
Field Description clientCert
External Secrets meta/v1.SecretKeySelector clientKey
External Secrets meta/v1.SecretKeySelector"},{"location":"api/spec/#external-secrets.io/v1beta1.ChefAuth","title":"ChefAuth","text":" (Appears on: ChefProvider)
ChefAuth contains a secretRef for credentials.
Field Description secretRef
ChefAuthSecretRef"},{"location":"api/spec/#external-secrets.io/v1beta1.ChefAuthSecretRef","title":"ChefAuthSecretRef","text":" (Appears on: ChefAuth)
ChefAuthSecretRef holds secret references for chef server login credentials.
Field Description privateKeySecretRef
External Secrets meta/v1.SecretKeySelector SecretKey is the Signing Key in PEM format, used for authentication.
"},{"location":"api/spec/#external-secrets.io/v1beta1.ChefProvider","title":"ChefProvider","text":" (Appears on: SecretStoreProvider)
ChefProvider configures a store to sync secrets using basic chef server connection credentials.
Field Description auth
ChefAuth Auth defines the information necessary to authenticate against chef Server
username
string UserName should be the user ID on the chef server
serverUrl
string ServerURL is the chef server URL used to connect to. If using orgs you should include your org in the url and terminate the url with a \u201c/\u201d
"},{"location":"api/spec/#external-secrets.io/v1beta1.ClusterExternalSecret","title":"ClusterExternalSecret","text":"
ClusterExternalSecret is the Schema for the clusterexternalsecrets API.
Field Description metadata
Kubernetes meta/v1.ObjectMeta Refer to the Kubernetes API documentation for the fields of the metadata
field. spec
ClusterExternalSecretSpec externalSecretSpec
ExternalSecretSpec The spec for the ExternalSecrets to be created
externalSecretName
string (Optional) The name of the external secrets to be created defaults to the name of the ClusterExternalSecret
externalSecretMetadata
ExternalSecretMetadata (Optional) The metadata of the external secrets to be created
namespaceSelector
Kubernetes meta/v1.LabelSelector (Optional) The labels to select by to find the Namespaces to create the ExternalSecrets in. Deprecated: Use NamespaceSelectors instead.
namespaceSelectors
[]*k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector (Optional) A list of labels to select by to find the Namespaces to create the ExternalSecrets in. The selectors are ORed.
namespaces
[]string (Optional) Choose namespaces by name. This field is ORed with anything that NamespaceSelectors ends up choosing.
refreshTime
Kubernetes meta/v1.Duration The time in which the controller should reconcile its objects and recheck namespaces for labels.
status
ClusterExternalSecretStatus"},{"location":"api/spec/#external-secrets.io/v1beta1.ClusterExternalSecretConditionType","title":"ClusterExternalSecretConditionType (string
alias)","text":" (Appears on: ClusterExternalSecretStatusCondition)
Value Description \"Ready\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.ClusterExternalSecretNamespaceFailure","title":"ClusterExternalSecretNamespaceFailure","text":" (Appears on: ClusterExternalSecretStatus)
ClusterExternalSecretNamespaceFailure represents a failed namespace deployment and it\u2019s reason.
Field Description namespace
string Namespace is the namespace that failed when trying to apply an ExternalSecret
reason
string (Optional) Reason is why the ExternalSecret failed to apply to the namespace
"},{"location":"api/spec/#external-secrets.io/v1beta1.ClusterExternalSecretSpec","title":"ClusterExternalSecretSpec","text":" (Appears on: ClusterExternalSecret)
ClusterExternalSecretSpec defines the desired state of ClusterExternalSecret.
Field Description externalSecretSpec
ExternalSecretSpec The spec for the ExternalSecrets to be created
externalSecretName
string (Optional) The name of the external secrets to be created defaults to the name of the ClusterExternalSecret
externalSecretMetadata
ExternalSecretMetadata (Optional) The metadata of the external secrets to be created
namespaceSelector
Kubernetes meta/v1.LabelSelector (Optional) The labels to select by to find the Namespaces to create the ExternalSecrets in. Deprecated: Use NamespaceSelectors instead.
namespaceSelectors
[]*k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector (Optional) A list of labels to select by to find the Namespaces to create the ExternalSecrets in. The selectors are ORed.
namespaces
[]string (Optional) Choose namespaces by name. This field is ORed with anything that NamespaceSelectors ends up choosing.
refreshTime
Kubernetes meta/v1.Duration The time in which the controller should reconcile its objects and recheck namespaces for labels.
"},{"location":"api/spec/#external-secrets.io/v1beta1.ClusterExternalSecretStatus","title":"ClusterExternalSecretStatus","text":" (Appears on: ClusterExternalSecret)
ClusterExternalSecretStatus defines the observed state of ClusterExternalSecret.
Field Description externalSecretName
string ExternalSecretName is the name of the ExternalSecrets created by the ClusterExternalSecret
failedNamespaces
[]ClusterExternalSecretNamespaceFailure (Optional) Failed namespaces are the namespaces that failed to apply an ExternalSecret
provisionedNamespaces
[]string (Optional) ProvisionedNamespaces are the namespaces where the ClusterExternalSecret has secrets
conditions
[]ClusterExternalSecretStatusCondition (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.ClusterExternalSecretStatusCondition","title":"ClusterExternalSecretStatusCondition","text":" (Appears on: ClusterExternalSecretStatus)
Field Description type
ClusterExternalSecretConditionType status
Kubernetes core/v1.ConditionStatus message
string (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.ClusterSecretStore","title":"ClusterSecretStore","text":"
ClusterSecretStore represents a secure external location for storing secrets, which can be referenced as part of storeRef
fields.
Field Description metadata
Kubernetes meta/v1.ObjectMeta Refer to the Kubernetes API documentation for the fields of the metadata
field. spec
SecretStoreSpec controller
string (Optional) Used to select the correct ESO controller (think: ingress.ingressClassName) The ESO controller is instantiated with a specific controller name and filters ES based on this property
provider
SecretStoreProvider Used to configure the provider. Only one provider may be set
retrySettings
SecretStoreRetrySettings (Optional) Used to configure http retries if failed
refreshInterval
int (Optional) Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
conditions
[]ClusterSecretStoreCondition (Optional) Used to constraint a ClusterSecretStore to specific namespaces. Relevant only to ClusterSecretStore
status
SecretStoreStatus"},{"location":"api/spec/#external-secrets.io/v1beta1.ClusterSecretStoreCondition","title":"ClusterSecretStoreCondition","text":" (Appears on: SecretStoreSpec)
ClusterSecretStoreCondition describes a condition by which to choose namespaces to process ExternalSecrets in for a ClusterSecretStore instance.
Field Description namespaceSelector
Kubernetes meta/v1.LabelSelector (Optional) Choose namespace using a labelSelector
namespaces
[]string Choose namespaces by name
"},{"location":"api/spec/#external-secrets.io/v1beta1.ConjurAPIKey","title":"ConjurAPIKey","text":" (Appears on: ConjurAuth)
Field Description account
string userRef
External Secrets meta/v1.SecretKeySelector apiKeyRef
External Secrets meta/v1.SecretKeySelector"},{"location":"api/spec/#external-secrets.io/v1beta1.ConjurAuth","title":"ConjurAuth","text":" (Appears on: ConjurProvider)
Field Description apikey
ConjurAPIKey (Optional) jwt
ConjurJWT (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.ConjurJWT","title":"ConjurJWT","text":" (Appears on: ConjurAuth)
Field Description account
string serviceID
string The conjur authn jwt webservice id
hostId
string (Optional) Optional HostID for JWT authentication. This may be used depending on how the Conjur JWT authenticator policy is configured.
secretRef
External Secrets meta/v1.SecretKeySelector (Optional) Optional SecretRef that refers to a key in a Secret resource containing JWT token to authenticate with Conjur using the JWT authentication method.
serviceAccountRef
External Secrets meta/v1.ServiceAccountSelector (Optional) Optional ServiceAccountRef specifies the Kubernetes service account for which to request a token for with the TokenRequest
API.
"},{"location":"api/spec/#external-secrets.io/v1beta1.ConjurProvider","title":"ConjurProvider","text":" (Appears on: SecretStoreProvider)
Field Description url
string caBundle
string (Optional) caProvider
CAProvider (Optional) auth
ConjurAuth"},{"location":"api/spec/#external-secrets.io/v1beta1.DelineaProvider","title":"DelineaProvider","text":" (Appears on: SecretStoreProvider)
See https://github.com/DelineaXPM/dsv-sdk-go/blob/main/vault/vault.go.
Field Description clientId
DelineaProviderSecretRef ClientID is the non-secret part of the credential.
clientSecret
DelineaProviderSecretRef ClientSecret is the secret part of the credential.
tenant
string Tenant is the chosen hostname / site name.
urlTemplate
string (Optional) URLTemplate If unset, defaults to \u201chttps://%s.secretsvaultcloud.%s/v1/%s%s\u201d.
tld
string (Optional) TLD is based on the server location that was chosen during provisioning. If unset, defaults to \u201ccom\u201d.
"},{"location":"api/spec/#external-secrets.io/v1beta1.DelineaProviderSecretRef","title":"DelineaProviderSecretRef","text":" (Appears on: DelineaProvider)
Field Description value
string (Optional) Value can be specified directly to set a value without using a secret.
secretRef
External Secrets meta/v1.SecretKeySelector (Optional) SecretRef references a key in a secret that will be used as value.
"},{"location":"api/spec/#external-secrets.io/v1beta1.DopplerAuth","title":"DopplerAuth","text":" (Appears on: DopplerProvider)
Field Description secretRef
DopplerAuthSecretRef"},{"location":"api/spec/#external-secrets.io/v1beta1.DopplerAuthSecretRef","title":"DopplerAuthSecretRef","text":" (Appears on: DopplerAuth)
Field Description dopplerToken
External Secrets meta/v1.SecretKeySelector The DopplerToken is used for authentication. See https://docs.doppler.com/reference/api#authentication for auth token types. The Key attribute defaults to dopplerToken if not specified.
"},{"location":"api/spec/#external-secrets.io/v1beta1.DopplerProvider","title":"DopplerProvider","text":" (Appears on: SecretStoreProvider)
DopplerProvider configures a store to sync secrets using the Doppler provider. Project and Config are required if not using a Service Token.
Field Description auth
DopplerAuth Auth configures how the Operator authenticates with the Doppler API
project
string (Optional) Doppler project (required if not using a Service Token)
config
string (Optional) Doppler config (required if not using a Service Token)
nameTransformer
string (Optional) Environment variable compatible name transforms that change secret names to a different format
format
string (Optional) Format enables the downloading of secrets as a file (string)
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecret","title":"ExternalSecret","text":"
ExternalSecret is the Schema for the external-secrets API.
Field Description metadata
Kubernetes meta/v1.ObjectMeta Refer to the Kubernetes API documentation for the fields of the metadata
field. spec
ExternalSecretSpec secretStoreRef
SecretStoreRef (Optional) target
ExternalSecretTarget (Optional) refreshInterval
Kubernetes meta/v1.Duration RefreshInterval is the amount of time before the values are read again from the SecretStore provider Valid time units are \u201cns\u201d, \u201cus\u201d (or \u201c\u00b5s\u201d), \u201cms\u201d, \u201cs\u201d, \u201cm\u201d, \u201ch\u201d May be set to zero to fetch and create it once. Defaults to 1h.
data
[]ExternalSecretData (Optional) Data defines the connection between the Kubernetes Secret keys and the Provider data
dataFrom
[]ExternalSecretDataFromRemoteRef (Optional) DataFrom is used to fetch all properties from a specific Provider data If multiple entries are specified, the Secret keys are merged in the specified order
status
ExternalSecretStatus"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretConditionType","title":"ExternalSecretConditionType (string
alias)","text":" (Appears on: ExternalSecretStatusCondition)
Value Description \"Deleted\"
\"Ready\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretConversionStrategy","title":"ExternalSecretConversionStrategy (string
alias)","text":" (Appears on: ExternalSecretDataRemoteRef, ExternalSecretFind)
Value Description \"Default\"
\"Unicode\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretCreationPolicy","title":"ExternalSecretCreationPolicy (string
alias)","text":" (Appears on: ExternalSecretTarget)
ExternalSecretCreationPolicy defines rules on how to create the resulting Secret.
Value Description \"Merge\"
Merge does not create the Secret, but merges the data fields to the Secret.
\"None\"
None does not create a Secret (future use with injector).
\"Orphan\"
Orphan creates the Secret and does not set the ownerReference. I.e. it will be orphaned after the deletion of the ExternalSecret.
\"Owner\"
Owner creates the Secret and sets .metadata.ownerReferences to the ExternalSecret resource.
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretData","title":"ExternalSecretData","text":" (Appears on: ExternalSecretSpec)
ExternalSecretData defines the connection between the Kubernetes Secret key (spec.data.) and the Provider data. Field Description secretKey
string
SecretKey defines the key in which the controller stores the value. This is the key in the Kind=Secret
remoteRef
ExternalSecretDataRemoteRef RemoteRef points to the remote secret and defines which secret (version/property/..) to fetch.
sourceRef
StoreSourceRef SourceRef allows you to override the source from which the value will pulled from.
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretDataFromRemoteRef","title":"ExternalSecretDataFromRemoteRef","text":" (Appears on: ExternalSecretSpec)
Field Description extract
ExternalSecretDataRemoteRef (Optional) Used to extract multiple key/value pairs from one secret Note: Extract does not support sourceRef.Generator or sourceRef.GeneratorRef.
find
ExternalSecretFind (Optional) Used to find secrets based on tags or regular expressions Note: Find does not support sourceRef.Generator or sourceRef.GeneratorRef.
rewrite
[]ExternalSecretRewrite (Optional) Used to rewrite secret Keys after getting them from the secret Provider Multiple Rewrite operations can be provided. They are applied in a layered order (first to last)
sourceRef
StoreGeneratorSourceRef SourceRef points to a store or generator which contains secret values ready to use. Use this in combination with Extract or Find pull values out of a specific SecretStore. When sourceRef points to a generator Extract or Find is not supported. The generator returns a static map of values
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretDataRemoteRef","title":"ExternalSecretDataRemoteRef","text":" (Appears on: ExternalSecretData, ExternalSecretDataFromRemoteRef)
ExternalSecretDataRemoteRef defines Provider data location.
Field Description key
string Key is the key used in the Provider, mandatory
metadataPolicy
ExternalSecretMetadataPolicy (Optional) Policy for fetching tags/labels from provider secrets, possible options are Fetch, None. Defaults to None
property
string (Optional) Used to select a specific property of the Provider value (if a map), if supported
version
string (Optional) Used to select a specific version of the Provider value, if supported
conversionStrategy
ExternalSecretConversionStrategy (Optional) Used to define a conversion Strategy
decodingStrategy
ExternalSecretDecodingStrategy (Optional) Used to define a decoding Strategy
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretDecodingStrategy","title":"ExternalSecretDecodingStrategy (string
alias)","text":" (Appears on: ExternalSecretDataRemoteRef, ExternalSecretFind)
Value Description \"Auto\"
\"Base64\"
\"Base64URL\"
\"None\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretDeletionPolicy","title":"ExternalSecretDeletionPolicy (string
alias)","text":" (Appears on: ExternalSecretTarget)
ExternalSecretDeletionPolicy defines rules on how to delete the resulting Secret.
Value Description \"Delete\"
Delete deletes the secret if all provider secrets are deleted. If a secret gets deleted on the provider side and is not accessible anymore this is not considered an error and the ExternalSecret does not go into SecretSyncedError status.
\"Merge\"
Merge removes keys in the secret, but not the secret itself. If a secret gets deleted on the provider side and is not accessible anymore this is not considered an error and the ExternalSecret does not go into SecretSyncedError status.
\"Retain\"
Retain will retain the secret if all provider secrets have been deleted. If a provider secret does not exist the ExternalSecret gets into the SecretSyncedError status.
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretFind","title":"ExternalSecretFind","text":" (Appears on: ExternalSecretDataFromRemoteRef)
Field Description path
string (Optional) A root path to start the find operations.
name
FindName (Optional) Finds secrets based on the name.
tags
map[string]string (Optional) Find secrets based on tags.
conversionStrategy
ExternalSecretConversionStrategy (Optional) Used to define a conversion Strategy
decodingStrategy
ExternalSecretDecodingStrategy (Optional) Used to define a decoding Strategy
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretMetadata","title":"ExternalSecretMetadata","text":" (Appears on: ClusterExternalSecretSpec)
ExternalSecretMetadata defines metadata fields for the ExternalSecret generated by the ClusterExternalSecret.
Field Description annotations
map[string]string (Optional) labels
map[string]string (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretMetadataPolicy","title":"ExternalSecretMetadataPolicy (string
alias)","text":" (Appears on: ExternalSecretDataRemoteRef)
Value Description \"Fetch\"
\"None\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretRewrite","title":"ExternalSecretRewrite","text":" (Appears on: ExternalSecretDataFromRemoteRef)
Field Description regexp
ExternalSecretRewriteRegexp (Optional) Used to rewrite with regular expressions. The resulting key will be the output of a regexp.ReplaceAll operation.
transform
ExternalSecretRewriteTransform (Optional) Used to apply string transformation on the secrets. The resulting key will be the output of the template applied by the operation.
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretRewriteRegexp","title":"ExternalSecretRewriteRegexp","text":" (Appears on: ExternalSecretRewrite)
Field Description source
string Used to define the regular expression of a re.Compiler.
target
string Used to define the target pattern of a ReplaceAll operation.
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretRewriteTransform","title":"ExternalSecretRewriteTransform","text":" (Appears on: ExternalSecretRewrite)
Field Description template
string Used to define the template to apply on the secret name. .value
will specify the secret name in the template.
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretSpec","title":"ExternalSecretSpec","text":" (Appears on: ClusterExternalSecretSpec, ExternalSecret)
ExternalSecretSpec defines the desired state of ExternalSecret.
Field Description secretStoreRef
SecretStoreRef (Optional) target
ExternalSecretTarget (Optional) refreshInterval
Kubernetes meta/v1.Duration RefreshInterval is the amount of time before the values are read again from the SecretStore provider Valid time units are \u201cns\u201d, \u201cus\u201d (or \u201c\u00b5s\u201d), \u201cms\u201d, \u201cs\u201d, \u201cm\u201d, \u201ch\u201d May be set to zero to fetch and create it once. Defaults to 1h.
data
[]ExternalSecretData (Optional) Data defines the connection between the Kubernetes Secret keys and the Provider data
dataFrom
[]ExternalSecretDataFromRemoteRef (Optional) DataFrom is used to fetch all properties from a specific Provider data If multiple entries are specified, the Secret keys are merged in the specified order
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretStatus","title":"ExternalSecretStatus","text":" (Appears on: ExternalSecret)
Field Description refreshTime
Kubernetes meta/v1.Time refreshTime is the time and date the external secret was fetched and the target secret updated
syncedResourceVersion
string SyncedResourceVersion keeps track of the last synced version
conditions
[]ExternalSecretStatusCondition (Optional) binding
Kubernetes core/v1.LocalObjectReference Binding represents a servicebinding.io Provisioned Service reference to the secret
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretStatusCondition","title":"ExternalSecretStatusCondition","text":" (Appears on: ExternalSecretStatus)
Field Description type
ExternalSecretConditionType status
Kubernetes core/v1.ConditionStatus reason
string (Optional) message
string (Optional) lastTransitionTime
Kubernetes meta/v1.Time (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretTarget","title":"ExternalSecretTarget","text":" (Appears on: ExternalSecretSpec)
ExternalSecretTarget defines the Kubernetes Secret to be created There can be only one target per ExternalSecret.
Field Description name
string (Optional) Name defines the name of the Secret resource to be managed This field is immutable Defaults to the .metadata.name of the ExternalSecret resource
creationPolicy
ExternalSecretCreationPolicy (Optional) CreationPolicy defines rules on how to create the resulting Secret Defaults to \u2018Owner\u2019
deletionPolicy
ExternalSecretDeletionPolicy (Optional) DeletionPolicy defines rules on how to delete the resulting Secret Defaults to \u2018Retain\u2019
template
ExternalSecretTemplate (Optional) Template defines a blueprint for the created Secret resource.
immutable
bool (Optional) Immutable defines if the final secret will be immutable
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretTemplate","title":"ExternalSecretTemplate","text":" (Appears on: ExternalSecretTarget)
ExternalSecretTemplate defines a blueprint for the created Secret resource. we can not use native corev1.Secret, it will have empty ObjectMeta values: https://github.com/kubernetes-sigs/controller-tools/issues/448
Field Description type
Kubernetes core/v1.SecretType (Optional) engineVersion
TemplateEngineVersion EngineVersion specifies the template engine version that should be used to compile/execute the template specified in .data and .templateFrom[].
metadata
ExternalSecretTemplateMetadata (Optional) mergePolicy
TemplateMergePolicy data
map[string]string (Optional) templateFrom
[]TemplateFrom (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretTemplateMetadata","title":"ExternalSecretTemplateMetadata","text":" (Appears on: ExternalSecretTemplate)
ExternalSecretTemplateMetadata defines metadata fields for the Secret blueprint.
Field Description annotations
map[string]string (Optional) labels
map[string]string (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretValidator","title":"ExternalSecretValidator","text":""},{"location":"api/spec/#external-secrets.io/v1beta1.FakeProvider","title":"FakeProvider","text":" (Appears on: SecretStoreProvider)
FakeProvider configures a fake provider that returns static values.
Field Description data
[]FakeProviderData"},{"location":"api/spec/#external-secrets.io/v1beta1.FakeProviderData","title":"FakeProviderData","text":" (Appears on: FakeProvider)
Field Description key
string value
string valueMap
map[string]string Deprecated: ValueMap is deprecated and is intended to be removed in the future, use the value
field instead.
version
string"},{"location":"api/spec/#external-secrets.io/v1beta1.FindName","title":"FindName","text":" (Appears on: ExternalSecretFind)
Field Description regexp
string (Optional) Finds secrets base
"},{"location":"api/spec/#external-secrets.io/v1beta1.FortanixProvider","title":"FortanixProvider","text":" (Appears on: SecretStoreProvider)
Field Description apiUrl
string APIURL is the URL of SDKMS API. Defaults to sdkms.fortanix.com
.
apiKey
FortanixProviderSecretRef APIKey is the API token to access SDKMS Applications.
"},{"location":"api/spec/#external-secrets.io/v1beta1.FortanixProviderSecretRef","title":"FortanixProviderSecretRef","text":" (Appears on: FortanixProvider)
Field Description secretRef
External Secrets meta/v1.SecretKeySelector SecretRef is a reference to a secret containing the SDKMS API Key.
"},{"location":"api/spec/#external-secrets.io/v1beta1.GCPSMAuth","title":"GCPSMAuth","text":" (Appears on: GCPSMProvider)
Field Description secretRef
GCPSMAuthSecretRef (Optional) workloadIdentity
GCPWorkloadIdentity (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.GCPSMAuthSecretRef","title":"GCPSMAuthSecretRef","text":" (Appears on: GCPSMAuth)
Field Description secretAccessKeySecretRef
External Secrets meta/v1.SecretKeySelector (Optional) The SecretAccessKey is used for authentication
"},{"location":"api/spec/#external-secrets.io/v1beta1.GCPSMProvider","title":"GCPSMProvider","text":" (Appears on: SecretStoreProvider)
GCPSMProvider Configures a store to sync secrets using the GCP Secret Manager provider.
Field Description auth
GCPSMAuth (Optional) Auth defines the information necessary to authenticate against GCP
projectID
string ProjectID project where secret is located
"},{"location":"api/spec/#external-secrets.io/v1beta1.GCPWorkloadIdentity","title":"GCPWorkloadIdentity","text":" (Appears on: GCPSMAuth)
Field Description serviceAccountRef
External Secrets meta/v1.ServiceAccountSelector clusterLocation
string clusterName
string clusterProjectID
string"},{"location":"api/spec/#external-secrets.io/v1beta1.GeneratorRef","title":"GeneratorRef","text":" (Appears on: StoreGeneratorSourceRef, StoreSourceRef)
GeneratorRef points to a generator custom resource.
Field Description apiVersion
string Specify the apiVersion of the generator resource
kind
string Specify the Kind of the resource, e.g. Password, ACRAccessToken etc.
name
string Specify the name of the generator resource
"},{"location":"api/spec/#external-secrets.io/v1beta1.GenericStore","title":"GenericStore","text":"
GenericStore is a common interface for interacting with ClusterSecretStore or a namespaced SecretStore.
"},{"location":"api/spec/#external-secrets.io/v1beta1.GenericStoreValidator","title":"GenericStoreValidator","text":""},{"location":"api/spec/#external-secrets.io/v1beta1.GitlabAuth","title":"GitlabAuth","text":" (Appears on: GitlabProvider)
Field Description SecretRef
GitlabSecretRef"},{"location":"api/spec/#external-secrets.io/v1beta1.GitlabProvider","title":"GitlabProvider","text":" (Appears on: SecretStoreProvider)
Configures a store to sync secrets with a GitLab instance.
Field Description url
string URL configures the GitLab instance URL. Defaults to https://gitlab.com/.
auth
GitlabAuth Auth configures how secret-manager authenticates with a GitLab instance.
projectID
string ProjectID specifies a project where secrets are located.
inheritFromGroups
bool InheritFromGroups specifies whether parent groups should be discovered and checked for secrets.
groupIDs
[]string GroupIDs specify, which gitlab groups to pull secrets from. Group secrets are read from left to right followed by the project variables.
environment
string Environment environment_scope of gitlab CI/CD variables (Please see https://docs.gitlab.com/ee/ci/environments/#create-a-static-environment on how to create environments)
"},{"location":"api/spec/#external-secrets.io/v1beta1.GitlabSecretRef","title":"GitlabSecretRef","text":" (Appears on: GitlabAuth)
Field Description accessToken
External Secrets meta/v1.SecretKeySelector AccessToken is used for authentication.
"},{"location":"api/spec/#external-secrets.io/v1beta1.IBMAuth","title":"IBMAuth","text":" (Appears on: IBMProvider)
Field Description secretRef
IBMAuthSecretRef containerAuth
IBMAuthContainerAuth"},{"location":"api/spec/#external-secrets.io/v1beta1.IBMAuthContainerAuth","title":"IBMAuthContainerAuth","text":" (Appears on: IBMAuth)
IBM Container-based auth with IAM Trusted Profile.
Field Description profile
string the IBM Trusted Profile
tokenLocation
string Location the token is mounted on the pod
iamEndpoint
string"},{"location":"api/spec/#external-secrets.io/v1beta1.IBMAuthSecretRef","title":"IBMAuthSecretRef","text":" (Appears on: IBMAuth)
Field Description secretApiKeySecretRef
External Secrets meta/v1.SecretKeySelector The SecretAccessKey is used for authentication
"},{"location":"api/spec/#external-secrets.io/v1beta1.IBMProvider","title":"IBMProvider","text":" (Appears on: SecretStoreProvider)
Configures an store to sync secrets using a IBM Cloud Secrets Manager backend.
Field Description auth
IBMAuth Auth configures how secret-manager authenticates with the IBM secrets manager.
serviceUrl
string ServiceURL is the Endpoint URL that is specific to the Secrets Manager service instance
"},{"location":"api/spec/#external-secrets.io/v1beta1.KeeperSecurityProvider","title":"KeeperSecurityProvider","text":" (Appears on: SecretStoreProvider)
KeeperSecurityProvider Configures a store to sync secrets using Keeper Security.
Field Description authRef
External Secrets meta/v1.SecretKeySelector folderID
string"},{"location":"api/spec/#external-secrets.io/v1beta1.KubernetesAuth","title":"KubernetesAuth","text":" (Appears on: KubernetesProvider)
Field Description cert
CertAuth (Optional) has both clientCert and clientKey as secretKeySelector
token
TokenAuth (Optional) use static token to authenticate with
serviceAccount
External Secrets meta/v1.ServiceAccountSelector (Optional) points to a service account that should be used for authentication
"},{"location":"api/spec/#external-secrets.io/v1beta1.KubernetesProvider","title":"KubernetesProvider","text":" (Appears on: SecretStoreProvider)
Configures a store to sync secrets with a Kubernetes instance.
Field Description server
KubernetesServer configures the Kubernetes server Address.
auth
KubernetesAuth Auth configures how secret-manager authenticates with a Kubernetes instance.
remoteNamespace
string (Optional) Remote namespace to fetch the secrets from
"},{"location":"api/spec/#external-secrets.io/v1beta1.KubernetesServer","title":"KubernetesServer","text":" (Appears on: KubernetesProvider)
Field Description url
string (Optional) configures the Kubernetes server Address.
caBundle
[]byte (Optional) CABundle is a base64-encoded CA certificate
caProvider
CAProvider (Optional) see: https://external-secrets.io/v0.4.1/spec/#external-secrets.io/v1alpha1.CAProvider
"},{"location":"api/spec/#external-secrets.io/v1beta1.NoSecretError","title":"NoSecretError","text":"
NoSecretError shall be returned when a GetSecret can not find the desired secret. This is used for deletionPolicy.
"},{"location":"api/spec/#external-secrets.io/v1beta1.OnboardbaseAuthSecretRef","title":"OnboardbaseAuthSecretRef","text":" (Appears on: OnboardbaseProvider)
OnboardbaseAuthSecretRef holds secret references for onboardbase API Key credentials.
Field Description apiKeyRef
External Secrets meta/v1.SecretKeySelector OnboardbaseAPIKey is the APIKey generated by an admin account. It is used to recognize and authorize access to a project and environment within onboardbase
passcodeRef
External Secrets meta/v1.SecretKeySelector OnboardbasePasscode is the passcode attached to the API Key
"},{"location":"api/spec/#external-secrets.io/v1beta1.OnboardbaseProvider","title":"OnboardbaseProvider","text":" (Appears on: SecretStoreProvider)
OnboardbaseProvider configures a store to sync secrets using the Onboardbase provider. Project and Config are required if not using a Service Token.
Field Description auth
OnboardbaseAuthSecretRef Auth configures how the Operator authenticates with the Onboardbase API
apiHost
string APIHost use this to configure the host url for the API for selfhosted installation, default is https://public.onboardbase.com/api/v1/
project
string Project is an onboardbase project that the secrets should be pulled from
environment
string Environment is the name of an environmnent within a project to pull the secrets from
"},{"location":"api/spec/#external-secrets.io/v1beta1.OnePasswordAuth","title":"OnePasswordAuth","text":" (Appears on: OnePasswordProvider)
OnePasswordAuth contains a secretRef for credentials.
Field Description secretRef
OnePasswordAuthSecretRef"},{"location":"api/spec/#external-secrets.io/v1beta1.OnePasswordAuthSecretRef","title":"OnePasswordAuthSecretRef","text":" (Appears on: OnePasswordAuth)
OnePasswordAuthSecretRef holds secret references for 1Password credentials.
Field Description connectTokenSecretRef
External Secrets meta/v1.SecretKeySelector The ConnectToken is used for authentication to a 1Password Connect Server.
"},{"location":"api/spec/#external-secrets.io/v1beta1.OnePasswordProvider","title":"OnePasswordProvider","text":" (Appears on: SecretStoreProvider)
OnePasswordProvider configures a store to sync secrets using the 1Password Secret Manager provider.
Field Description auth
OnePasswordAuth Auth defines the information necessary to authenticate against OnePassword Connect Server
connectHost
string ConnectHost defines the OnePassword Connect Server to connect to
vaults
map[string]int Vaults defines which OnePassword vaults to search in which order
"},{"location":"api/spec/#external-secrets.io/v1beta1.OracleAuth","title":"OracleAuth","text":" (Appears on: OracleProvider)
Field Description tenancy
string Tenancy is the tenancy OCID where user is located.
user
string User is an access OCID specific to the account.
secretRef
OracleSecretRef SecretRef to pass through sensitive information.
"},{"location":"api/spec/#external-secrets.io/v1beta1.OraclePrincipalType","title":"OraclePrincipalType (string
alias)","text":" (Appears on: OracleProvider)
Value Description \"InstancePrincipal\"
InstancePrincipal represents a instance principal.
\"UserPrincipal\"
UserPrincipal represents a user principal.
\"Workload\"
WorkloadPrincipal represents a workload principal.
"},{"location":"api/spec/#external-secrets.io/v1beta1.OracleProvider","title":"OracleProvider","text":" (Appears on: SecretStoreProvider)
Configures an store to sync secrets using a Oracle Vault backend.
Field Description region
string Region is the region where vault is located.
vault
string Vault is the vault\u2019s OCID of the specific vault where secret is located.
compartment
string (Optional) Compartment is the vault compartment OCID. Required for PushSecret
encryptionKey
string (Optional) EncryptionKey is the OCID of the encryption key within the vault. Required for PushSecret
principalType
OraclePrincipalType (Optional) The type of principal to use for authentication. If left blank, the Auth struct will determine the principal type. This optional field must be specified if using workload identity.
auth
OracleAuth (Optional) Auth configures how secret-manager authenticates with the Oracle Vault. If empty, use the instance principal, otherwise the user credentials specified in Auth.
serviceAccountRef
External Secrets meta/v1.ServiceAccountSelector (Optional) ServiceAccountRef specified the service account that should be used when authenticating with WorkloadIdentity.
"},{"location":"api/spec/#external-secrets.io/v1beta1.OracleSecretRef","title":"OracleSecretRef","text":" (Appears on: OracleAuth)
Field Description privatekey
External Secrets meta/v1.SecretKeySelector PrivateKey is the user\u2019s API Signing Key in PEM format, used for authentication.
fingerprint
External Secrets meta/v1.SecretKeySelector Fingerprint is the fingerprint of the API private key.
"},{"location":"api/spec/#external-secrets.io/v1beta1.PassboltAuth","title":"PassboltAuth","text":" (Appears on: PassboltProvider)
Passbolt contains a secretRef for the passbolt credentials.
Field Description passwordSecretRef
External Secrets meta/v1.SecretKeySelector privateKeySecretRef
External Secrets meta/v1.SecretKeySelector"},{"location":"api/spec/#external-secrets.io/v1beta1.PassboltProvider","title":"PassboltProvider","text":" (Appears on: SecretStoreProvider)
Field Description auth
PassboltAuth Auth defines the information necessary to authenticate against Passbolt Server
host
string Host defines the Passbolt Server to connect to
"},{"location":"api/spec/#external-secrets.io/v1beta1.PasswordDepotAuth","title":"PasswordDepotAuth","text":" (Appears on: PasswordDepotProvider)
Field Description secretRef
PasswordDepotSecretRef"},{"location":"api/spec/#external-secrets.io/v1beta1.PasswordDepotProvider","title":"PasswordDepotProvider","text":" (Appears on: SecretStoreProvider)
Configures a store to sync secrets with a Password Depot instance.
Field Description host
string URL configures the Password Depot instance URL.
database
string Database to use as source
auth
PasswordDepotAuth Auth configures how secret-manager authenticates with a Password Depot instance.
"},{"location":"api/spec/#external-secrets.io/v1beta1.PasswordDepotSecretRef","title":"PasswordDepotSecretRef","text":" (Appears on: PasswordDepotAuth)
Field Description credentials
External Secrets meta/v1.SecretKeySelector (Optional) Username / Password is used for authentication.
"},{"location":"api/spec/#external-secrets.io/v1beta1.Provider","title":"Provider","text":"
Provider is a common interface for interacting with secret backends.
"},{"location":"api/spec/#external-secrets.io/v1beta1.PulumiProvider","title":"PulumiProvider","text":" (Appears on: SecretStoreProvider)
Field Description apiUrl
string APIURL is the URL of the Pulumi API.
accessToken
PulumiProviderSecretRef AccessToken is the access tokens to sign in to the Pulumi Cloud Console.
organization
string Organization are a space to collaborate on shared projects and stacks. To create a new organization, visit https://app.pulumi.com/ and click \u201cNew Organization\u201d.
environment
string Environment are YAML documents composed of static key-value pairs, programmatic expressions, dynamically retrieved values from supported providers including all major clouds, and other Pulumi ESC environments. To create a new environment, visit https://www.pulumi.com/docs/esc/environments/ for more information.
"},{"location":"api/spec/#external-secrets.io/v1beta1.PulumiProviderSecretRef","title":"PulumiProviderSecretRef","text":" (Appears on: PulumiProvider)
Field Description secretRef
External Secrets meta/v1.SecretKeySelector SecretRef is a reference to a secret containing the Pulumi API token.
"},{"location":"api/spec/#external-secrets.io/v1beta1.PushSecretData","title":"PushSecretData","text":"
PushSecretData is an interface to allow using v1alpha1.PushSecretData content in Provider registered in v1beta1.
"},{"location":"api/spec/#external-secrets.io/v1beta1.PushSecretRemoteRef","title":"PushSecretRemoteRef","text":"
PushSecretRemoteRef is an interface to allow using v1alpha1.PushSecretRemoteRef in Provider registered in v1beta1.
"},{"location":"api/spec/#external-secrets.io/v1beta1.ScalewayProvider","title":"ScalewayProvider","text":" (Appears on: SecretStoreProvider)
Field Description apiUrl
string (Optional) APIURL is the url of the api to use. Defaults to https://api.scaleway.com
region
string Region where your secrets are located: https://developers.scaleway.com/en/quickstart/#region-and-zone
projectId
string ProjectID is the id of your project, which you can find in the console: https://console.scaleway.com/project/settings
accessKey
ScalewayProviderSecretRef AccessKey is the non-secret part of the api key.
secretKey
ScalewayProviderSecretRef SecretKey is the non-secret part of the api key.
"},{"location":"api/spec/#external-secrets.io/v1beta1.ScalewayProviderSecretRef","title":"ScalewayProviderSecretRef","text":" (Appears on: ScalewayProvider)
Field Description value
string (Optional) Value can be specified directly to set a value without using a secret.
secretRef
External Secrets meta/v1.SecretKeySelector (Optional) SecretRef references a key in a secret that will be used as value.
"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStore","title":"SecretStore","text":"
SecretStore represents a secure external location for storing secrets, which can be referenced as part of storeRef
fields.
Field Description metadata
Kubernetes meta/v1.ObjectMeta Refer to the Kubernetes API documentation for the fields of the metadata
field. spec
SecretStoreSpec controller
string (Optional) Used to select the correct ESO controller (think: ingress.ingressClassName) The ESO controller is instantiated with a specific controller name and filters ES based on this property
provider
SecretStoreProvider Used to configure the provider. Only one provider may be set
retrySettings
SecretStoreRetrySettings (Optional) Used to configure http retries if failed
refreshInterval
int (Optional) Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
conditions
[]ClusterSecretStoreCondition (Optional) Used to constraint a ClusterSecretStore to specific namespaces. Relevant only to ClusterSecretStore
status
SecretStoreStatus"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStoreCapabilities","title":"SecretStoreCapabilities (string
alias)","text":" (Appears on: SecretStoreStatus)
SecretStoreCapabilities defines the possible operations a SecretStore can do.
Value Description \"ReadOnly\"
\"ReadWrite\"
\"WriteOnly\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStoreConditionType","title":"SecretStoreConditionType (string
alias)","text":" (Appears on: SecretStoreStatusCondition)
Value Description \"Ready\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStoreProvider","title":"SecretStoreProvider","text":" (Appears on: SecretStoreSpec)
SecretStoreProvider contains the provider-specific configuration.
Field Description aws
AWSProvider (Optional) AWS configures this store to sync secrets using AWS Secret Manager provider
azurekv
AzureKVProvider (Optional) AzureKV configures this store to sync secrets using Azure Key Vault provider
akeyless
AkeylessProvider (Optional) Akeyless configures this store to sync secrets using Akeyless Vault provider
vault
VaultProvider (Optional) Vault configures this store to sync secrets using Hashi provider
gcpsm
GCPSMProvider (Optional) GCPSM configures this store to sync secrets using Google Cloud Platform Secret Manager provider
oracle
OracleProvider (Optional) Oracle configures this store to sync secrets using Oracle Vault provider
ibm
IBMProvider (Optional) IBM configures this store to sync secrets using IBM Cloud provider
yandexcertificatemanager
YandexCertificateManagerProvider (Optional) YandexCertificateManager configures this store to sync secrets using Yandex Certificate Manager provider
yandexlockbox
YandexLockboxProvider (Optional) YandexLockbox configures this store to sync secrets using Yandex Lockbox provider
gitlab
GitlabProvider (Optional) GitLab configures this store to sync secrets using GitLab Variables provider
alibaba
AlibabaProvider (Optional) Alibaba configures this store to sync secrets using Alibaba Cloud provider
onepassword
OnePasswordProvider (Optional) OnePassword configures this store to sync secrets using the 1Password Cloud provider
webhook
WebhookProvider (Optional) Webhook configures this store to sync secrets using a generic templated webhook
kubernetes
KubernetesProvider (Optional) Kubernetes configures this store to sync secrets using a Kubernetes cluster provider
fake
FakeProvider (Optional) Fake configures a store with static key/value pairs
senhasegura
SenhaseguraProvider (Optional) Senhasegura configures this store to sync secrets using senhasegura provider
scaleway
ScalewayProvider (Optional) Scaleway
doppler
DopplerProvider (Optional) Doppler configures this store to sync secrets using the Doppler provider
onboardbase
OnboardbaseProvider (Optional) Onboardbase configures this store to sync secrets using the Onboardbase provider
keepersecurity
KeeperSecurityProvider (Optional) KeeperSecurity configures this store to sync secrets using the KeeperSecurity provider
conjur
ConjurProvider (Optional) Conjur configures this store to sync secrets using conjur provider
delinea
DelineaProvider (Optional) Delinea DevOps Secrets Vault https://docs.delinea.com/online-help/products/devops-secrets-vault/current
chef
ChefProvider (Optional) Chef configures this store to sync secrets with chef server
pulumi
PulumiProvider (Optional) Pulumi configures this store to sync secrets using the Pulumi provider
fortanix
FortanixProvider (Optional) Fortanix configures this store to sync secrets using the Fortanix provider
passworddepot
PasswordDepotProvider (Optional) passbolt
PassboltProvider (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStoreRef","title":"SecretStoreRef","text":" (Appears on: ExternalSecretSpec, StoreGeneratorSourceRef, StoreSourceRef)
SecretStoreRef defines which SecretStore to fetch the ExternalSecret data.
Field Description name
string Name of the SecretStore resource
kind
string (Optional) Kind of the SecretStore resource (SecretStore or ClusterSecretStore) Defaults to SecretStore
"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStoreRetrySettings","title":"SecretStoreRetrySettings","text":" (Appears on: SecretStoreSpec)
Field Description maxRetries
int32 retryInterval
string"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStoreSpec","title":"SecretStoreSpec","text":" (Appears on: ClusterSecretStore, SecretStore)
SecretStoreSpec defines the desired state of SecretStore.
Field Description controller
string (Optional) Used to select the correct ESO controller (think: ingress.ingressClassName) The ESO controller is instantiated with a specific controller name and filters ES based on this property
provider
SecretStoreProvider Used to configure the provider. Only one provider may be set
retrySettings
SecretStoreRetrySettings (Optional) Used to configure http retries if failed
refreshInterval
int (Optional) Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
conditions
[]ClusterSecretStoreCondition (Optional) Used to constraint a ClusterSecretStore to specific namespaces. Relevant only to ClusterSecretStore
"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStoreStatus","title":"SecretStoreStatus","text":" (Appears on: ClusterSecretStore, SecretStore)
SecretStoreStatus defines the observed state of the SecretStore.
Field Description conditions
[]SecretStoreStatusCondition (Optional) capabilities
SecretStoreCapabilities (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStoreStatusCondition","title":"SecretStoreStatusCondition","text":" (Appears on: SecretStoreStatus)
Field Description type
SecretStoreConditionType status
Kubernetes core/v1.ConditionStatus reason
string (Optional) message
string (Optional) lastTransitionTime
Kubernetes meta/v1.Time (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretsClient","title":"SecretsClient","text":"
SecretsClient provides access to secrets.
"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretsManager","title":"SecretsManager","text":" (Appears on: AWSProvider)
SecretsManager defines how the provider behaves when interacting with AWS SecretsManager. Some of these settings are only applicable to controlling how secrets are deleted, and hence only apply to PushSecret (and only when deletionPolicy is set to Delete).
Field Description forceDeleteWithoutRecovery
bool (Optional) Specifies whether to delete the secret without any recovery window. You can\u2019t use both this parameter and RecoveryWindowInDays in the same call. If you don\u2019t use either, then by default Secrets Manager uses a 30 day recovery window. see: https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_DeleteSecret.html#SecretsManager-DeleteSecret-request-ForceDeleteWithoutRecovery
recoveryWindowInDays
int64 (Optional) The number of days from 7 to 30 that Secrets Manager waits before permanently deleting the secret. You can\u2019t use both this parameter and ForceDeleteWithoutRecovery in the same call. If you don\u2019t use either, then by default Secrets Manager uses a 30 day recovery window. see: https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_DeleteSecret.html#SecretsManager-DeleteSecret-request-RecoveryWindowInDays
"},{"location":"api/spec/#external-secrets.io/v1beta1.SenhaseguraAuth","title":"SenhaseguraAuth","text":" (Appears on: SenhaseguraProvider)
SenhaseguraAuth tells the controller how to do auth in senhasegura.
Field Description clientId
string clientSecretSecretRef
External Secrets meta/v1.SecretKeySelector"},{"location":"api/spec/#external-secrets.io/v1beta1.SenhaseguraModuleType","title":"SenhaseguraModuleType (string
alias)","text":" (Appears on: SenhaseguraProvider)
SenhaseguraModuleType enum defines senhasegura target module to fetch secrets
Value Description \"DSM\"
SenhaseguraModuleDSM is the senhasegura DevOps Secrets Management module\nsee: https://senhasegura.com/devops\n
"},{"location":"api/spec/#external-secrets.io/v1beta1.SenhaseguraProvider","title":"SenhaseguraProvider","text":" (Appears on: SecretStoreProvider)
SenhaseguraProvider setup a store to sync secrets with senhasegura.
Field Description url
string URL of senhasegura
module
SenhaseguraModuleType Module defines which senhasegura module should be used to get secrets
auth
SenhaseguraAuth Auth defines parameters to authenticate in senhasegura
ignoreSslCertificate
bool IgnoreSslCertificate defines if SSL certificate must be ignored
"},{"location":"api/spec/#external-secrets.io/v1beta1.StoreGeneratorSourceRef","title":"StoreGeneratorSourceRef","text":" (Appears on: ExternalSecretDataFromRemoteRef)
StoreGeneratorSourceRef allows you to override the source from which the secret will be pulled from. You can define at maximum one property.
Field Description storeRef
SecretStoreRef (Optional) generatorRef
GeneratorRef (Optional) GeneratorRef points to a generator custom resource.
"},{"location":"api/spec/#external-secrets.io/v1beta1.StoreSourceRef","title":"StoreSourceRef","text":" (Appears on: ExternalSecretData)
StoreSourceRef allows you to override the SecretStore source from which the secret will be pulled from. You can define at maximum one property.
Field Description storeRef
SecretStoreRef (Optional) generatorRef
GeneratorRef GeneratorRef points to a generator custom resource.
Deprecated: The generatorRef is not implemented in .data[]. this will be removed with v1.
"},{"location":"api/spec/#external-secrets.io/v1beta1.Tag","title":"Tag","text":"Field Description key
string value
string"},{"location":"api/spec/#external-secrets.io/v1beta1.TemplateEngineVersion","title":"TemplateEngineVersion (string
alias)","text":" (Appears on: ExternalSecretTemplate)
Value Description \"v1\"
\"v2\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.TemplateFrom","title":"TemplateFrom","text":" (Appears on: ExternalSecretTemplate)
Field Description configMap
TemplateRef secret
TemplateRef target
TemplateTarget (Optional) literal
string (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.TemplateMergePolicy","title":"TemplateMergePolicy (string
alias)","text":" (Appears on: ExternalSecretTemplate)
Value Description \"Merge\"
\"Replace\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.TemplateRef","title":"TemplateRef","text":" (Appears on: TemplateFrom)
Field Description name
string items
[]TemplateRefItem"},{"location":"api/spec/#external-secrets.io/v1beta1.TemplateRefItem","title":"TemplateRefItem","text":" (Appears on: TemplateRef)
Field Description key
string templateAs
TemplateScope"},{"location":"api/spec/#external-secrets.io/v1beta1.TemplateScope","title":"TemplateScope (string
alias)","text":" (Appears on: TemplateRefItem)
Value Description \"KeysAndValues\"
\"Values\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.TemplateTarget","title":"TemplateTarget (string
alias)","text":" (Appears on: TemplateFrom)
Value Description \"Annotations\"
\"Data\"
\"Labels\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.TokenAuth","title":"TokenAuth","text":" (Appears on: KubernetesAuth)
Field Description bearerToken
External Secrets meta/v1.SecretKeySelector"},{"location":"api/spec/#external-secrets.io/v1beta1.ValidationResult","title":"ValidationResult (byte
alias)","text":"Value Description 2
Error indicates that there is a misconfiguration.
0
Ready indicates that the client is configured correctly and can be used.
1
Unknown indicates that the client can be used but information is missing and it can not be validated.
"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultAppRole","title":"VaultAppRole","text":" (Appears on: VaultAuth)
VaultAppRole authenticates with Vault using the App Role auth mechanism, with the role and secret stored in a Kubernetes Secret resource.
Field Description path
string Path where the App Role authentication backend is mounted in Vault, e.g: \u201capprole\u201d
roleId
string (Optional) RoleID configured in the App Role authentication backend when setting up the authentication backend in Vault.
roleRef
External Secrets meta/v1.SecretKeySelector (Optional) Reference to a key in a Secret that contains the App Role ID used to authenticate with Vault. The key
field must be specified and denotes which entry within the Secret resource is used as the app role id.
secretRef
External Secrets meta/v1.SecretKeySelector Reference to a key in a Secret that contains the App Role secret used to authenticate with Vault. The key
field must be specified and denotes which entry within the Secret resource is used as the app role secret.
"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultAuth","title":"VaultAuth","text":" (Appears on: VaultProvider)
VaultAuth is the configuration used to authenticate with a Vault server. Only one of tokenSecretRef
, appRole
, kubernetes
, ldap
, userPass
, jwt
or cert
can be specified. A namespace to authenticate against can optionally be specified.
Field Description namespace
string (Optional) Name of the vault namespace to authenticate to. This can be different than the namespace your secret is in. Namespaces is a set of features within Vault Enterprise that allows Vault environments to support Secure Multi-tenancy. e.g: \u201cns1\u201d. More about namespaces can be found here https://www.vaultproject.io/docs/enterprise/namespaces This will default to Vault.Namespace field if set, or empty otherwise
tokenSecretRef
External Secrets meta/v1.SecretKeySelector (Optional) TokenSecretRef authenticates with Vault by presenting a token.
appRole
VaultAppRole (Optional) AppRole authenticates with Vault using the App Role auth mechanism, with the role and secret stored in a Kubernetes Secret resource.
kubernetes
VaultKubernetesAuth (Optional) Kubernetes authenticates with Vault by passing the ServiceAccount token stored in the named Secret resource to the Vault server.
ldap
VaultLdapAuth (Optional) Ldap authenticates with Vault by passing username/password pair using the LDAP authentication method
jwt
VaultJwtAuth (Optional) Jwt authenticates with Vault by passing role and JWT token using the JWT/OIDC authentication method
cert
VaultCertAuth (Optional) Cert authenticates with TLS Certificates by passing client certificate, private key and ca certificate Cert authentication method
iam
VaultIamAuth (Optional) Iam authenticates with vault by passing a special AWS request signed with AWS IAM credentials AWS IAM authentication method
userPass
VaultUserPassAuth (Optional) UserPass authenticates with Vault by passing username/password pair
"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultAwsAuth","title":"VaultAwsAuth","text":"
VaultAwsAuth tells the controller how to do authentication with aws. Only one of secretRef or jwt can be specified. if none is specified the controller will try to load credentials from its own service account assuming it is IRSA enabled.
Field Description secretRef
VaultAwsAuthSecretRef (Optional) jwt
VaultAwsJWTAuth (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultAwsAuthSecretRef","title":"VaultAwsAuthSecretRef","text":" (Appears on: VaultAwsAuth, VaultIamAuth)
VaultAWSAuthSecretRef holds secret references for AWS credentials both AccessKeyID and SecretAccessKey must be defined in order to properly authenticate.
Field Description accessKeyIDSecretRef
External Secrets meta/v1.SecretKeySelector The AccessKeyID is used for authentication
secretAccessKeySecretRef
External Secrets meta/v1.SecretKeySelector The SecretAccessKey is used for authentication
sessionTokenSecretRef
External Secrets meta/v1.SecretKeySelector The SessionToken used for authentication This must be defined if AccessKeyID and SecretAccessKey are temporary credentials see: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html
"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultAwsJWTAuth","title":"VaultAwsJWTAuth","text":" (Appears on: VaultAwsAuth, VaultIamAuth)
Authenticate against AWS using service account tokens.
Field Description serviceAccountRef
External Secrets meta/v1.ServiceAccountSelector"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultCertAuth","title":"VaultCertAuth","text":" (Appears on: VaultAuth)
VaultJwtAuth authenticates with Vault using the JWT/OIDC authentication method, with the role name and token stored in a Kubernetes Secret resource.
Field Description clientCert
External Secrets meta/v1.SecretKeySelector (Optional) ClientCert is a certificate to authenticate using the Cert Vault authentication method
secretRef
External Secrets meta/v1.SecretKeySelector SecretRef to a key in a Secret resource containing client private key to authenticate with Vault using the Cert authentication method
"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultClientTLS","title":"VaultClientTLS","text":" (Appears on: VaultProvider)
VaultClientTLS is the configuration used for client side related TLS communication, when the Vault server requires mutual authentication.
Field Description certSecretRef
External Secrets meta/v1.SecretKeySelector CertSecretRef is a certificate added to the transport layer when communicating with the Vault server. If no key for the Secret is specified, external-secret will default to \u2018tls.crt\u2019.
keySecretRef
External Secrets meta/v1.SecretKeySelector KeySecretRef to a key in a Secret resource containing client private key added to the transport layer when communicating with the Vault server. If no key for the Secret is specified, external-secret will default to \u2018tls.key\u2019.
"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultIamAuth","title":"VaultIamAuth","text":" (Appears on: VaultAuth)
VaultIamAuth authenticates with Vault using the Vault\u2019s AWS IAM authentication method. Refer: https://developer.hashicorp.com/vault/docs/auth/aws
Field Description path
string Path where the AWS auth method is enabled in Vault, e.g: \u201caws\u201d
region
string AWS region
role
string This is the AWS role to be assumed before talking to vault
vaultRole
string Vault Role. In vault, a role describes an identity with a set of permissions, groups, or policies you want to attach a user of the secrets engine
externalID
string AWS External ID set on assumed IAM roles
vaultAwsIamServerID
string X-Vault-AWS-IAM-Server-ID is an additional header used by Vault IAM auth method to mitigate against different types of replay attacks. More details here: https://developer.hashicorp.com/vault/docs/auth/aws
secretRef
VaultAwsAuthSecretRef (Optional) Specify credentials in a Secret object
jwt
VaultAwsJWTAuth (Optional) Specify a service account with IRSA enabled
"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultJwtAuth","title":"VaultJwtAuth","text":" (Appears on: VaultAuth)
VaultJwtAuth authenticates with Vault using the JWT/OIDC authentication method, with the role name and a token stored in a Kubernetes Secret resource or a Kubernetes service account token retrieved via TokenRequest
.
Field Description path
string Path where the JWT authentication backend is mounted in Vault, e.g: \u201cjwt\u201d
role
string (Optional) Role is a JWT role to authenticate using the JWT/OIDC Vault authentication method
secretRef
External Secrets meta/v1.SecretKeySelector (Optional) Optional SecretRef that refers to a key in a Secret resource containing JWT token to authenticate with Vault using the JWT/OIDC authentication method.
kubernetesServiceAccountToken
VaultKubernetesServiceAccountTokenAuth (Optional) Optional ServiceAccountToken specifies the Kubernetes service account for which to request a token for with the TokenRequest
API.
"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultKVStoreVersion","title":"VaultKVStoreVersion (string
alias)","text":" (Appears on: VaultProvider)
Value Description \"v1\"
\"v2\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultKubernetesAuth","title":"VaultKubernetesAuth","text":" (Appears on: VaultAuth)
Authenticate against Vault using a Kubernetes ServiceAccount token stored in a Secret.
Field Description mountPath
string Path where the Kubernetes authentication backend is mounted in Vault, e.g: \u201ckubernetes\u201d
serviceAccountRef
External Secrets meta/v1.ServiceAccountSelector (Optional) Optional service account field containing the name of a kubernetes ServiceAccount. If the service account is specified, the service account secret token JWT will be used for authenticating with Vault. If the service account selector is not supplied, the secretRef will be used instead.
secretRef
External Secrets meta/v1.SecretKeySelector (Optional) Optional secret field containing a Kubernetes ServiceAccount JWT used for authenticating with Vault. If a name is specified without a key, token
is the default. If one is not specified, the one bound to the controller will be used.
role
string A required field containing the Vault Role to assume. A Role binds a Kubernetes ServiceAccount with a set of Vault policies.
"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultKubernetesServiceAccountTokenAuth","title":"VaultKubernetesServiceAccountTokenAuth","text":" (Appears on: VaultJwtAuth)
VaultKubernetesServiceAccountTokenAuth authenticates with Vault using a temporary Kubernetes service account token retrieved by the TokenRequest
API.
Field Description serviceAccountRef
External Secrets meta/v1.ServiceAccountSelector Service account field containing the name of a kubernetes ServiceAccount.
audiences
[]string (Optional) Optional audiences field that will be used to request a temporary Kubernetes service account token for the service account referenced by serviceAccountRef
. Defaults to a single audience vault
it not specified. Deprecated: use serviceAccountRef.Audiences instead
expirationSeconds
int64 (Optional) Optional expiration time in seconds that will be used to request a temporary Kubernetes service account token for the service account referenced by serviceAccountRef
. Deprecated: this will be removed in the future. Defaults to 10 minutes.
"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultLdapAuth","title":"VaultLdapAuth","text":" (Appears on: VaultAuth)
VaultLdapAuth authenticates with Vault using the LDAP authentication method, with the username and password stored in a Kubernetes Secret resource.
Field Description path
string Path where the LDAP authentication backend is mounted in Vault, e.g: \u201cldap\u201d
username
string Username is a LDAP user name used to authenticate using the LDAP Vault authentication method
secretRef
External Secrets meta/v1.SecretKeySelector SecretRef to a key in a Secret resource containing password for the LDAP user used to authenticate with Vault using the LDAP authentication method
"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultProvider","title":"VaultProvider","text":" (Appears on: SecretStoreProvider)
Configures an store to sync secrets using a HashiCorp Vault KV backend.
Field Description auth
VaultAuth Auth configures how secret-manager authenticates with the Vault server.
server
string Server is the connection address for the Vault server, e.g: \u201chttps://vault.example.com:8200\u201d.
path
string (Optional) Path is the mount path of the Vault KV backend endpoint, e.g: \u201csecret\u201d. The v2 KV secret engine version specific \u201c/data\u201d path suffix for fetching secrets from Vault is optional and will be appended if not present in specified path.
version
VaultKVStoreVersion Version is the Vault KV secret engine version. This can be either \u201cv1\u201d or \u201cv2\u201d. Version defaults to \u201cv2\u201d.
namespace
string (Optional) Name of the vault namespace. Namespaces is a set of features within Vault Enterprise that allows Vault environments to support Secure Multi-tenancy. e.g: \u201cns1\u201d. More about namespaces can be found here https://www.vaultproject.io/docs/enterprise/namespaces
caBundle
[]byte (Optional) PEM encoded CA bundle used to validate Vault server certificate. Only used if the Server URL is using HTTPS protocol. This parameter is ignored for plain HTTP protocol connection. If not set the system root certificates are used to validate the TLS connection.
tls
VaultClientTLS (Optional) The configuration used for client side related TLS communication, when the Vault server requires mutual authentication. Only used if the Server URL is using HTTPS protocol. This parameter is ignored for plain HTTP protocol connection. It\u2019s worth noting this configuration is different from the \u201cTLS certificates auth method\u201d, which is available under the auth.cert
section.
caProvider
CAProvider (Optional) The provider for the CA bundle to use to validate Vault server certificate.
readYourWrites
bool (Optional) ReadYourWrites ensures isolated read-after-write semantics by providing discovered cluster replication states in each request. More information about eventual consistency in Vault can be found here https://www.vaultproject.io/docs/enterprise/consistency
forwardInconsistent
bool (Optional) ForwardInconsistent tells Vault to forward read-after-write requests to the Vault leader instead of simply retrying within a loop. This can increase performance if the option is enabled serverside. https://www.vaultproject.io/docs/configuration/replication#allow_forwarding_via_header
"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultUserPassAuth","title":"VaultUserPassAuth","text":" (Appears on: VaultAuth)
VaultUserPassAuth authenticates with Vault using UserPass authentication method, with the username and password stored in a Kubernetes Secret resource.
Field Description path
string Path where the UserPassword authentication backend is mounted in Vault, e.g: \u201cuser\u201d
username
string Username is a user name used to authenticate using the UserPass Vault authentication method
secretRef
External Secrets meta/v1.SecretKeySelector SecretRef to a key in a Secret resource containing password for the user used to authenticate with Vault using the UserPass authentication method
"},{"location":"api/spec/#external-secrets.io/v1beta1.WebhookCAProvider","title":"WebhookCAProvider","text":" (Appears on: WebhookProvider)
Defines a location to fetch the cert for the webhook provider from.
Field Description type
WebhookCAProviderType The type of provider to use such as \u201cSecret\u201d, or \u201cConfigMap\u201d.
name
string The name of the object located at the provider type.
key
string The key the value inside of the provider type to use, only used with \u201cSecret\u201d type
namespace
string (Optional) The namespace the Provider type is in.
"},{"location":"api/spec/#external-secrets.io/v1beta1.WebhookCAProviderType","title":"WebhookCAProviderType (string
alias)","text":" (Appears on: WebhookCAProvider)
Value Description \"ConfigMap\"
\"Secret\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.WebhookProvider","title":"WebhookProvider","text":" (Appears on: SecretStoreProvider)
AkeylessProvider Configures an store to sync secrets using Akeyless KV.
Field Description method
string Webhook Method
url
string Webhook url to call
headers
map[string]string (Optional) Headers
body
string (Optional) Body
timeout
Kubernetes meta/v1.Duration (Optional) Timeout
result
WebhookResult Result formatting
secrets
[]WebhookSecret (Optional) Secrets to fill in templates These secrets will be passed to the templating function as key value pairs under the given name
caBundle
[]byte (Optional) PEM encoded CA bundle used to validate webhook server certificate. Only used if the Server URL is using HTTPS protocol. This parameter is ignored for plain HTTP protocol connection. If not set the system root certificates are used to validate the TLS connection.
caProvider
WebhookCAProvider (Optional) The provider for the CA bundle to use to validate webhook server certificate.
"},{"location":"api/spec/#external-secrets.io/v1beta1.WebhookResult","title":"WebhookResult","text":" (Appears on: WebhookProvider)
Field Description jsonPath
string (Optional) Json path of return value
"},{"location":"api/spec/#external-secrets.io/v1beta1.WebhookSecret","title":"WebhookSecret","text":" (Appears on: WebhookProvider)
Field Description name
string Name of this secret in templates
secretRef
External Secrets meta/v1.SecretKeySelector Secret ref to fill in credentials
"},{"location":"api/spec/#external-secrets.io/v1beta1.YandexCertificateManagerAuth","title":"YandexCertificateManagerAuth","text":" (Appears on: YandexCertificateManagerProvider)
Field Description authorizedKeySecretRef
External Secrets meta/v1.SecretKeySelector (Optional) The authorized key used for authentication
"},{"location":"api/spec/#external-secrets.io/v1beta1.YandexCertificateManagerCAProvider","title":"YandexCertificateManagerCAProvider","text":" (Appears on: YandexCertificateManagerProvider)
Field Description certSecretRef
External Secrets meta/v1.SecretKeySelector"},{"location":"api/spec/#external-secrets.io/v1beta1.YandexCertificateManagerProvider","title":"YandexCertificateManagerProvider","text":" (Appears on: SecretStoreProvider)
YandexCertificateManagerProvider Configures a store to sync secrets using the Yandex Certificate Manager provider.
Field Description apiEndpoint
string (Optional) Yandex.Cloud API endpoint (e.g. \u2018api.cloud.yandex.net:443\u2019)
folderID
string (Optional) If provided sets the ability to get secrets by its name in the specified folder
auth
YandexCertificateManagerAuth Auth defines the information necessary to authenticate against Yandex Certificate Manager
caProvider
YandexCertificateManagerCAProvider (Optional) The provider for the CA bundle to use to validate Yandex.Cloud server certificate.
"},{"location":"api/spec/#external-secrets.io/v1beta1.YandexLockboxAuth","title":"YandexLockboxAuth","text":" (Appears on: YandexLockboxProvider)
Field Description authorizedKeySecretRef
External Secrets meta/v1.SecretKeySelector (Optional) The authorized key used for authentication
"},{"location":"api/spec/#external-secrets.io/v1beta1.YandexLockboxCAProvider","title":"YandexLockboxCAProvider","text":" (Appears on: YandexLockboxProvider)
Field Description certSecretRef
External Secrets meta/v1.SecretKeySelector"},{"location":"api/spec/#external-secrets.io/v1beta1.YandexLockboxProvider","title":"YandexLockboxProvider","text":" (Appears on: SecretStoreProvider)
YandexLockboxProvider Configures a store to sync secrets using the Yandex Lockbox provider.
Field Description apiEndpoint
string (Optional) Yandex.Cloud API endpoint (e.g. \u2018api.cloud.yandex.net:443\u2019)
folderID
string (Optional) If provided sets the ability to get secrets by its name in the specified folder
auth
YandexLockboxAuth Auth defines the information necessary to authenticate against Yandex Lockbox
caProvider
YandexLockboxCAProvider (Optional) The provider for the CA bundle to use to validate Yandex.Cloud server certificate.
Generated with gen-crd-api-reference-docs
.
"},{"location":"api/generator/","title":"Index","text":"Generators allow you to generate values. See Generators Guide
"},{"location":"api/generator/acr/","title":"Azure Container Registry","text":"The Azure Container Registry (ACR) generator creates a short-lived refresh or access token for accessing ACR. The token is generated for a particular ACR registry defined in spec.registry
.
"},{"location":"api/generator/acr/#output-keys-and-values","title":"Output Keys and Values","text":"Key Description username username for the docker login
command password password for the docker login
command"},{"location":"api/generator/acr/#authentication","title":"Authentication","text":"You must choose one out of three authentication mechanisms:
- service principal
- managed identity
- workload identity
The generated token will inherit the permissions from the assigned policy. I.e. when you assign a read-only policy all generated tokens will be read-only. You must assign a Azure RBAC role, such as AcrPush
or AcrPull
to the service principal in order to be able to authenticate with the Azure container registry API.
You can scope tokens to a particular repository using spec.scope
.
"},{"location":"api/generator/acr/#scope","title":"Scope","text":"First, an Azure Active Directory access token is obtained with the desired authentication method. This AAD access token will be used to authenticate against ACR to issue a refresh token or access token. If spec.scope
if it is defined it obtains an ACR access token. If spec.scope
is missing it obtains an ACR refresh token:
- access tokens are scoped to a specific repository or action (pull,push)
- refresh tokens can are scoped to whatever policy is attached to the identity that creates the acr refresh token
The Scope grammar is defined in the Docker Registry spec. Note: You can not use a wildcards in the scope parameter, you can match exactly one repository and defined multiple actions like pull
or push
.
Example scopes:
repository:my-repository:pull,push\nrepository:my-repository:pull\n
"},{"location":"api/generator/acr/#example-manifest","title":"Example Manifest","text":"apiVersion: generators.external-secrets.io/v1alpha1\nkind: ACRAccessToken\nmetadata:\n name: my-azurecr\nspec:\n tenantId: 11111111-2222-3333-4444-111111111111\n registry: example.azurecr.io\n\n # optional; scope token down to a single repository/action\n # if set, it will generate an access token instead of an refresh token.\n scope: \"repository:foo:pull,push\"\n\n # Specify Azure cloud type, defaults to PublicCloud.\n # This is used for authenticating with Azure Active Directory.\n # available options: PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud\n environmentType: \"PublicCloud\"\n\n # choose one authentication method\n auth:\n\n # option 1: point to a secret that contains a client-id and client-secret\n servicePrincipal:\n secretRef:\n clientSecret:\n name: az-secret\n key: clientsecret\n clientId:\n name: az-secret\n key: clientid\n\n # option 2:\n managedIdentity:\n identityId: \"xxxxx\"\n\n # option 3:\n workloadIdentity:\n # note: you can reference service accounts across namespaces.\n serviceAccountRef:\n name: \"my-service-account\"\n audiences: []\n
Example ExternalSecret
that references the ACR generator:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: azurecr-credentials\nspec:\n dataFrom:\n - sourceRef:\n generatorRef:\n apiVersion: generators.external-secrets.io/v1alpha1\n kind: ACRAccessToken\n name: my-azurecr\n refreshInterval: 12h\n target:\n name: azurecr-credentials\n template:\n type: kubernetes.io/dockerconfigjson\n data:\n .dockerconfigjson: |\n {\n \"auths\": {\n \"myregistry.azurecr.io\": {\n \"username\": \"{{ .username }}\",\n \"identitytoken\": \"{{ .password }}\"\n }\n }\n }\n
"},{"location":"api/generator/ecr/","title":"AWS Elastic Container Registry","text":"ECRAuthorizationTokenSpec uses the GetAuthorizationToken API to retrieve an authorization token. The authorization token is valid for 12 hours. For more information, see registry authentication in the Amazon Elastic Container Registry User Guide.
"},{"location":"api/generator/ecr/#output-keys-and-values","title":"Output Keys and Values","text":"Key Description username username for the docker login
command. password password for the docker login
command. proxy_endpoint The registry URL to use for this authorization token in a docker login
command. expires_at time when token expires in UNIX time (seconds since January 1, 1970 UTC)."},{"location":"api/generator/ecr/#authentication","title":"Authentication","text":"You can choose from three authentication mechanisms:
- static credentials using
spec.auth.secretRef
- point to a IRSA Service Account with
spec.auth.jwt
- use credentials from the SDK default credentials chain from the controller environment
"},{"location":"api/generator/ecr/#example-manifest","title":"Example Manifest","text":"apiVersion: generators.external-secrets.io/v1alpha1\nkind: ECRAuthorizationToken\nmetadata:\n name: ecr-gen\nspec:\n\n # specify aws region (mandatory)\n region: eu-west-1\n\n # assume role with the given authentication credentials\n role: \"my-role\"\n\n # choose an authentication strategy\n # if no auth strategy is defined it falls back to using\n # credentials from the environment of the controller.\n auth:\n\n # 1: static credentials\n # point to a secret that contains static credentials\n # like AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY\n secretRef:\n accessKeyIDSecretRef:\n name: \"my-aws-creds\"\n key: \"key-id\"\n secretAccessKeySecretRef:\n name: \"my-aws-creds\"\n key: \"access-secret\"\n\n # option 2: IAM Roles for Service Accounts\n # point to a service account that should be used\n # that is configured for IAM Roles for Service Accounts (IRSA)\n jwt:\n serviceAccountRef:\n name: \"oci-token-sync\"\n
Example ExternalSecret
that references the ECR generator:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: \"ecr-secret\"\nspec:\n refreshInterval: \"1h\"\n target:\n name: ecr-secret\n dataFrom:\n - sourceRef:\n generatorRef:\n apiVersion: generators.external-secrets.io/v1alpha1\n kind: ECRAuthorizationToken\n name: \"ecr-gen\"\n
"},{"location":"api/generator/fake/","title":"Fake","text":"The Fake generator provides hard-coded key/value pairs. The intended use is just for debugging and testing. The key/value pairs defined in spec.data
is returned as-is.
"},{"location":"api/generator/fake/#example-manifest","title":"Example Manifest","text":"apiVersion: generators.external-secrets.io/v1alpha1\nkind: Fake\nmetadata:\n name: fake-key\nspec:\n data:\n foo: bar\n baz: bang\n
Example ExternalSecret
that references the Fake generator:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: \"fake\"\nspec:\n refreshInterval: \"30m\"\n target:\n name: fake\n dataFrom:\n - sourceRef:\n generatorRef:\n apiVersion: generators.external-secrets.io/v1alpha1\n kind: Fake\n name: \"fake-key\"\n
"},{"location":"api/generator/gcr/","title":"Google Container Registry","text":"GCRAccessToken creates a GCP Access token that can be used to authenticate with GCR in order to pull OCI images. You won't need any extra permissions to request for a token, but the token would only work against a GCR if the token requester (service Account or WI) has the appropriate access
You must specify the spec.projectID
in which GCR is located.
"},{"location":"api/generator/gcr/#output-keys-and-values","title":"Output Keys and Values","text":"Key Description username username for the docker login
command. password password for the docker login
command. expiry time when token expires in UNIX time (seconds since January 1, 1970 UTC)."},{"location":"api/generator/gcr/#authentication","title":"Authentication","text":""},{"location":"api/generator/gcr/#workload-identity","title":"Workload Identity","text":"Use spec.auth.workloadIdentity
to point to a Service Account that has Workload Identity enabled. For details see GCP Secret Manager.
"},{"location":"api/generator/gcr/#gcp-service-account","title":"GCP Service Account","text":"Use spec.auth.secretRef
to point to a Secret that contains a GCP Service Account. For details see GCP Secret Manager.
"},{"location":"api/generator/gcr/#example-manifest","title":"Example Manifest","text":"apiVersion: generators.external-secrets.io/v1alpha1\nkind: GCRAccessToken\nmetadata:\n name: gcr-gen\nspec:\n # project where gcr lives in\n projectID: \"\"\n\n # choose authentication strategy\n auth:\n # option 1: workload identity\n workloadIdentity:\n # point to the workload identity\n # service account\n serviceAccountRef:\n name: \"\"\n audiences: []\n # the cluster can live in a different project or location\n # use the following fields to configure where the cluster lives\n clusterLocation: \"\"\n clusterName: \"\"\n clusterProjectID: \"\"\n\n\n # option 2: GCP service account\n secretRef:\n secretAccessKeySecretRef:\n name: \"\"\n key: \"\"\n
Example ExternalSecret
that references the GCR generator:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: \"gcr-token\"\nspec:\n refreshInterval: \"30m\"\n target:\n name: gcr-token\n dataFrom:\n - sourceRef:\n generatorRef:\n apiVersion: generators.external-secrets.io/v1alpha1\n kind: GCRAccessToken\n name: \"gcr-gen\"\n
"},{"location":"api/generator/password/","title":"Password","text":"The Password generator provides random passwords that you can feed into your applications. It uses lower and uppercase alphanumeric characters as well as symbols. Please see below for the symbols in use.
Passwords are completely randomized
It is possible that we may generate passwords that don't match the expected character set from your application.
"},{"location":"api/generator/password/#output-keys-and-values","title":"Output Keys and Values","text":"Key Description password the generated password"},{"location":"api/generator/password/#parameters","title":"Parameters","text":"You can influence the behavior of the generator by providing the following args
Key Default Description length 24 Length of the password to be generated. digits 25% of the length Specify the number of digits in the generated password. symbols 25% of the length Specify the number of symbol characters in the generated. symbolCharacters ~!@#$%^&*()_+`-={}|[]\\:\"<>?,./ Specify the character set that should be used when generating the password. noUpper false disable uppercase characters. allowRepeat false allow repeating characters."},{"location":"api/generator/password/#example-manifest","title":"Example Manifest","text":"apiVersion: generators.external-secrets.io/v1alpha1\nkind: Password\nmetadata:\n name: my-password\nspec:\n length: 42\n digits: 5\n symbols: 5\n symbolCharacters: \"-_$@\"\n noUpper: false\n allowRepeat: true\n
Example ExternalSecret
that references the Password generator:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: \"password\"\nspec:\n refreshInterval: \"30m\"\n target:\n name: password-secret\n dataFrom:\n - sourceRef:\n generatorRef:\n apiVersion: generators.external-secrets.io/v1alpha1\n kind: Password\n name: \"my-password\"\n
Which will generate a Kind=Secret
with a key called 'password' that may look like:
RMngCHKtZ@@h@3aja$WZDuDVhkCkN48JBa9OF8jH$R\nVB$pX8SSUMIlk9K8g@XxJAhGz$0$ktbJ1ArMukg-bD\nHi$-aK_3Rrrw1Pj9-sIpPZuk5abvEDJlabUYUcS$9L\n
With default values you would get something like:
2Cp=O*&8x6sdwM!<74G_gUz5\n-MS`e#n24K|h5A<&6q9Yv7Cj\nZRv-k!y6x/V\"29:43aErSf$1\nVk9*mwXE30Q+>H?lY$5I64_q\n
"},{"location":"api/generator/vault/","title":"Vault Dynamic Secret","text":"The VaultDynamicSecret
Generator provides an interface to HashiCorp Vault's Secrets engines. Specifically, it enables obtaining dynamic secrets not covered by the HashiCorp Vault provider.
Any Vault authentication method supported by the provider can be used here (provider
block of the spec).
All secrets engines should be supported by providing matching path
, method
and parameters
values to the Generator spec (see example below).
Exact output keys and values depend on the Vault secret engine used; nested values are stored into the resulting Secret in JSON format.
"},{"location":"api/generator/vault/#example-manifest","title":"Example manifest","text":"apiVersion: generators.external-secrets.io/v1alpha1\nkind: VaultDynamicSecret\nmetadata:\n name: \"pki-example\"\nspec:\n path: \"/pki/issue/example-dot-com\"\n method: \"POST\"\n parameters:\n common_name: \"localhost\"\n ip_sans: \"127.0.0.1,127.0.0.11\"\n provider:\n server: \"http://vault.default.svc.cluster.local:8200\"\n auth:\n kubernetes:\n mountPath: \"kubernetes\"\n role: \"external-secrets-operator\"\n serviceAccountRef:\n name: \"default\"\n
Example ExternalSecret
that references the Vault generator:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: \"pki-example-com\"\nspec:\n refreshInterval: \"768h\"\n target:\n name: pki-example-com\n dataFrom:\n - sourceRef:\n generatorRef:\n apiVersion: generators.external-secrets.io/v1alpha1\n kind: VaultDynamicSecret\n name: \"pki-example\"\n
"},{"location":"api/generator/webhook/","title":"Webhook","text":"The Webhook generator is very similar to SecretStore generator, and provides a way to use external systems to generate sensitive information.
"},{"location":"api/generator/webhook/#output-keys-and-values","title":"Output Keys and Values","text":"Webhook calls are expected to produce valid JSON objects. All keys within that JSON object will be exported as keys to the kubernetes Secret.
"},{"location":"api/generator/webhook/#example-manifest","title":"Example Manifest","text":"apiVersion: generators.external-secrets.io/v1alpha1\nkind: Webhook\nmetadata:\n name: webhook\nspec:\n url: \"http://httpbin.org/get?parameter={{ .auth.param }}\"\n result:\n jsonPath: \"$.args\"\n headers:\n Content-Type: application/json\n Authorization: Basic {{ print .auth.username \":\" .auth.password | b64enc }}\n secrets:\n - name: auth\n secretRef:\n name: webhook-credentials\n---\napiVersion: v1\nkind: Secret\nmetadata:\n name: webhook-credentials\n labels:\n generators.external-secrets.io/type: webhook #Needed to allow webhook to use this secret\ndata:\n username: dGVzdA== # \"test\"\n password: dGVzdA== # \"test\"\n param: dGVzdA== # \"test\"\n
Example ExternalSecret
that references the Webhook generator using an internal Secret
:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: \"webhook\"\nspec:\n refreshInterval: \"30m\"\n target:\n name: webhook-secret\n dataFrom:\n - sourceRef:\n generatorRef:\n apiVersion: generators.external-secrets.io/v1alpha1\n kind: Webhook\n name: \"webhook\"\n
This will generate a kubernetes secret with the following values:
parameter: test\n
"},{"location":"contributing/coc/","title":"Code of Conduct","text":""},{"location":"contributing/coc/#our-pledge","title":"Our Pledge","text":"We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
"},{"location":"contributing/coc/#our-standards","title":"Our Standards","text":"Examples of behavior that contributes to a positive environment for our community include:
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
- Focusing on what is best not just for us as individuals, but for the overall community
Examples of unacceptable behavior include:
- The use of sexualized language or imagery, and sexual attention or advances of any kind
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email address, without their explicit permission
- Other conduct which could reasonably be considered inappropriate in a professional setting
"},{"location":"contributing/coc/#enforcement-responsibilities","title":"Enforcement Responsibilities","text":"Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
"},{"location":"contributing/coc/#scope","title":"Scope","text":"This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
"},{"location":"contributing/coc/#enforcement","title":"Enforcement","text":"Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at cncf-ExternalSecretsOp-maintainers@lists.cncf.io. All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the reporter of any incident.
"},{"location":"contributing/coc/#enforcement-guidelines","title":"Enforcement Guidelines","text":"Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
"},{"location":"contributing/coc/#1-correction","title":"1. Correction","text":"Community Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
Consequence: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
"},{"location":"contributing/coc/#2-warning","title":"2. Warning","text":"Community Impact: A violation through a single incident or series of actions.
Consequence: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
"},{"location":"contributing/coc/#3-temporary-ban","title":"3. Temporary Ban","text":"Community Impact: A serious violation of community standards, including sustained inappropriate behavior.
Consequence: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
"},{"location":"contributing/coc/#4-permanent-ban","title":"4. Permanent Ban","text":"Community Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
Consequence: A permanent ban from any sort of public interaction within the community.
"},{"location":"contributing/coc/#attribution","title":"Attribution","text":"This Code of Conduct is adapted from the Contributor Covenant, version 2.0, available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by Mozilla's code of conduct enforcement ladder.
For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.
"},{"location":"contributing/devguide/","title":"Developer guide","text":""},{"location":"contributing/devguide/#getting-started","title":"Getting Started","text":"You must have a working Go environment and then clone the repo:
git clone https://github.com/external-secrets/external-secrets.git\ncd external-secrets\n
Note: many of the make
commands use yq, version 4.2X.X or higher.
Our helm chart is tested using helm-unittest
. You will need it to run tests locally if you modify the helm chart. Install it with the following command:
$ helm plugin install https://github.com/helm-unittest/helm-unittest\n
"},{"location":"contributing/devguide/#building-testing","title":"Building & Testing","text":"The project uses the make
build system. It'll run code generators, tests and static code analysis.
Building the operator binary and docker image:
make build\nmake docker.build IMAGE_NAME=external-secrets IMAGE_TAG=latest\n
Run tests and lint the code:
make test\nmake lint # OR\ndocker run --rm -v $(pwd):/app -w /app golangci/golangci-lint:v1.49.0 golangci-lint run\n
Build the documentation:
make docs\n
"},{"location":"contributing/devguide/#using-tilt","title":"Using Tilt","text":"Tilt can be used to develop external-secrets. Tilt will hot-reload changes to the code and replace the running binary in the container using a process manager of its own.
To run tilt, download the utility for your operating system and run make tilt-up
. This will do two things: - downloads tilt for the current OS and ARCH under bin/tilt
- make manifest files of your current changes and place them under ./bin/deploy/manifests/external-secrets.yaml
- run tilt with tilt run
Hit space
and you can observe all the pods starting up and track their output in the tilt UI.
"},{"location":"contributing/devguide/#installing","title":"Installing","text":"To install the External Secret Operator into a Kubernetes Cluster run:
helm repo add external-secrets https://charts.external-secrets.io\nhelm repo update\nhelm install external-secrets external-secrets/external-secrets\n
You can alternatively run the controller on your host system for development purposes:
make crds.install\nmake run\n
To remove the CRDs run:
make crds.uninstall\n
If you need to test some other k8s integrations and need the operator to be deployed to the actual cluster while developing, you can use the following workflow:
# Start a local K8S cluster with KinD\nkind create cluster --name external-secrets\n\nexport TAG=$(make docker.tag)\nexport IMAGE=$(make docker.imagename)\n\n# Build docker image\nmake docker.build\n\n# Load docker image into local kind cluster\nkind load docker-image $IMAGE:$TAG --name external-secrets\n\n# (Optional) Pull the image from GitHub Repo to copy into kind\n# docker pull ghcr.io/external-secrets/external-secrets:v0.8.2\n# kind load docker-image ghcr.io/external-secrets/external-secrets:v0.8.2 -n external-secrets\n# export TAG=v0.8.2\n\n# Update helm charts and install to KinD cluster\nmake helm.generate\nhelm upgrade --install external-secrets ./deploy/charts/external-secrets/ \\\n--set image.repository=$IMAGE --set image.tag=$TAG \\\n--set webhook.image.repository=$IMAGE --set webhook.image.tag=$TAG \\\n--set certController.image.repository=$IMAGE --set certController.image.tag=$TAG\n\n\n# Command to delete the cluster when done\n# kind delete cluster -n external-secrets\n
Contributing Flow
The HOW TO guide for contributing is at the Contributing Process page.
"},{"location":"contributing/devguide/#documentation","title":"Documentation","text":"We use mkdocs material and mike to generate this documentation. See /docs
for the source code and /hack/api-docs
for the build process.
When writing documentation it is advised to run the mkdocs server with livereload:
make docs.serve\n
Run the following command to run a complete build. The rendered assets are available under /site
.
make docs\nmake docs.serve\n
Open http://localhost:8000
in your browser.
Since mike uses a branch to create/update documentation, any docs operation will create a diff on your local gh-pages
branch.
When finished writing/reviewing the docs, clean up your local docs branch changes with git branch -D gh-pages
"},{"location":"contributing/process/","title":"Contributing Process","text":""},{"location":"contributing/process/#project-management","title":"Project Management","text":"The Code, our TODOs and Documentation is maintained on GitHub. All Issues should be opened in that repository. We have a Roadmap to track progress for our road towards GA.
"},{"location":"contributing/process/#issues","title":"Issues","text":"Features, bugs and any issues regarding the documentation should be filed as GitHub Issue in our repository. We use labels like kind/feature
, kind/bug
, area/aws
to organize the issues. Issues labeled good first issue
and help wanted
are especially good for a first contribution. If you want to pick up an issue just leave a comment.
"},{"location":"contributing/process/#submitting-a-pull-request","title":"Submitting a Pull Request","text":"This project uses the well-known pull request process from GitHub. To submit a pull request, fork the repository and push any changes to a branch on the copy, from there a pull request can be made in the main repo. Merging a pull request requires the following steps to be completed before the pull request will be merged:
- ideally, there is an issue that documents the problem or feature in depth.
- code must have a reasonable amount of test coverage
- tests must pass
- PR needs be reviewed and approved
Once these steps are completed the PR will be merged by a code owner. We're using the pull request assignee
feature to track who is responsible for the lifecycle of the PR: review, merging, ping on inactivity, close. We close pull requests or issues if there is no response from the author for a period of time. Feel free to reopen if you want to get back on it.
"},{"location":"contributing/process/#triggering-e2e-tests","title":"Triggering e2e tests","text":"We have an extensive set of e2e tests that test the integration with real cloud provider APIs. Maintainers must trigger these kind of tests manually for PRs that come from forked repositories. These tests run inside a kind
cluster in the GitHub Actions runner:
/ok-to-test sha=xxxxxx\n
"},{"location":"contributing/process/#executing-e2e-tests-locally","title":"Executing e2e tests locally","text":"You have to prepare your shell environment with the necessary variables so the e2e test runner knows what credentials to use. See e2e/run.sh
for the variables that are passed in. If you e.g. want to test AWS integration make sure set all AWS_*
variables mentioned in that file.
Use ginkgo labels to select the tests you want to execute. You have to specify !managed
to ensure that you do not run managed tests.
make test.e2e GINKGO_LABELS='gcp&&!managed'\n
"},{"location":"contributing/process/#managed-kubernetes-e2e-tests","title":"Managed Kubernetes e2e tests","text":"There's another suite of e2e tests that integrate with managed Kubernetes offerings. They create real infrastructure at a cloud provider and deploy the controller into that environment. This is necessary to test the authentication integration (GCP Workload Identity, EKS IRSA...).
These tests are time intensive (~20-45min) and must be triggered manually by a maintainer when a particular provider or authentication mechanism was changed:
/ok-to-test-managed sha=xxxxxx provider=aws\n# or\n/ok-to-test-managed sha=xxxxxx provider=gcp\n# or\n/ok-to-test-managed sha=xxxxxx provider=azure\n
Both tests can run in parallel. Once started they add a dynamic GitHub check integration-managed-(gcp|aws|azure)
to the PR that triggered the test.
"},{"location":"contributing/process/#executing-managed-kubernetes-e2e-tests-locally","title":"Executing Managed Kubernetes e2e tests locally","text":"You have to prepare your shell environment with the necessary variables so the e2e test runner knows what credentials to use. See .github/workflows/e2e-managed.yml
for the variables that are passed in. If you e.g. want to test AWS integration make sure set all variables containing AWS_*
and TF_VAR_AWS_*
mentioned in that file.
Then execute tf.apply.aws
or tf.apply.gcp
to create the infrastructure.
make tf.apply.aws\n
Then run the managed
testsuite. You will need push permissions to the external-secrets ghcr repository. You can set IMAGE_NAME
to control which image registry is used to store the controller and e2e test images in.
You also have to setup a proper Kubeconfig so the e2e test pod gets deployed into the managed cluster.
aws eks update-kubeconfig --name ${AWS_CLUSTER_NAME}\nor\ngcloud container clusters get-credentials ${GCP_GKE_CLUSTER} --region europe-west1-b\n
Use ginkgo labels to select the tests you want to execute.
# you may have to set IMAGE_NAME=docker.io/your-user/external-secrets\nmake test.e2e.managed GINKGO_LABELS='gcp'\n
"},{"location":"contributing/process/#proposal-process","title":"Proposal Process","text":"Before we introduce significant changes to the project we want to gather feedback from the community to ensure that we progress in the right direction before we develop and release big changes. Significant changes include for example:
- creating new custom resources
- proposing breaking changes
- changing the behavior of the controller significantly
Please create a document in the design/
directory based on the template 000-template.md
and fill in your proposal. Open a pull request in draft mode and request feedback. Once the proposal is accepted and the pull request is merged we can create work packages and proceed with the implementation.
"},{"location":"contributing/process/#release-planning","title":"Release Planning","text":"We have a GitHub Project Board where we organize issues on a high level. We group issues by milestone. Once all issues of a given milestone are closed we should prepare a new feature release. Issues of the next milestone have priority over other issues - but that does not mean that no one is allowed to start working on them.
Issues must be manually added to that board (at least for now, see GH Roadmap). Milestones must be assigned manually as well. If no milestone is assigned it is basically a backlog item. It is the responsibility of the maintainers to:
- assign new issues to the GH Project
- add a milestone if needed
- add appropriate labels
If you would like to raise the priority of an issue for whatever reason feel free to comment on the issue or ping a maintainer.
"},{"location":"contributing/process/#support-questions","title":"Support & Questions","text":"Providing support to end users is an important and difficult task. We have three different channels through which support questions arise:
- Kubernetes Slack #external-secrets
- GitHub Discussions
- GitHub Issues
We use labels to identify GitHub Issues. Specifically for managing support cases we use the following labels to identify the state a support case is in:
triage/needs-information
: Indicates an issue needs more information in order to work on it. triage/not-reproducible
: Indicates an issue can not be reproduced as described. triage/support
: Indicates an issue that is a support question.
"},{"location":"contributing/process/#cutting-releases","title":"Cutting Releases","text":"The external-secrets project is released on a as-needed basis. Feel free to open a issue to request a release. Details on how to cut a release can be found in the release page.
"},{"location":"contributing/release/","title":"Release Process","text":"ESO and the ESO Helm Chart have two distinct lifecycles and can be released independently. Helm Chart releases are named external-secrets-x.y.z
.
The external-secrets project is released on a as-needed basis. Feel free to open a issue to request a release.
"},{"location":"contributing/release/#release-eso","title":"Release ESO","text":"When doing a release it's best to start with with the \"Create Release\" issue template, it has a checklist to go over.
\u26a0\ufe0f Note: when releasing multiple versions, make sure to first release the \"old\" version, then the newer version. Otherwise the latest
documentation will point to the older version. Also avoid to release both versions at the same time to avoid race conditions in the CI pipeline (updating docs, GitHub Release, helm chart release).
- Run
Create Release
Action to create a new release, pass in the desired version number to release. - choose the right
branch
to execute the action: use main
when creating a new release. Use release-x.y
when you want to bump a LTS release. - \u26a0\ufe0f make sure that CI on the relevant branch has completed the docker build/push jobs. Otherwise an old image will be promoted.
- GitHub Release, Changelog will be created by the
release.yml
workflow which also promotes the container image. - update Helm Chart, see below
- update OLM bundle, see helm-operator docs
"},{"location":"contributing/release/#release-helm-chart","title":"Release Helm Chart","text":" - Update
version
and/or appVersion
in Chart.yaml
and run make helm.docs helm.update.appversion helm.test.update helm.test
- push to branch and open pr
- run
/ok-to-test-managed
commands for all cloud providers - merge PR if everyhing is green
- CI picks up the new chart version and creates a new GitHub Release for it
- create/merge into release branch
- on a
minor
release: create a new branch release-x.y
- on a
patch
release: merge main into release-x.y
"},{"location":"contributing/release/#release-olm-bundle","title":"Release OLM Bundle","text":"In order to make the latest release available to OperatorHub.io we need to create a bundle and open a PR in the community-operators repository.
To create a bundle first increment the VERSION
in the Makefile as described above. Then run the following commands in the root of the repository:
# clone repo\ngit clone https://github.com/external-secrets/external-secrets-helm-operator\ncd external-secrets-helm-operator\n\n# bump version\nexport VERSION=x.y.z\nsed -i \"s/^VERSION ?= .*/VERSION ?= ${VERSION}/\" Makefile\n\n# prep release\nmake prepare-stable-release ATTACH_IMAGE_DIGESTS=0\n
Check the generated files in the bundle/
directory. If they look good add & commit them, open a PR against this repository. You can always use the OperatorHub.io/preview page to preview the generated CSV.
git status\ngit add .\ngit commit -s -m \"chore: bump version xyz\"\ngit push\n
Once the PR is merged and the image build job on main
has completed, we need create a pull request against both community-operators repositories. There's a make target that does the heavy lifting for you:
make attach-image-digests\nmake bundle-operatorhub\n
This command will add/commit/push and open pull requests in the respective repositories.
"},{"location":"contributing/roadmap/","title":"The road to external-secrets GA","text":"The following external-secret custom resource APIs are considered stable:
ExternalSecret
ClusterExternalSecret
SecretStore
ClusterSecretStore
These CRDs are currently at v1beta1
and are considered production ready. Going forward, breaking changes to these APIs will be accompanied by a conversion mechanism.
We have identified the following areas of work. This is subject to change while we gather feedback. We have a GitHub Project Board where we organize issues and milestones on a high level.
- Conformance testing
- \u2713 end to end testing with ArgoCD and Flux
- \u2713 end to end testing for all project maintained providers
- API enhancements
- consolidate provider fields
- \u2713 dataFrom key rewrites
- provider versioning strategy
- \u2713 pushing secrets to a provider
- Documentation Improvements
- Troubleshooting Guides
- \u2713 FAQ
- \u2713 review multi tenancy docs
- \u2713 security model for infosec teams
- \u2713 security best practices guide
- \u2713 provider specific guides
- Observability
- \u2713 Provide Grafana Dashboard and Prometheus alerts
- \u2713 add provider-level metrics
- Pentest
- \u2713 SBOM
"},{"location":"examples/anchore-engine-credentials/","title":"Getting started","text":"Anchore Engine is an open-source project that provides a centralized service for inspection, analysis, and certification of container images. With Kubernetes, it also brings nice features like preventing unscanned images from being deployed into your clusters
"},{"location":"examples/anchore-engine-credentials/#installing-with-helm","title":"Installing with Helm","text":"There are several parts of the installation that require credentials these being :-
ANCHORE_ADMIN_USERNAME ANCHORE_ADMIN_PASSWORD ANCHORE_DB_PASSWORD db-url db-user postgres-password
Creating the following external secret ensure the credentials are drawn from the backend provider of choice. The example shown here works with Hashicorp Vault and AWS Secrets Manager providers.
"},{"location":"examples/anchore-engine-credentials/#hashicorp-vault","title":"Hashicorp Vault","text":"apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: anchore-access-credentials\n namespace: security\nspec:\n refreshInterval: 1m\n secretStoreRef:\n name: vault-backend\n kind: ClusterSecretStore\n target:\n name: anchore-access-credentials\n template:\n\n data:\n ANCHORE_ADMIN_USERNAME: >-\n {{ printf \"{{ .username | toString }}\" }}\n ANCHORE_ADMIN_PASSWORD: >-\n {{ printf \"{{ .password | toString }}\" }}\n ANCHORE_DB_PASSWORD: >-\n {{ printf \"{{ .dbPassword | toString }}\" }}\n db-url: >-\n {{ printf \"{{ .dbUrl | toString }}\" }}\n db-user: >-\n {{ printf \"{{ .dbUser | toString }}\" }}\n postgres-password: >-\n {{ printf \"{{ .postgresPassword | toString }}\" }}\n\n data:\n - secretKey: password\n remoteRef:\n key: anchore-engine\n property: ANCHORE_ADMIN_PASSWORD\n - secretKey: username\n remoteRef:\n key: anchore-engine\n property: ANCHORE_ADMIN_USERNAME\n - secretKey: dbPassword\n remoteRef:\n key: anchore-engine\n property: ANCHORE_DB_PASSWORD\n - secretKey: dbUrl\n remoteRef:\n key: anchore-engine\n property: db-url\n - secretKey: dbUser\n remoteRef:\n key: anchore-engine\n property: db-user\n - secretKey: postgresPassword\n remoteRef:\n key: anchore-engine\n property: postgres-password\n
"},{"location":"examples/anchore-engine-credentials/#aws-secrets-manager","title":"AWS Secrets Manager","text":"---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: anchore-access-credentials\n namespace: ci\nspec:\n refreshInterval: 1m\n secretStoreRef:\n name: cluster-secrets-store\n kind: ClusterSecretStore\n target:\n name: anchore-access-credentials\n dataFrom:\n - extract:\n key: service/anchore-engine/engineAccess\n
"},{"location":"examples/bitwarden/","title":"Bitwarden support using webhook provider","text":"Bitwarden is an integrated open source password management solution for individuals, teams, and business organizations.
"},{"location":"examples/bitwarden/#how-is-it-working","title":"How is it working ?","text":"To make external-secret compatible with BitWarden, we need:
- External-Secret >= 0.8.0
- To use the Webhook Provider
- 2 (Cluster)SecretStores
- BitWarden CLI image running
bw serve
When you create a new external-secret object, External-Secret Webhook provider will do a query to the Bitwarden CLI pod, which is synced with the BitWarden server.
"},{"location":"examples/bitwarden/#requirements","title":"Requirements","text":" - Bitwarden account (it works also with VaultWarden)
- A Kubernetes secret which contains your BitWarden Credentials
- You need a Docker image with BitWarden CLI installed. You could use
ghcr.io/charlesthomas/bitwarden-cli:2023.12.1
or build your own.
Here an example of Dockerfile use to build this image:
FROM debian:sid\n\nENV BW_CLI_VERSION=2023.12.1\n\nRUN apt update && \\\n apt install -y wget unzip && \\\n wget https://github.com/bitwarden/clients/releases/download/cli-v${BW_CLI_VERSION}/bw-linux-${BW_CLI_VERSION}.zip && \\\n unzip bw-linux-${BW_CLI_VERSION}.zip && \\\n chmod +x bw && \\\n mv bw /usr/local/bin/bw && \\\n rm -rfv *.zip\n\nCOPY entrypoint.sh /\n\nCMD [\"/entrypoint.sh\"]\n
And the content of entrypoint.sh
#!/bin/bash\n\nset -e\n\nbw config server ${BW_HOST}\n\nexport BW_SESSION=$(bw login ${BW_USER} --passwordenv BW_PASSWORD --raw)\n\nbw unlock --check\n\necho 'Running `bw server` on port 8087'\nbw serve --hostname 0.0.0.0 #--disable-origin-protection\n
"},{"location":"examples/bitwarden/#deploy-bitwarden-credentials","title":"Deploy Bitwarden Credentials","text":"apiVersion: v1\ndata:\n BW_HOST: ...\n BW_USERNAME: ...\n BW_PASSWORD: ....\nkind: Secret\nmetadata:\n name: bitwarden-cli\n namespace: bitwarden\ntype: Opaque\n
"},{"location":"examples/bitwarden/#deploy-bitwarden-cli-container","title":"Deploy Bitwarden CLI container","text":"apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: bitwarden-cli\n namespace: bitwarden\n labels:\n app.kubernetes.io/instance: bitwarden-cli\n app.kubernetes.io/name: bitwarden-cli\nspec:\n replicas: 1\n strategy:\n type: Recreate\n selector:\n matchLabels:\n app.kubernetes.io/name: bitwarden-cli\n app.kubernetes.io/instance: bitwarden-cli\n template:\n metadata:\n labels:\n app.kubernetes.io/name: bitwarden-cli\n app.kubernetes.io/instance: bitwarden-cli\n spec:\n containers:\n - name: bitwarden-cli\n image: YOUR_BITWARDEN_CLI_IMAGE\n imagePullPolicy: IfNotPresent\n env:\n - name: BW_HOST\n valueFrom:\n secretKeyRef:\n name: bitwarden-cli\n key: BW_HOST\n - name: BW_USER\n valueFrom:\n secretKeyRef:\n name: bitwarden-cli\n key: BW_USERNAME\n - name: BW_PASSWORD\n valueFrom:\n secretKeyRef:\n name: bitwarden-cli\n key: BW_PASSWORD\n ports:\n - name: http\n containerPort: 8087\n protocol: TCP\n livenessProbe:\n exec:\n command:\n - wget\n - -q\n - http://127.0.0.1:8087/sync?force=true\n - --post-data=''\n initialDelaySeconds: 20\n failureThreshold: 3\n timeoutSeconds: 1\n periodSeconds: 120\n readinessProbe:\n tcpSocket:\n port: 8087\n initialDelaySeconds: 20\n failureThreshold: 3\n timeoutSeconds: 1\n periodSeconds: 10\n startupProbe:\n tcpSocket:\n port: 8087\n initialDelaySeconds: 10\n failureThreshold: 30\n timeoutSeconds: 1\n periodSeconds: 5\n---\napiVersion: v1\nkind: Service\nmetadata:\n name: bitwarden-cli\n namespace: bitwarden\n labels:\n app.kubernetes.io/instance: bitwarden-cli\n app.kubernetes.io/name: bitwarden-cli\n annotations:\nspec:\n type: ClusterIP\n ports:\n - port: 8087\n targetPort: http\n protocol: TCP\n name: http\n selector:\n app.kubernetes.io/name: bitwarden-cli\n app.kubernetes.io/instance: bitwarden-cli\n---\nkind: NetworkPolicy\napiVersion: networking.k8s.io/v1\nmetadata:\n namespace: bitwarden\n name: external-secret-2-bw-cli\nspec:\n podSelector:\n matchLabels:\n app.kubernetes.io/instance: bitwarden-cli\n app.kubernetes.io/name: bitwarden-cli\n ingress:\n - from:\n - podSelector:\n matchLabels:\n app.kubernetes.io/instance: external-secrets\n app.kubernetes.io/name: external-secrets\n
NOTE: Deploying a network policy is recommended since, there is no authentication to query the BitWarden CLI, which means that your secrets are exposed.
NOTE: In this example the Liveness probe is quering /sync to ensure that the BitWarden CLI is able to connect to the server and also to sync secrets. (The secret sync is only every 2 minutes in this example)
"},{"location":"examples/bitwarden/#deploy-clustersecretstore-or-secretstore","title":"Deploy ClusterSecretStore (Or SecretStore)","text":"Here the two ClusterSecretStore to deploy
---\napiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\n name: bitwarden-login\nspec:\n provider:\n webhook:\n url: \"http://bitwarden-cli:8087/object/item/{{ .remoteRef.key }}\"\n headers:\n Content-Type: application/json\n result:\n jsonPath: \"$.data.login.{{ .remoteRef.property }}\"\n---\napiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\n name: bitwarden-fields\nspec:\n provider:\n webhook:\n url: \"http://bitwarden-cli:8087/object/item/{{ .remoteRef.key }}\"\n result:\n jsonPath: \"$.data.fields[?@.name==\\\"{{ .remoteRef.property }}\\\"].value\"\n---\napiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\n name: bitwarden-notes\nspec:\n provider:\n webhook:\n url: \"http://bitwarden-cli:8087/object/item/{{ .remoteRef.key }}\"\n result:\n jsonPath: \"$.data.notes\"\n
"},{"location":"examples/bitwarden/#how-to-use-it","title":"How to use it ?","text":" - If you need the
username
or the password
of a secret, you have to use bitwarden-login
- If you need a custom field of a secret, you have to use
bitwarden-fields
- If you need to use a Bitwarden Note for multiline strings (SSH keys, service account json files), you have to use
bitwarden-notes
- The
key
is the ID of a secret, which can be find in the URL with the itemId
value: https://myvault.com/#/vault?itemId=........-....-....-....-............
- The
property
is the name of the field: username
for the username of a secret (bitwarden-login
SecretStore) password
for the password of a secret (bitwarden-login
SecretStore) name_of_the_custom_field
for any custom field (bitwarden-fields
SecretStore)
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: my-db-secrets\n namespace: default\nspec:\n target:\n name: my-db-secrets\n deletionPolicy: Delete\n template:\n type: Opaque\n data:\n username: |-\n {{ .username }}\n password: |-\n {{ .password }}\n postgres-password: |-\n {{ .postgres_password }}\n postgres-replication-password: |-\n {{ .postgres_replication_password }}\n db_url: |-\n postgresql://{{ .username }}:{{ .password }}@my-postgresql:5432/mydb\n service_account_key: |-\n {{ .service_account_key }}\n data:\n - secretKey: username\n sourceRef:\n storeRef:\n name: bitwarden-login\n kind: ClusterSecretStore # or SecretStore\n remoteRef:\n key: aaaabbbb-cccc-dddd-eeee-000011112222\n property: username\n - secretKey: password\n sourceRef:\n storeRef:\n name: bitwarden-login\n kind: ClusterSecretStore # or SecretStore\n remoteRef:\n key: aaaabbbb-cccc-dddd-eeee-000011112222\n property: password\n - secretKey: postgres_password\n sourceRef:\n storeRef:\n name: bitwarden-fields\n kind: ClusterSecretStore # or SecretStore\n remoteRef:\n key: aaaabbbb-cccc-dddd-eeee-000011112222\n property: admin-password\n - secretKey: postgres_replication_password\n sourceRef:\n storeRef:\n name: bitwarden-fields\n kind: ClusterSecretStore # or SecretStore\n remoteRef:\n key: aaaabbbb-cccc-dddd-eeee-000011112222\n property: postgres-replication-password\n - secretKey: service_account_key\n sourceRef:\n storeRef:\n name: bitwarden-notes\n kind: ClusterSecretStore # or SecretStore\n remoteRef:\n key: service_account_key\n
"},{"location":"examples/gitops-using-fluxcd/","title":"GitOps using FluxCD (v2)","text":"FluxCD is a GitOps operator for Kubernetes. It synchronizes the status of the cluster from manifests allocated in different repositories (Git or Helm). This approach fits perfectly with External Secrets on clusters which are dynamically created, to get credentials with no manual intervention from the beginning.
"},{"location":"examples/gitops-using-fluxcd/#advantages","title":"Advantages","text":"This approach has several advantages as follows:
- Homogenize environments allowing developers to use the same toolset in Kind in the same way they do in the cloud provider distributions such as EKS or GKE. This accelerates the development
- Reduce security risks, because credentials can be easily obtained, so temptation to store them locally is reduced.
- Application compatibility increase: Applications are deployed in different ways, and sometimes they need to share credentials. This can be done using External Secrets as a wire for them at real time.
- Automation by default oh, come on!
"},{"location":"examples/gitops-using-fluxcd/#the-approach","title":"The approach","text":"FluxCD is composed by several controllers dedicated to manage different custom resources. The most important ones are Kustomization (to clarify, Flux one, not Kubernetes' one) and HelmRelease to deploy using the approaches of the same names.
External Secrets can be deployed using Helm as explained here. The deployment includes the CRDs if enabled on the values.yaml
, but after this, you need to deploy some SecretStore
to start getting credentials from your secrets manager with External Secrets.
The idea of this guide is to deploy the whole stack, using flux, needed by developers not to worry about the credentials, but only about the application and its code.
"},{"location":"examples/gitops-using-fluxcd/#the-problem","title":"The problem","text":"This can sound easy, but External Secrets is deployed using Helm, which is managed by the HelmController, and your custom resources, for example a ClusterSecretStore
and the related Secret
, are often deployed using a kustomization.yaml
, which is deployed by the KustomizeController.
Both controllers manage the resources independently, at different moments, with no possibility to wait each other. This means that we have a wonderful race condition where sometimes the CRs (SecretStore
,ClusterSecretStore
...) tries to be deployed before than the CRDs needed to recognize them.
"},{"location":"examples/gitops-using-fluxcd/#the-solution","title":"The solution","text":"Let's see the conditions to start working on a solution:
- The External Secrets operator is deployed with Helm, and admits disabling the CRDs deployment
- The race condition only affects the deployment of
CustomResourceDefinition
and the CRs needed later - CRDs can be deployed directly from the Git repository of the project using a Flux
Kustomization
- Required CRs can be deployed using a Flux
Kustomization
too, allowing dependency between CRDs and CRs - All previous manifests can be applied with a Kubernetes
kustomization
"},{"location":"examples/gitops-using-fluxcd/#create-the-main-kustomization","title":"Create the main kustomization","text":"To have a better view of things needed later, the first manifest to be created is the kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n# Deploy the Vault access secret\n- namespace.yaml\n- secret-token.yaml\n\n# Deploy the repositories\n- repositories.yaml\n\n# Deploy the CRDs\n- deployment-crds.yaml\n\n# Deploy the operator\n- deployment.yaml\n\n# Deploy default Custom Resources from 'crs' directory\n# INFO: This depends on the CRDs deployment. Will happen after it\n- deployment-crs.yaml\n
"},{"location":"examples/gitops-using-fluxcd/#create-the-secret","title":"Create the secret","text":"To access your secret manager, External Secrets needs some credentials. They are stored inside a Secret, which is intended to be deployed by automation as a good practise. This time, a placeholder called secret-token.yaml
is show as an example:
# The namespace.yaml first\napiVersion: v1\nkind: Namespace\nmetadata:\n name: external-secrets\n
apiVersion: v1\nkind: Secret\nmetadata:\n name: vault-token-global\n namespace: external-secrets\nstringData:\n # This token must be patched by overlays. Not here for security reasons\n token: change-me-placeholder\n
"},{"location":"examples/gitops-using-fluxcd/#creating-the-references-to-repositories","title":"Creating the references to repositories","text":"Create a manifest called repositories.yaml
to store the references to external repositories for Flux
# Reference to Helm repository\napiVersion: source.toolkit.fluxcd.io/v1beta1\nkind: HelmRepository\nmetadata:\n name: external-secrets\n namespace: flux-system\nspec:\n interval: 10m\n url: https://charts.external-secrets.io\n---\napiVersion: source.toolkit.fluxcd.io/v1beta1\nkind: GitRepository\nmetadata:\n name: external-secrets\n namespace: flux-system\nspec:\n interval: 10m\n ref:\n branch: main\n url: http://github.com/external-secrets/external-secrets\n
"},{"location":"examples/gitops-using-fluxcd/#deploy-the-crds","title":"Deploy the CRDs","text":"As mentioned, CRDs can be deployed using the official Helm package, but to solve the race condition, they will be deployed from our git repository using a Kustomization manifest called deployment-crds.yaml
as follows:
---\napiVersion: kustomize.toolkit.fluxcd.io/v1beta2\nkind: Kustomization\nmetadata:\n name: external-secrets-crds\n namespace: flux-system\nspec:\n interval: 10m\n path: ./deploy/crds\n prune: true\n sourceRef:\n kind: GitRepository\n name: external-secrets\n
"},{"location":"examples/gitops-using-fluxcd/#deploy-the-operator","title":"Deploy the operator","text":"The operator is deployed using a HelmRelease manifest to deploy the Helm package, but due to the special race condition, the deployment must be disabled in the values
of the manifest called deployment.yaml
, as follows:
# How to manage values files. Ref: https://fluxcd.io/docs/guides/helmreleases/#refer-to-values-inside-the-chart\n# How to inject values: https://fluxcd.io/docs/guides/helmreleases/#cloud-storage\n---\napiVersion: helm.toolkit.fluxcd.io/v2beta1\nkind: HelmRelease\nmetadata:\n name: external-secrets\n namespace: flux-system\nspec:\n # Override Release name to avoid the pattern Namespace-Release\n # Ref: https://fluxcd.io/docs/components/helm/api/#helm.toolkit.fluxcd.io/v2beta1.HelmRelease\n releaseName: external-secrets\n targetNamespace: external-secrets\n interval: 10m\n chart:\n spec:\n chart: external-secrets\n version: 0.9.4\n sourceRef:\n kind: HelmRepository\n name: external-secrets\n namespace: flux-system\n values:\n installCRDs: false\n\n # Ref: https://fluxcd.io/docs/components/helm/api/#helm.toolkit.fluxcd.io/v2beta1.Install\n install:\n createNamespace: true\n
"},{"location":"examples/gitops-using-fluxcd/#deploy-the-crs","title":"Deploy the CRs","text":"Now, be ready for the arcane magic. Create a Kustomization manifest called deployment-crs.yaml
with the following content:
---\napiVersion: kustomize.toolkit.fluxcd.io/v1beta2\nkind: Kustomization\nmetadata:\n name: external-secrets-crs\n namespace: flux-system\nspec:\n dependsOn:\n - name: external-secrets-crds\n interval: 10m\n path: ./infrastructure/external-secrets/crs\n prune: true\n sourceRef:\n kind: GitRepository\n name: flux-system\n
There are several interesting details to see here, that finally solves the race condition:
- First one is the field
dependsOn
, which points to a previous Kustomization called external-secrets-crds
. This dependency forces this deployment to wait for the other to be ready, before start being deployed. - The reference to the place where to find the CRs
path: ./infrastructure/external-secrets/crs\nsourceRef:\n kind: GitRepository\n name: flux-system\n
Custom Resources will be searched in the relative path ./infrastructure/external-secrets/crs
of the GitRepository called flux-system
, which is a reference to the same repository that FluxCD watches to synchronize the cluster. With fewer words, a reference to itself, but going to another directory called crs
Of course, allocate inside the mentioned path ./infrastructure/external-secrets/crs
, all the desired CRs to be deployed, for example, a manifest clusterSecretStore.yaml
to reach your Hashicorp Vault as follows:
apiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\n name: vault-backend-global\nspec:\n provider:\n vault:\n server: \"https://vault.your-domain.com\"\n path: secret\n version: v2\n auth:\n # points to a secret that contains a vault token\n # https://www.vaultproject.io/docs/auth/token\n tokenSecretRef:\n name: \"vault-token-global\"\n key: \"token\"\n namespace: external-secrets\n
"},{"location":"examples/gitops-using-fluxcd/#results","title":"Results","text":"At the end, the required files tree is shown in the following picture:
"},{"location":"examples/jenkins-kubernetes-credentials/","title":"Getting started","text":"Jenkins is one of the most popular automation servers for continuous integration, automation, scheduling jobs and for generic pipelining. It has an extensive set of plugins that extend or provide additional functionality including the kubernetes credentials plugin. This plugin takes kubernetes secrets and creates Jenkins credentials from them removing the need for manual entry of secrets, local storage and manual secret rotation.
"},{"location":"examples/jenkins-kubernetes-credentials/#examples","title":"Examples","text":"The Jenkins credentials plugin uses labels and annotations on a kubernetes secret to create a Jenkins credential.
The different types of Jenkins credentials that can be created are SecretText, privateSSHKey, UsernamePassword.
"},{"location":"examples/jenkins-kubernetes-credentials/#secrettext","title":"SecretText","text":"Here are some examples of SecretText with the Hashicorp Vault and AWS External Secrets providers:
"},{"location":"examples/jenkins-kubernetes-credentials/#hashicorp-vault","title":"Hashicorp Vault","text":"apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: sonarqube-api-token\n namespace: ci\nspec:\n refreshInterval: 1m\n secretStoreRef:\n name: vault-backend\n kind: ClusterSecretStore\n target:\n name: sonarqube-api-token\n template:\n metadata:\n labels:\n \"jenkins.io/credentials-type\": \"secretText\"\n annotations:\n \"jenkins.io/credentials-description\": \"sonarqube api token\"\n data:\n text: >-\n {{ printf \"{{ .password | toString }}\" }}\n data:\n - secretKey: password\n remoteRef:\n key: jenkins-credentials\n property: sonarqube-api-token\n
"},{"location":"examples/jenkins-kubernetes-credentials/#aws-secrets-manager","title":"AWS Secrets Manager","text":"---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: sonarqube-api-token\n namespace: ci\nspec:\n refreshInterval: 1m\n secretStoreRef:\n name: cluster-secrets-store\n kind: ClusterSecretStore\n target:\n name: sonarqube-api-token\n template:\n metadata:\n labels:\n \"jenkins.io/credentials-type\": \"secretText\"\n annotations:\n \"jenkins.io/credentials-description\": \"Sonar API token\"\n data:\n - secretKey: text\n remoteRef:\n key: service/sonarqube/apiToken\n
"},{"location":"examples/jenkins-kubernetes-credentials/#usernamepassword","title":"UsernamePassword","text":"Here are some examples of UsernamePassword credentials with the Hashicorp Vault and AWS External Secrets providers:
"},{"location":"examples/jenkins-kubernetes-credentials/#hashicorp-vault_1","title":"Hashicorp Vault","text":"apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: harbor-chart-robot\n namespace: ci\nspec:\n refreshInterval: 1m\n secretStoreRef:\n name: vault-backend\n kind: ClusterSecretStore\n target:\n name: harbor-chart-robot\n template:\n metadata:\n labels:\n \"jenkins.io/credentials-type\": \"usernamePassword\"\n annotations:\n \"jenkins.io/credentials-description\": \"harbor chart robot\"\n data:\n username: >-\n {{ printf \"{{ .username | toString }}\" }}\n password: >-\n {{ printf \"{{ .password | toString }}\" }}\n data:\n - secretKey: username\n remoteRef:\n key: my-kv\n property: harbor-chart-robot-username\n - secretKey: password\n remoteRef:\n key: my-kv\n property: harbor-chart-robot-token\n
"},{"location":"examples/jenkins-kubernetes-credentials/#aws-secrets-manager_1","title":"AWS Secrets Manager","text":"---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: harbor-chart-robot\n namespace: ci\nspec:\n refreshInterval: 1m\n secretStoreRef:\n name: cluster-secrets-store\n kind: ClusterSecretStore\n target:\n name: harbor-chart-robot\n template:\n metadata:\n labels:\n \"jenkins.io/credentials-type\": \"usernamePassword\"\n annotations:\n \"jenkins.io/credentials-description\": \"harbor chart robot access\"\n data:\n - secretKey: password\n remoteRef:\n key: service/harbor/chartRobot\n property: password\n - secretKey: username\n remoteRef:\n key: service/harbor/chartRobot\n property: username\n
"},{"location":"examples/jenkins-kubernetes-credentials/#basicsshuserprivatekey","title":"basicSSHUserPrivateKey","text":"Here are some examples of basicSSHUserPrivateKey credentials with the Hashicorp Vault and AWS External Secrets providers:
"},{"location":"examples/jenkins-kubernetes-credentials/#hashicorp-vault_2","title":"Hashicorp Vault","text":"apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: github-ssh-access\n namespace: ci\nspec:\n refreshInterval: 1m\n secretStoreRef:\n name: vault-backend\n kind: ClusterSecretStore\n target:\n name: github-ssh-access\n template:\n metadata:\n labels:\n \"jenkins.io/credentials-type\": \"basicSSHUserPrivateKey\"\n annotations:\n \"jenkins.io/credentials-description\": \"github-ssh-access key\"\n data:\n username: >-\n {{ printf \"{{ .username | toString }}\" }}\n privateKey: >-\n {{ printf \"{{ .privateKey | toString }}\" }}\n data:\n - secretKey: username\n remoteRef:\n key: my-kv\n property: github-ssh-access-username\n - secretKey: privateKey\n remoteRef:\n key: my-kv\n property: github-ssh-access-private-key\n
"},{"location":"examples/jenkins-kubernetes-credentials/#aws-secrets-manager_2","title":"AWS Secrets Manager","text":"---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: github-ssh-access\n namespace: ci\nspec:\n refreshInterval: 1m\n secretStoreRef:\n name: cluster-parameter-store\n kind: ClusterSecretStore\n target:\n name: github-ssh-access\n template:\n metadata:\n labels:\n \"jenkins.io/credentials-type\": \"basicSSHUserPrivateKey\"\n annotations:\n \"jenkins.io/credentials-description\": \"github-ssh-access key\"\n data:\n - secretKey: username\n remoteRef:\n key: /service/github/sshUserPrivateKeyUserName\n - secretKey: privateKey\n remoteRef:\n key: /service/github/sshUserPrivateKey\n
"},{"location":"guides/all-keys-one-secret/","title":"All Keys, One Secret","text":"To get multiple key-values from an external secret, not having to worry about how many, or what these keys are, we have to use the dataFrom field of the ExternalSecret resource, instead of the data field. We will give an example here with the gcp provider (should work with other providers in the same way).
Please follow the authentication and SecretStore steps of the Google Cloud Secrets Manager guide to setup access to your google cloud account first.
Then create a secret in Google Cloud Secret Manager that contains a JSON string with multiple key values like this:
Let's call this secret all-keys-example-secret on Google Cloud.
"},{"location":"guides/all-keys-one-secret/#creating-datafrom-external-secret","title":"Creating dataFrom external secret","text":"Now, when creating our ExternalSecret resource, instead of using the data field, we use the dataFrom field:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example\nspec:\n refreshInterval: 1h # rate SecretManager pulls GCPSM\n secretStoreRef:\n kind: SecretStore\n name: example # name of the SecretStore (or kind specified)\n target:\n name: secret-to-be-created # name of the k8s Secret to be created\n creationPolicy: Owner\n dataFrom:\n - extract:\n key: all-keys-example-secret # name of the GCPSM secret\n
Here, \"example\" is the name of the external secret that will be created in our cluster. Whereas, \"secret-to-be-created\" is the name of Kubernetes secrets that will be created. Note: Since these secrets are namespace-based resources, you can also explicitly specify the \"namespace\" under the \"metadata\" block of the above external secret file. when we use, dataFrom:\n - extract:\n key: all-keys-example-secret\n
We get all the key-value pairs present over the remote secret store (GCP or AWS or Azure) and can pass either all or a few key-values as environment variables. Please note that, \"all-keys-example-secret\" is the name of your secret present on GCP/AWS secrets manager/Azure We can pass a few secrets as env variables as below:
env:\n - name: key1\n valueFrom:\n secretKeyRef:\n name: secret-to-be-created\n key: username\n\n - name: key2\n valueFrom:\n secretKeyRef:\n name: secret-to-be-created\n key: surname\n
Here, \\<key1> and \\ are the names of keys that will be created and passed as env variables. \\<secret-to-be-created>: is the name of your Kubernetes secret created by you. \\<username> and \\: is the particular key in the secrets manager whose value you want to pass. To check both values we can run:
kubectl get secret secret-to-be-created -n <namespace> -o jsonpath='{.data.username}' | base64 -d\nkubectl get secret secret-to-be-created -n <namespace> -o jsonpath='{.data.surname}' | base64 -d\n
Also, if you have a large number of secrets and you want to pass all of them as enviromnent variables, then either you can replicate the above steps in your deployment file for all the keys or you can use the envFrom block as below:
spec:\n containers:\n - command:\n - mkdir abc.sh\n envFrom:\n - secretRef:\n name: secret-to-be-created\n
"},{"location":"guides/common-k8s-secret-types/","title":"A few common k8s secret types examples","text":"Here we will give some examples of how to work with a few common k8s secret types. We will give this examples here with the gcp provider (should work with other providers in the same way). Please also check the guides on Advanced Templating to understand the details.
Please follow the authentication and SecretStore steps of the Google Cloud Secrets Manager guide to setup access to your google cloud account first.
"},{"location":"guides/common-k8s-secret-types/#dockerconfigjson-example","title":"Dockerconfigjson example","text":"First create a secret in Google Cloud Secrets Manager containing your docker config:
Let's call this secret docker-config-example on Google Cloud.
Then create a ExternalSecret resource taking advantage of templating to populate the generated secret:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: dk-cfg-example\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: example\n kind: SecretStore\n target:\n template:\n type: kubernetes.io/dockerconfigjson\n data:\n .dockerconfigjson: \"{{ .mysecret | toString }}\"\n name: secret-to-be-created\n creationPolicy: Owner\n data:\n - secretKey: mysecret\n remoteRef:\n key: docker-config-example\n
For Helm users: since Helm interprets the template above, the ExternalSecret resource can be written this way:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: dk-cfg-example\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: example\n kind: SecretStore\n target:\n template:\n type: kubernetes.io/dockerconfigjson\n engineVersion: v2\n data:\n .dockerconfigjson: \"{{ `{{ .mysecret }}` }}\"\n name: secret-to-be-created\n creationPolicy: Owner\n data:\n - secretKey: mysecret\n remoteRef:\n key: docker-config-example\n
For more information, please see this issue
This will generate a valid dockerconfigjson secret for you to use!
You can get the final value with:
kubectl get secret secret-to-be-created -n <namespace> -o jsonpath=\"{.data\\.dockerconfigjson}\" | base64 -d\n
Alternately, if you only have the container registry name and password value, you can take advantage of the advanced ExternalSecret templating functions to create the secret:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: dk-cfg-example\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: example\n kind: SecretStore\n target:\n template:\n type: kubernetes.io/dockerconfigjson\n data:\n .dockerconfigjson: '{\"auths\":{\"{{ .registryName | lower }}.{{ .registryHost }}\":{\"username\":\"{{ .registryName }}\",\"password\":\"{{ .password }}\",\"auth\":\"{{ printf \"%s:%s\" .registryName .password | b64enc }}\"}}}'\n data:\n - secretKey: registryName\n remoteRef:\n key: secret/docker-registry-name # \"myRegistry\"\n - secretKey: registryHost\n remoteRef:\n key: secret/docker-registry-host # \"docker.io\"\n - secretKey: password\n remoteRef:\n key: secret/docker-registry-password\n
"},{"location":"guides/common-k8s-secret-types/#tls-cert-example","title":"TLS Cert example","text":"We are assuming here that you already have valid certificates, maybe generated with letsencrypt or any other CA. So to simplify you can use openssl to generate a single secret pkcs12 cert based on your cert.pem and privkey.pen files.
openssl pkcs12 -export -out certificate.p12 -inkey privkey.pem -in cert.pem\n
With a certificate.p12 you can upload it to Google Cloud Secrets Manager:
And now you can create an ExternalSecret that gets it. You will end up with a k8s secret of type tls with pem values.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: template-tls-example\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: example\n kind: SecretStore\n target:\n name: secret-to-be-created\n # this is how the Kind=Secret will look like\n template:\n type: kubernetes.io/tls\n data:\n tls.crt: \"{{ .mysecret | pkcs12cert | pemCertificate }}\"\n tls.key: \"{{ .mysecret | pkcs12key | pemPrivateKey }}\"\n\n data:\n # this is a pkcs12 archive that contains\n # a cert and a private key\n - secretKey: mysecret\n remoteRef:\n key: ssl-certificate-p12-example\n
You can get their values with:
kubectl get secret secret-to-be-created -n <namespace> -o jsonpath=\"{.data.tls\\.crt}\" | base64 -d\nkubectl get secret secret-to-be-created -n <namespace> -o jsonpath=\"{.data.tls\\.key}\" | base64 -d\n
"},{"location":"guides/common-k8s-secret-types/#ssh-auth-example","title":"SSH Auth example","text":"Add the ssh privkey to a new Google Cloud Secrets Manager secret:
And now you can create an ExternalSecret that gets it. You will end up with a k8s secret of type ssh-auth with the privatekey value.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: ssh-auth-example\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: example\n kind: SecretStore\n target:\n name: secret-to-be-created\n template:\n type: kubernetes.io/ssh-auth\n data:\n ssh-privatekey: \"{{ .mysecret | toString }}\"\n name: secret-to-be-created\n creationPolicy: Owner\n data:\n - secretKey: mysecret\n remoteRef:\n key: ssh-priv-key-example\n
You can get the privkey value with:
kubectl get secret secret-to-be-created -n <namespace> -o jsonpath=\"{.data.ssh-privatekey}\" | base64 -d\n
"},{"location":"guides/common-k8s-secret-types/#more-examples","title":"More examples","text":"We need more examples here
Feel free to contribute with our docs and add more examples here!
"},{"location":"guides/controller-class/","title":"Controller Classes","text":"NOTE: this feature is experimental and not highly tested
Controller classes are a property set during the deployment that allows multiple controllers to work in a group of workload. It works by separating which secretStores are going to be attributed to which controller. For the behavior of a single controller, no extra configuration is needed.
"},{"location":"guides/controller-class/#setting-up-controller-class","title":"Setting up Controller Class","text":"In order to deploy the controller with a specific class, install the helm charts specifying the controller class, and create a SecretStore
with the appropriate spec.controller
values:
helm install custom-external-secrets external-secrets/external-secrets --set controllerClass=custom\n
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: controller-custom-example\nspec:\n #define the controller label to the matching value of the deployment\n controller: custom\n #configure provider the same way\n provider:\n vault:\n server: \"http://vault.default:8200\"\n path: \"secret\"\n version: \"v2\"\n auth:\n kubernetes:\n mountPath: \"kubernetes\"\n role: \"demo-role\"\n
Now, any ExternalSecret
bound to this secret store will be evaluated by the operator with the controllerClass custom.
Note: Any SecretStore without spec.controller
set will be considered as valid by any operator, regardless of their respective controllerClasses.
"},{"location":"guides/datafrom-rewrite/","title":"Rewriting Keys in DataFrom","text":"When calling out an ExternalSecret with dataFrom.extract
or dataFrom.find
, it is possible that you end up with a kubernetes secret that has conflicts in the key names, or that you simply want to remove a common path from the secret keys.
In order to do so, it is possible to define a set of rewrite operations using dataFrom.rewrite
. These operations can be stacked, hence allowing complex manipulations of the secret keys.
Rewrite operations are all applied before ConversionStrategy
is applied.
"},{"location":"guides/datafrom-rewrite/#methods","title":"Methods","text":""},{"location":"guides/datafrom-rewrite/#regexp","title":"Regexp","text":"This method implements rewriting through the use of regular expressions. It needs a source
and a target
field. The source field is where the definition of the matching regular expression goes, where the target
field is where the replacing expression goes.
Some considerations about the implementation of Regexp Rewrite:
- The input of a subsequent rewrite operation are the outputs of the previous rewrite.
- If a given set of keys do not match any Rewrite operation, there will be no error. Rather, the original keys will be used.
- If a
source
is not a compilable regexp
expression, an error will be produced and the external secret goes into a error state.
"},{"location":"guides/datafrom-rewrite/#examples","title":"Examples","text":""},{"location":"guides/datafrom-rewrite/#removing-a-common-path-from-find-operations","title":"Removing a common path from find operations","text":"The following ExternalSecret:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example\nspec:\n refreshInterval: 1h\n secretStoreRef:\n kind: SecretStore\n name: backend\n target:\n name: secret-to-be-created\n dataFrom:\n - find:\n path: path/to/my\n name: \n regexp: secrets\n rewrite:\n - regexp:\n source: \"path/to/my/secrets/(.*)\"\n target: \"$1\"\n
Will get all the secrets matching path/to/my/secrets/*
and then rewrite them by removing the common path away. In this example, if we had the following secrets available in the provider:
path/to/my/secrets/username\npath/to/my/secrets/password\n
the output kubernetes secret would be: apiVersion: v1\nkind: Secret\ntype: Opaque\ndata:\n username: ...\n password: ...\n
"},{"location":"guides/datafrom-rewrite/#avoiding-key-collisions","title":"Avoiding key collisions","text":"The following ExternalSecret:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example\nspec:\n refreshInterval: 1h\n secretStoreRef:\n kind: SecretStore\n name: backend\n target:\n name: secret-to-be-created\n dataFrom:\n - extract:\n key: my-secrets-dev\n rewrite:\n - regexp:\n source: \"(.*)\"\n target: \"dev-$1\" \n - extract:\n key: my-secrets-prod\n rewrite:\n - regexp:\n source: \"(.*)\"\n target: \"prod-$1\"\n
Will allow two secrets with the same JSON keys to be imported into a Kubernetes Secret without any conflict. In this example, if we had the following secrets available in the provider: {\n \"my-secrets-dev\": {\n \"password\": \"bar\",\n },\n \"my-secrets-prod\": {\n \"password\": \"safebar\",\n }\n}\n
the output kubernetes secret would be: apiVersion: v1\nkind: Secret\ntype: Opaque\ndata:\n dev_password: YmFy #bar\n prod_password: c2FmZWJhcg== #safebar\n
"},{"location":"guides/datafrom-rewrite/#remove-invalid-characters","title":"Remove invalid characters","text":"The following ExternalSecret:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example\nspec:\n refreshInterval: 1h\n secretStoreRef:\n kind: SecretStore\n name: backend\n target:\n name: secret-to-be-created\n dataFrom:\n - extract:\n key: development\n rewrite:\n - regexp:\n source: \"[^a-zA-Z0-9 -]\"\n target: \"_\"\n
Will remove invalid characters from the secret key. In this example, if we had the following secrets available in the provider: {\n \"development\": {\n \"foo/bar\": \"1111\",\n \"foo$baz\": \"2222\"\n }\n}\n
the output kubernetes secret would be: apiVersion: v1\nkind: Secret\ntype: Opaque\ndata:\n foo_bar: MTExMQ== #1111\n foo_baz: MjIyMg== #2222\n
"},{"location":"guides/datafrom-rewrite/#limitations","title":"Limitations","text":"Regexp Rewrite is based on golang regexp
, which in turns implements RE2
regexp language. There a a series of known limitations to this implementation, such as:
- Lack of ability to do lookaheads or lookbehinds;
- Lack of negation expressions;
- Lack of support for conditional branches;
- Lack of support for possessive repetitions.
A list of compatibility and known limitations considering other commonly used regexp frameworks (such as PCRE and PERL) are listed here.
"},{"location":"guides/decoding-strategy/","title":"Decoding Strategies","text":"The External Secrets Operator has the feature to allow multiple decoding strategies during an object generation.
The decodingStrategy
field allows the user to set the following Decoding Strategies based on their needs. decodingStrategy
can be placed under spec.data.remoteRef
, spec.dataFrom.extract
or spec.dataFrom.find
. It will configure the decoding strategy for that specific operation, leaving others with the default behavior if not set.
"},{"location":"guides/decoding-strategy/#none-default","title":"None (default)","text":"ESO will not try to decode the secret value.
"},{"location":"guides/decoding-strategy/#base64","title":"Base64","text":"ESO will try to decode the secret value using base64 method. If the decoding fails, an error is produced.
"},{"location":"guides/decoding-strategy/#base64url","title":"Base64URL","text":"ESO will try to decode the secret value using base64url method. If the decoding fails, an error is produced.
"},{"location":"guides/decoding-strategy/#auto","title":"Auto","text":"ESO will try to decode using Base64/Base64URL strategies. If the decoding fails, ESO will apply decoding strategy None. No error is produced to the user.
"},{"location":"guides/decoding-strategy/#examples","title":"Examples","text":""},{"location":"guides/decoding-strategy/#setting-decoding-strategy-auto-in-a-datafromextract","title":"Setting Decoding strategy Auto in a DataFrom.Extract","text":"Given that we have the given secret information:
{\n \"name\": \"Gustavo\",\n \"surname\": \"Fring\",\n \"address\":\"aGFwcHkgc3RyZWV0\",\n}\n
if we apply the following dataFrom: spec:\n dataFrom:\n - extract:\n key: my-secret\n decodingStrategy: Auto\n
It will render the following Kubernetes Secret: data:\n name: R3VzdGF2bw== #Gustavo\n surname: RnJpbmc= #Fring\n address: aGFwcHkgc3RyZWV0 #happy street\n
"},{"location":"guides/decoding-strategy/#limitations","title":"Limitations","text":"At this time, decoding Strategy Auto is only trying to check if the original input is valid to perform Base64 operations. This means that some non-encoded secret values might end up being decoded, producing gibberish. This is the case for numbered values like 123456
or some specially crafted string values such as happy/street
.
Note
If you are using decodeStrategy: Auto
and start to see ESO pulling completely wrong secret values into your kubernetes secret, consider changing it to None
to investigate it.
"},{"location":"guides/disable-cluster-features/","title":"Deploying without ClusterSecretStore and ClusterExternalSecret","text":"When deploying External Secrets Operator via Helm chart, the default configuration will install ClusterSecretStore
and ClusterExternalSecret
CRDs and these objects will be processed by the operator.
In order to disable both or one of these features, it is necessary to configure the crds.*
Helm value, as well as the process*
Helm value, as these 2 values are connected.
If you would like to install the operator without ClusterSecretStore
and ClusterExternalSecret
management, you will have to :
- set
crds.createClusterExternalSecret
to false - set
crds.createClusterSecretStore
to false - set
processClusterExternalSecret
to false - set
processClusterStore
to false
Example:
helm install external-secrets external-secrets/external-secrets --set crds.createClusterExternalSecret=false \\\n--set crds.createClusterSecretStore=false \\\n--set processClusterExternalSecret=false \\\n--set processClusterStore=false\n
"},{"location":"guides/generator/","title":"Generators","text":"Generators allow you to generate values. They are used through a ExternalSecret spec.DataFrom
. They are referenced from a custom resource using sourceRef.generatorRef
.
If the External Secret should be refreshed via spec.refreshInterval
the generator produces a map of values with the generator.spec
as input. The generator does not keep track of the produced values. Every invocation produces a new set of values.
These values can be used with the other features like rewrite
or template
. I.e. you can modify, encode, decode, pack the values as needed.
"},{"location":"guides/generator/#reference-custom-resource","title":"Reference Custom Resource","text":"Generators can be defined as a custom resource and re-used across different ExternalSecrets. Every invocation creates a new set of values. I.e. you can not share the same value produced by a generator across different ExternalSecrets
or spec.dataFrom[]
entries.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: \"ecr-token\"\nspec:\n refreshInterval: \"30m\"\n target:\n name: ecr-token\n dataFrom:\n - sourceRef:\n generatorRef:\n apiVersion: generators.external-secrets.io/v1alpha1\n kind: ECRAuthorizationToken\n name: \"my-ecr\"\n
"},{"location":"guides/getallsecrets/","title":"Fetching information from multiple secrets","text":"In some use cases, it might be impractical to bundle all sensitive information into a single secret, or even it is not possible to fully know a given secret name. In such cases, it is possible that a user might need to sync multiple secrets from an external provider into a single Kubernetes Secret. This is possible to be done in external-secrets with the dataFrom.find
option.
Note
The secret's contents as defined in the provider are going to be stored in the kubernetes secret as a single key. Currently, it's possible to apply a decoding Strategy during a find operation, but only at the secret level (e.g. if a secret is a JSON with some B64 encoded data within, decodingStrategy: Auto
would not decode it)
"},{"location":"guides/getallsecrets/#fetching-secrets-matching-a-given-name-pattern","title":"Fetching secrets matching a given name pattern","text":"To fetch multiple secrets matching a name pattern from a common SecretStore you can apply the following manifest:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: find-by-tags\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: secretstore-sample\n kind: SecretStore\n target:\n name: secret-to-be-created\n dataFrom:\n - find:\n name:\n regexp: \"key\"\n
Suppose we contain secrets /path/key1
, key2/path
, and path/to/keyring
with their respective values. The above YAML will produce the following kubernetes Secret:
_path_key1: Cg==\nkey2_path: Cg==\npath_to_keyring: Cg==\n
"},{"location":"guides/getallsecrets/#fetching-secrets-matching-a-set-of-metadata-tags","title":"Fetching secrets matching a set of metadata tags","text":"To fetch multiple secrets matching a name pattern from a common SecretStore you can apply the following manifest:
apiVersion: external-secrets.io/v1beta1 \nkind: ExternalSecret\nmetadata:\n name: find-by-tags\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: secretstore-sample\n kind: SecretStore\n target:\n name: secret-to-be-created\n dataFrom:\n - find:\n tags:\n environment: \"prod\"\n application: \"app-name\"\n
This will match any secrets containing all of the metadata labels in the tags
parameter. At least one tag must be provided in order to allow finding secrets by metadata tags."},{"location":"guides/getallsecrets/#searching-only-in-a-given-path","title":"Searching only in a given path","text":"Some providers support filtering out a find operation only to a given path, instead of the root path. In order to use this feature, you can pass find.path
to filter out these secrets into only this path, instead of the root path.
"},{"location":"guides/getallsecrets/#avoiding-name-conflicts","title":"Avoiding name conflicts","text":"By default, kubernetes Secrets accepts only a given range of characters. Find
operations will automatically replace any not allowed character with a _
. So if we have a given secret a_c
and a/c
would lead to a naming conflict.
If you happen to have a case where a conflict is happening, you can use the rewrite
block to apply a regexp on one of the find operations (for more information please refer to Rewriting Keys from DataFrom).
You can also set dataFrom.find.conversionStrategy: Unicode
to reduce the collistion probability. When using Unicode
, any invalid character will be replaced by its unicode, in the form of _UXXXX_
. In this case, the available kubernetes keys would be a_c
and a_U2215_c
, hence avoiding most of possible conflicts.
PRs welcome
Some providers might not have the implementation needed for fetching multiple secrets. If that's your case, please feel free to contribute!
"},{"location":"guides/introduction/","title":"Guides","text":"The following guides demonstrate use-cases and provide examples of how to use the API. Please pick one of the following guides:
- Multi-Tenancy Design Considerations
- Find multiple secrets & Extract Secret values
- Advanced Templating
- Generating Passwords using generators
- Ownership and Deletion Policy
- Key Rewriting
- Controller Class
- Decoding Strategy
- v1beta1 Migration
- Deploying image from main
- Deploying without cluster features
"},{"location":"guides/multi-tenancy/","title":"Multi Tenancy","text":"External Secrets Operator provides different modes of operation to fulfill organizational needs. This guide outlines the flexibility of ESO and should give you a first impression of how you can employ this operator in your organization.
For a multi-tenant deployment you should first examine your organizational structure:
- what roles (i.e. Application Developers, Cluster Admins, ...) do you have in your organization,
- what responsibilities do they have and
- how does that map to Kubernetes RBAC roles.
Further, you should examine how your external API provider manages access control for your secrets. Can you limit access by secret names (e.g. db/dev/*
)? Or only on a bucket level? Please keep in mind that not all external APIs provide fine-grained access management for secrets.
Note: The following examples should not be considered as best practice but rather as a example to show how to combine different mechanics and techniques for tenant isolation.
"},{"location":"guides/multi-tenancy/#shared-clustersecretstore","title":"Shared ClusterSecretStore","text":"A Cluster Administrator deploys a ClusterSecretStore
(CSS) and manages access to the external API. The CSS is shared by all tenants within the cluster. Application Developers do reference it in a ExternalSecret
but can not create a ClusterSecretStores or SecretStores on their own. Now all application developers have access to all the secrets. You probably want to limit access to certain keys or prefixes that should be used. ESO does not provide a mechanic to limit access to certain keys per namespace. More advanced validation should be done with an Admission Webhook, e.g. with Kyverno or Open Policy Agent).
This setup suites well if you have one central bucket that contains all of your secrets and your Cluster Administrators should manage access to it. This setup is very simple but does not scale very well.
"},{"location":"guides/multi-tenancy/#managed-secretstore-per-namespace","title":"Managed SecretStore per Namespace","text":"Cluster Administrators manage one or multiple SecretStores
per Namespace. Each SecretStore uses it's own role that limits access to a small set of keys. The peculiarity of this is approach is, that access is actually managed by the external API which provides the roles. The Cluster Administrator does just the wiring. This approach may be desirable if you have an external entity - let's call it Secret Administrator - that manages access and lifecycle of the secrets.
"},{"location":"guides/multi-tenancy/#eso-as-a-service","title":"ESO as a Service","text":"Every namespace is self-contained. Application developers manage SecretStore
, ExternalSecret
and secret infrastructure on their own. Cluster Administrators just provide the External Secrets Operator as a service.
This makes sense if application developers should be completely autonomous while a central team provides common services.
"},{"location":"guides/ownership-deletion-policy/","title":"Lifecycle","text":"The External Secrets Operator manages the lifecycle of secrets in Kubernetes. With creationPolicy
and deletionPolicy
you get fine-grained control of its lifecycle.
Creation/Deletion Policy Combinations
Some combinations of creationPolicy/deletionPolicy are not allowed as they would delete existing secrets: - deletionPolicy=Delete
& creationPolicy=Merge
- deletionPolicy=Delete
& creationPolicy=None
- deletionPolicy=Merge
& creationPolicy=None
"},{"location":"guides/ownership-deletion-policy/#creation-policy","title":"Creation Policy","text":"The field spec.target.creationPolicy
defines how the operator creates the a secret.
"},{"location":"guides/ownership-deletion-policy/#owner-default","title":"Owner (default)","text":"The External Secret Operator creates secret and sets the ownerReference
field on the Secret. This secret is subject to garbage collection if the initial ExternalSecret
is absent. If a secret with the same name already exists that is not owned by the controller it will result in a conflict. The operator will just error out, not claiming the ownership.
Secrets with ownerReference
field not found
If the secret exists and the ownerReference field is not found, the controller treats this secret as orphaned. It will take ownership of this secret by adding an ownerReference
field and updating it.
"},{"location":"guides/ownership-deletion-policy/#orphan","title":"Orphan","text":"The operator creates the secret but does not set the ownerReference
on the Secret. That means the Secret will not be subject to garbage collection. If a secret with the same name already exists it will be updated.
"},{"location":"guides/ownership-deletion-policy/#merge","title":"Merge","text":"The operator does not create a secret. Instead, it expects the secret to already exist. Values from the secret provider will be merged into the existing secret. Note: the controller takes ownership of a field even if it is owned by a different entity. Multiple ExternalSecrets can use creationPolicy=Merge
with a single secret as long as the fields don't collide - otherwise you end up in an oscillating state.
"},{"location":"guides/ownership-deletion-policy/#none","title":"None","text":"The operator does not create or update the secret, this is basically a no-op.
"},{"location":"guides/ownership-deletion-policy/#deletion-policy","title":"Deletion Policy","text":"DeletionPolicy defines what should happen if a given secret gets deleted from the provider.
DeletionPolicy is only supported on the specific providers, please refer to our stability/support table.
"},{"location":"guides/ownership-deletion-policy/#retain-default","title":"Retain (default)","text":"Retain will retain the secret if all provider secrets have been deleted. If a provider secret does not exist the ExternalSecret gets into the SecretSyncedError status.
"},{"location":"guides/ownership-deletion-policy/#delete","title":"Delete","text":"Delete deletes the secret if all provider secrets are deleted. If a secret gets deleted on the provider side and is not accessible anymore this is not considered an error and the ExternalSecret does not go into SecretSyncedError status. This is also true for new ExternalSecrets mapping to non-existing secrets in the provider.
"},{"location":"guides/ownership-deletion-policy/#merge_1","title":"Merge","text":"Merge removes keys in the secret, but not the secret itself. If a secret gets deleted on the provider side and is not accessible anymore this is not considered an error and the ExternalSecret does not go into SecretSyncedError status.
"},{"location":"guides/pushsecrets/","title":"Push Secrets","text":"Contrary to what ExternalSecret
does by pulling secrets from secret providers and creating kind=Secret
in your cluster, PushSecret
reads a local kind=Secret
and pushes its content to a secret provider.
The update behavior of PushSecret
is controlled by spec.updatePolicy
. The default policy is Replace
, such that secrets are overwritten in the provider, regardless of whether there already is a secret present in the provider at the given location. If you do not want PushSecret
to overwrite existing secrets in the provider, you can set spec.UpdatePolicy
to IfNotExists
. With this policy, the provider becomes the source of truth. Please note that with using spec.updatePolicy=IfNotExists
it is possible that the secret value referenced by the PushSecret
within the cluster differs from the secret value at the given location in the provider.
By default, the secret created in the secret provided will not be deleted even after deleting the PushSecret
, unless you set spec.deletionPolicy
to Delete
.
apiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\n name: pushsecret-example # Customisable\n namespace: default # Same of the SecretStores\nspec:\n updatePolicy: Replace # Policy to overwrite existing secrets in the provider on sync\n deletionPolicy: Delete # the provider' secret will be deleted if the PushSecret is deleted\n refreshInterval: 10s # Refresh interval for which push secret will reconcile\n secretStoreRefs: # A list of secret stores to push secrets to\n - name: aws-parameterstore\n kind: SecretStore\n selector:\n secret:\n name: pokedex-credentials # Source Kubernetes secret to be pushed\n template:\n metadata:\n annotations: { }\n labels: { }\n data:\n best-pokemon: \"{{ .best-pokemon | toString | upper }} is the really best!\"\n # Uses an existing template from configmap\n # Secret is fetched, merged and templated within the referenced configMap data\n # It does not update the configmap, it creates a secret with: data[\"alertmanager.yml\"] = ...result...\n templateFrom:\n - configMap:\n name: application-config-tmpl\n items:\n - key: config.yml\n data:\n - conversionStrategy: None # Also supports the ReverseUnicode strategy\n match:\n secretKey: best-pokemon # Source Kubernetes secret key to be pushed\n remoteRef:\n remoteKey: my-first-parameter # Remote reference (where the secret is going to be pushed)\n
"},{"location":"guides/pushsecrets/#backup-use-case","title":"Backup use case","text":"An interesting use case for kind=PushSecret
is backing up your current secret from one provider to another one.
Imagine you have your secrets in GCP and you want to back them up in Azure Key Vault. You would then create a SecretStore
for each provider, and an ExternalSecret
to pull the secrets from GCP. This will generate a kind=Secret
in your cluster that you can use as the source of a PushSecret
configured with the Azure SecretStore
.
"},{"location":"guides/pushsecrets/#pushing-the-whole-secret","title":"Pushing the whole secret","text":"There are two ways to push an entire secret without defining all keys individually.
By leaving off the secret key and remote property options.
apiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\n name: pushsecret-example # Customisable\n namespace: default # Same of the SecretStores\nspec:\n deletionPolicy: Delete # the provider' secret will be deleted if the PushSecret is deleted\n refreshInterval: 10s # Refresh interval for which push secret will reconcile\n secretStoreRefs: # A list of secret stores to push secrets to\n - name: aws-parameterstore\n kind: SecretStore\n selector:\n secret:\n name: pokedex-credentials # Source Kubernetes secret to be pushed\n data:\n - match:\n remoteRef:\n remoteKey: my-first-parameter # Remote reference (where the secret is going to be pushed)\n
This will result in all keys being pushed as they are into the remote location.
By leaving off the secret key but setting the remote property option.
apiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\n name: pushsecret-example # Customisable\n namespace: default # Same of the SecretStores\nspec:\n deletionPolicy: Delete # the provider' secret will be deleted if the PushSecret is deleted\n refreshInterval: 10s # Refresh interval for which push secret will reconcile\n secretStoreRefs: # A list of secret stores to push secrets to\n - name: aws-parameterstore\n kind: SecretStore\n selector:\n secret:\n name: pokedex-credentials # Source Kubernetes secret to be pushed\n data:\n - match:\n secretKey: best-pokemon # Source Kubernetes secret key to be pushed\n remoteRef:\n remoteKey: my-first-parameter # Remote reference (where the secret is going to be pushed)\n property: single-value-secret # the property to use to push into\n
This will marshal the entire secret data and push it into this single property as a JSON object.
Warning
This should ONLY be done if the secret data is marshal-able. Values like, binary data cannot be marshaled and will result in error or invalid secret data.
"},{"location":"guides/pushsecrets/#key-conversion-strategy","title":"Key conversion strategy","text":"You can also set data[*].conversionStrategy: ReverseUnicode
to reverse the invalid character replaced by the conversionStrategy: Unicode
configuration in the ExternalSecret
object as documented here.
"},{"location":"guides/security-best-practices/","title":"Security Best Practices","text":"The purpose of this document is to outline a set of best practices for securing the External Secrets Operator (ESO). These practices aim to mitigate the risk of successful attacks against ESO and the Kubernetes cluster it integrates with.
"},{"location":"guides/security-best-practices/#security-functions-and-features","title":"Security Functions and Features","text":""},{"location":"guides/security-best-practices/#1-namespace-isolation","title":"1. Namespace Isolation","text":"To maintain security boundaries, ESO ensures that namespaced resources like SecretStore
and ExternalSecret
are limited to their respective namespaces. The following rules apply:
ExternalSecret
resources must not have cross-namespace references of Kind=SecretStore
or Kind=Secret
resources SecretStore
resources must not have cross-namespace references of Kind=Secret
or others
For cluster-wide resources like ClusterSecretStore
and ClusterExternalSecret
, exercise caution since they have access to Secret resources across all namespaces. Minimize RBAC permissions for administrators and developers to the necessary minimum. If cluster-wide resources are not required, it is recommended to disable them.
"},{"location":"guides/security-best-practices/#2-configure-clustersecretstore-match-conditions","title":"2. Configure ClusterSecretStore match conditions","text":"Utilize the ClusterSecretStore resource to define specific match conditions using namespaceSelector
or an explicit namespaces list. This restricts the usage of the ClusterSecretStore
to a predetermined list of namespaces or a namespace that matches a predefined label. Here's an example:
apiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\n name: fake\nspec:\n conditions:\n - namespaceSelector:\n matchLabels:\n app: frontend\n
"},{"location":"guides/security-best-practices/#3-selectively-disable-reconciliation-of-cluster-wide-resources","title":"3. Selectively Disable Reconciliation of Cluster-Wide Resources","text":"ESO allows you to selectively disable the reconciliation of cluster-wide resources such as ClusterSecretStore
, ClusterExternalSecret
, and PushSecret
. You can disable the installation of CRDs in the Helm chart or disable reconciliation in the core-controller using the following options:
To disable CRD installation:
# disable cluster-wide resources & push secret\ncrds:\n createClusterExternalSecret: false\n createClusterSecretStore: false\n createPushSecret: false\n
To disable reconciliation in the core-controller:
--enable-cluster-external-secret-reconciler\n--enable-cluster-store-reconciler\n
"},{"location":"guides/security-best-practices/#4-implement-namespace-scoped-installation","title":"4. Implement Namespace-Scoped Installation","text":"To further enhance security, consider installing ESO into a specific namespace with restricted access to only that namespace's resources. This prevents access to cluster-wide secrets. Use the following Helm values to scope the controller to a specific namespace:
# If set to true, create scoped RBAC roles under the scoped namespace\n# and implicitly disable cluster stores and cluster external secrets\nscopedRBAC: true\n\n# Specify the namespace where external secrets should be reconciled\nscopedNamespace: my-namespace\n
"},{"location":"guides/security-best-practices/#pod-security","title":"Pod Security","text":"The Pods of the External Secrets Operator have been configured to meet the Pod Security Standards, specifically the restricted profile. This configuration ensures a strong security posture by implementing recommended best practices for hardening Pods, including those outlined in the NSA Kubernetes Hardening Guide.
By adhering to these standards, the External Secrets Operator benefits from a secure and resilient operating environment. The restricted profile has been set as the default configuration since version v0.8.2
, and it is recommended to maintain this setting to align with the principle of least privilege.
"},{"location":"guides/security-best-practices/#role-based-access-control-rbac","title":"Role-Based Access Control (RBAC)","text":"The External Secrets Operator operates with elevated privileges within your Kubernetes cluster, allowing it to read and write to all secrets across all namespaces. It is crucial to properly restrict access to ESO resources such as ExternalSecret
and SecretStore
where necessary. This is particularly important for cluster-scoped resources like ClusterExternalSecret
and ClusterSecretStore
. Unauthorized tampering with these resources by an attacker could lead to unauthorized access to secrets or potential data exfiltration from your system.
In most scenarios, the External Secrets Operator is deployed cluster-wide. However, if you prefer to run it on a per-namespace basis, you can scope it to a specific namespace using the scopedRBAC
and scopedNamespace
options in the helm chart.
To ensure a secure RBAC configuration, consider the following checklist:
- Restrict access to execute shell commands (pods/exec) within the External Secrets Operator Pod.
- Restrict access to (Cluster)ExternalSecret and (Cluster)SecretStore resources.
- Limit access to aggregated ClusterRoles (view/edit/admin) as needed.
- If necessary, deploy ESO with scoped RBAC or within a specific namespace.
By carefully managing RBAC permissions and scoping the External Secrets Operator appropriately, you can enhance the security of your Kubernetes cluster.
"},{"location":"guides/security-best-practices/#network-traffic-and-security","title":"Network Traffic and Security","text":"To ensure a secure network environment, it is recommended to restrict network traffic to and from the External Secrets Operator using NetworkPolicies
or similar mechanisms. By default, the External Secrets Operator does not include pre-defined Network Policies.
To implement network restrictions effectively, consider the following steps:
- Define and apply appropriate NetworkPolicies to limit inbound and outbound traffic for the External Secrets Operator.
- Specify a \"deny all\" policy by default and selectively permit necessary communication based on your specific requirements.
- Restrict access to only the required endpoints and protocols for the External Secrets Operator, such as communication with the Kubernetes API server or external secret providers.
- Regularly review and update the Network Policies to align with changes in your network infrastructure and security requirements.
It is the responsibility of the user to define and configure Network Policies tailored to their specific environment and security needs. By implementing proper network restrictions, you can enhance the overall security posture of the External Secrets Operator within your Kubernetes cluster.
Data Exfiltration Risk
If not configured properly ESO may be used to exfiltrate data out of your cluster. It is advised to create tight NetworkPolicies and use a policy engine such as kyverno to prevent data exfiltration.
"},{"location":"guides/security-best-practices/#outbound-traffic-restrictions","title":"Outbound Traffic Restrictions","text":""},{"location":"guides/security-best-practices/#core-controller","title":"Core Controller","text":"Restrict outbound traffic from the core controller component to the following destinations:
kube-apiserver
: The Kubernetes API server. - Secret provider (e.g., AWS, GCP): Whenever possible, use private endpoints to establish secure and private communication.
"},{"location":"guides/security-best-practices/#webhook","title":"Webhook","text":" - Restrict outbound traffic from the webhook component to the
kube-apiserver
.
"},{"location":"guides/security-best-practices/#cert-controller","title":"Cert Controller","text":" - Restrict outbound traffic from the cert controller component to the
kube-apiserver
.
"},{"location":"guides/security-best-practices/#inbound-traffic-restrictions","title":"Inbound Traffic Restrictions","text":""},{"location":"guides/security-best-practices/#core-controller_1","title":"Core Controller","text":" - Restrict inbound traffic to the core controller component by allowing communication on port
8080
from your monitoring agent.
"},{"location":"guides/security-best-practices/#cert-controller_1","title":"Cert Controller","text":" - Restrict inbound traffic to the cert controller component by allowing communication on port
8080
from your monitoring agent. - Additionally, permit inbound traffic on port
8081
from the kubelet for health check endpoints (healthz/readyz).
"},{"location":"guides/security-best-practices/#webhook_1","title":"Webhook","text":"Restrict inbound traffic to the webhook component as follows:
- Allow communication on port
10250
from the kube-apiserver. - Allow communication on port
8080
from your monitoring agent. - Permit inbound traffic on port
8081
from the kubelet for health check endpoints (healthz/readyz).
"},{"location":"guides/security-best-practices/#policy-engine-best-practices","title":"Policy Engine Best Practices","text":"To enhance the security and enforce specific policies for External Secrets Operator (ESO) resources such as SecretStore and ExternalSecret, it is recommended to utilize a policy engine like Kyverno or OPA Gatekeeper. These policy engines provide a way to define and enforce custom policies that restrict changes made to ESO resources.
Data Exfiltration Risk
ESO could be used to exfiltrate data out of your cluster. You should disable all providers you don't need. Further, you should implement NetworkPolicies
to restrict network access to known entities (see above), to prevent data exfiltration.
Here are some recommendations to consider when configuring your policies:
- Explicitly Deny Unused Providers: Create policies that explicitly deny the usage of secret providers that are not required in your environment. This prevents unauthorized access to unnecessary providers and reduces the attack surface.
- Restrict Access to Secrets: Implement policies that restrict access to secrets based on specific conditions. For example, you can define policies to allow access to secrets only if they have a particular prefix in the
.spec.data[].remoteRef.key
field. This helps ensure that only authorized entities can access sensitive information. - Restrict
ClusterSecretStore
References: Define policies to restrict the usage of ClusterSecretStore references within ExternalSecret resources. This ensures that the resources are properly scoped and prevent potential unauthorized access to secrets across namespaces.
By leveraging a policy engine, you can implement these recommendations and enforce custom policies that align with your organization's security requirements. Please refer to the documentation of the chosen policy engine (e.g., Kyverno or OPA Gatekeeper) for detailed instructions on how to define and enforce policies for ESO resources.
Provider Validation Example Policy
The following policy validates the usage of the provider
field in the SecretStore manifest.
apiVersion: kyverno.io/v1\nkind: ClusterPolicy\nmetadata:\n name: require-secretstore-aws-provider\nspec:\n validationFailureAction: Enforce\n rules:\n - name: require-secretstore-aws-provider\n match:\n any:\n - resources:\n kinds:\n - SecretStore\n - ClusterSecretStore\n validate:\n message: \"You must only use AWS SecretsManager\"\n pattern:\n spec:\n provider:\n aws:\n service: SecretsManager\n
"},{"location":"guides/security-best-practices/#regular-patches","title":"Regular Patches","text":"To maintain a secure environment, it is crucial to regularly patch and update all software components of External Secrets Operator and the underlying cluster. By doing so, known vulnerabilities can be addressed, and the overall system's security can be improved. Here are some recommended practices for ensuring timely updates:
- Automated Patching and Updating: Utilize automated patching and updating tools to streamline the process of keeping software components up-to-date
- Regular Update ESO: Stay informed about the latest updates and releases provided for ESO. The development team regularly releases updates to improve stability, performance, and security. Please refer to the Stability and Support documentation for more information on the available updates
- Cluster-wide Updates: Apart from ESO, ensure that all other software components within your cluster, such as the operating system, container runtime, and Kubernetes itself, are regularly patched and updated.
By adhering to a regular patching and updating schedule, you can proactively mitigate security risks associated with known vulnerabilities and ensure the overall stability and security of your ESO deployment.
"},{"location":"guides/security-best-practices/#verify-artefacts","title":"Verify Artefacts","text":""},{"location":"guides/security-best-practices/#verify-container-images","title":"Verify Container Images","text":"The container images of External Secrets Operator are signed using Cosign and the keyless signing feature. To ensure the authenticity and integrity of the container image, you can follow the steps outlined below:
# Retrieve Image Signature\n$ crane digest ghcr.io/external-secrets/external-secrets:v0.8.1\nsha256:36e606279dbebac51b4b9300b9fa85e8c08c1c673ba3ecc38af1402a0b035554\n\n# verify signature\n$ COSIGN_EXPERIMENTAL=1 cosign verify ghcr.io/external-secrets/external-secrets@sha256:36e606279dbebac51b4b9300b9fa85e8c08c1c673ba3ecc38af1402a0b035554 | jq\n\n# ...\n[\n {\n \"critical\": {\n \"identity\": {\n \"docker-reference\": \"ghcr.io/external-secrets/external-secrets\"\n },\n \"image\": {\n \"docker-manifest-digest\": \"sha256:36e606279dbebac51b4b9300b9fa85e8c08c1c673ba3ecc38af1402a0b035554\"\n },\n \"type\": \"cosign container image signature\"\n },\n \"optional\": {\n \"1.3.6.1.4.1.57264.1.1\": \"https://token.actions.githubusercontent.com\",\n \"1.3.6.1.4.1.57264.1.2\": \"workflow_dispatch\",\n \"1.3.6.1.4.1.57264.1.3\": \"a0d2aef2e35c259c9ee75d65f7587e6ed71ef2ad\",\n \"1.3.6.1.4.1.57264.1.4\": \"Create Release\",\n \"1.3.6.1.4.1.57264.1.5\": \"external-secrets/external-secrets\",\n \"1.3.6.1.4.1.57264.1.6\": \"refs/heads/main\",\n \"Bundle\": {\n # ...\n },\n \"GITHUB_ACTOR\": \"gusfcarvalho\",\n \"Issuer\": \"https://token.actions.githubusercontent.com\",\n \"Subject\": \"https://github.com/external-secrets/external-secrets/.github/workflows/release.yml@refs/heads/main\",\n \"githubWorkflowName\": \"Create Release\",\n \"githubWorkflowRef\": \"refs/heads/main\",\n \"githubWorkflowRepository\": \"external-secrets/external-secrets\",\n \"githubWorkflowSha\": \"a0d2aef2e35c259c9ee75d65f7587e6ed71ef2ad\",\n \"githubWorkflowTrigger\": \"workflow_dispatch\"\n }\n }\n]\n
In the output of the verification process, pay close attention to the optional.Issuer
and optional.Subject
fields. These fields contain important information about the image's authenticity. Verify that the values of Issuer and Subject match the expected values for the ESO container image. If they do not match, it indicates that the image is not legitimate and should not be used.
By following these steps and confirming that the Issuer and Subject fields align with the expected values for the ESO container image, you can ensure that the image has not been tampered with and is safe to use.
"},{"location":"guides/security-best-practices/#verifying-provenance","title":"Verifying Provenance","text":"The External Secrets Operator employs the SLSA (Supply Chain Levels for Software Artifacts) standard to create and attest to the provenance of its builds. Provenance verification is essential to ensure the integrity and trustworthiness of the software supply chain. This outlines the process of verifying the attested provenance of External Secrets Operator builds using the cosign tool.
$ COSIGN_EXPERIMENTAL=1 cosign verify-attestation --type slsaprovenance ghcr.io/external-secrets/external-secrets:v0.8.1 | jq .payload -r | base64 --decode | jq\n\nVerification for ghcr.io/external-secrets/external-secrets:v0.8.1 --\nThe following checks were performed on each of these signatures:\n - The cosign claims were validated\n - Existence of the claims in the transparency log was verified offline\n - Any certificates were verified against the Fulcio roots.\nCertificate subject: https://github.com/external-secrets/external-secrets/.github/workflows/release.yml@refs/heads/main\nCertificate issuer URL: https://token.actions.githubusercontent.com\nGitHub Workflow Trigger: workflow_dispatch\nGitHub Workflow SHA: a0d2aef2e35c259c9ee75d65f7587e6ed71ef2ad\nGitHub Workflow Name: Create Release\nGitHub Workflow Trigger external-secrets/external-secrets\nGitHub Workflow Ref: refs/heads/main\n{\n \"_type\": \"https://in-toto.io/Statement/v0.1\",\n \"predicateType\": \"https://slsa.dev/provenance/v0.2\",\n \"subject\": [\n {\n \"name\": \"ghcr.io/external-secrets/external-secrets\",\n \"digest\": {\n \"sha256\": \"36e606279dbebac51b4b9300b9fa85e8c08c1c673ba3ecc38af1402a0b035554\"\n }\n }\n ],\n \"predicate\": {\n \"builder\": {\n \"id\": \"https://github.com/external-secrets/external-secrets/Attestations/GitHubHostedActions@v1\"\n },\n \"buildType\": \"https://github.com/Attestations/GitHubActionsWorkflow@v1\",\n \"invocation\": {\n \"configSource\": {\n \"uri\": \"git+https://github.com/external-secrets/external-secrets\",\n \"digest\": {\n \"sha1\": \"a0d2aef2e35c259c9ee75d65f7587e6ed71ef2ad\"\n },\n \"entryPoint\": \"Create Release\"\n },\n \"parameters\": {\n \"version\": \"v0.8.1\"\n }\n },\n [...]\n }\n}\n
"},{"location":"guides/security-best-practices/#fetching-sbom","title":"Fetching SBOM","text":"Every External Secrets Operator image is accompanied by an SBOM (Software Bill of Materials) in SPDX JSON format. The SBOM provides detailed information about the software components and dependencies used in the image. This technical documentation explains the process of downloading and verifying the SBOM for a specific version of External Secrets Operator using the Cosign tool.
$ crane digest ghcr.io/external-secrets/external-secrets:v0.8.1\nsha256:36e606279dbebac51b4b9300b9fa85e8c08c1c673ba3ecc38af1402a0b035554\n\n$ COSIGN_EXPERIMENTAL=1 cosign verify-attestation --type spdx ghcr.io/external-secrets/external-secrets@sha256:36e606279dbebac51b4b9300b9fa85e8c08c1c673ba3ecc38af1402a0b035554 | jq '.payload |= @base64d | .payload | fromjson' | jq '.predicate.Data | fromjson'\n\n[...]\n{\n \"SPDXID\": \"SPDXRef-DOCUMENT\",\n \"name\": \"ghcr.io/external-secrets/external-secrets@sha256-36e606279dbebac51b4b9300b9fa85e8c08c1c673ba3ecc38af1402a0b035554\",\n \"spdxVersion\": \"SPDX-2.2\",\n \"creationInfo\": {\n \"created\": \"2023-03-17T23:17:01.568002344Z\",\n \"creators\": [\n \"Organization: Anchore, Inc\",\n \"Tool: syft-0.40.1\"\n ],\n \"licenseListVersion\": \"3.16\"\n },\n \"dataLicense\": \"CC0-1.0\",\n \"documentNamespace\": \"https://anchore.com/syft/image/ghcr.io/external-secrets/external-secrets@sha256-36e606279dbebac51b4b9300b9fa85e8c08c1c673ba3ecc38af1402a0b035554-83484ebb-b469-45fa-8fcc-9290c4ea4f6f\",\n \"packages\": [\n [...]\n {\n \"SPDXID\": \"SPDXRef-c809070b0beb099e\",\n \"name\": \"tzdata\",\n \"licenseConcluded\": \"NONE\",\n \"downloadLocation\": \"NOASSERTION\",\n \"externalRefs\": [\n {\n \"referenceCategory\": \"SECURITY\",\n \"referenceLocator\": \"cpe:2.3:a:tzdata:tzdata:2021a-1\\\\+deb11u8:*:*:*:*:*:*:*\",\n \"referenceType\": \"cpe23Type\"\n },\n {\n \"referenceCategory\": \"PACKAGE_MANAGER\",\n \"referenceLocator\": \"pkg:deb/debian/tzdata@2021a-1+deb11u8?arch=all&distro=debian-11\",\n \"referenceType\": \"purl\"\n }\n ],\n \"filesAnalyzed\": false,\n \"licenseDeclared\": \"NONE\",\n \"originator\": \"Person: GNU Libc Maintainers <debian-glibc@lists.debian.org>\",\n \"sourceInfo\": \"acquired package info from DPKG DB: /var/lib/dpkg/status.d/tzdata, /usr/share/doc/tzdata/copyright\",\n \"versionInfo\": \"2021a-1+deb11u8\"\n }\n ]\n}\n
"},{"location":"guides/templating-v1/","title":"Advanced Templating v1","text":"Warning
Templating Engine v1 is deprecated and will be removed in the future. Please migrate to engine v2 and take a look at our upgrade guide for changes.
With External Secrets Operator you can transform the data from the external secret provider before it is stored as Kind=Secret
. You can do this with the Spec.Target.Template
. Each data value is interpreted as a golang template.
"},{"location":"guides/templating-v1/#examples","title":"Examples","text":"You can use templates to inject your secrets into a configuration file that you mount into your pod:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: template\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: secretstore-sample\n kind: SecretStore\n target:\n name: secret-to-be-created\n\n # v2 is the default engineVersion in external-secrets.io/v1beta1\n # v1 is the default engineVersion in external-secrets.io/v1alpha1 (deprecated)\n engineVersion: v1\n\n # this is how the Kind=Secret will look like\n template:\n type: kubernetes.io/tls\n data:\n # multiline string\n config: |\n datasources:\n - name: Graphite\n type: graphite\n access: proxy\n url: http://localhost:8080\n password: \"{{ .password | toString }}\" # <-- convert []byte to string\n user: \"{{ .user | toString }}\" # <-- convert []byte to string\n\n data:\n - secretKey: user\n remoteRef:\n key: /grafana/user\n - secretKey: password\n remoteRef:\n key: /grafana/password\n
You can also use pre-defined functions to extract data from your secrets. Here: extract key/cert from a pkcs12 archive and store it as PEM.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: template\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: secretstore-sample\n kind: SecretStore\n target:\n name: secret-to-be-created\n # this is how the Kind=Secret will look like\n template:\n type: kubernetes.io/tls\n data:\n tls.crt: \"{{ .mysecret | pkcs12cert | pemCertificate }}\"\n tls.key: \"{{ .mysecret | pkcs12key | pemPrivateKey }}\"\n\n data:\n # this is a pkcs12 archive that contains\n # a cert and a private key\n - secretKey: mysecret\n remoteRef:\n key: example\n
"},{"location":"guides/templating-v1/#templatefrom","title":"TemplateFrom","text":"You do not have to define your templates inline in an ExternalSecret but you can pull ConfigMaps
or other Secrets that contain a template. Consider the following example:
# define your template in a config map\napiVersion: v1\nkind: ConfigMap\nmetadata:\n name: grafana-config-tpl\ndata:\n config.yaml: |\n datasources:\n - name: Graphite\n type: graphite\n access: proxy\n url: http://localhost:8080\n password: \"{{ .password | toString }}\" # <-- convert []byte to string\n user: \"{{ .user | toString }}\" # <-- convert []byte to string\n---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: my-template-example\nspec:\n # ...\n target:\n name: secret-to-be-created\n template:\n templateFrom:\n - configMap:\n # name of the configmap to pull in\n name: grafana-config-tpl\n # here you define the keys that should be used as template\n items:\n - key: config.yaml\n data:\n - secretKey: user\n remoteRef:\n key: /grafana/user\n - secretKey: password\n remoteRef:\n key: /grafana/password\n
"},{"location":"guides/templating-v1/#helper-functions","title":"Helper functions","text":"We provide a bunch of convenience functions that help you transform your secrets. A secret value is a []byte
.
Function Description Input Output pkcs12key extracts the private key from a pkcs12 archive []byte
[]byte
pkcs12keyPass extracts the private key from a pkcs12 archive using the provided password password string
, data []byte
[]byte
pkcs12cert extracts the certificate from a pkcs12 archive []byte
[]byte
pkcs12certPass extracts the certificate from a pkcs12 archive using the provided password password string
, data []byte
[]byte
pemPrivateKey PEM encodes the provided bytes as private key []byte
string
pemCertificate PEM encodes the provided bytes as certificate []byte
string
jwkPublicKeyPem takes an json-serialized JWK as []byte
and returns an PEM block of type PUBLIC KEY
that contains the public key (see here) for details []byte
string
jwkPrivateKeyPem takes an json-serialized JWK as []byte
and returns an PEM block of type PRIVATE KEY
that contains the private key in PKCS #8 format (see here) for details []byte
string
base64decode decodes the provided bytes as base64 []byte
[]byte
base64encode encodes the provided bytes as base64 []byte
[]byte
fromJSON parses the bytes as JSON so you can access individual properties []byte
any
toJSON encodes the provided object as json string any
string
toString converts bytes to string []byte
string
toBytes converts string to bytes string
[]byte
upper converts all characters to their upper case string
string
lower converts all character to their lower case string
string
"},{"location":"guides/templating/","title":"Advanced Templating v2","text":"With External Secrets Operator you can transform the data from the external secret provider before it is stored as Kind=Secret
. You can do this with the Spec.Target.Template
. Each data value is interpreted as a golang template.
Note
Consider using camelcase when defining .'spec.data.secretkey', example: serviceAccountToken
If your secret keys contain -
(dashes), you will need to reference them using index
Example: \\{\\{ index .data \"service-account-token\" \\}\\}
"},{"location":"guides/templating/#helm","title":"Helm","text":"When installing ExternalSecrets via helm
, the template must be escaped so that helm
will not try to render it. The most straightforward way to accomplish this would be to use backticks (raw string constants):
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: template\nspec:\n # ...\n target:\n template:\n engineVersion: v2\n data:\n name: admin\n # password: \"{{ .mysecret }}\" # If you are using plain manifests or gitops tools\n password: \"{{ `{{ .mysecret }}` }}\" # If you are using helm\n data:\n - secretKey: mysecret\n remoteRef:\n key: /credentials\n
"},{"location":"guides/templating/#examples","title":"Examples","text":"You can use templates to inject your secrets into a configuration file that you mount into your pod:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: template\nspec:\n # ...\n target:\n name: secret-to-be-created\n # this is how the Kind=Secret will look like\n template:\n engineVersion: v2\n data:\n # multiline string\n config: |\n datasources:\n - name: Graphite\n type: graphite\n access: proxy\n url: http://localhost:8080\n password: \"{{ .password }}\"\n user: \"{{ .user }}\"\n # using replace function to rewrite secret\n connection: '{{ .dburl | replace \"postgres://\" \"postgresql://\" }}'\n\n data:\n - secretKey: user\n remoteRef:\n key: /grafana/user\n - secretKey: password\n remoteRef:\n key: /grafana/password\n - secretKey: dburl\n remoteRef:\n key: /database/url\n
Another example with two keys in the same secret:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: template\nspec:\n # ...\n target:\n template:\n engineVersion: v2\n data:\n name: admin\n password: \"{{ .mysecret }}\" # If you are using plain manifests or gitops tools\n # password: \"{{ `{{ .mysecret }}` }}\" # If you are using templated tools like helm\n data:\n - secretKey: mysecret\n remoteRef:\n key: /credentials\n
"},{"location":"guides/templating/#mergepolicy","title":"MergePolicy","text":"By default, the templating mechanism will not use any information available from the original data
and dataFrom
queries to the provider, and only keep the templated information. It is possible to change this behavior through the use of the mergePolicy
field. mergePolicy
currently accepts two values: Replace
(the default) and Merge
. When using Merge
, data
and dataFrom
keys will also be embedded into the templated secret, having lower priority than the template outcome. See the example for more information:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: template\nspec:\n # ...\n target:\n template:\n mergePolicy: Merge\n engineVersion: v2\n data:\n name: admin\n password: \"{{ .password | b64dec }}\" # Overwrites the password from the data call and use this output\n data:\n - secretKey: password\n remoteRef:\n key: /credentials/password\n - secretKey: username # Preserves the username in the templated Secret\n remoteRef:\n key: /credentials/username\n
"},{"location":"guides/templating/#templatefrom","title":"TemplateFrom","text":"You do not have to define your templates inline in an ExternalSecret but you can pull ConfigMaps
or other Secrets that contain a template. Consider the following example:
# define your template in a config map\napiVersion: v1\nkind: ConfigMap\nmetadata:\n name: grafana-config-tpl\ndata:\n config.yaml: |\n datasources:\n - name: Graphite\n type: graphite\n access: proxy\n url: \"{{ .uri }}\"\n password: \"{{ .password }}\"\n user: \"{{ .user }}\"\n templated: |\n # key and value templated\n my-application-{{ .user}}: {{ .password | b64enc }}\n # conditional keys\n {{- if hasPrefix \"oci://\" .uri }}\n enableOCI: true\n {{- else }}\n enableOCI: false\n {{- end }}\n # Fixed values\n application-type: grafana\n annotations: |\n #dynamic timestamp generation\n last-synced-for-user/{{ .user }}: {{ now }}\n---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: my-template-example\nspec:\n # ...\n target:\n name: secret-to-be-created\n template:\n engineVersion: v2\n templateFrom:\n - target: Data\n configMap:\n # name of the configmap to pull in\n name: grafana-config-tpl\n # here you define the keys that should be used as template\n items:\n - key: config.yaml\n templateAs: Values\n - key: templated\n templateAs: KeysAndValues\n - target: Annotations\n configMap:\n # name of the configmap to pull in\n name: grafana-config-tpl\n # here you define the keys that should be used as template\n items:\n - key: annotations\n templateAs: KeysAndValues\n data:\n - secretKey: user\n remoteRef:\n key: /grafana/user\n - secretKey: password\n remoteRef:\n key: /grafana/password\n - secretKey: uri\n remoteRef:\n key: /grafana/uri\n
TemplateFrom
also gives you the ability to Target your template to the Secret's Annotations, Labels or the Data block. It also allows you to render the templated information as Values
or as KeysAndValues
through the templateAs
configuration:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: my-template-example\nspec:\n # ...\n target:\n name: secret-to-be-created\n template:\n engineVersion: v2\n templateFrom:\n - target: Annotations\n literal: \"last-sync-for-user/{{ .user }}: {{ .now }}\"\n data:\n - secretKey: user\n remoteRef:\n key: /grafana/user\n - secretKey: password\n remoteRef:\n key: /grafana/password\n
Lastly, TemplateFrom
also supports adding Literal
blocks for quick templating. These Literal
blocks differ from Template.Data
as they are rendered as a a key:value
pair (while the Template.Data
, you can only template the value).
See an example, how to produce a htpasswd
file that can be used by an ingress-controller (for example: https://kubernetes.github.io/ingress-nginx/examples/auth/basic/) where the contents of the htpasswd
file needs to be presented via the auth
key. We use the htpasswd
function to create a bcrytped
hash of the password.
Suppose you have multiple key-value pairs within your provider secret like
{\n \"user1\": \"password1\",\n \"user2\": \"password2\",\n ...\n}\n
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: my-template-example\nspec:\n # ...\n target:\n name: secret-to-be-created\n template:\n engineVersion: v2\n templateFrom:\n - target: Data\n literal: |-\n {{- $creds := list }}\n {{- range $user, $pw := . }}\n {{- $creds = append $creds (printf \"%s\" (htpasswd $user $pw)) }}\n {{- end }}\n auth: {{ $creds | join \"\\n\" | quote }}\n dataFrom:\n - extract:\n key: /ingress-controller/valid-users\n
"},{"location":"guides/templating/#extract-keys-and-certificates-from-pkcs12-archive","title":"Extract Keys and Certificates from PKCS#12 Archive","text":"You can use pre-defined functions to extract data from your secrets. Here: extract keys and certificates from a PKCS#12 archive and store it as PEM.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: template\nspec:\n # ...\n target:\n template:\n type: kubernetes.io/tls\n engineVersion: v2\n data:\n tls.crt: \"{{ .mysecret | pkcs12cert }}\"\n tls.key: \"{{ .mysecret | pkcs12key }}\"\n\n # if needed unlock the pkcs12 with the password\n tls.crt: \"{{ .mysecret | pkcs12certPass \"my-password\" }}\"\n
"},{"location":"guides/templating/#extract-from-jwk","title":"Extract from JWK","text":"You can extract the public or private key parts of a JWK and use them as PKCS#8 private key or PEM-encoded PKIX public key.
A JWK looks similar to this:
{\n \"kty\": \"RSA\",\n \"kid\": \"cc34c0a0-bd5a-4a3c-a50d-a2a7db7643df\",\n \"use\": \"sig\",\n \"n\": \"pjdss...\",\n \"e\": \"AQAB\"\n // ...\n}\n
And what you want may be a PEM-encoded public or private key portion of it. Take a look at this example on how to transform it into the desired format:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: template\nspec:\n # ...\n target:\n template:\n engineVersion: v2\n data:\n # .myjwk is a json-encoded JWK string.\n #\n # this template will produce for jwk_pub a PEM encoded public key:\n # -----BEGIN PUBLIC KEY-----\n # MIIBI...\n # ...\n # ...AQAB\n # -----END PUBLIC KEY-----\n jwk_pub: \"{{ .myjwk | jwkPublicKeyPem }}\"\n # private key is a pem-encoded PKCS#8 private key\n jwk_priv: \"{{ .myjwk | jwkPrivateKeyPem }}\"\n
"},{"location":"guides/templating/#filter-pem-blocks","title":"Filter PEM blocks","text":"Consider you have a secret that contains both a certificate and a private key encoded in PEM format and it is your goal to use only the certificate from that secret.
-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCvxGZOW4IXvGlh\n . . .\nm8JCpbJXDfSSVxKHgK1Siw4K6pnTsIA2e/Z+Ha2fvtocERjq7VQMAJFaIZSTKo9Q\nJwwY+vj0yxWjyzHUzZB33tg=\n-----END PRIVATE KEY-----\n-----BEGIN CERTIFICATE-----\nMIIDMDCCAhigAwIBAgIQabPaXuZCQaCg+eQAVptGGDANBgkqhkiG9w0BAQsFADAV\n . . .\nNtFUGA95RGN9s+pl6XY0YARPHf5O76ErC1OZtDTR5RdyQfcM+94gYZsexsXl0aQO\n9YD3Wg==\n-----END CERTIFICATE-----\n
You can achieve that by using the filterPEM
function to extract a specific type of PEM block from that secret. If multiple blocks of that type (here: CERTIFICATE
) exist, all of them are returned in the order specified. To extract a specific type of PEM block, pass the type as a string argument to the filterPEM function. Take a look at this example of how to transform a secret which contains a private key and a certificate into the desired format:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: template\nspec:\n # ...\n target:\n template:\n type: kubernetes.io/tls\n engineVersion: v2\n data:\n tls.crt: \"{{ .mysecret | filterPEM \"CERTIFICATE\" }}\"\n tls.key: \"{{ .mysecret | filterPEM \"PRIVATE KEY\" }}\"\n
"},{"location":"guides/templating/#templating-with-pushsecret","title":"Templating with PushSecret","text":"PushSecret
templating is much like ExternalSecrets
templating. In-fact under the hood, it's using the same data structure. Which means, anything described in the above should be possible with push secret as well resulting in a templated secret created at the provider.
apiVersion: external-secrets.io/v1beta1\nkind: PushSecret\nmetadata:\n name: template\nspec:\n # ...\n template:\n engineVersion: v2\n data:\n token: \"{{ .token | toString | upper }} was templated\"\n data:\n - match:\n secretKey: token\n remoteRef:\n remoteKey: create-secret-name\n property: token\n
"},{"location":"guides/templating/#helper-functions","title":"Helper functions","text":"Info
Note: we removed env
and expandenv
from sprig functions for security reasons.
We provide a couple of convenience functions that help you transform your secrets. This is useful when dealing with PKCS#12 archives or JSON Web Keys (JWK).
In addition to that you can use over 200+ sprig functions. If you feel a function is missing or might be valuable feel free to open an issue and submit a pull request.
Function Description pkcs12key Extracts all private keys from a PKCS#12 archive and encodes them in PKCS#8 PEM format. pkcs12keyPass Same as pkcs12key
. Uses the provided password to decrypt the PKCS#12 archive. pkcs12cert Extracts all certificates from a PKCS#12 archive and orders them if possible. If disjunct or multiple leaf certs are provided they are returned as-is. Sort order: leaf / intermediate(s) / root
. pkcs12certPass Same as pkcs12cert
. Uses the provided password to decrypt the PKCS#12 archive. pemToPkcs12 Takes a PEM encoded certificate and key and creates a base64 enoded PKCS#12 archive. pemToPkcs12Pass Same as pemToPkcs12
. Uses the provided password to encrypt the PKCS#12 archive. filterPEM Filters PEM blocks with a specific type from a list of PEM blocks. jwkPublicKeyPem Takes an json-serialized JWK and returns an PEM block of type PUBLIC KEY
that contains the public key. See here for details. jwkPrivateKeyPem Takes an json-serialized JWK as string
and returns an PEM block of type PRIVATE KEY
that contains the private key in PKCS #8 format. See here for details. toYaml Takes an interface, marshals it to yaml. It returns a string, even on marshal error (empty string). fromYaml Function converts a YAML document into a map[string]any."},{"location":"guides/templating/#migrating-from-v1","title":"Migrating from v1","text":"If you are still using v1alpha1
, You have to opt-in to use the new engine version by specifying template.engineVersion=v2
:
apiVersion: external-secrets.io/v1alpha1\nkind: ExternalSecret\nmetadata:\n name: secret\nspec:\n # ...\n target:\n template:\n engineVersion: v2\n # ...\n
The biggest change was that basically all function parameter types were changed from accepting/returning []byte
to string
. This is relevant for you because now you don't need to specify toString
all the time at the end of a template pipeline.
apiVersion: external-secrets.io/v1alpha1\nkind: ExternalSecret\n# ...\nspec:\n target:\n template:\n engineVersion: v2\n data:\n # this used to be {{ .foobar | toString }}\n egg: \"new: {{ .foobar }}\"\n
"},{"location":"guides/templating/#functions-removedreplaced","title":"Functions removed/replaced","text":" base64encode
was renamed to b64enc
. base64decode
was renamed to b64dec
. Any errors that occur during decoding are silenced. fromJSON
was renamed to fromJson
. Any errors that occur during unmarshalling are silenced. toJSON
was renamed to toJson
. Any errors that occur during marshalling are silenced. pkcs12key
and pkcs12keyPass
encode the PKCS#8 key directly into PEM format. There is no need to call pemPrivateKey
anymore. Also, these functions do extract all private keys from the PKCS#12 archive not just the first one. pkcs12cert
and pkcs12certPass
encode the certs directly into PEM format. There is no need to call pemCertificate
anymore. These functions now extract all certificates from the PKCS#12 archive not just the first one. toString
implementation was replaced by the sprig
implementation and should be api-compatible. toBytes
was removed. pemPrivateKey
was removed. It's now implemented within the pkcs12*
functions. pemCertificate
was removed. It's now implemented within the pkcs12*
functions.
"},{"location":"guides/threat-model/","title":"Threat Model","text":""},{"location":"guides/threat-model/#background","title":"Background","text":"The External Secrets Operator is a Kubernetes Operator that seamlessly incorporates external secret management systems into Kubernetes. This Operator retrieves data from the external API and generates Kubernetes Secret resources using the corresponding secret values. This process occurs continuously in the background through regular polling of the external API. Consequently, whenever a secret undergoes changes in the external API, the corresponding Kubernetes Secret will also be updated accordingly.
"},{"location":"guides/threat-model/#summary","title":"Summary","text":"Purpose Description Intended Usage Sync Secrets into Kubernetes Data Classifiation Critical Highest Risk Impact Organisation takeover"},{"location":"guides/threat-model/#components","title":"Components","text":"ESO comprises three main components: webhook
, cert controller
and a core controller
. For more detailed information, please refer to the documentation on components.
"},{"location":"guides/threat-model/#overview","title":"Overview","text":"This section provides an overview of the security aspects of the External Secrets Operator (ESO) and includes information on assets, threats, and controls involved in its operation.
The following diagram illustrates the security perspective of how ESO functions, highlighting the assets (items to protect), threats (potential risks), and controls (measures to mitigate threats).
"},{"location":"guides/threat-model/#scope","title":"Scope","text":"For the purpose of this threat model, we assume an ESO installation using helm and default settings on a public cloud provider. It is important to note that the Kubernetes SIG Security team has defined an Admission Control Threat Model, which is recommended reading for a better understanding of the security aspects that partially apply to External Secrets Operator.
ESO utilizes the ValidatingWebhookConfiguration
mechanism to validate (Cluster)SecretStore
and (Cluster)ExternalSecret
resources. However, it is essential to understand that this validation process does not serve as a security control mechanism. Instead, ESO performs validation by enforcing additional rules that go beyond the CustomResourceDefinition OpenAPI v3 Validation schema.
"},{"location":"guides/threat-model/#assets","title":"Assets","text":""},{"location":"guides/threat-model/#a01-cluster-level-access-to-secrets","title":"A01: Cluster-Level access to secrets","text":"The controller possesses privileged access to the kube-apiserver
and is authorized to read and write secret resources across all namespaces within a cluster.
"},{"location":"guides/threat-model/#a02-crd-and-webhook-write-access","title":"A02: CRD and Webhook Write access","text":"The cert-controller component has read/write access to ValidatingWebhookConfigurations
and CustomResourceDefinitions
resources. This access is necessary to inject/modify the caBundle property.
"},{"location":"guides/threat-model/#a03-secret-provider-access","title":"A03: secret provider access","text":"The core-controller
component accesses a secret provider using user-supplied credentials. These credentials can be derived from environment variables, mounted service account tokens, files within the controller container, or fetched from the Kubernetes API (e.g., Kind=Secret
). The scope of these credentials may vary, potentially providing full access to a cloud provider.
"},{"location":"guides/threat-model/#a04-capability-to-modify-resources","title":"A04: capability to modify resources","text":"The webhook component validates and converts ExternalSecret and SecretStore resources. The conversion webhook is essential for migrating resources from the old version v1alpha1
to the new version v1beta1
. The webhook component possesses the ability to modify resources during runtime.
"},{"location":"guides/threat-model/#threats","title":"Threats","text":""},{"location":"guides/threat-model/#t01-tampering-with-resources-through-mitm","title":"T01: Tampering with resources through MITM","text":"An adversary could launch a Man-in-the-Middle (MITM) attack to hijack the webhook pod, enabling them to manipulate the data of the conversion webhook. This could involve injecting malicious resources or causing a Denial-of-Service (DoS) attack. To mitigate this threat, a mutual authentication mechanism should be enforced for the connection between the Kubernetes API server and the webhook service to ensure that only authenticated endpoints can communicate.
"},{"location":"guides/threat-model/#t02-webhook-dos","title":"T02: Webhook DOS","text":"Currently, ESO generates an X.509 certificate for webhook registration without authenticating the kube-apiserver. Consequently, if an attacker gains network access to the webhook Pod, they can overload the webhook server and initiate a DoS attack. As a result, modifications to ESO resources may fail, and the ESO core controller may be impacted due to the unavailability of the conversion webhook.
"},{"location":"guides/threat-model/#t03-unauthorized-access-to-cluster-secrets","title":"T03: Unauthorized access to cluster secrets","text":"An attacker can gain unauthorized access to secrets by utilizing the service account token of the ESO core controller Pod or exploiting software vulnerabilities. This unauthorized access allows the attacker to read secrets within the cluster, potentially leading to a cluster takeover.
"},{"location":"guides/threat-model/#t04-unauthorized-access-to-secret-provider-credentials","title":"T04: unauthorized access to secret provider credentials","text":"An attacker can gain unauthorized access to credentials that provide access to external APIs storing secrets. If the credentials have overly broad permissions, this could result in an organization takeover.
"},{"location":"guides/threat-model/#t05-data-exfiltration-through-malicious-resources","title":"T05: data exfiltration through malicious resources","text":"An attacker can exfiltrate data from the cluster by utilizing maliciously crafted resources. Multiple attack vectors can be employed, e.g.:
- copying data from a namespace to an unauthorized namespace
- exfiltrating data to an unauthorized secret provider
- exfiltrating data through an authorized secret provider to a malicious provider account
Successful data exfiltration can lead to intellectual property loss, information misuse, loss of customer trust, and damage to the brand or reputation.
"},{"location":"guides/threat-model/#t06-supply-chain-attacks","title":"T06: supply chain attacks","text":"An attack can infiltrate the ESO container through various attack vectors. The following are some potential entry points, although this is not an exhaustive list. For a comprehensive analysis, refer to SLSA Threats and mitigations or GCP software supply chain threats.
- Source Threats: Unauthorized changes or inclusion of vulnerable code in ESO through code submissions.
- Build Threats: Creation and distribution of malicious builds of ESO, such as in container registries, Artifact Hub, or Operator Hub.
- Dependency Threats: Introduction of vulnerable code into ESO dependencies.
- Deployment and Runtime Threats: Injection of malicious code through compromised deployment processes.
"},{"location":"guides/threat-model/#t07-malicious-workloads-in-eso-namespace","title":"T07: malicious workloads in eso namespace","text":"An attacker can deploy malicious workloads within the external-secrets namespace, taking advantage of the ESO service account with potentially cluster-wide privileges.
"},{"location":"guides/threat-model/#controls","title":"Controls","text":""},{"location":"guides/threat-model/#c01-network-security-policy","title":"C01: Network Security Policy","text":"Implement a NetworkPolicy to restrict traffic in both inbound and outbound directions on all networks. Employ a \"deny all\" / \"permit by exception\" approach for inbound and outbound network traffic. The specific network policies for the core-controller depend on the chosen provider. The webhook and cert-controller have well-defined sets of endpoints they communicate with. Refer to the Security Best Practices documentation for inbound and outbound network requirements.
Please note that ESO does not provide pre-packaged network policies, and it is the user's responsibility to implement the necessary security controls.
"},{"location":"guides/threat-model/#c02-least-privilege-rbac","title":"C02: Least Privilege RBAC","text":"Adhere to the principle of least privilege by configuring Role-Based Access Control (RBAC) permissions not only for the ESO workload but also for all users interacting with it. Ensure that RBAC permissions on provider side are appropriate according to your setup, by for example limiting which sensitive information a given credential can have access to. Ensure that kubernetes RBAC are set up to grant access to ESO resources only where necessary. For example, allowing write access to ClusterSecretStore
/ExternalSecret
may be sufficient for a threat to become a reality.
"},{"location":"guides/threat-model/#c03-policy-enforcement","title":"C03: Policy Enforcement","text":"Implement a Policy Engine such as Kyverno or OPA to enforce restrictions on changes to ESO resources. The specific policies to be enforced depend on the environment. Here are a few suggestions:
- (Cluster)SecretStore: Restrict the allowed secret providers, disallowing unused or undesired providers (e.g. Webhook).
- (Cluster)SecretStore: Restrict the permitted authentication mechanisms (e.g. prevent usage of
secretRef
). - (Cluster)SecretStore: Enforce limitations on modifications to provider-specific fields relevant for security, such as
caBundle
, caProvider
, region
, role
, url
, environmentType
, identityId
, and others
. - ClusterSecretStore: Control the usage of
namespaceSelector
, such as forbidding or mandating the usage of the kube-system
namespace. - ClusterExternalSecret: Restrict the usage of
namespaceSelector
.
Please note that ESO does not provide pre-packaged policies, and it is the user's responsibility to implement the necessary security controls.
"},{"location":"guides/threat-model/#c04-provider-access-policy","title":"C04: Provider Access Policy","text":"Configure fine-grained access control on the HTTP endpoint of the secret provider to prevent data exfiltration across accounts or organizations. Consult the documentation of your specific provider (e.g.: AWS Secrets Manager VPC Endpoint Policies, GCP Private Service Connect, or Azure Private Link) for guidance on setting up access policies.
"},{"location":"guides/threat-model/#c05-entirely-disable-crds","title":"C05: Entirely disable CRDs","text":"You should disable unused CRDs to narrow down your attack surface. Not all users require the use of PushSecret
, ClusterSecretStore
or ClusterExternalSecret
resources.
"},{"location":"guides/using-latest-image/","title":"Using Latest Image","text":"You can test a feature that was not yet released using the following methods, use them at your own discretion:
"},{"location":"guides/using-latest-image/#helm","title":"Helm","text":" - Create a
values.yaml
file with the following content: replicaCount: 1\n\nimage:\n repository: ghcr.io/external-secrets/external-secrets\n pullPolicy: IfNotPresent\n # -- The image tag to use. The default is the chart appVersion.\n tag: \"main\"\n\n# -- If set, install and upgrade CRDs through helm chart.\ninstallCRDs: false\n
- Install the crds
make crds.install\n
- Install the external-secrets Helm chart indicating the values file created before:
helm install external-secrets external-secrets/external-secrets -f values.yaml\n
"},{"location":"guides/using-latest-image/#manual","title":"Manual","text":" - Build the Docker image
docker build -f Dockerfile.standalone -t my-org/external-secrets:latest .\n
- Apply the
bundle.yaml
kubectl apply -f deploy/crds/bundle.yaml\n
- Modify your configs to use the image
kind: Deployment\nmetadata:\n name: external-secrets|external-secrets-webhook|external-secrets-cert-controller\n...\n image: my-org/external-secrets:latest\n
"},{"location":"guides/v1beta1/","title":"Upgrading CRD versions","text":"From version v0.5.0, v1alpha1
version is deprecated, and v1beta1
is in place. This guide will cover the main differences between the two versions, and a procedure on how to safely upgrade it.
"},{"location":"guides/v1beta1/#differences-between-versions","title":"Differences between versions","text":"Versions v1alpha1 and v1beta1 are fully-compatible for SecretStores and ClusterSecretStores. For ExternalSecrets, there is a difference on the dataFrom
method.
While in v1alpha1, we could define a dataFrom
with the following format:
spec:\n dataFrom:\n - key: my-key\n - key: my-other-key\n
In v1beta1 is possible to use two methods. One of them is Extract
and has the exact same behavior as dataFrom
in v1alpha1. The other is Find
, which allows finding multiple external secrets and map them into a single Kubernetes secret. Here is an example of Find
:
spec:\n dataFrom:\n - find:\n name: #matches any secret name ending in foo-bar\n regexp: .*foo-bar$\n - find:\n tags: #matches any secrets with the following metadata.\n env: dev \n app: web\n
"},{"location":"guides/v1beta1/#upgrading","title":"Upgrading","text":"If you already have an installation of ESO using v1alpha1
, we recommend you to upgrade to v1beta1
. If you do not use dataFrom
in your ExternalSecrets, or if you deploy the CRDs using the official Helm charts, the upgrade can be done with no risk of losing data.
If you are installing CRDs manually, you will need to deploy the bundle CRD file available at deploys/crds/bundle.yaml
. This bundle file contains v1beta1
definition and a conversion webhook configuration. This configuration will ensure that new requests to handle any CRD object will only be valid after the upgrade is successfully complete - so there are no risks of losing data due to an incomplete upgrade. Once the new CRDs are applied, you can proceed to upgrade the controller version.
Once the upgrade is finished, at each reconcile, any ExternalSecret
, SecretStore
, and ClusterSecretStore
stored in v1alpha1
will be automatically converted to v1beta1
.
"},{"location":"introduction/deprecation-policy/","title":"Deprecation Policy","text":"We follow the Kubernetes Deprecation Policy and API Versioning Scheme: alpha, beta, GA.
The project is currently in beta
state. Please try the beta
features and provide feedback. After the features exits beta, it may not be practical to make more changes.
-
alpha
- The support for a feature may be dropped at any time without notice.
- The API may change in incompatible ways in a later software release without notice.
- The software is recommended for use only in short-lived testing clusters, due to increased risk of bugs and lack of long-term support.
-
beta
- The software is well tested. Enabling a feature is considered safe. Features are enabled by default.
- The support for a feature will not be dropped, though the details may change.
- The schema and/or semantics of objects may change in incompatible ways in a subsequent beta or stable release. When this happens, migration instructions are provided. Schema changes may require deleting, editing, and re-creating API objects. The editing process may not be straightforward. The migration may require downtime for applications that rely on the feature.
- The software is not recommended for production uses. Subsequent releases may introduce incompatible changes. If you have multiple clusters which can be upgraded independently, you may be able to relax this restriction.
- GA
- The stable versions of features appear in released software for many subsequent versions.
- Use it in production ;)
"},{"location":"introduction/deprecation-policy/#api-surface","title":"API Surface","text":"We define the following scope that is covered by our deprecation policy. We follow the 9 Rules of the Kubernetes Deprecation Policy.
"},{"location":"introduction/deprecation-policy/#scope","title":"Scope","text":" - API Objects and fields:
.Spec
, .Status
and .Status.Conditions[]
- Enums and constant values
- Controller Configuration: CLI flags & environment variables
- Metrics as defined in the Kubernetes docs
- a feature or specific behavior:
ExternalSecret
update mechanics
"},{"location":"introduction/deprecation-policy/#non-scope","title":"Non-Scope","text":"We do not provide stability guarantee for source code imports. The Interfaces and the behavior will change in a unexpected and backwards-incompatible way. However, The maintained helm chart is not part of this deprecation policy.
"},{"location":"introduction/faq/","title":"FAQ","text":""},{"location":"introduction/faq/#can-i-manually-trigger-a-secret-refresh","title":"Can I manually trigger a secret refresh?","text":"You can trigger a secret refresh by using kubectl or any other kubernetes api client. You just need to change an annotation, label or the spec of the resource:
kubectl annotate es my-es force-sync=$(date +%s) --overwrite\n
"},{"location":"introduction/faq/#how-do-i-know-when-my-secret-was-last-synced","title":"How do I know when my secret was last synced?","text":"The last synchronization timestamp of an ExternalSecret can be retrieved from the field refreshTime
.
kubectl get es my-external-secret -o yaml | grep refreshTime\n refreshTime: \"2022-05-21T23:02:47Z\"\n
The interval can be changed by the spec.refreshInterval
in the ExternalSecret.
"},{"location":"introduction/faq/#how-do-i-know-when-the-status-of-my-secret-changed-the-last-time","title":"How do I know when the status of my secret changed the last time?","text":"Every ExternalSecret resource contains a status condition that indicates whether a secret was successfully synchronized, along with the timestamp of the last status change of the ExternalSecret (e.g. from SecretSyncedError to SecretSynced). This can be obtained from the field lastTransitionTime
:
kubectl get es my-external-secret -o yaml | grep condition -A 5\n conditions:\n - lastTransitionTime: \"2022-05-21T21:02:47Z\"\n message: Secret was synced\n reason: SecretSynced\n status: \"True\"\n type: Ready\n
"},{"location":"introduction/faq/#differences-to-csi-secret-store","title":"Differences to csi-secret-store","text":"Please take a look at this issue comment here.
"},{"location":"introduction/faq/#how-do-i-debug-an-external-secret-that-doesnt-sync","title":"How do I debug an external-secret that doesn't sync?","text":"First, check the status of the ExternalSecret resource using kubectl describe
. That displays the status conditions as well as recent events. You should expect a status condition with Type=Ready
, Status=True
. Further you shouldn't see any events with Type=Warning
. Read carefully if they exist.
kubectl describe es my-external-secret\n[...]\nStatus:\n Conditions:\n Last Transition Time: 2022-05-21T21:02:47Z\n Message: Secret was synced\n Reason: SecretSynced\n Status: True\n Type: Ready\n Refresh Time: 2022-05-21T21:06:47Z\n Synced Resource Version: 1-5c833527afd7ba3f426cb0082ee7e083\nEvents:\n Type Reason Age From Message\n ---- ------ ---- ---- -------\n Warning UpdateFailed 4m12s external-secrets secrets \"yyyyyyy\" already exists\n Normal Updated 12s (x4 over 3m12s) external-secrets Updated Secret\n
If everything looks good you should check the corresponding secret store resource that is referenced from an ExternalSecret. Again, use kubectl describe
to show status conditions and events and look for warning signs as described above.
In an ideally, the store should be validated and Ready.
kubectl describe css kubernetes\n[...]\nStatus:\n Conditions:\n Last Transition Time: 2022-05-21T21:02:47Z\n Message: store validated\n Reason: Valid\n Status: True\n Type: Ready\nEvents:\n Type Reason Age From Message\n ---- ------ ---- ---- -------\n Normal Valid 52s (x4 over 10m) cluster-secret-store store validated\n Normal Valid 52s (x4 over 10m) cluster-secret-store store validated\n
If everything looks normal so far, please go ahead and ensure that the created secret has the expected value. Also, take a look at the logs of the controller.
"},{"location":"introduction/faq/#upgrading-from-kes-to-eso","title":"Upgrading from KES to ESO","text":"Migrating from KES to ESO is quite tricky! There is a tool we built to help users out available here, and there is a small migration procedure.
There are some incompatibilities between KES to ESO, and while the tool tries to cover most of them, some of them will require manual intervention. We recommend to first convert the manifest files, and actually see if the tool provides a warning about any file needed to be changed. Beware that the tool points the SecretStores to use KES Service Account, so you'll also need to tweak that if you plan to uninstall KES after the upgrade.
"},{"location":"introduction/getting-started/","title":"Getting started","text":"External-secrets runs within your Kubernetes cluster as a deployment resource. It utilizes CustomResourceDefinitions to configure access to secret providers through SecretStore resources and manages Kubernetes secret resources with ExternalSecret resources.
Note: The minimum supported version of Kubernetes is 1.16.0
. Users still running Kubernetes v1.15 or below should upgrade to a supported version before installing external-secrets.
"},{"location":"introduction/getting-started/#installing-with-helm","title":"Installing with Helm","text":"The default install options will automatically install and manage the CRDs as part of your helm release. If you do not want the CRDs to be automatically upgraded and managed, you must set the installCRDs
option to false
. (e.g. --set installCRDs=false
)
You can install those CRDs outside of helm
using:
kubectl apply -k \"https://github.com/external-secrets/external-secrets//config/crds/bases?ref=v0.9.11\"\n
Uncomment the relevant line in the next steps to disable the automatic install of CRDs.
"},{"location":"introduction/getting-started/#option-1-install-from-chart-repository","title":"Option 1: Install from chart repository","text":"helm repo add external-secrets https://charts.external-secrets.io\n\nhelm install external-secrets \\\n external-secrets/external-secrets \\\n -n external-secrets \\\n --create-namespace \\\n # --set installCRDs=false\n
"},{"location":"introduction/getting-started/#option-2-install-chart-from-local-build","title":"Option 2: Install chart from local build","text":"Build and install the Helm chart locally after cloning the repository.
make helm.build\n\nhelm install external-secrets \\\n ./bin/chart/external-secrets.tgz \\\n -n external-secrets \\\n --create-namespace \\\n # --set installCRDs=false\n
"},{"location":"introduction/getting-started/#create-a-secret-containing-your-aws-credentials","title":"Create a secret containing your AWS credentials","text":"echo -n 'KEYID' > ./access-key\necho -n 'SECRETKEY' > ./secret-access-key\nkubectl create secret generic awssm-secret --from-file=./access-key --from-file=./secret-access-key\n
"},{"location":"introduction/getting-started/#create-your-first-secretstore","title":"Create your first SecretStore","text":"Create a file 'basic-secret-store.yaml' with the following content.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: secretstore-sample\nspec:\n provider:\n aws:\n service: SecretsManager\n region: us-east-1\n auth:\n secretRef:\n accessKeyIDSecretRef:\n name: awssm-secret\n key: access-key\n secretAccessKeySecretRef:\n name: awssm-secret\n key: secret-access-key\n
Apply it to create a SecretStore resource.
kubectl apply -f \"basic-secret-store.yaml\"\n
"},{"location":"introduction/getting-started/#create-your-first-externalsecret","title":"Create your first ExternalSecret","text":"Create a file 'basic-external-secret.yaml' with the following content.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: secretstore-sample\n kind: SecretStore\n target:\n name: secret-to-be-created\n creationPolicy: Owner\n data:\n - secretKey: secret-key-to-be-managed\n remoteRef:\n key: provider-key\n version: provider-key-version\n property: provider-key-property\n dataFrom:\n - extract:\n key: remote-key-in-the-provider\n
Apply it to create an External Secret resource.
kubectl apply -f \"basic-external-secret.yaml\"\n
kubectl describe externalsecret example\n# [...]\nName: example\nStatus:\n Binding:\n Name: secret-to-be-created\n Conditions:\n Last Transition Time: 2021-02-24T16:45:23Z\n Message: Secret was synced\n Reason: SecretSynced\n Status: True\n Type: Ready\n Refresh Time: 2021-02-24T16:45:24Z\nEvents: <none>\n
For more advanced examples, please read the other guides.
"},{"location":"introduction/getting-started/#installing-with-olm","title":"Installing with OLM","text":"External-secrets can be managed by Operator Lifecycle Manager (OLM) via an installer operator. It is made available through OperatorHub.io, this installation method is suited best for OpenShift. See installation instructions on the external-secrets-operator package.
"},{"location":"introduction/getting-started/#uninstalling","title":"Uninstalling","text":"Before continuing, ensure that all external-secret resources that have been created by users have been deleted. You can check for any existing resources with the following command:
kubectl get SecretStores,ClusterSecretStores,ExternalSecrets --all-namespaces\n
Once all these resources have been deleted you are ready to uninstall external-secrets.
"},{"location":"introduction/getting-started/#uninstalling-with-helm","title":"Uninstalling with Helm","text":"Uninstall the helm release using the delete command.
helm delete external-secrets --namespace external-secrets\n
"},{"location":"introduction/overview/","title":"API Overview","text":""},{"location":"introduction/overview/#architecture","title":"Architecture","text":"The External Secrets Operator extends Kubernetes with Custom Resources, which define where secrets live and how to synchronize them. The controller fetches secrets from an external API and creates Kubernetes secrets. If the secret from the external API changes, the controller will reconcile the state in the cluster and update the secrets accordingly.
"},{"location":"introduction/overview/#resource-model","title":"Resource model","text":"To understand the mechanics of the operator let's start with the data model. The SecretStore references a bucket of key/value pairs. But because every external API is slightly different this bucket may be e.g. an instance of an Azure KeyVault or a AWS Secrets Manager in a certain AWS Account and region. Please take a look at the provider documentation to see what the Bucket actually maps to.
"},{"location":"introduction/overview/#secretstore","title":"SecretStore","text":"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, the SecretStore specifies how to access. This resource is namespaced.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: secretstore-sample\nspec:\n provider:\n aws:\n service: SecretsManager\n region: us-east-1\n auth:\n secretRef:\n accessKeyIDSecretRef:\n name: awssm-secret\n key: access-key\n secretAccessKeySecretRef:\n name: awssm-secret\n key: secret-access-key\n
The SecretStore
contains references to secrets which hold credentials to access the external API."},{"location":"introduction/overview/#externalsecret","title":"ExternalSecret","text":"An ExternalSecret declares what data to fetch. It has a reference to a SecretStore
which knows how to access that data. The controller uses that ExternalSecret
as a blueprint to create secrets.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: secretstore-sample\n kind: SecretStore\n target:\n name: secret-to-be-created\n creationPolicy: Owner\n data:\n - secretKey: secret-key-to-be-managed\n remoteRef:\n key: provider-key\n version: provider-key-version\n property: provider-key-property\n dataFrom:\n - extract:\n key: remote-key-in-the-provider\n
"},{"location":"introduction/overview/#clustersecretstore","title":"ClusterSecretStore","text":"The ClusterSecretStore is a global, cluster-wide SecretStore that can be referenced from all namespaces. You can use it to provide a central gateway to your secret provider.
"},{"location":"introduction/overview/#behavior","title":"Behavior","text":"The External Secret Operator (ESO for brevity) reconciles ExternalSecrets
in the following manner:
- ESO uses
spec.secretStoreRef
to find an appropriate SecretStore
. If it doesn't exist or the spec.controller
field doesn't match it won't further process this ExternalSecret. - ESO instanciates an external API client using the specified credentials from the
SecretStore
spec. - ESO fetches the secrets as requested by the
ExternalSecret
, it will decode the secrets if required - ESO creates an
Kind=Secret
based on the template provided by ExternalSecret.target.template
. The Secret.data
can be templated using the secret values from the external API. - ESO ensures that the secret values stay in sync with the external API
"},{"location":"introduction/overview/#roles-and-responsibilities","title":"Roles and responsibilities","text":"The External Secret Operator is designed to target the following persona:
- Cluster Operator: The cluster operator is responsible for setting up the External Secret Operator, managing access policies and creating ClusterSecretStores.
- Application developer: The Application developer is responsible for defining ExternalSecrets and the application configuration
Each persona will roughly map to a Kubernetes RBAC role. Depending on your environment these roles can map to a single user. Note: There is no Secret Operator that handles the lifecycle of the secret, this is out of the scope of ESO.
"},{"location":"introduction/overview/#access-control","title":"Access Control","text":"The External Secrets Operator runs as a deployment in your cluster with elevated privileges. It will create/read/update secrets in all namespaces and has access to secrets stored in some external API. Ensure that the credentials you provide give ESO the least privilege necessary.
Design your SecretStore
/ClusterSecretStore
carefully! Be sure to restrict access of application developers to read only certain keys in a shared environment.
You should also consider using Kubernetes' admission control system (e.g. OPA or Kyverno) for fine-grained access control.
"},{"location":"introduction/overview/#running-multiple-controller","title":"Running multiple Controller","text":"You can run multiple controllers within the cluster. One controller can be limited to only process SecretStores
with a predefined spec.controller
field.
Testers welcome
This is not widely tested. Please help us test the setup and/or document use-cases.
"},{"location":"introduction/stability-support/","title":"Stability and Support","text":"This page lists the status, timeline and policy for currently supported ESO releases and its providers. Please also see our deprecation policy that describes API versioning, deprecation and API surface.
"},{"location":"introduction/stability-support/#supported-versions","title":"Supported Versions","text":"We want to provide security patches and critical bug fixes in a timely manner to our users. To do so, we offer long-term support for our latest two (N, N-1) software releases. We aim for a 2-3 month minor release cycle, i.e. a given release is supported for about 4-6 months.
We want to cover the following cases:
- regular image rebuilds to update OS dependencies
- regular go dependency updates
- backport bug fixes on demand
ESO Version Kubernetes Version Release Date End of Life 0.9.x 1.19 \u2192 1.29 Jun 22, 2023 Release of 1.1 0.8.x 1.19 \u2192 1.28 Mar 16, 2023 Release of 1.0 0.7.x 1.19 \u2192 1.26 Dec 11, 2022 Jun 22, 2023 0.6.x 1.19 \u2192 1.24 Oct 9, 2022 Mar 16, 2023 0.5.x 1.19 \u2192 1.24 Apr 6, 2022 Dec 11, 2022 0.4.x 1.16 \u2192 1.24 Feb 2, 2022 Oct 9, 2022 0.3.x 1.16 \u2192 1.24 Jul 25, 2021 Apr 6, 2022"},{"location":"introduction/stability-support/#provider-stability-and-support-level","title":"Provider Stability and Support Level","text":"The following table describes the stability level of each provider and who's responsible.
Provider Stability Maintainer AWS Secrets Manager stable external-secrets AWS Parameter Store stable external-secrets Hashicorp Vault stable external-secrets GCP Secret Manager stable external-secrets Azure Keyvault stable external-secrets IBM Cloud Secrets Manager stable @knelasevero @sebagomez @ricardoptcosta @IdanAdar Kubernetes beta external-secrets Yandex Lockbox alpha @AndreyZamyslov @knelasevero GitLab Variables alpha @Jabray5 Alibaba Cloud KMS alpha @ElsaChelala Oracle Vault alpha @KianTigger @EladGabay Akeyless alpha @renanaAkeyless 1Password alpha @SimSpaceCorp @snarlysodboxer Generic Webhook alpha @willemm senhasegura DevOps Secrets Management (DSM) alpha @lfraga Doppler SecretOps Platform alpha @ryan-blunden @nmanoogian Keeper Security alpha @ppodevlab Scaleway alpha @azert9 Conjur stable @davidh-cyberark @szh Delinea alpha @michaelsauter Pulumi ESC alpha @dirien Passbolt alpha"},{"location":"introduction/stability-support/#provider-feature-support","title":"Provider Feature Support","text":"The following table show the support for features across different providers.
Provider find by name find by tags metadataPolicy Fetch referent authentication store validation push secret DeletionPolicy Merge/Delete AWS Secrets Manager x x x x x x x AWS Parameter Store x x x x x x x Hashicorp Vault x x x x x x x GCP Secret Manager x x x x x x x Azure Keyvault x x x x x x x Kubernetes x x x x x x x IBM Cloud Secrets Manager x x x Yandex Lockbox x GitLab Variables x x x Alibaba Cloud KMS x Oracle Vault x Akeyless x x x 1Password x x x x Generic Webhook x senhasegura DSM x Doppler x x Keeper Security x x x Scaleway x x x x x Conjur x x x Delinea x x Pulumi ESC x x Passbolt x x"},{"location":"introduction/stability-support/#support-policy","title":"Support Policy","text":"We provide technical support and security / bug fixes for the above listed versions.
"},{"location":"introduction/stability-support/#technical-support","title":"Technical support","text":"We provide assistance for deploying/upgrading etc. on a best-effort basis. You can request support through the following channels:
- Kubernetes Slack #external-secrets
- GitHub Issues
- GitHub Discussions
Even though we have active maintainers and people assigned to this project, we kindly ask for patience when asking for support. We will try to get to priority issues as fast as possible, but there may be some delays.
"},{"location":"provider/1password-automation/","title":"1Password Secrets Automation","text":""},{"location":"provider/1password-automation/#1password-secrets-automation","title":"1Password Secrets Automation","text":"External Secrets Operator integrates with 1Password Secrets Automation for secret management.
"},{"location":"provider/1password-automation/#important-note-about-this-documentation","title":"Important note about this documentation","text":"The 1Password API calls the entries in vaults 'Items'. These docs use the same term.
"},{"location":"provider/1password-automation/#behavior","title":"Behavior","text":" - How an Item is equated to an ExternalSecret:
remoteRef.key
is equated to an Item's Title remoteRef.property
is equated to: - An Item's field's Label (Password type)
- An Item's file's Name (Document type)
- If empty, defaults to the first file name, or the field labeled
password
remoteRef.version
is currently not supported. - One Item in a vault can equate to one Kubernetes Secret to keep things easy to comprehend.
- Support for 1Password secret types of
Password
and Document
. - The
Password
type can get data from multiple fields
in the Item. - The
Document
type can get data from files. - See creating 1Password Items compatible with ExternalSecrets.
- Ordered vaults
- Specify an ordered list of vaults in a SecretStore and the value will be sourced from the first vault with a matching Item.
- If no matching Item is found, an error is returned.
- This supports having a default or shared set of values that can also be overriden for specific environments.
dataFrom
: find.path
is equated to Item Title. find.name.regexp
is equated to field Labels. find.tags
are not supported at this time.
"},{"location":"provider/1password-automation/#prerequisites","title":"Prerequisites","text":" - 1Password requires running a 1Password Connect Server to which the API requests will be made.
- External Secrets does not run this server. See Deploy a Connect Server.
- One Connect Server is needed per 1Password Automation Environment.
- Many Vaults can be added to an Automation Environment, and Tokens can be generated in that Environment with access to any set or subset of those Vaults.
- 1Password Connect Server version 1.5.6 or higher.
"},{"location":"provider/1password-automation/#setup-authentication","title":"Setup Authentication","text":"Authentication requires a 1password-credentials.json
file provided to the Connect Server, and a related 'Access Token' for the client in this provider to authenticate to that Connect Server. Both of these are generated by 1Password.
- Setup an Automation Environment at 1Password.com, or via the op CLI.
- Note: don't be confused by the
op connect server create
syntax. This will create an Automation Environment in 1Password, and corresponding credentials for a Connect Server, nothing more. - This will result in a
1password-credentials.json
file to provide to a Connect Server Deployment, and an Access Token to provide as a Secret referenced by a SecretStore
or ClusterSecretStore
.
- Create a Kubernetes secret with the Access Token
---\napiVersion: v1\nkind: Secret\nmetadata:\n name: onepassword-connect-token-staging\ntype: Opaque\nstringData:\n token: my-token\n
- Reference the secret in a SecretStore or ClusterSecretStore
---\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: staging\nspec:\n provider:\n onepassword:\n connectHost: https://onepassword-connect-staging\n vaults:\n staging: 1 # look in this vault first\n shared: 2 # next look in here. error if not found\n auth:\n secretRef:\n connectTokenSecretRef:\n name: onepassword-connect-token-staging\n key: token\n
- Create a Kubernetes secret with the Connect Server credentials
---\napiVersion: v1\nkind: Secret\nmetadata:\n name: connect-server-credentials\ntype: Opaque\nstringData:\n # NOTE: This secret value must be base64 encoded after it becomes the OP_SESSION env var in the Connect Server Deployment, that means double base64 encoded here. (Or single w/ stringData.)\n 1password-credentials.json: |-\n eyJ2ZXJpZmllciI6eyJzYWx0IjoiZXhhbXBsZSIsImxvY2FsSGFzaCI6ImV4YW1wbGUifSwiZW5jQ3JlZGVudGlhbHMiOnsia2lkIjoiZXhhbXBsZSIsImVuYyI6ImV4YW1wbGUiLCJjdHkiOiJleGFtcGxlIiwiaXYiOiJleGFtcGxlIiwiZGF0YSI6ImV4YW1wbGUifSwidmVyc2lvbiI6IjIiLCJkZXZpY2VVdWlkIjoiZXhhbXBsZSIsInVuaXF1ZUtleSI6eyJhbGciOiJleGFtcGxlIiwiZXh0Ijp0cnVlLCJrIjoiZXhhbXBsZSIsImtleV9vcHMiOlsiZW5jcnlwdCIsImRlY3J5cHQiXSwia3R5Ijoib2N0Iiwia2lkIjoiZXhhbXBsZSJ9fQ==\n
- Reference the secret in a Connect Server Deployment
---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: onepassword-connect-staging\nspec:\n template:\n spec:\n containers:\n - name: connect-api\n image: 1password/connect-api:1.5.0\n env:\n - name: OP_SESSION\n valueFrom:\n secretKeyRef:\n name: connect-server-credentials\n key: 1password-credentials.json\n ...\n - name: connect-sync\n image: 1password/connect-sync:1.5.0\n env:\n - name: OP_SESSION\n valueFrom:\n secretKeyRef:\n name: connect-server-credentials\n key: 1password-credentials.json\n ...\n ...\n
"},{"location":"provider/1password-automation/#deploy-a-connect-server","title":"Deploy a Connect Server","text":" - Follow the remaining instructions in the Quick Start guide.
- Deploy at minimum a Deployment and Service for a Connect Server, to go along with the Secret for the Server created in the Setup Authentication section.
- The Service's name will be referenced in SecretStores/ClusterSecretStores.
- Keep in mind the likely need for additional Connect Servers for other Automation Environments when naming objects. For example dev, staging, prod, etc.
- Unencrypted secret values are passed over the connection between the Operator and the Connect Server. Encrypting the connection is recommended.
"},{"location":"provider/1password-automation/#creating-compatible-1password-items","title":"Creating Compatible 1Password Items","text":"Also see examples below for matching SecretStore and ExternalSecret specs.
"},{"location":"provider/1password-automation/#manually-password-type","title":"Manually (Password type)","text":" - Click the plus button to create a new Password type Item.
- Change the title to what you want
remoteRef.key
to be. - Set what you want
remoteRef.property
to be in the field sections where is says 'label', and values where it says 'new field'. - Click the 'Save' button.
"},{"location":"provider/1password-automation/#manually-document-type","title":"Manually (Document type)","text":" - Click the plus button to create a new Document type Item.
- Choose the file to upload and upload it.
- Change the title to match
remoteRef.key
- Click the 'Add New File' button to add more files.
- Click the 'Save' button.
"},{"location":"provider/1password-automation/#scripting-password-type-with-op-cli","title":"Scripting (Password type with op CLI)","text":" - Create
file.json
with the following contents, swapping in your keys and values. Note: section.name
's and section.title
's values are ignored by the Operator, but cannot be empty for the op
CLI {\n \"title\": \"my-title\",\n \"vault\": {\n \"id\": \"vault-id\"\n },\n \"category\": \"LOGIN\",\n \"fields\": [\n {\n \"id\": \"username\",\n \"type\": \"STRING\",\n \"purpose\": \"USERNAME\",\n \"label\": \"username\",\n \"value\": \"a-username\"\n },\n {\n \"id\": \"password\",\n \"type\": \"CONCEALED\",\n \"purpose\": \"PASSWORD\",\n \"label\": \"password\",\n \"password_details\": {\n \"strength\": \"TERRIBLE\"\n },\n \"value\": \"a-password\"\n },\n {\n \"id\": \"notesPlain\",\n \"type\": \"STRING\",\n \"purpose\": \"NOTES\",\n \"label\": \"notesPlain\",\n \"value\": \"notesPlain\"\n },\n {\n \"id\": \"customField\",\n \"type\": \"CONCEALED\",\n \"purpose\": \"custom\",\n \"label\": \"custom\",\n \"value\": \"custom-value\"\n }\n ]\n }\n
- Run
op item create --template file.json
"},{"location":"provider/1password-automation/#scripting-document-type","title":"Scripting (Document type)","text":" - Unfortunately the
op
CLI doesn't seem to support uploading multiple files to the same Item, and the current Go lib has a bug. op
can be used to create a Document type Item with one file in it, but for now it's necessary to add multiple files to the same Document via the GUI.
"},{"location":"provider/1password-automation/#in-built-field-labeled-password-on-password-type-items","title":"In-built field labeled password
on Password type Items","text":" - TL;DR if you need a field labeled
password
, use the in-built one rather than the one in a fields Section.
- 1Password automatically adds a field labeled
password
on every Password type Item, whether it's created through a GUI or the API or op
CLI. - There's no problem with using this field just like any other field, just make sure you don't end up with two fields with the same label. (For example, by automating the
op
CLI to create Items.) - The in-built
password
field is not otherwise special for the purposes of ExternalSecrets. It can be ignored when not in use.
"},{"location":"provider/1password-automation/#examples","title":"Examples","text":"Examples of using the my-env-config
and my-cert
Items seen above.
- Note: with this configuration a 1Password Item titled
my-env-config
is correlated to a ExternalSecret named my-env-config
that results in a Kubernetes secret named my-env-config
, all with matching names for the key/value pairs. This is a way to increase comprehensibility. ---\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: staging\nspec:\n provider:\n onepassword:\n connectHost: https://onepassword-connect-staging\n vaults:\n staging: 1 # look in this vault first\n shared: 2 # next look in here. error if not found\n auth:\n secretRef:\n connectTokenSecretRef:\n name: onepassword-connect-token-staging\n key: token\n
---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: my-env-config\nspec:\n secretStoreRef:\n kind: SecretStore\n name: staging\n target:\n creationPolicy: Owner\n data:\n - secretKey: MY_ENV_VAR1\n remoteRef:\n key: my-env-config\n property: MY_ENV_VAR1\n - secretKey: MY_ENV_VAR2\n remoteRef:\n key: my-env-config\n property: MY_ENV_VAR2\n # OR\n dataFrom:\n - extract:\n key: my-env-config\n property: MY_ENV_VAR1 # optional field Label to match exactly\n # OR\n - find:\n path: my-env-config # optional Item Title to match exactly\n name:\n regexp: \"^MY_ENV_VAR.*\"\n
---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: my-cert\nspec:\n secretStoreRef:\n kind: SecretStore\n name: staging\n target:\n creationPolicy: Owner\n data:\n - secretKey: cert.crt\n remoteRef:\n key: my-cert\n property: cert.crt\n - secretKey: cert.key\n remoteRef:\n key: my-cert\n property: cert.key\n # OR\n dataFrom:\n - extract:\n key: my-cert\n property: cert.key # optional field Label to match exactly\n # OR\n - find:\n path: my-cert # optional Item Title to match exactly\n name:\n regexp: \"^cert.*\"\n
"},{"location":"provider/1password-automation/#additional-notes","title":"Additional Notes","text":""},{"location":"provider/1password-automation/#general","title":"General","text":" - It's intuitive to use Document type Items for Kubernetes secrets mounted as files, and Password type Items for ones that will be mounted as environment variables, but either can be used for either. It comes down to what's more convenient.
"},{"location":"provider/1password-automation/#why-no-version-history","title":"Why no version history","text":" - 1Password only supports version history on their in-built
password
field. Therefore, implementing version history in this provider would require one Item in 1Password per remoteRef
in an ExternalSecret. Additionally remoteRef.property
would be pointless/unusable. - For example, a Kubernetes secret with 15 keys (say, used in
envFrom
,) would require 15 Items in the 1Password vault, instead of 15 Fields in 1 Item. This would quickly get untenable for more than a few secrets, because: - All Items would have to have unique names which means
secretKey
couldn't match the Item name the remoteRef
is targeting. - Maintenance, particularly clean up of no longer used secrets, would be significantly more work.
- A vault would often become a huge list of unorganized entries as opposed to a much smaller list organized by Kubernetes Secret.
- To support new and old versions of a secret value at the same time, create a new Item in 1Password with the new value, and point some ExternalSecrets at a time to the new Item.
"},{"location":"provider/1password-automation/#keeping-misconfiguration-from-working","title":"Keeping misconfiguration from working","text":" - One instance of the ExternalSecrets Operator can work with many Connect Server instances, but it may not be the best approach.
- With one Operator instance per Connect Server instance, namespaces and RBAC can be used to improve security posture, and perhaps just as importantly, it's harder to misconfigure something and have it work (supply env A's secret values to env B for example.)
- You can run as many 1Password Connect Servers as you need security boundaries to help protect against accidental misconfiguration.
"},{"location":"provider/1password-automation/#patching-externalsecrets-with-kustomize","title":"Patching ExternalSecrets with Kustomize","text":" - An overlay can provide a SecretStore specific to that overlay, and then use JSON6902 to patch all the ExternalSecrets coming from base to point to that SecretStore. Here's an example
overlays/staging/kustomization.yaml
: ---\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- ../../base/something-with-external-secrets\n- secretStore.staging.yaml\n\npatchesJson6902:\n- target:\n kind: ExternalSecret\n name: \".*\"\n patch: |-\n - op: replace\n path: /spec/secretStoreRef/name\n value: staging\n
"},{"location":"provider/akeyless/","title":"Akeyless","text":""},{"location":"provider/akeyless/#akeyless-secrets-management-platform","title":"Akeyless Secrets Management Platform","text":"External Secrets Operator integrates with the Akeyless Secrets Management Platform.
"},{"location":"provider/akeyless/#create-secret-store","title":"Create Secret Store:","text":"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:
"},{"location":"provider/akeyless/#authentication-with-kubernetes","title":"Authentication with Kubernetes:","text":"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
"},{"location":"provider/akeyless/#create-the-akeyless-secret-store-provider-with-kubernetes-auth-method","title":"Create the Akeyless Secret Store Provider with Kubernetes Auth-Method","text":"apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: akeyless-secret-store\nspec:\n provider:\n akeyless:\n # URL of your akeyless API\n akeylessGWApiURL: \"https://api.akeyless.io\"\n authSecretRef:\n kubernetesAuth:\n accessID: \"p-XXXXXX\"\n k8sConfName: \"my-conf-name\"\n\n # Optional service account field containing the name\n # of a kubernetes ServiceAccount\n serviceAccountRef:\n name: \"my-sa\"\n\n # Optional secret field containing a Kubernetes ServiceAccount JWT\n # used for authenticating with Akeyless\n secretRef:\n name: \"my-secret\"\n key: \"token\"\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
for serviceAccountRef
and secretRef
according to the namespaces where the secrets reside."},{"location":"provider/akeyless/#authentication-with-cloud-identity-or-api-access-key","title":"Authentication With Cloud-Identity or Api-Access-Key","text":"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"},{"location":"provider/akeyless/#creating-an-akeyless-credentials-secret","title":"Creating an Akeyless Credentials Secret","text":"Create a secret containing your credentials using the following example as a guide:
apiVersion: v1\nkind: Secret\nmetadata:\n name: akeyless-secret-creds\ntype: Opaque\nstringData:\n accessId: \"p-XXXX\"\n accessType: # gcp/azure_ad/api_key/k8s/aws_iam\n accessTypeParam: # optional: can be one of the following: gcp-audience/azure-obj-id/access-key/k8s-conf-name\n
"},{"location":"provider/akeyless/#create-the-akeyless-secret-store-provider-with-the-credentials-secret","title":"Create the Akeyless Secret Store Provider with the Credentials Secret","text":"apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: akeyless-secret-store\nspec:\n provider:\n akeyless:\n # URL of your akeyless API\n akeylessGWApiURL: \"https://api.akeyless.io\"\n authSecretRef:\n secretRef:\n accessID:\n name: akeyless-secret-creds\n key: accessId\n accessType:\n name: akeyless-secret-creds\n key: accessType\n accessTypeParam:\n name: akeyless-secret-creds\n key: accessTypeParam\n
NOTE: In case of a ClusterSecretStore
, be sure to provide namespace
for accessID
, accessType
and accessTypeParam
according to the namespaces where the secrets reside."},{"location":"provider/akeyless/#create-the-akeyless-secret-store-with-cas-for-tls-handshake","title":"Create the Akeyless Secret Store With CAs for TLS handshake","text":"....\nspec:\n provider:\n akeyless:\n akeylessGWApiURL: \"https://your.akeyless.gw:8080/v2\"\n\n # Optional caBundle - PEM/base64 encoded CA certificate\n caBundle: \"<base64 encoded cabundle>\"\n # Optional caProvider:\n # Instead of caBundle you can also specify a caProvider\n # this will retrieve the cert from a Secret or ConfigMap\n caProvider:\n type: \"Secret/ConfigMap\" # Can be Secret or ConfigMap\n name: \"<name of secret or configmap>\"\n key: \"<key inside secret>\"\n # namespace is mandatory for ClusterSecretStore and not relevant for SecretStore\n namespace: \"my-cert-secret-namespace\"\n ....\n
"},{"location":"provider/akeyless/#creating-an-external-secret","title":"Creating an external secret","text":"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\nkind: ExternalSecret\nmetadata:\n name: database-credentials\nspec:\n refreshInterval: 1h\n\n secretStoreRef:\n kind: SecretStore\n name: akeyless-secret-store # Must match SecretStore on the cluster\n\n target:\n name: database-credentials # Name for the secret to be created on the cluster\n creationPolicy: Owner\n\n data:\n - secretKey: username # Key given to the secret to be created on the cluster\n remoteRef:\n key: db-username # Full path of the secret on Akeyless\n - secretKey: password # Key given to the secret to be created on the cluster\n remoteRef:\n key: db-password # Full path of the secret on Akeyless\n
"},{"location":"provider/akeyless/#using-datafrom","title":"Using DataFrom","text":"DataFrom can be used to get a secret as a JSON string and attempt to parse it.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: database-credentials\nspec:\n refreshInterval: 1h\n\n secretStoreRef:\n kind: SecretStore\n name: akeyless-secret-store # Must match SecretStore on the cluster\n\n target:\n name: database-credentials-json # Name for the secret to be created on the cluster\n creationPolicy: Owner\n\n # for json formatted secrets: each key in the json will be used as the secret key in the SECRET k8s target object\n dataFrom:\n - extract:\n key: database-credentials # Full path of the secret on Akeyless\n
"},{"location":"provider/akeyless/#getting-the-kubernetes-secret","title":"Getting the Kubernetes Secret","text":"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\n
kubectl get secret database-credentials-json -o jsonpath='{.data}'\n
"},{"location":"provider/alibaba/","title":"Alibaba Cloud","text":""},{"location":"provider/alibaba/#alibaba-cloud-secrets-manager","title":"Alibaba Cloud Secrets Manager","text":"External Secrets Operator integrates with Alibaba Cloud Key Management Service for secrets and Keys management.
"},{"location":"provider/alibaba/#authentication","title":"Authentication","text":"We support Access key and RRSA authentication.
To use RRSA authentication, you should follow Use RRSA to authorize pods to access different cloud services to assign the RAM role to external-secrets operator.
"},{"location":"provider/alibaba/#access-key-authentication","title":"Access Key authentication","text":"To use accessKeyID
and accessKeySecrets
, simply create them as a regular Kind: Secret
beforehand and associate it with the SecretStore
:
apiVersion: v1\nkind: Secret\nmetadata:\n name: secret-sample\ndata:\n accessKeyID: bXlhd2Vzb21lYWNjZXNza2V5aWQ=\n accessKeySecret: bXlhd2Vzb21lYWNjZXNza2V5c2VjcmV0\n
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: secretstore-sample\nspec:\n provider:\n alibaba:\n regionID: ap-southeast-1\n auth:\n secretRef:\n accessKeyIDSecretRef:\n name: secret-sample\n key: accessKeyID\n accessKeySecretSecretRef:\n name: secret-sample\n key: accessKeySecret\n
"},{"location":"provider/alibaba/#rrsa-authentication","title":"RRSA authentication","text":"When using RRSA authentication we manually project the OIDC token file to pod as volume
extraVolumes:\n - name: oidc-token\n projected:\n sources:\n - serviceAccountToken:\n path: oidc-token\n expirationSeconds: 7200 # The validity period of the OIDC token in seconds.\n audience: \"sts.aliyuncs.com\"\n\nextraVolumeMounts:\n - name: oidc-token\n mountPath: /var/run/secrets/tokens\n
and provide the RAM role ARN and OIDC volume path to the secret store
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: secretstore-sample\nspec:\n provider:\n alibaba:\n regionID: ap-southeast-1\n auth:\n rrsa:\n oidcProviderArn: acs:ram::1234:oidc-provider/ack-rrsa-ce123456\n oidcTokenFilePath: /var/run/secrets/tokens/oidc-token\n roleArn: acs:ram::1234:role/test-role\n sessionName: secrets\n
"},{"location":"provider/alibaba/#creating-external-secret","title":"Creating external secret","text":"To create a kubernetes secret from the Alibaba Cloud Key Management Service secret a Kind=ExternalSecret
is needed.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: secretstore-sample\n kind: SecretStore\n target:\n name: example-secret\n creationPolicy: Owner\n data:\n - secretKey: secret-key\n remoteRef:\n key: ext-secret\n
"},{"location":"provider/aws-parameter-store/","title":"AWS Parameter Store","text":""},{"location":"provider/aws-parameter-store/#parameter-store","title":"Parameter Store","text":"A ParameterStore
points to AWS SSM Parameter Store in a certain account within a defined region. You should define Roles that define fine-grained access to individual secrets and pass them to ESO using spec.provider.aws.role
. This way users of the SecretStore
can only access the secrets necessary.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: parameterstore\nspec:\n provider:\n aws:\n service: ParameterStore\n # define a specific role to limit access\n # to certain secrets\n role: arn:aws:iam::123456789012:role/external-secrets\n region: eu-central-1\n auth:\n secretRef:\n accessKeyIDSecretRef:\n name: awssm-secret\n key: access-key\n secretAccessKeySecretRef:\n name: awssm-secret\n key: secret-access-key\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in accessKeyIDSecretRef
and secretAccessKeySecretRef
with the namespaces where the secrets reside.
API Pricing & Throttling
The SSM Parameter Store API is charged by throughput and is available in different tiers, see pricing. Please estimate your costs before using ESO. Cost depends on the RefreshInterval of your ExternalSecrets.
"},{"location":"provider/aws-parameter-store/#iam-policy","title":"IAM Policy","text":"The example policy below shows the minimum required permissions for fetching SSM parameters. This policy permits pinning down access to secrets with a path matching dev-*
. Other operations may require additional permission. For example, finding parameters based on tags will also require ssm:DescribeParameters
and tag:GetResources
permission with \"Resource\": \"*\"
. Generally, the specific permission required will be logged as an error if an operation fails.
For further information see AWS Documentation.
{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"ssm:GetParameter*\",\n ],\n \"Resource\": \"arn:aws:ssm:us-east-2:1234567889911:parameter/dev-*\"\n }\n ]\n}\n
"},{"location":"provider/aws-parameter-store/#json-secret-values","title":"JSON Secret Values","text":"You can store JSON objects in a parameter. You can access nested values or arrays using gjson syntax:
Consider the following JSON object that is stored in the Parameter Store key friendslist
:
{\n \"name\": {\"first\": \"Tom\", \"last\": \"Anderson\"},\n \"friends\": [\n {\"first\": \"Dale\", \"last\": \"Murphy\"},\n {\"first\": \"Roger\", \"last\": \"Craig\"},\n {\"first\": \"Jane\", \"last\": \"Murphy\"}\n ]\n}\n
This is an example on how you would look up nested keys in the above json object:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: extract-data\nspec:\n # [omitted for brevity]\n data:\n - secretKey: my_name\n remoteRef:\n key: friendslist\n property: name.first # Tom\n - secretKey: first_friend\n remoteRef:\n key: friendslist\n property: friends.1.first # Roger\n\n # metadataPolicy to fetch all the tags in JSON format\n - secretKey: tags\n remoteRef:\n metadataPolicy: Fetch\n key: database-credentials\n\n # metadataPolicy to fetch a specific tag (dev) from the source secret\n - secretKey: developer\n remoteRef:\n metadataPolicy: Fetch\n key: database-credentials\n property: dev\n
"},{"location":"provider/aws-parameter-store/#parameter-versions","title":"Parameter Versions","text":"ParameterStore creates a new version of a parameter every time it is updated with a new value. The parameter can be referenced via the version
property
"},{"location":"provider/aws-parameter-store/#setsecret","title":"SetSecret","text":"The SetSecret method for the Parameter Store allows the user to set the value stored within the Kubernetes cluster to the remote AWS Parameter Store.
"},{"location":"provider/aws-parameter-store/#creating-a-push-secret","title":"Creating a Push Secret","text":"apiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\n name: pushsecret-example # Customisable\n namespace: default # Same of the SecretStores\nspec:\n updatePolicy: Replace # Policy to overwrite existing secrets in the provider on sync\n deletionPolicy: Delete # the provider' secret will be deleted if the PushSecret is deleted\n refreshInterval: 10s # Refresh interval for which push secret will reconcile\n secretStoreRefs: # A list of secret stores to push secrets to\n - name: aws-parameterstore\n kind: SecretStore\n selector:\n secret:\n name: pokedex-credentials # Source Kubernetes secret to be pushed\n template:\n metadata:\n annotations: { }\n labels: { }\n data:\n best-pokemon: \"{{ .best-pokemon | toString | upper }} is the really best!\"\n # Uses an existing template from configmap\n # Secret is fetched, merged and templated within the referenced configMap data\n # It does not update the configmap, it creates a secret with: data[\"alertmanager.yml\"] = ...result...\n templateFrom:\n - configMap:\n name: application-config-tmpl\n items:\n - key: config.yml\n data:\n - conversionStrategy: None # Also supports the ReverseUnicode strategy\n match:\n secretKey: best-pokemon # Source Kubernetes secret key to be pushed\n remoteRef:\n remoteKey: my-first-parameter # Remote reference (where the secret is going to be pushed)\n
"},{"location":"provider/aws-parameter-store/#check-successful-secret-sync","title":"Check successful secret sync","text":"To be able to check that the secret has been succesfully synced you can run the following command:
kubectl get pushsecret pushsecret-example\n
If the secret has synced successfully it will show the status as \"Synced\".
"},{"location":"provider/aws-parameter-store/#test-new-secret-using-aws-cli","title":"Test new secret using AWS CLI","text":"To View your parameter on AWS Parameter Store using the AWS CLI, install and login to the AWS CLI using the following guide: AWS CLI.
Run the following commands to get your synchronized parameter from AWS Parameter Store:
aws ssm get-parameter --name=my-first-parameter --region=us-east-1\n
You should see something similar to the following output:
{\n \"Parameter\": {\n \"Name\": \"my-first-parameter\",\n \"Type\": \"String\",\n \"Value\": \"charmander\",\n \"Version\": 4,\n \"LastModifiedDate\": \"2022-09-15T13:04:31.098000-03:00\",\n \"ARN\": \"arn:aws:ssm:us-east-1:1234567890123:parameter/my-first-parameter\",\n \"DataType\": \"text\"\n }\n}\n
"},{"location":"provider/aws-parameter-store/#aws-authentication","title":"AWS Authentication","text":""},{"location":"provider/aws-parameter-store/#controllers-pod-identity","title":"Controller's Pod Identity","text":"Note: If you are using Parameter Store replace service: SecretsManager
with service: ParameterStore
in all examples below.
This is basicially a zero-configuration authentication method that inherits the credentials from the runtime environment using the aws sdk default credential chain.
You can attach a role to the pod using IRSA, kiam or kube2iam. When no other authentication method is configured in the Kind=Secretstore
this role is used to make all API calls against AWS Secrets Manager or SSM Parameter Store.
Based on the Pod's identity you can do a sts:assumeRole
before fetching the secrets to limit access to certain keys in your provider. This is optional.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: team-b-store\nspec:\n provider:\n aws:\n service: SecretsManager\n region: eu-central-1\n # optional: do a sts:assumeRole before fetching secrets\n role: team-b\n
"},{"location":"provider/aws-parameter-store/#access-key-id-secret-access-key","title":"Access Key ID & Secret Access Key","text":"You can store Access Key ID & Secret Access Key in a Kind=Secret
and reference it from a SecretStore.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: team-b-store\nspec:\n provider:\n aws:\n service: SecretsManager\n region: eu-central-1\n # optional: assume role before fetching secrets\n role: team-b\n auth:\n secretRef:\n accessKeyIDSecretRef:\n name: awssm-secret\n key: access-key\n secretAccessKeySecretRef:\n name: awssm-secret\n key: secret-access-key\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in accessKeyIDSecretRef
, secretAccessKeySecretRef
with the namespaces where the secrets reside.
"},{"location":"provider/aws-parameter-store/#eks-service-account-credentials","title":"EKS Service Account credentials","text":"This feature lets you use short-lived service account tokens to authenticate with AWS. You must have Service Account Volume Projection enabled - it is by default on EKS. See EKS guide on how to set up IAM roles for service accounts.
The big advantage of this approach is that ESO runs without any credentials.
apiVersion: v1\nkind: ServiceAccount\nmetadata:\n annotations:\n eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/team-a\n name: my-serviceaccount\n namespace: default\n
Reference the service account from above in the Secret Store:
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: secretstore-sample\nspec:\n provider:\n aws:\n service: SecretsManager\n region: eu-central-1\n auth:\n jwt:\n serviceAccountRef:\n name: my-serviceaccount\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
for serviceAccountRef
with the namespace where the service account resides.
"},{"location":"provider/aws-parameter-store/#custom-endpoints","title":"Custom Endpoints","text":"You can define custom AWS endpoints if you want to use regional, vpc or custom endpoints. See List of endpoints for Secrets Manager, Secure Systems Manager and Security Token Service.
Use the following environment variables to point the controller to your custom endpoints. Note: All resources managed by this controller are affected.
ENV VAR DESCRIPTION AWS_SECRETSMANAGER_ENDPOINT Endpoint for the Secrets Manager Service. The controller uses this endpoint to fetch secrets from AWS Secrets Manager. AWS_SSM_ENDPOINT Endpoint for the AWS Secure Systems Manager. The controller uses this endpoint to fetch secrets from SSM Parameter Store. AWS_STS_ENDPOINT Endpoint for the Security Token Service. The controller uses this endpoint when creating a session and when doing assumeRole
or assumeRoleWithWebIdentity
calls."},{"location":"provider/aws-secrets-manager/","title":"AWS Secrets Manager","text":""},{"location":"provider/aws-secrets-manager/#secrets-manager","title":"Secrets Manager","text":"A SecretStore
points to AWS Secrets Manager in a certain account within a defined region. You should define Roles that define fine-grained access to individual secrets and pass them to ESO using spec.provider.aws.role
. This way users of the SecretStore
can only access the secrets necessary.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: aws-secretsmanager\nspec:\n provider:\n aws:\n service: SecretsManager\n # define a specific role to limit access\n # to certain secrets.\n # role is a optional field that\n # can be omitted for test purposes\n role: arn:aws:iam::123456789012:role/external-secrets\n region: eu-central-1\n auth:\n secretRef:\n accessKeyIDSecretRef:\n name: awssm-secret\n key: access-key\n secretAccessKeySecretRef:\n name: awssm-secret\n key: secret-access-key\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in accessKeyIDSecretRef
and secretAccessKeySecretRef
with the namespaces where the secrets reside."},{"location":"provider/aws-secrets-manager/#iam-policy","title":"IAM Policy","text":"Create a IAM Policy to pin down access to secrets matching dev-*
.
{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"secretsmanager:GetResourcePolicy\",\n \"secretsmanager:GetSecretValue\",\n \"secretsmanager:DescribeSecret\",\n \"secretsmanager:ListSecretVersionIds\"\n ],\n \"Resource\": [\n \"arn:aws:secretsmanager:us-west-2:111122223333:secret:dev-*\"\n ]\n }\n ]\n}\n
"},{"location":"provider/aws-secrets-manager/#permissions-for-pushsecret","title":"Permissions for PushSecret","text":"If you're planning to use PushSecret
, ensure you also have the following permissions in your IAM policy:
{\n \"Effect\": \"Allow\",\n \"Action\": [\n \"secretsmanager:CreateSecret\",\n \"secretsmanager:PutSecretValue\",\n \"secretsmanager:TagResource\",\n \"secretsmanager:DeleteSecret\"\n ],\n \"Resource\": [\n \"arn:aws:secretsmanager:us-west-2:111122223333:secret:dev-*\"\n ]\n}\n
Here's a more restrictive version of the IAM policy:
{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"secretsmanager:CreateSecret\",\n \"secretsmanager:PutSecretValue\",\n \"secretsmanager:TagResource\"\n ],\n \"Resource\": [\n \"arn:aws:secretsmanager:us-west-2:111122223333:secret:dev-*\"\n ]\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"secretsmanager:DeleteSecret\"\n ],\n \"Resource\": [\n \"arn:aws:secretsmanager:us-west-2:111122223333:secret:dev-*\"\n ],\n \"Condition\": {\n \"StringEquals\": {\n \"secretsmanager:ResourceTag/managed-by\": \"external-secrets\"\n }\n }\n }\n ]\n}\n
In this policy, the DeleteSecret action is restricted to secrets that have the specified tag, ensuring that deletion operations are more controlled and in line with the intended management of the secrets.
"},{"location":"provider/aws-secrets-manager/#additional-settings-for-pushsecret","title":"Additional Settings for PushSecret","text":"Additional settings can be set at the SecretStore
level to control the behavior of PushSecret
when interacting with AWS Secrets Manager.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: aws-secretsmanager\nspec:\n provider:\n aws:\n service: SecretsManager\n role: arn:aws:iam::123456789012:role/external-secrets\n region: eu-central-1\n secretsManager:\n # Additional parameters can be added to the AWS Secrets Manager DeleteSecret API call.\n # These parameters are only relevant when the deletionPolicy is set to Delete.\n # See: https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_DeleteSecret.html#API_DeleteSecret_RequestSyntax\n forceDeleteWithoutRecovery: true\n # recoveryWindowInDays: 9 (conflicts with forceDeleteWithoutRecovery)\n
"},{"location":"provider/aws-secrets-manager/#additional-metadata-for-pushsecret","title":"Additional Metadata for PushSecret","text":"It's possible to configure AWS Secrets Manager to either push secrets in binary
format or as plain string
.
To control this behaviour set the following provider metadata:
apiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\n name: pushsecret-example # Customisable\n namespace: teamb # Same of the SecretStores\nspec:\n deletionPolicy: Delete\n refreshInterval: 10s # Refresh interval for which push secret will reconcile\n secretStoreRefs: # A list of secret stores to push secrets to\n - name: teamb-secret-store\n kind: SecretStore\n selector:\n secret:\n name: my-secret # Source Kubernetes secret to be pushed\n data:\n - match:\n secretKey: key1 # Source Kubernetes secret key to be pushed\n remoteRef:\n remoteKey: teamb-my-first-parameter-3 # Remote reference (where the secret is going to be pushed)\n metadata:\n secretPushFormat: string\n
secretPushFormat
takes two options. binary
and string
, where binary
is the default.
"},{"location":"provider/aws-secrets-manager/#json-secret-values","title":"JSON Secret Values","text":"SecretsManager supports simple key/value pairs that are stored as json. If you use the API you can store more complex JSON objects. You can access nested values or arrays using gjson syntax:
Consider the following JSON object that is stored in the SecretsManager key friendslist
:
{\n \"name\": {\"first\": \"Tom\", \"last\": \"Anderson\"},\n \"friends\": [\n {\"first\": \"Dale\", \"last\": \"Murphy\"},\n {\"first\": \"Roger\", \"last\": \"Craig\"},\n {\"first\": \"Jane\", \"last\": \"Murphy\"}\n ]\n}\n
This is an example on how you would look up nested keys in the above json object:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example\nspec:\n refreshInterval: 1m\n secretStoreRef:\n name: aws-secretsmanager\n kind: SecretStore\n target:\n name: friends\n creationPolicy: Owner\n data:\n - secretKey: my_name\n remoteRef:\n key: friendslist\n property: name.first # Tom\n - secretKey: first_friend\n remoteRef:\n key: friendslist\n property: friends.1.first # Roger\n\n # metadataPolicy to fetch all the labels in JSON format\n - secretKey: tags\n remoteRef:\n metadataPolicy: Fetch \n key: database-credentials\n\n # metadataPolicy to fetch a specific label (dev) from the source secret\n - secretKey: developer\n remoteRef:\n metadataPolicy: Fetch \n key: database-credentials\n property: dev\n
"},{"location":"provider/aws-secrets-manager/#secret-versions","title":"Secret Versions","text":"SecretsManager creates a new version of a secret every time it is updated. The secret version can be reference in two ways, the VersionStage
and the VersionId
. The VersionId
is a unique uuid which is generated every time the secret changes. This id is immutable and will always refer to the same secret data. The VersionStage
is an alias to a VersionId
, and can refer to different secret data as the secret is updated. By default, SecretsManager will add the version stages AWSCURRENT
and AWSPREVIOUS
to every secret, but other stages can be created via the update-secret-version-stage api.
The version
field on the remoteRef
of the ExternalSecret will normally consider the version to be a VersionStage
, but if the field is prefixed with uuid/
, then the version will be considered a VersionId
.
So in this example, the operator will request the same secret with different versions: AWSCURRENT
and AWSPREVIOUS
:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: versioned-api-key\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: aws-secretsmanager\n kind: SecretStore\n target:\n name: versioned-api-key\n creationPolicy: Owner\n data:\n - secretKey: previous-api-key\n remoteRef:\n key: \"production/api-key\"\n version: \"AWSPREVIOUS\"\n - secretKey: current-api-key\n remoteRef:\n key: \"production/api-key\"\n version: \"AWSCURRENT\"\n
While in this example, the operator will request the secret with VersionId
as abcd-1234
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: versioned-api-key\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: aws-secretsmanager\n kind: SecretStore\n target:\n name: versioned-api-key\n creationPolicy: Owner\n data:\n - secretKey: api-key\n remoteRef:\n key: \"production/api-key\"\n version: \"uuid/123e4567-e89b-12d3-a456-426614174000\"\n
"},{"location":"provider/aws-secrets-manager/#aws-authentication","title":"AWS Authentication","text":""},{"location":"provider/aws-secrets-manager/#controllers-pod-identity","title":"Controller's Pod Identity","text":"Note: If you are using Parameter Store replace service: SecretsManager
with service: ParameterStore
in all examples below.
This is basicially a zero-configuration authentication method that inherits the credentials from the runtime environment using the aws sdk default credential chain.
You can attach a role to the pod using IRSA, kiam or kube2iam. When no other authentication method is configured in the Kind=Secretstore
this role is used to make all API calls against AWS Secrets Manager or SSM Parameter Store.
Based on the Pod's identity you can do a sts:assumeRole
before fetching the secrets to limit access to certain keys in your provider. This is optional.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: team-b-store\nspec:\n provider:\n aws:\n service: SecretsManager\n region: eu-central-1\n # optional: do a sts:assumeRole before fetching secrets\n role: team-b\n
"},{"location":"provider/aws-secrets-manager/#access-key-id-secret-access-key","title":"Access Key ID & Secret Access Key","text":"You can store Access Key ID & Secret Access Key in a Kind=Secret
and reference it from a SecretStore.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: team-b-store\nspec:\n provider:\n aws:\n service: SecretsManager\n region: eu-central-1\n # optional: assume role before fetching secrets\n role: team-b\n auth:\n secretRef:\n accessKeyIDSecretRef:\n name: awssm-secret\n key: access-key\n secretAccessKeySecretRef:\n name: awssm-secret\n key: secret-access-key\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in accessKeyIDSecretRef
, secretAccessKeySecretRef
with the namespaces where the secrets reside.
"},{"location":"provider/aws-secrets-manager/#eks-service-account-credentials","title":"EKS Service Account credentials","text":"This feature lets you use short-lived service account tokens to authenticate with AWS. You must have Service Account Volume Projection enabled - it is by default on EKS. See EKS guide on how to set up IAM roles for service accounts.
The big advantage of this approach is that ESO runs without any credentials.
apiVersion: v1\nkind: ServiceAccount\nmetadata:\n annotations:\n eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/team-a\n name: my-serviceaccount\n namespace: default\n
Reference the service account from above in the Secret Store:
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: secretstore-sample\nspec:\n provider:\n aws:\n service: SecretsManager\n region: eu-central-1\n auth:\n jwt:\n serviceAccountRef:\n name: my-serviceaccount\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
for serviceAccountRef
with the namespace where the service account resides.
"},{"location":"provider/aws-secrets-manager/#custom-endpoints","title":"Custom Endpoints","text":"You can define custom AWS endpoints if you want to use regional, vpc or custom endpoints. See List of endpoints for Secrets Manager, Secure Systems Manager and Security Token Service.
Use the following environment variables to point the controller to your custom endpoints. Note: All resources managed by this controller are affected.
ENV VAR DESCRIPTION AWS_SECRETSMANAGER_ENDPOINT Endpoint for the Secrets Manager Service. The controller uses this endpoint to fetch secrets from AWS Secrets Manager. AWS_SSM_ENDPOINT Endpoint for the AWS Secure Systems Manager. The controller uses this endpoint to fetch secrets from SSM Parameter Store. AWS_STS_ENDPOINT Endpoint for the Security Token Service. The controller uses this endpoint when creating a session and when doing assumeRole
or assumeRoleWithWebIdentity
calls."},{"location":"provider/azure-key-vault/","title":"Azure Key Vault","text":""},{"location":"provider/azure-key-vault/#azure-key-vault","title":"Azure Key vault","text":"External Secrets Operator integrates with Azure Key vault for secrets, certificates and Keys management.
"},{"location":"provider/azure-key-vault/#authentication","title":"Authentication","text":"We support authentication with Microsoft Entra identities that can be used as Workload Identity or AAD Pod Identity as well as with Service Principal credentials.
Since the AAD Pod Identity is deprecated, it is recommended to use the Workload Identity authentication.
We support connecting to different cloud flavours azure supports: PublicCloud
, USGovernmentCloud
, ChinaCloud
and GermanCloud
. You have to specify the environmentType
and point to the correct cloud flavour. This defaults to PublicCloud
.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: azure-backend\nspec:\n provider:\n azurekv:\n # PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud\n environmentType: PublicCloud # default\n
Minimum required permissions are Get
over secret and certificate permissions. This can be done by adding a Key Vault access policy:
KUBELET_IDENTITY_OBJECT_ID=$(az aks show --resource-group <AKS_CLUSTER_RG_NAME> --name <AKS_CLUSTER_NAME> --query 'identityProfile.kubeletidentity.objectId' -o tsv)\naz keyvault set-policy --name kv-name-with-certs --object-id \"$KUBELET_IDENTITY_OBJECT_ID\" --certificate-permissions get --secret-permissions get\n
"},{"location":"provider/azure-key-vault/#service-principal-key-authentication","title":"Service Principal key authentication","text":"A service Principal client and Secret is created and the JSON keyfile is stored in a Kind=Secret
. The ClientID
and ClientSecret
should be configured for the secret. This service principal should have proper access rights to the keyvault to be managed by the operator
"},{"location":"provider/azure-key-vault/#managed-identity-authentication","title":"Managed Identity authentication","text":"A Managed Identity should be created in Azure, and that Identity should have proper rights to the keyvault to be managed by the operator.
Use aad-pod-identity to assign the identity to external-secrets operator. To add the selector to external-secrets operator, use podLabels
in your values.yaml in case of Helm installation of external-secrets.
If there are multiple Managed Identities for different keyvaults, the operator should have been assigned all identities via aad-pod-identity, then the SecretStore configuration should include the Id of the identity to be used via the identityId
field.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: azure-store\nspec:\n provider:\n # provider type: azure keyvault\n azurekv:\n authType: ManagedIdentity\n # Optionally set the Id of the Managed Identity, if multiple identities are assigned to external-secrets operator\n identityId: \"<MI_clientId>\"\n # URL of your vault instance, see: https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates\n vaultUrl: \"https://my-keyvault-name.vault.azure.net\"\n
"},{"location":"provider/azure-key-vault/#workload-identity","title":"Workload Identity","text":"In Microsoft Entra, Workload Identity can be Application, user-assigned Managed Identity and Service Principal.
You can use Azure AD Workload Identity Federation to access Azure managed services like Key Vault without needing to manage secrets. You need to configure a trust relationship between your Kubernetes Cluster and Azure AD. This can be done in various ways, for instance using terraform
, the Azure Portal or the az
cli. We found the azwi cli very helpful. The Azure Workload Identity Quick Start Guide is also good place to get started.
This is basically a two step process:
- Create a Kubernetes Service Account (guide)
azwi serviceaccount create phase sa \\\n --aad-application-name \"${APPLICATION_NAME}\" \\\n --service-account-namespace \"${SERVICE_ACCOUNT_NAMESPACE}\" \\\n --service-account-name \"${SERVICE_ACCOUNT_NAME}\"\n
2. Configure the trust relationship between Azure AD and Kubernetes (guide) azwi serviceaccount create phase federated-identity \\\n --aad-application-name \"${APPLICATION_NAME}\" \\\n --service-account-namespace \"${SERVICE_ACCOUNT_NAMESPACE}\" \\\n --service-account-name \"${SERVICE_ACCOUNT_NAME}\" \\\n --service-account-issuer-url \"${SERVICE_ACCOUNT_ISSUER}\"\n
With these prerequisites met you can configure ESO
to use that Service Account. You have two options:
"},{"location":"provider/azure-key-vault/#mounted-service-account","title":"Mounted Service Account","text":"You run the controller and mount that particular service account into the pod by adding the label azure.workload.identity/use: \"true\"
to the pod. That grants everyone who is able to create a secret store or reference a correctly configured one the ability to read secrets. This approach is usually not recommended. But may make sense when you want to share an identity with multiple namespaces. Also see our Multi-Tenancy Guide for design considerations.
apiVersion: v1\nkind: ServiceAccount\nmetadata:\n # this service account was created by azwi\n name: workload-identity-sa\n annotations:\n azure.workload.identity/client-id: 7d8cdf74-xxxx-xxxx-xxxx-274d963d358b\n azure.workload.identity/tenant-id: 5a02a20e-xxxx-xxxx-xxxx-0ad5b634c5d8\n---\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: azure-store\nspec:\n provider:\n azurekv:\n authType: WorkloadIdentity\n vaultUrl: \"https://xx-xxxx-xx.vault.azure.net\"\n # note: no serviceAccountRef was provided\n
"},{"location":"provider/azure-key-vault/#referenced-service-account","title":"Referenced Service Account","text":"You run the controller without service account (effectively without azure permissions). Now you have to configure the SecretStore and set the serviceAccountRef
and point to the service account you have just created. This is usually the recommended approach. It makes sense for everyone who wants to run the controller without Azure permissions and delegate authentication via service accounts in particular namespaces. Also see our Multi-Tenancy Guide for design considerations.
apiVersion: v1\nkind: ServiceAccount\nmetadata:\n # this service account was created by azwi\n name: workload-identity-sa\n annotations:\n azure.workload.identity/client-id: 7d8cdf74-xxxx-xxxx-xxxx-274d963d358b\n azure.workload.identity/tenant-id: 5a02a20e-xxxx-xxxx-xxxx-0ad5b634c5d8\n---\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: azure-store\nspec:\n provider:\n azurekv:\n authType: WorkloadIdentity\n vaultUrl: \"https://xx-xxxx-xx.vault.azure.net\"\n serviceAccountRef:\n name: workload-identity-sa\n
In case you don't have the clientId when deploying the SecretStore, such as when deploying a Helm chart that includes instructions for creating a Managed Identity using Azure Service Operator next to the SecretStore definition, you may encounter an interpolation problem. Helm lacks dependency management, which means it can create an issue when the clientId is only known after everything is deployed. Although the Service Account can inject clientId
and tenantId
into a pod, it doesn't support secretKeyRef/configMapKeyRef. Therefore, you can deliver the clientId and tenantId directly, bypassing the Service Account.
The following example demonstrates using the secretRef field to directly deliver the clientId
and tenantId
to the SecretStore while utilizing Workload Identity authentication.
apiVersion: v1\nkind: ServiceAccount\nmetadata:\n # this service account was created by azwi\n name: workload-identity-sa\n annotations: {}\n---\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: azure-store\nspec:\n provider:\n azurekv:\n # tenantId spec option #1\n tenantId: \"5a02a20e-xxxx-xxxx-xxxx-0ad5b634c5d8\"\n authType: WorkloadIdentity\n vaultUrl: \"https://xx-xxxx-xx.vault.azure.net\"\n serviceAccountRef:\n name: workload-identity-sa\n authSecretRef:\n clientId:\n name: umi-secret\n key: clientId\n # tenantId spec option #2\n tenantId:\n name: umi-secret\n key: tenantId\n
"},{"location":"provider/azure-key-vault/#update-secret-store","title":"Update secret store","text":"Be sure the azurekv
provider is listed in the Kind=SecretStore
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: azure-store\nspec:\n provider:\n # provider type: azure keyvault\n azurekv:\n # azure tenant ID, see: https://docs.microsoft.com/en-us/azure/active-directory/fundamentals/active-directory-how-to-find-tenant\n tenantId: \"2ed1d494-6c5a-4c5d-aa24-479446fb844d\"\n # URL of your vault instance, see: https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates\n vaultUrl: \"https://kvtestpushsecret.vault.azure.net\"\n authSecretRef:\n # points to the secret that contains\n # the azure service principal credentials\n clientId:\n name: azure-secret-sp\n key: ClientID\n clientSecret:\n name: azure-secret-sp\n key: ClientSecret\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in clientId
and clientSecret
with the namespaces where the secrets reside. Or in case of Managed Identity authentication:
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: azure-store\nspec:\n provider:\n # provider type: azure keyvault\n azurekv:\n authType: ManagedIdentity\n # Optionally set the Id of the Managed Identity, if multiple identities are assigned to external-secrets operator\n identityId: \"<MI_clientId>\"\n # URL of your vault instance, see: https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates\n vaultUrl: \"https://my-keyvault-name.vault.azure.net\"\n
"},{"location":"provider/azure-key-vault/#object-types","title":"Object Types","text":"Azure Key Vault manages different object types, we support keys
, secrets
and certificates
. Simply prefix the key with key
, secret
or cert
to retrieve the desired type (defaults to secret).
Object Type Return Value secret
the raw secret value. key
A JWK which contains the public key. Azure Key Vault does not export the private key. You may want to use template functions to transform this JWK into PEM encoded PKIX ASN.1 DER format. certificate
The raw CER contents of the x509 certificate. You may want to use template functions to transform this into your desired encoding"},{"location":"provider/azure-key-vault/#creating-external-secret","title":"Creating external secret","text":"To create a Kubernetes secret from the Azure Key vault secret a Kind=ExternalSecret
is needed.
You can manage keys/secrets/certificates saved inside the keyvault , by setting a \"/\" prefixed type in the secret name, the default type is a secret
. Other supported values are cert
and key
.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: database-credentials\nspec:\n refreshInterval: 1h\n secretStoreRef:\n kind: SecretStore\n name: azure-store\n\n target:\n name: database-credentials\n creationPolicy: Owner\n\n data:\n # name of the SECRET in the Azure KV (no prefix is by default a SECRET)\n - secretKey: database-username\n remoteRef:\n key: database-username\n\n # explicit type and name of secret in the Azure KV\n - secretKey: database-password\n remoteRef:\n key: secret/database-password\n\n # metadataPolicy to fetch all the tags in JSON format\n - secretKey: database-credentials-metadata\n remoteRef:\n key: database-credentials\n metadataPolicy: Fetch\n\n # metadataPolicy to fetch a specific tag which name must be in property\n - secretKey: database-credentials\n remoteRef:\n key: database-credentials\n metadataPolicy: Fetch\n property: environment\n\n # type/name of certificate in the Azure KV\n # raw value will be returned, use templating features for data processing\n - secretKey: db-client-cert\n remoteRef:\n key: cert/db-client-cert\n\n # type/name of the public key in the Azure KV\n # the key is returned PEM encoded\n - secretKey: encryption-pubkey\n remoteRef:\n key: key/encryption-pubkey\n
The operator will fetch the Azure Key vault secret and inject it as a Kind=Secret
. Then the Kubernetes secret can be fetched by issuing:
kubectl get secret secret-to-be-created -n <namespace> -o jsonpath='{.data.dev-secret-test}' | base64 -d\n
To select all secrets inside the key vault or all tags inside a secret, you can use the dataFrom
directive:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: all-secrets\nspec:\n refreshInterval: 1h # rate ESO pulls Azure Key Vault\n secretStoreRef:\n kind: SecretStore\n name: azure-store # name of the SecretStore (or kind specified)\n target:\n name: all-secrets # name of the k8s Secret to be created\n creationPolicy: Owner\n dataFrom:\n # find all secrets starting with dev-\n - find:\n name:\n regexp: \"^dev\"\n # find all secrets with tags\n - find:\n tags:\n environment: dev\n\n # extract data from a json value\n - extract:\n key: database-credentials\n\n # fetch tags from `database-credentials`\n # and store them as individual keys in a secret\n - extract:\n key: database-credentials\n metadataPolicy: Fetch\n
To get a PKCS#12 certificate from Azure Key Vault and inject it as a Kind=Secret
of type kubernetes.io/tls
:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: tls-client-credentials\nspec:\n refreshInterval: 1h\n secretStoreRef:\n kind: SecretStore\n name: azure-store\n target:\n template:\n type: kubernetes.io/tls\n engineVersion: v2\n data:\n tls.crt: \"{{ .tls | b64dec | pkcs12cert }}\"\n tls.key: \"{{ .tls | b64dec | pkcs12key }}\"\n data:\n - secretKey: tls\n remoteRef:\n # Azure Key Vault certificates must be fetched as secret/cert-name\n key: secret/tls-client-credentials\n
"},{"location":"provider/azure-key-vault/#creating-a-pushsecret","title":"Creating a PushSecret","text":"You can push secrets to Azure Key Vault into the different secret
, key
and certificate
APIs.
"},{"location":"provider/azure-key-vault/#pushing-to-a-secret","title":"Pushing to a Secret","text":"Pushing to a Secret requires no previous setup. with the secret available in Kubernetes, you can simply refer it to a PushSecret object to have it created on Azure Key Vault:
apiVersion: v1\nkind: Secret\nmetadata:\n name: source-secret\nstringData:\n source-key: \"my-secret\"\n---\napiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\n name: pushsecret-example\n namespace: default\nspec:\n refreshInterval: 10s # Refresh interval for which push secret will reconcile\n deletionPolicy: Delete\n secretStoreRefs: # A list of secret stores to push secrets to\n - name: azure-store\n kind: SecretStore\n selector:\n secret:\n name: source-secret # Source Kubernetes secret to be pushed\n data:\n - match:\n secretKey: source-key # Source Kubernetes secret key containing the secret\n remoteRef:\n remoteKey: my-azkv-secret-name \n
Note
In order to create a PushSecret targeting keys, CreateSecret
and DeleteSecret
actions must be granted to the Service Principal/Identity configured on the SecretStore.
"},{"location":"provider/azure-key-vault/#pushing-to-a-key","title":"Pushing to a Key","text":"The first step is to generate a valid Private Key. Supported Formats include PRIVATE KEY
, RSA PRIVATE KEY
AND EC PRIVATE KEY
(EC/PKCS1/PKCS8 types). After uploading your key to a Kubernetes Secret, the next step is to create a PushSecret manifest with the following configuration:
apiVersion: v1\nkind: Secret\nmetadata:\n name: source-key\ndata:\n tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlKSndJQkFBS0NBZ0VBcTRJTEFXRkZRdXNCMTFtYk1FQ2ZSRjh2WUJWeVhqYmFBczN5SE5RWXBNbUNWNkt0CmxKOVcrMlRMRUc3WnlhN1hwTGNuTlc1QWtOM3FrYW1zWGNiV0dLMUZIK3BKcXlKK2RkaktrMjlXa1RHYnV2THgKdkNWSGp6cndPN0NFdTVGWmIvV2NxcjMzb2l4YWdwNlBFYVZKR0t6U3hJaFMvZDlXR1JuN0MySnhKRnlaWlBLWgpYY01KOEg0TmZ5UDcrWjVZTjJMaWQ4eWdWUlpDWXgzQktadXdsQmdwMkpjMmpkN0x4WmQrYmx3REdGUEw4VHpPCk5LZjFRT2JndmdWY2E4M0NWVTJLZ3p0R0M0YVhkVDR3TkYrV25Hdmgza1JrVlBqMDRsbms4Z001M0ZJZ0dJV2oKalphRVd2b2RBMFJSWEtwL3IyMFI4aFRRNXlZMGJ4ejVSQVJyTEdkY1BlejRJY3FSZG5nUm10VldkQ29ZMzZNMgphdE9HRnNPd0ZCbEpuRVhUY0dxWXlnbnZYQlVzVXRNSmdYY3pDWlB1czlTODZtTGxjajlZK3BNb3FSY0NpMCtOCjBtd3VvNUt3dG1tSjBURnBXR3RLS0VSVUpOZkduNWIxekZrWGxsZSt5ODMzMkN2Nk9yWXNCemNya0pFOGJHRmUKTytZY1lqYytGblJpN3JhWXpwTzRReDJ5dzUxSGRScis3aldxNnFrejEzUlZya3hSQ1NFVW5wbVE1M0RvSTZjWgpDakN0UjZWZ3VVY0xnYndFM2w0dlluV0VXMHVNNmZjenlQem1LVis5M0RFd1U4Q3pXR09neTJrNjBYcmx2YkJwCjYrbFdlZVZnNzJJZjZEb0oyVFZZQStFZUpOWDBpaHVUTmpDNmk3VVZYdm5KRWNhSnFTRXE1QTY4OUs4Q0F3RUEKQVFLQ0FnQWN3S2x0cXN2OHd2OUZCaDJ4UWpReE55L3ZFTWxpcUJsMmZPWkpGUG1vcnF1dVczUjBSUjVFK1FuZQpFR2RzbTJaRmsvcjd4eWNGNGw1UDJ6MHRYNGRIRGMxWDQyUkVUMzBaN3FWUGdFdm4vWVFaSEYrUVprT1A3SmFYCnV5a1ZkUEdraG0ya1prS2Nxb2psK3dVTE5VV0M0SDVaT20ySGFDaTcvcElLdjQ4dVJHUG0rNURnbWpFUlkyQ0oKM3hPQUxwNmxjbXQ3SUJBRkU3MC9kcDZLaGpKZE1ZdmFac2RiazIxZ0M5ekRUYU9yTVdrd1lUeEVzWis1S0x1bQp2NmxWM1dIbUFTRG1qVXBaNWs5LzlWUUpnN2p4TWxqa2RWeklyaEFIM29BMlhub1Z5S0xlMlpDb3pRSVZhbmJ3CnRFUmJuNjNXVUJmQkdPSkl6aXZlTU9KTkY5eUxoOTBrWmszaDR0N3dqWFNodUR2SGp2ZmVaVzhjOStTVTh3VlUKTlRZQzUxaHFKYXNDdWdHa0NVZGp3V0pucXc4QU1VNGZFQkM0V1JBRWpKMTdYMDVJNmt3c2V2ZVRrNjlmOTNWSgoxS3ZVcmpKTkNpeVVXVWVzc0lrWllacGxJZnYrbExJUWNrTmVpOFdRRjV0RTh0Z09heHJLZXBWMW81NlkvT2tUCmFyYjg1Z2VYb0Z0Tm9NMUd6TkxqQnQrZ2pIY2owcExZakZ5L2Jsa2ZrZnRNMW1hN0U3L3ROK0d2bHBhQXE3RUcKNTc3a2xoNXJGWGQza09meVY1U3E3cmFQWDRZOWlPSU5EaXBVblpXcENHYjRHQS8wSFozdWpacTB6SlQ4Z0NyaQpSQndBRFBVY0J0UzYxUzE0WjJhU0Q1R1NKUmFHbFNGdVRoY1lxR0MrK08xcTllbkRpUUtDQVFFQTJjN21EN2FvClRlcExYRklWMzU0Zk5QTFhGYm9JSXZPZHhLVnYvR25NajZhMVhCd3RPdWhlQTlmNlhacUY2ZXViVmtLK1ZobWgKR1k5dm5nWHd2ZHBiZTIzdmN5d2duYWxTSDVYRGZnaE9LZU5ZMDJSYnhtWlVTMEtvWGRhSStHVDA3QWN6ZFFkaQpMRnBYTWtybmQwZC9taHZGNkVxN0t0Mkw2YkVoSXptQU5sTWMyY1lBeEIwY0UzRjJLQTNqV3dyQjRuMUZrRTlQCnMzby9tbmVXNEswMVlMVEsyMGhPOTlNeG5oNzNTV1h1SWFXdlI3T1pRcHFEMWFtYXBGUGlqY0RlRVpQczVUMFIKNEk3aVczNWF4YTl5WncxSkYrMTV5aEhkTTNHZllGaXJudy8zRlpQL282RzBJeW50YUZLNkFGU0dIaHpMcEs1awphSWRMYWVBbWlMYnpmUUtDQVFFQXlaVExET1h5V2VTZjUwV0oxUzVtTHJDMVJUNUI4K1dvZzhiVSsvSWxZTjF6Cm82eTM2QkVJcTlMWGhUUTl6cGp0MlcwNTRHa3FjU1hKcTJtajFHSEE5Q3FCTGNTaldyNHR6ZHFXTzREcnoxN0gKVCtpaEZqZ016R2praXhNSlpkZ2JoWGprQ3RkVEMzdGJhaFBiNjN4TjJGM0d6aE8xRmRUVWZ6bXM3WkVzWmRhYgpTaFZaaUFBOU40dnpmYWYyZ3I2SlB2azZwbEdpV2hvT2xkclRvVG4zSFRPNGJNYWJxc20vSFNTU2FyNUtXTUlXCnZlSVN4YjFoQTFIL1dTMXcvN1dqVHJ1UUZqWDRtU1BkT2lqL3hZblVWWjcrTjhLN3VKREJZNjcrWXVNM2RQNHgKdUJ2RjcvdDdwd3g0b002QnhBbGpQZExwZ2dxRFFLb3drVk9reFZ3b213S0NBUUJJS0pOdmdVUWhEQTRMZCtabgpQeXQzanp4U3BsOHJ0U24vakErZHdDOVZLQlhOZmtnOXk5M1p5Q1BaL3VkK3A5KytwRDRLcUZNRzlNNDF2Q0lWCnc5R3JBckRocHl6bkRzRjJWVmQrMmFHTG54WStjbkUxT1pHVG5YSEtKTmtiOGRaeW03QWdoV0d3Ny8wVFhGMXkKMXUwZlVUUXYwUkpSRVRUWkp5V2pWZGwwSmZUWThSQXY2TFQwZkJKNUVxRFArTEJqS0wxeklkTjEwbnBmNGw3Sgo4SmhPZ1piekx2RjZpUzFYQlV0SHRjMCt1SFZwZThhNm1oWXpJdzFvZzZINjlIcWR1RFF6ZmhmK0hWaEFsNHZiCkVsVUVieEpZS3dTK1BVemJUamxPNGhGNWtRQjYxWjFMeUxhMUw1N0hnU0MrRzBLVGwxYWdLR1o3ZXRjeExHR1gKeVlUQkFvSUJBRms2NWc3VmtzdTc2aFJqc2JtT0NtbE1pMUVWVi9od2hvR2VlQlQyZ1JrNXJjQ2I2ZVJ0OWRxcApRQUdVdUc5RlByUHFKNTV3cnZyYThVUlJSTlgwVjRjOWNXVWpEL1JSRHRGNm10bklIWm56cUdKMDVTbUNzaGVoCnJ0anBHbFhjcllJTm0xUTVNR2Q2dVdKaFhBNEhQaVl5akpnWUhTYUd5WEZ2eEY1OHpweGR2T3UwTzZkNkE1OGMKOGpHRE1obDU0aUxnQzlnbmRxaFB0SGtkSG1UVjFjODFYOE8ydnAyQkpIbndBR2dEeDhFMldQN0FuZkt0KzgyTwpkR3V6TTd2ZFdXYTJtL2RZK0t4Qk5lSlMxN1ZIWjVobkFyMElGRFNFenpZaTlqUXJ4QmFqbHJxYWdLblVOazRoCnRSdnBqWU9MYkVTbm9mbVFVYjFFR0srYnlPb2IrMVVDZ2dFQUJJTFZ0eVV6cFNobW1FN0crZ3I0aGpBb0UxQlgKTDd2SHVIbGdrMStNbFR6RlNLZXpZUDY4RnFsRjRocEFRT2kxTnN3Sy9zaXppdGEycUdUUDJyd1d3NkJUUW9wawplbkdDaEtWNUp0SHRBeDZ2bEZ0aUxUVzE5QTlvUXZEbEllYmNsaFRob2ZWeHV0NFI4RC8vSXZRQXRxbm5jUFFuCnZ5RzRUakl4VCtsWDZqcXdHbUlwRVI4TlpLdjVXU2EzOVVNdlF0ZUJ3Q1hUZEF6Wnlqc0RjRENodlJVRno3S2YKNVlMZ1pVdEt2cEZnbVNYNGF0b2t1TCt5Nm9LYm93Tld6bVdhNzhHbzRLUlhGK2xxUk5OL0dTM0lkM01MdDNmKwovLzRvcWNZa1lyU0dEbjJPenRabGpFcjFrK0NCQ0Rvc3pFMms2b2ZmN2pBck1YUG5McUVXQXkrWDdBPT0KLS0tLS1FTkQgUlNBIFBSSVZBVEUgS0VZLS0tLS0K\n---\napiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\n name: pushsecret-example\n namespace: default\nspec:\n refreshInterval: 10s # Refresh interval for which push secret will reconcile\n deletionPolicy: Delete\n secretStoreRefs: # A list of secret stores to push secrets to\n - name: azure-store\n kind: SecretStore\n selector:\n secret:\n name: source-key # Source Kubernetes secret to be pushed\n data:\n - match:\n secretKey: tls.key # Source Kubernetes secret key containing the JWK\n remoteRef:\n remoteKey: key/my-azkv-key-name\n
Note
In order to create a PushSecret targeting keys, ImportKey
and DeleteKey
actions must be granted to the Service Principal/Identity configured on the SecretStore.
"},{"location":"provider/azure-key-vault/#pushing-to-a-certificate","title":"Pushing to a Certificate","text":"The first step is to generate a valid P12 certificate. Currently, only PKCS1/PKCS8 types are supported. Currently only password-less P12 certificates are supported.
After uploading your P12 certificate to a Kubernetes Secret, the next step is to create a PushSecret manifest with the following configuration
apiVersion: v1\nkind: Secret\nmetadata:\n name: source-certificate\ndata:\n cert.p12: MIIQZgIBAzCCECwGCSqGSIb3DQEHAaCCEB0EghAZMIIQFTCCBi8GCSqGSIb3DQEHBqCCBiAwggYcAgEAMIIGFQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQIl69kTzb7QegCAggAgIIF6IOxs3Cr7vl4eT2/YdPNuVoadkQUMO6P5Ad6iuLvY7cDU7D9DO/cga/BVO0/OSIYXgTzbOg3KhreFUcoCTWne7/rbByYi6RHt2AjcZbs6CC6lTraRp5NzppfLGUUAX7v4BR93q55mB0H/j+FNx4QWhgC7sEjSawdvmeNyi+5IrCib0xDYqQ8AvN/g5Vhhp8nAqChx+1n26tRaDh7ULAY+/7D2ffG+gXHNxYn5tM7DGrcCW1FZtEqF53XVzbtyqAqtiWvSyXWYc9CyDN2mqfVG50BDAVGJT3SvuqCs7VO1w8Gs3LbT/eHRfczt2yjVZMLemVuMgHJ6Z3C1W5KjcFRsAhGLzi63d2rj091OnzhWP5YX0QrsAxgLYVeszhsq2GIb/vqIDubwawN0lZQk/guTFRAtcBMb+WDfzqJNPjOElz63/ugxNPTslWNyB7FpNWAtRxjT7qYB28JqnA8nepbzuQc/PZYPcuNFcZJD5YKE0aAhQEgaVOT0ygFdp+/VQ9LsfHgn2AVtsAmDUbt2UaXfyDDwLH19hVs6YPnYGNFiOSRBoTIgCzBreUeo3d/tJ8Ha4CA1TXrdisOGcqO9vszf8bXqgCQQzLl8lxAKZgCYCRoBF9TMkK/4IZ6NeEdxuO4hDhm6bbapIlVw5KsmqPk5i0wYT9TebH6aPyMT4OtYgVdZmTXI8RfkjduKjVxyEDIiX776yTZS0H8F0KtzJdfxX9euwneVg8ap9/7zEZNqfrtj8BGY/12LsXowExbeGLuyb+cgW8F83Pszyilc/EOrXzJOrmEwu3c/fIm93+NhZSoeZ5NwbkhUjOn0qox//FPZF8eSOFkB8Br5gnLuyFl41cOQ0rpVOI0Byz5TFhP4gQ1hH6AuAhRMdGhDWmg4Vot0CAOr3vthbBn/b9B7QQY23UzKlgeog9McrvJ1leM1Jeyl6Az/8tGFJTN7gIZNq91tKuV3bLqLvl6yCKGChy3Hrik+WJFvoaMwLsX38ljgYUYV/+d6gP0Oe87u+9pQ7xnZPaUJ8EJDA3KtFuagfNC2O/F/kZU2KV1Z4Q+3SDZ6O2KGbQestO9BYz/AZAiIfw0qw1Rb0ilskByXH0CLT3FxrefUDMGa57vxQOBeIpJXk91LCg5YDuZ/a8pcnII2dQrXfB+6rK/3fxQdZhliV8KSvQenyw6ZoVqwK+Z1nS1htikfOf3UW/KXHfGsX9L+cS2CA8IaA5EZAZS/boeXxt2ke16LNj2jlfxK8LX051MJ1sTM0I5K9hIp0oNaAKhTmdpWzudbGRRwtZJVhPOaUG4MHaTmrFNQLqOFtUvUDPl6w31fX4LQcPrZncrEahKPoq9vD9AqFvoI+Ku1hfuO+6/pB88fcE/eRtUU824nWB5EU9T7LOQim36fjZrYYAgBZbmwqiERGV68ILnpARbyaA/B/Sj4pIFYmPHo7mhhVWjz8o08QQC3zC4z5R3xisFb/67OCUqxk+ouI0mrM93IBzWVG1INTmmEvz3neeSlSNuUwj40hDOeKaUkUnQCsJWZy9Bx9yIeYfPVhE9GM57qkmzTKnJhM3cCSZEaZuXzvkut6rb7mkorfRI2pMFSK4TjWe743L7TWYXspMtRHe++nsNweZNQCniYvI+S6hVe8GYwbCMxRue+f57I3rBBdcKmBn2npTOcX/5fwYMCgjYEIJdWZZBSXhqEYw2ZEwU2rNvWXpGFcp5cPYwpKWjiD5GpL3eXOTj7Q5u9UHQWhMUQN7Lt/d6Fd9bsoTBhQlRnU6Xe4fdHtCyBMYTjyygqSfa/8XZUp+tZ2tX3zBxCYdw3bepOw4o7skUbqpKKGW0hjEoNgeoB8EFszeM48IY7M75CQY3adFqFzcG+XnTg5K5dJUihcCgn7LwWE1pu8mQTk8FjNkfJjD51Bv/YfEoPTa1XPDumIRZwSJO47mUOdVjg+qUzp3mRz6Gs4/1EJBfTOk3vLkpMUx/YutbzUD6sUZNa8PgICVPEapPbZHQdO/0LgD6DQi2kUsHuhiE2zCCCd4GCSqGSIb3DQEHAaCCCc8EggnLMIIJxzCCCcMGCyqGSIb3DQEMCgECoIIJbjCCCWowHAYKKoZIhvcNAQwBAzAOBAiVo1C5uK6CRwICCAAEgglIfhBryp3NDqqoOhAcaoKj2X2JXamh8KKk7vDW62QfYJVtormTKdnEXHE9f67ZfiB6ippsiTH1Sp1uFWirfiaBb0WhYjoQcUY6vry9Zb/GUd0NnyXnIz6WILFPfE9KC8v1Eo+pxOVj0qRWmf+CGrZCtZbi479k44/aCacBwrut8DaSuaTf9rDc3dgZj1ESYBINkBDXwm0lm/mpObhDbyaoL6+uwloM/EhE8VrtYmZLQ8781EuD6XVfem1GMuHCPiQBL8/23hze2yyB3NnjQzEcC9RLw2yPilWmB+PjfDUzIaCnOty6OUINZZqJ6ivoaA3qS8xh+kZTiCmAlHW/+5RyYXUL/c1bvlBMZz6z9n3lXBjnee3kRVbrQV/aa+069Nd76Mi8WBXhsjkm3+K14fuJksg1x3NohcL3/kW/iYHBXBFug2w6wX8l1T3XcxekBKDDNDfoy/ZExmDmsDAmUfIWb4zonLlaGq6z/9l3LkjrNS9/7C2YYEmh0xmMGD0mjzj1k932LWzvLdPaEIZTm2YsoI4TyraKc2yjXmmQWldGeN4yB/s0RfoaxPrMjkQsO6ZaU+gPqucd0JjL/e9gDVUWB0CL6Wy1T+H60iWBQhj0h5PoXuIbsocVj9PC08zniXmXUiVvbt62AyPm7oYci8BXJIc18WQ/BcO1EzPbQCVqI8DMWkyVCN/XUR7Oufseib//qZyf5XOSqwTHaetWU5tsIVKHcU8vzwPHqiDrFRmkBvn8pmtaQibaartr1XmiTCCkRX5yCzstbWWhjnRB/UD1zTxiMQUEmkmFD3zldLYuXWaaQNpNExog7vyJSMLUuTpff68sElBTRUA5pqqiVua5VsorzWaVMORsdagii4iJ/KQDoSs3KLZ6tXqNHBxoP69Mf6WJF8LZ+3FyYr+Ckpii2zgxx7D274fK6XfQpTS1yxeJPTxPZoEEZs9G03UKkrfi3Uv106akNB4XyAMxsyK26GTbKGkSig1C2gme/oCJfG8ZYin8hhl6QTlGk4ao2RWXT8Rh+qW6PDm+SVA4WJl9NI/eJwEtjmE2U1nt0IfkNy2miug3rHbr1yso4gnfdQUtMsHz055y7GgauJKADGa7N2dUdq7jbK4rbD59QsloYKpkN0TX2g86APMuMlHai33A942bsFnp+IC4ONHpj+LQZHgbr1ygVhI6EQs+x6OAw/0UrEq8fP0KVJBZHR96GJZHGCkVy6z+FVlRGTw4Lgb+dMpjucJeLQw852TLN3zHKsCglsygzGf6dfZhHs4o0tB+NyWr4Pgw/F8n3iXhTQCv95fHoTz9lav/LU1KTxADPhgczNUE6e2zrfZ0724d+eBOZXPY5endc+t2Kci+O2S2xS3XDxt4GDEWEogy6kjQoObjaHEoiOUcplbTfgptpXseivK1y3DU3gJPbNYTE8qJIOnFDwUxYDGYjlUH9h+SguCeRkO8sR5iQrYsjQQbDcPxss3rg6DeytcnsFwKf8bE/mwOpzHOE9CMrWuOoPrmtn7Lad7aTn1YN3hyeaHHVVAWzsbOyhhvEmsX5pifM26ZF57cabEiOU3itt5cYI9qxb90V4hc69NgfONx89RtrgsXd61rIsf8CeQDx3rQmQWZ54Pb0o5WUMnCbui/Z5Nw4RjeKdl38josYB3VZCXBz7g1y3ZWZUpl8GTn6TUZGXtXw8e4g18RJxpgt5OC3d27jY4fsDrVlUlYuZV21fbOG/MyT1YKQvNZlazpNPXXXyHK+Swj+A3H4It0K7IhM4R5+riH3ngcgbtF3M3StIM4lT5KVA84CRUWmDPIUskNbTUJWLw3nhDa5mmgCC9eRrb724leAFWG/FAvlsXmMl5BWWm5KYynu+y0pNpDbLmNNP6PlEBi9Ipms51BaUbQa2Y+LbFXj7dm4MBl07qroxQTOAu/DmUrxkBXU0ElpYhYrYoGbODuH/fD0C2KOJ5d6O8jRg3nN0228A2wrd18p47Q63mHyJlezxKI69o1Um6FNUjTtk6KU1Zp0AtW4mE5jkdKLfRNhlDPrgZAeYoT3OFU9UaPRauw/EJBNhSjmZC6aa4wqu60gmQ8xfnJ6YEd/XayZXqjoAiE9cAC3tF3bO8x3gpp0D0uKFhha5VgtYb9LTVlbE+Kb4DLi5fEkRWyTfywVMXLPgm5HnVE3Pz6SRwH8jHUjNSnqRRbwJfJ4Sb8LzQSzf1y0imoAfGRUcjbIC0tKAitYZ5LduaIzNyi4hBaAwsXLkLEkBClUqtI4LtCf6ETgPNRWmSWYKeiV6vzjyR0xhBi1VixpS8HN4OdA8Te3t41lp6w8nFaJcrD0LnLNPMeotJv5u+6gc3d1Jd/to+DtvxpFulh8J5WMEXCHJOV6nSKRb+rGUFh+2jp9qkSB98XGCcKn3blAFxEGYwtJXqpP53pPxa6Up/f0/KR87a4IWD0y5fZ90+HcvDCnQofuQWsMobpiFWN7ScYttbcO85xv7J6Qs+yUf9hzraN8rLW9o7LKnW+fCT8c0ggTIqTyaW1HwTtYDZtYDUIG9KDj3KY1YZN2yca+ErnS1phfI71m8JqjvH2k/+finxs2IexESmjzRTeqgEKGrhx1BdhwJ5/nd9moF6HuWqR3XCd2UtiLyhQbFt+Lo70vHm3m0Duzu03pKgGGXQQQqa1QM6YIAV6s3TSs/5cYm5KGZCd7UoKlMRzivHst/Nm6Zy+3jckpn626f7RkP/hIfT9Qvrd80PGYeCe2nNvTMfAfScYbczZ225knqeT6Z7vdY8+jgabAjREPLzKvZlL3wS6FquFEsGYn/BNAbkuJ9OhxWBgwqhTVLGaJdTAtl9cgcJqUKE76cclwit9ZF0ucUBdqV9twE2prGB/ujSKmhJ7Qd/FwEr7/UdJwQ8iVbs3+qJHBg91WPhTR9eab0YHzM+62FePZFWpQQ8m9RfP5Ku262YLhGEqmBHAHcOomhWUF/t3fQWewUIADG1Mr4nICeYUbLjsnS3IpASwM2uzFNBgdIe/i/xq5KZMvjtaaEqUviVPkAcHrS96L58DoEnsC+96ljH9lyBwJcJ3q2eT7rQNFY/yANRvNi5ix1mtZV8J6d/HWr2v5P67W3TnbN6yFjIVNwz2vqXOG5tsZ/5AWrctnu7kaanaHvmXgVgIkijHmzW21ZQQANPNgjGBkycGUXZMMUIwGwYJKoZIhvcNAQkUMQ4eDABNAHkAQwBlAHIAdDAjBgkqhkiG9w0BCRUxFgQU59WMkYzN/aRcemeMQJxzpRcC5nwwMTAhMAkGBSsOAwIaBQAEFN17vdeYvqbjC2HcRpRxhBWpv7ydBAgrPrMeGR5G/wICCAA=\n# Alternatively, you could also do it like this:\n#stringData:\n# certPem: |\n# -----BEGIN CERTIFICATE-----\n# ...\n# -----END CERTIFICATE-----\n# -----BEGIN PRIVATE KEY-----\n# ...\n# -----END PRIVATEKEY-----\n\n---\napiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\n name: pushsecret-example\n namespace: default\nspec:\n refreshInterval: 10s # Refresh interval for which push secret will reconcile\n deletionPolicy: Delete\n secretStoreRefs: # A list of secret stores to push secrets to\n - name: azure-store\n kind: SecretStore\n selector:\n secret:\n name: source-certificate # Source Kubernetes secret to be pushed\n data:\n - match:\n secretKey: cert.p12 # Source Kubernetes secret key containing the certificate\n remoteRef:\n remoteKey: cert/my-azkv-cert-name\n
Note
In order to create a PushSecret targeting keys, ImportCertificate
and DeleteCertificate
actions must be granted to the Service Principal/Identity configured on the SecretStore.
"},{"location":"provider/chef/","title":"Chef","text":""},{"location":"provider/chef/#chef","title":"Chef","text":"Chef External Secrets provider
will enable users to seamlessly integrate their Chef-based secret management with Kubernetes through the existing External Secrets framework.
In many enterprises, legacy applications and infrastructure are still tightly integrated with the Chef/Chef Infra Server/Chef Server Cluster for configuration and secrets management. Teams often rely on Chef data bags to securely store sensitive information such as application secrets and infrastructure configurations. These data bags serve as a centralized repository for managing and distributing sensitive data across the Chef ecosystem.
NOTE: Chef External Secrets provider
is designed only to fetch data from the Chef data bags into Kubernetes secrets, it won't update/delete any item in the data bags.
"},{"location":"provider/chef/#authentication","title":"Authentication","text":"Every request made to the Chef Infra server needs to be authenticated. Authentication is done using the Private keys of the Chef Users. The User needs to have appropriate Permissions to the data bags containing the data that they want to fetch using the External Secrets Operator.
The following command can be used to create Chef Users:
chef-server-ctl user-create USER_NAME FIRST_NAME [MIDDLE_NAME] LAST_NAME EMAIL 'PASSWORD' (options)\n
More details on the above command are available here Chef User Create Option. The above command will return the default private key (PRIVATE_KEY_VALUE), which we will use for authentication. Additionally, a Chef User with access to specific data bags, a private key pair with an expiration date can be created with the help of the knife user key command.
"},{"location":"provider/chef/#create-a-secret-containing-your-private-key","title":"Create a secret containing your private key","text":"We need to store the above User's API key into a secret resource. Example:
kubectl create secret generic chef-user-secret -n vivid --from-literal=user-private-key='PRIVATE_KEY_VALUE'\n
"},{"location":"provider/chef/#creating-clustersecretstore","title":"Creating ClusterSecretStore","text":"The Chef ClusterSecretStore
is a cluster-scoped SecretStore that can be referenced by all Chef ExternalSecrets
from all namespaces. You can follow the below example to create a ClusterSecretStore
resource.
apiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\n name: vivid-clustersecretstore # name of ClusterSecretStore\nspec:\n provider:\n chef:\n username: user # Chef User name\n serverUrl: https://manage.chef.io/organizations/testuser/ # Chef server URL\n auth:\n secretRef:\n privateKeySecretRef:\n key: user-private-key # name of the key inside Secret resource\n name: chef-user-secret # name of Kubernetes Secret resource containing the Chef User's private key\n namespace: vivid # the namespace in which the above Secret resource resides\n
"},{"location":"provider/chef/#creating-secretstore","title":"Creating SecretStore","text":"Chef SecretStores
are bound to a namespace and can not reference resources across namespaces. For cross-namespace SecretStores, you must use Chef ClusterSecretStores
.
You can follow the below example to create a SecretStore
resource.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: vivid-secretstore # name of SecretStore\n namespace: vivid # must be required for kind: SecretStore\nspec:\n provider:\n chef:\n username: user # Chef User name\n serverUrl: https://manage.chef.io/organizations/testuser/ # Chef server URL\n auth:\n secretRef:\n privateKeySecretRef:\n name: chef-user-secret # name of Kubernetes Secret resource containing the Chef User's private key\n key: user-private-key # name of the key inside Secret resource\n namespace: vivid # the ns where the k8s secret resource containing Chef User's private key resides\n
"},{"location":"provider/chef/#creating-externalsecret","title":"Creating ExternalSecret","text":"The Chef ExternalSecret
describes what data should be fetched from Chef Data bags, and how the data should be transformed and saved as a Kind=Secret.
You can follow the below example to create an ExternalSecret
resource.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: vivid-external-secrets # name of ExternalSecret\n namespace: vivid # namespace inside which the ExternalSecret will be created\n annotations:\n company/contacts: user.a@company.com, user.b@company.com\n company/team: vivid-dev\n labels:\n app.kubernetes.io/name: external-secrets\nspec:\n refreshInterval: 15m\n secretStoreRef:\n name: vivid-clustersecretstore # name of ClusterSecretStore\n kind: ClusterSecretStore\n data:\n - secretKey: USERNAME\n remoteRef:\n key: vivid_prod/global_user # databagName/dataItemName\n property: username # a json key in dataItem\n - secretKey: PASSWORD\n remoteRef:\n key: vivid_prod/global_user\n property: password\n - secretKey: APIKEY\n remoteRef:\n key: vivid_global/apikey\n property: api_key\n - secretKey: APP_PROPERTIES\n remoteRef:\n key: vivid_global/app_properties # databagName/dataItemName , it will fetch all key-vlaues present in the dataItem\n target:\n name: vivid-credentials # name of kubernetes Secret resource that will be created and will contain the obtained secrets\n creationPolicy: Owner\n template:\n mergePolicy: Replace \n engineVersion: v2\n data:\n secrets.json: |\n {\n \"username\": \"{{ .USERNAME }}\",\n \"password\": \"{{ .PASSWORD }}\",\n \"app_apikey\": \"{{ .APIKEY }}\",\n \"app_properties\": \"{{ .APP_PROPERTIES }}\"\n }\n
When the above ClusterSecretStore
and ExternalSecret
resources are created, the ExternalSecret
will connect to the Chef Server using the private key and will fetch the data bags contained in the vivid-credentials
secret resource.
To get all data items inside the data bag, you can use the dataFrom
directive:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: vivid-external-secrets # name of ExternalSecret\n namespace: vivid # namespace inside which the ExternalSecret will be created\n annotations:\n company/contacts: user.a@company.com, user.b@company.com\n company/team: vivid-dev\n labels:\n app.kubernetes.io/name: external-secrets\nspec:\n refreshInterval: 15m\n secretStoreRef:\n name: vivid-clustersecretstore # name of ClusterSecretStore\n kind: ClusterSecretStore\n dataFrom:\n - extract:\n key: vivid_global # only data bag name\n target:\n name: vivid_global_all_cred # name of Kubernetes Secret resource that will be created and will contain the obtained secrets\n creationPolicy: Owner\n
follow : this file for more info
"},{"location":"provider/cloak/","title":"Cloak End 2 End Encrypted Secrets","text":""},{"location":"provider/cloak/#cloak","title":"Cloak","text":"Sync secrets from the Cloak Encrypted Secrets Platform to Kubernetes using the External Secrets Operator.
Cloak uses the webhook provider built into the External Secrets Operator but also required a proxy service to handle decrypting secrets when they arrive into your cluster.
"},{"location":"provider/cloak/#key-setup","title":"Key Setup","text":"From the Cloak user interface create a service account and store the private key on your file system.
Now create a kubernetes secret in the same namespace as the External Secrets Operator.
HISTIGNORE='*kubectl*' kubectl --namespace=external-secrets \\\n create secret generic cloak-key \\\n --from-file=ecdh_private_key=$LOCATION_OF_YOUR_PEM_FILE\n
"},{"location":"provider/cloak/#deploy-the-decryption-proxy","title":"Deploy the decryption proxy","text":"# The cloak external secrets proxy\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: cloak-external-secrets\n namespace: external-secrets\nspec:\n selector:\n matchLabels:\n app: cloak-external-secrets\n replicas: 1\n template:\n metadata:\n labels:\n app: cloak-external-secrets\n spec:\n containers:\n - name: cloak-external-secrets\n image: purtontech/cloak-external-secrets:latest\n imagePullPolicy: IfNotPresent\n env: \n - name: ECDH_PRIVATE_KEY \n valueFrom: \n secretKeyRef: \n name: cloak-key \n key: ecdh_private_key \n ports:\n - containerPort: 7105\n
And a Kubernetes Service so External Secrets Operator can access the proxy.
apiVersion: v1\nkind: Service\nmetadata:\n name: cloak-external-secrets-service\n namespace: external-secrets\nspec:\n selector:\n app: cloak-external-secrets\n ports:\n - protocol: TCP\n port: 7105\n targetPort: 7105\n
"},{"location":"provider/cloak/#create-a-secret-store","title":"Create a secret store","text":"You can now place the configuration in any Kubernetes Namespace.
# An External secrets webhookl\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: cloak-backend\nspec:\n provider:\n webhook:\n url: \"http://cloak-external-secrets-service:7105/{{ .remoteRef.key }}\"\n result:\n jsonPath: \"$.value\"\n headers:\n Content-Type: application/json\n
"},{"location":"provider/cloak/#connect-a-secret-to-the-provider","title":"Connect a secret to the provider","text":"Each secretKey
reference in the yaml should point to the name of the secret as it is stored in Cloak.
# Access a secret\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: cloak-example\nspec:\n refreshInterval: \"15m\"\n secretStoreRef:\n name: cloak-backend\n kind: SecretStore\n target:\n name: example-sync\n data:\n - secretKey: access-token\n remoteRef:\n key: PULUMI_ACCESS_TOKEN\n - secretKey: do-access-token\n remoteRef:\n key: DIGITALOCEAN_ACCESS_TOKEN\n
"},{"location":"provider/conjur/","title":"CyberArk Conjur","text":""},{"location":"provider/conjur/#conjur-provider","title":"Conjur Provider","text":"This section describes how to set up the Conjur provider for External Secrets Operator (ESO). For a working example, see the Accelerator-K8s-External-Secrets repo.
"},{"location":"provider/conjur/#prerequisites","title":"Prerequisites","text":"Before installing the Conjur provider, you need:
- A running Conjur Server, with:
- An accessible Conjur endpoint (for example:
https://myapi.example.com
). - Your configured Conjur authentication info (such as
hostid
, apikey
, or JWT service ID). For more information on configuring Conjur, see Policy statement reference. - Support for your authentication method (
apikey
is supported by default, jwt
requires additional configuration). - Optional: Conjur server certificate (see below).
- A Kubernetes cluster with ESO installed.
"},{"location":"provider/conjur/#conjur-server-certificate","title":"Conjur server certificate","text":"If you set up your Conjur server with a self-signed certificate, we recommend that you populate the caBundle
field with the Conjur self-signed certificate in the secret-store definition. The certificate CA must be referenced in the secret-store definition using either caBundle
or caProvider
:
....\nspec:\n provider:\n conjur:\n # Service URL\n url: https://myapi.conjur.org\n\n # [OPTIONAL] base64 encoded string of certificate\n caBundle: \"<base64 encoded cabundle>\"\n\n # [OPTIONAL] caProvider:\n # Instead of caBundle you can also specify a caProvider,\n # which retrieves the cert from a Secret or ConfigMap\n caProvider:\n type: \"Secret\" # Can be Secret or ConfigMap\n name: \"<name of secret or configmap>\"\n key: \"<key inside secret or configmap>\"\n # namespace is required for ClusterSecretStore\n # but not relevant for SecretStore\n namespace: \"my-cert-secret-namespace\"\n ....\n
"},{"location":"provider/conjur/#external-secret-store","title":"External secret store","text":"The Conjur provider is configured as an external secret store in ESO. The Conjur provider supports these two methods to authenticate to Conjur:
apikey
: uses a Conjur hostid
and apikey
to authenticate with Conjur jwt
: uses a JWT to authenticate with Conjur
"},{"location":"provider/conjur/#option-1-external-secret-store-with-apikey-authentication","title":"Option 1: External secret store with apiKey authentication","text":"This method uses a Conjur hostid
and apikey
to authenticate with Conjur. It is the simplest method to set up and use because your Conjur instance requires no additional configuration.
"},{"location":"provider/conjur/#step-1-define-an-external-secret-store","title":"Step 1: Define an external secret store","text":"Tip
Save as the file as: conjur-secret-store.yaml
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: conjur\nspec:\n provider:\n conjur:\n # Service URL\n url: https://myapi.conjur.org\n # [OPTIONAL] base64 encoded string of certificate\n caBundle: OPTIONALxFIELDxxxBase64xCertxString== \n auth:\n apikey:\n # conjur account\n account: conjur\n userRef: # Get this from K8S secret\n name: conjur-creds\n key: hostid\n apiKeyRef: # Get this from K8S secret\n name: conjur-creds\n key: apikey\n
"},{"location":"provider/conjur/#step-2-create-kubernetes-secrets-for-conjur-credentials","title":"Step 2: Create Kubernetes secrets for Conjur credentials","text":"To connect to the Conjur server, the ESO Conjur provider needs to retrieve the apikey
credentials from K8s secrets.
Note
For more information about how to create K8s secrets, see Creating a secret.
Here is an example of how to create K8s secrets using the kubectl
command:
# This is all one line\nkubectl -n external-secrets create secret generic conjur-creds --from-literal=hostid=MYCONJURHOSTID --from-literal=apikey=MYAPIKEY\n\n# Example:\n# kubectl -n external-secrets create secret generic conjur-creds --from-literal=hostid=host/data/app1/host001 --from-literal=apikey=321blahblah\n
Note
conjur-creds
is the name
defined in the userRef
and apikeyRef
fields of the conjur-secret-store.yml
file.
"},{"location":"provider/conjur/#step-3-create-the-external-secrets-store","title":"Step 3: Create the external secrets store","text":"Important
Unless you are using a ClusterSecretStore, credentials must reside in the same namespace as the SecretStore.
# WARNING: creates the store in the \"external-secrets\" namespace, update the value as needed\n#\nkubectl apply -n external-secrets -f conjur-secret-store.yaml\n\n# WARNING: running the delete command will delete the secret store configuration\n#\n# If there is a need to delete the external secretstore\n# kubectl delete secretstore -n external-secrets conjur\n
"},{"location":"provider/conjur/#option-2-external-secret-store-with-jwt-authentication","title":"Option 2: External secret store with JWT authentication","text":"This method uses JWT tokens to authenticate with Conjur. You can use the following methods to retrieve a JWT token for authentication:
- JWT token from a referenced Kubernetes service account
- JWT token stored in a Kubernetes secret
"},{"location":"provider/conjur/#step-1-define-an-external-secret-store_1","title":"Step 1: Define an external secret store","text":"When you use JWT authentication, the following must be specified in the SecretStore
:
account
- The name of the Conjur account serviceId
- The ID of the JWT Authenticator WebService
configured in Conjur that is used to authenticate the JWT token
You can retrieve the JWT token from either a referenced service account or a Kubernetes secret.
For example, to retrieve a JWT token from a referenced Kubernetes service account, the following secret store definition can be used:
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: conjur\nspec:\n provider:\n conjur:\n # Service URL\n url: https://myapi.conjur.org\n # [OPTIONAL] base64 encoded string of certificate\n caBundle: OPTIONALxFIELDxxxBase64xCertxString==\n auth:\n jwt:\n # conjur account\n account: conjur\n # The authn-jwt service ID\n serviceID: my-jwt-auth-service\n # Service account to retrieve JWT token for\n serviceAccountRef:\n name: my-service-account\n # [OPTIONAL] audiences to include in JWT token\n audiences:\n - https://conjur.company.com\n
Important
This method is only supported in Kubernetes 1.22 and above as it uses the TokenRequest API to get the JWT token from the referenced service account. Audiences can be defined in the Conjur JWT authenticator.
Alternatively, here is an example where a secret containing a valid JWT token is referenced:
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: conjur\nspec:\n provider:\n conjur:\n # Service URL\n url: https://myapi.conjur.org\n # [OPTIONAL] base64 encoded string of certificate\n caBundle: OPTIONALxFIELDxxxBase64xCertxString==\n auth:\n jwt:\n # conjur account\n account: conjur\n # The authn-jwt service ID\n serviceID: my-jwt-auth-service\n # Secret containing a valid JWT token\n secretRef:\n name: my-jwt-secret\n key: token\n
The JWT token must identify your Conjur host, be compatible with your configured Conjur JWT authenticator, and meet all the Conjur JWT guidelines.
You can use an external JWT issuer or the Kubernetes API server to create the token. For example, a Kubernetes service account token can be created with this command:
kubectl create token my-service-account --audience='https://conjur.company.com' --duration=3600s\n
Save the secret store file as conjur-secret-store.yaml
.
"},{"location":"provider/conjur/#step-2-create-the-external-secrets-store","title":"Step 2: Create the external secrets store","text":"# WARNING: creates the store in the \"external-secrets\" namespace, update the value as needed\n#\nkubectl apply -n external-secrets -f conjur-secret-store.yaml\n\n# WARNING: running the delete command will delete the secret store configuration\n#\n# If there is a need to delete the external secretstore\n# kubectl delete secretstore -n external-secrets conjur\n
"},{"location":"provider/conjur/#define-an-external-secret","title":"Define an external secret","text":"After you have configured the Conjur provider secret store, you can fetch secrets from Conjur.
Here is an example of how to fetch a single secret from Conjur:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: conjur\nspec:\n refreshInterval: 10s\n secretStoreRef:\n # This name must match the metadata.name in the `SecretStore`\n name: conjur\n kind: SecretStore\n data:\n - secretKey: secret00\n remoteRef:\n key: data/app1/secret00\n
Save the external secret file as conjur-external-secret.yaml
.
"},{"location":"provider/conjur/#find-by-name-and-find-by-tag","title":"Find by Name and Find by Tag","text":"The Conjur provider also supports the Find by Name and Find by Tag ESO features. This means that you can use a regular expression or tags to dynamically fetch multiple secrets from Conjur.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: conjur-find-by-name\nspec:\n refreshInterval: 10s\n secretStoreRef:\n # This name must match the metadata.name in the `SecretStore`\n name: conjur\n kind: SecretStore\n target:\n name: k8s-secret-to-be-created\n dataFrom:\n - find:\n # You can use *either* `name` or `tags` to filter the secrets. Here are basic examples of both:\n name:\n # Match all secrets in the app1 namespace (e.g., `app1/secret00`, `app1/secret01`, etc.)\n regexp: \"^app1\\/.+$\"\n tags:\n # Only fetch Conjur secrets with the following annotations\n environment: \"prod\"\n application: \"app1\"\n
If you use these features, we strongly recommend that you limit the permissions of the Conjur host to only the secrets that it needs to access. This is more secure and it reduces the load on both the Conjur server and ESO.
"},{"location":"provider/conjur/#create-the-external-secret","title":"Create the external secret","text":"# WARNING: creates the external-secret in the \"external-secrets\" namespace, update the value as needed\n#\nkubectl apply -n external-secrets -f conjur-external-secret.yaml\n\n# WARNING: running the delete command will delete the external-secrets configuration\n#\n# If there is a need to delete the external secret\n# kubectl delete externalsecret -n external-secrets conjur\n
"},{"location":"provider/conjur/#get-the-k8s-secret","title":"Get the K8s secret","text":" - Log in to your Conjur server and verify that your secret exists
- Review the value of your Kubernetes secret to verify that it contains the same value as the Conjur server
# WARNING: this command will reveal the stored secret in plain text\n#\n# Assuming the secret name is \"secret00\", this will show the value\nkubectl get secret -n external-secrets conjur -o jsonpath=\"{.data.secret00}\" | base64 --decode && echo\n
"},{"location":"provider/conjur/#see-also","title":"See also","text":" - Accelerator-K8s-External-Secrets repo
- Configure Conjur JWT authentication
"},{"location":"provider/conjur/#license","title":"License","text":"Copyright (c) 2023-2024 CyberArk Software Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
"},{"location":"provider/delinea/","title":"Delinea","text":""},{"location":"provider/delinea/#delinea-devops-secrets-vault","title":"Delinea DevOps Secrets Vault","text":"External Secrets Operator integrates with Delinea DevOps Secrets Vault.
Please note that the Delinea Secret Server product is NOT in scope of this integration.
"},{"location":"provider/delinea/#creating-a-secretstore","title":"Creating a SecretStore","text":"You need client ID, client secret and tenant to authenticate with DSV. Both client ID and client secret can be specified either directly in the config, or by referencing a kubernetes secret.
To acquire client ID and client secret, refer to the policy management and client management documentation.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: secret-store\nspec:\n provider:\n delinea:\n tenant: <TENANT>\n tld: <TLD>\n clientId:\n value: <CLIENT_ID>\n clientSecret:\n secretRef:\n name: <NAME_OF_KUBE_SECRET>\n key: <KEY_IN_KUBE_SECRET>\n
Both clientId
and clientSecret
can either be specified directly via the value
field or can reference a kubernetes secret.
The tenant
field must correspond to the host name / site name of your DevOps vault. If you selected a region other than the US you must also specify the TLD, e.g. tld: eu
.
If required, the URL template (urlTemplate
) can be customized as well.
"},{"location":"provider/delinea/#referencing-secrets","title":"Referencing Secrets","text":"Secrets can be referenced by path. Getting a specific version of a secret is not yet supported.
Note that because all DSV secrets are JSON objects, you must specify remoteRef.property
. You can access nested values or arrays using gjson syntax.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: secret\nspec:\n refreshInterval: 20s\n secretStoreRef:\n kind: SecretStore\n name: secret-store\n data:\n - secretKey: <KEY_IN_KUBE_SECRET>\n remoteRef:\n key: <SECRET_PATH>\n property: <JSON_PROPERTY>\n
"},{"location":"provider/doppler/","title":"Doppler","text":""},{"location":"provider/doppler/#doppler-secretops-platform","title":"Doppler SecretOps Platform","text":"Sync secrets from the Doppler SecretOps Platform to Kubernetes using the External Secrets Operator.
"},{"location":"provider/doppler/#authentication","title":"Authentication","text":"Doppler Service Tokens are recommended as they restrict access to a single config.
NOTE: Doppler Personal Tokens are also supported but require project
and config
to be set on the SecretStore
or ClusterSecretStore
.
Create the Doppler Token secret by opening the Doppler dashboard and navigating to the desired Project and Config, then create a new Service Token from the Access tab:
Create the Doppler Token Kubernetes secret with your Service Token value:
HISTIGNORE='*kubectl*' kubectl create secret generic \\\n doppler-token-auth-api \\\n --from-literal dopplerToken=\"dp.st.xxxx\"\n
Then to create a generic SecretStore
:
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: doppler-auth-api\nspec:\n provider:\n doppler:\n auth:\n secretRef:\n dopplerToken:\n name: doppler-token-auth-api\n key: dopplerToken\n
NOTE: In case of a ClusterSecretStore
, be sure to set namespace
in secretRef.dopplerToken
.
"},{"location":"provider/doppler/#use-cases","title":"Use Cases","text":"The Doppler provider allows for a wide range of use cases:
- Fetch
- Fetch all
- Filter
- JSON secret
- Name transformer
- Download
Let's explore each use case using a fictional auth-api
Doppler project.
"},{"location":"provider/doppler/#1-fetch","title":"1. Fetch","text":"To sync one or more individual secrets:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: auth-api-db-url\nspec:\n secretStoreRef:\n kind: SecretStore\n name: doppler-auth-api\n\n target:\n name: auth-api-db-url\n\n data:\n - secretKey: DB_URL\n remoteRef:\n key: DB_URL\n
"},{"location":"provider/doppler/#2-fetch-all","title":"2. Fetch all","text":"To sync every secret from a config:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: auth-api-all\nspec:\n secretStoreRef:\n kind: SecretStore\n name: doppler-auth-api\n\n target:\n name: auth-api-all\n\n dataFrom:\n - find:\n name:\n regexp: .*\n
"},{"location":"provider/doppler/#3-filter","title":"3. Filter","text":"To filter secrets by path
(path prefix), name
(regular expression) or a combination of both:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: auth-api-db\nspec:\n secretStoreRef:\n kind: SecretStore\n name: doppler-auth-api\n\n target:\n name: auth-api-db\n\n dataFrom:\n - find:\n path: DB_\n
"},{"location":"provider/doppler/#4-json-secret","title":"4. JSON secret","text":"To parse a JSON secret to its key-value pairs:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: auth-api-sa-json\nspec:\n secretStoreRef:\n kind: SecretStore\n name: doppler-auth-api\n\n target:\n name: auth-api-sa-json\n\n dataFrom:\n - extract:\n key: SA_JSON\n
"},{"location":"provider/doppler/#5-name-transformer","title":"5. Name transformer","text":"Name transformers format keys from Doppler's UPPER_SNAKE_CASE to one of the following alternatives:
- upper-camel
- camel
- lower-snake
- tf-var
- dotnet-env
- lower-kebab
Name transformers require a specifically configured SecretStore
:
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: doppler-auth-api-dotnet-env\nspec:\n provider:\n doppler:\n auth:\n secretRef:\n dopplerToken:\n name: doppler-token-auth-api\n nameTransformer: dotnet-env\n
Then an ExternalSecret
referencing the SecretStore
:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: doppler-auth-api-dotnet-env\nspec:\n secretStoreRef:\n kind: SecretStore\n name: doppler-auth-api-dotnet-env\n\n target:\n name: doppler-auth-api-dotnet-env\n creationPolicy: Owner\n\n dataFrom:\n - find:\n name:\n regexp: .*\n
"},{"location":"provider/doppler/#6-download","title":"6. Download","text":"A single DOPPLER_SECRETS_FILE
key is set where the value is the secrets downloaded in one of the following formats:
- json
- dotnet-json
- env
- env-no-quotes
- yaml
Downloading secrets requires a specifically configured SecretStore
:
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: doppler-auth-api-json-file\nspec:\n provider:\n doppler:\n auth:\n secretRef:\n dopplerToken:\n name: doppler-token-auth-api\n key: dopplerToken\n format: json\n
Then an ExternalSecret
referencing the SecretStore
:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: auth-api-json-file\nspec:\n secretStoreRef:\n kind: SecretStore\n name: doppler-auth-api-json-file\n\n target:\n name: auth-api-json-file\n\n dataFrom:\n - find:\n path: DOPPLER_SECRETS_FILE\n
"},{"location":"provider/fake/","title":"Fake","text":"We provide a fake
implementation to help with testing. This provider returns static key/value pairs and nothing else. To use the fake
provider simply create a SecretStore
or ClusterSecretStore
and configure it like in the following example:
Note
The provider returns static data configured in value
. You can define a version
, too. If set the remoteRef
from an ExternalSecret must match otherwise no value is returned.
apiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\n name: fake\nspec:\n provider:\n fake:\n data:\n - key: \"/foo/bar\"\n value: \"HELLO1\"\n version: \"v1\"\n - key: \"/foo/bar\"\n value: \"HELLO2\"\n version: \"v2\"\n - key: \"/foo/baz\"\n value: '{\"john\": \"doe\"}'\n version: \"v1\"\n
Please note that value
is intended for exclusive use with data
for dataFrom
. You can use the data
to set a JSON
compliant value to be used as dataFrom
.
Here is an example ExternalSecret
that displays this behavior:
Warning
This provider supports specifying different data[].version
configurations. However, data[].property
is ignored.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: fake\n kind: ClusterSecretStore\n target:\n name: secret-to-be-created\n data:\n - secretKey: foo_bar\n remoteRef:\n key: /foo/bar\n version: v1\n dataFrom:\n - extract:\n key: /foo/baz\n version: v1\n
This results in the following secret:
apiVersion: v1\nkind: Secret\nmetadata:\n name: secret-to-be-created\n namespace: default\ndata:\n foo_bar: SEVMTE8x # HELLO1 (via data)\n john: ZG9l #doe (via dataFrom)\n
"},{"location":"provider/fortanix/","title":"Fortanix","text":""},{"location":"provider/fortanix/#fortanix-dsm-sdkms","title":"Fortanix DSM / SDKMS","text":"Populate kubernetes secrets from OPAQUE or SECRET security objects in Fortanix.
"},{"location":"provider/fortanix/#authentication","title":"Authentication","text":"SDKMS Application API Key
"},{"location":"provider/fortanix/#creating-a-secretstore","title":"Creating a SecretStore","text":"apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: secret-store\nspec:\n provider:\n fortanix:\n apiUrl: <HOST_OF_SDKMS_API>\n apiKey:\n secretRef:\n name: <NAME_OF_KUBE_SECRET>\n key: <KEY_IN_KUBE_SECRET>\n
"},{"location":"provider/fortanix/#referencing-secrets","title":"Referencing Secrets","text":"# Raw stored value\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: secret\nspec:\n refreshInterval: 1h\n secretStoreRef:\n kind: SecretStore\n name: secret-store\n data:\n - secretKey: <KEY_IN_KUBE_SECRET>\n remoteRef:\n key: <SDKMS_SECURITY_OBJECT_NAME>\n---\n# From stored key-value JSON\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: secret-from-property\nspec:\n refreshInterval: 1h\n secretStoreRef:\n kind: SecretStore\n name: secret-store\n data:\n - secretKey: <KEY_IN_KUBE_SECRET>\n remoteRef:\n key: <SDKMS_SECURITY_OBJECT_NAME>\n property: <SECURITY_OBJECT_VALUE_INNER_PROPERTY>\n---\n# Extract all keys from stored key-value JSON\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: secret-from-extract\nspec:\n refreshInterval: 1h\n secretStoreRef:\n kind: SecretStore\n name: secret-store\n dataFrom:\n - extract:\n key: <SDKMS_SECURITY_OBJECT_NAME>\n
"},{"location":"provider/gitlab-variables/","title":"GitLab Variables","text":""},{"location":"provider/gitlab-variables/#gitlab-variables","title":"GitLab Variables","text":"External Secrets Operator integrates with GitLab to sync GitLab Project Variables API and/or GitLab Group Variables API to secrets held on the Kubernetes cluster.
"},{"location":"provider/gitlab-variables/#configuring-gitlab","title":"Configuring GitLab","text":"The GitLab API requires an access token, project ID and/or groupIDs.
To create a new access token, go to your user settings and select 'access tokens'. Give your token a name, expiration date, and select the permissions required (Note 'api' is required).
Click 'Create personal access token', and your token will be generated and displayed on screen. Copy or save this token since you can't access it again.
"},{"location":"provider/gitlab-variables/#access-token-secret","title":"Access Token secret","text":"Create a secret containing your access token:
apiVersion: v1\nkind: Secret\nmetadata:\n name: gitlab-secret\n labels: \n type: gitlab\ntype: Opaque \nstringData:\n token: \"**access token goes here**\"\n
"},{"location":"provider/gitlab-variables/#configuring-the-secret-store","title":"Configuring the secret store","text":"Be sure the gitlab
provider is listed in the Kind=SecretStore
and the ProjectID is set. If you are not using https://gitlab.com
, you must set the url
field as well.
In order to sync group variables inheritFromGroups
must be true or groupIDs
have to be defined.
In case you have defined multiple environments in Gitlab, the secret store should be constrained to a specific environment_scope
.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: gitlab-secret-store\nspec:\n provider:\n # provider type: gitlab\n gitlab:\n # url: https://gitlab.mydomain.com/\n auth:\n SecretRef:\n accessToken:\n name: gitlab-secret\n key: token\n projectID: \"**project ID goes here**\"\n groupIDs: \"**groupID(s) go here**\"\n inheritFromGroups: \"**automatically looks for variables in parent groups**\"\n environment: \"**environment scope goes here**\"\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in accessToken
with the namespace where the secret resides. Your project ID can be found on your project's page.
"},{"location":"provider/gitlab-variables/#creating-external-secret","title":"Creating external secret","text":"To sync a GitLab variable to a secret on the Kubernetes cluster, a Kind=ExternalSecret
is needed.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: gitlab-external-secret-example\nspec:\n refreshInterval: 1h\n\n secretStoreRef:\n kind: SecretStore\n name: gitlab-secret-store # Must match SecretStore on the cluster\n\n target:\n name: gitlab-secret-to-create # Name for the secret to be created on the cluster\n creationPolicy: Owner\n\n data:\n - secretKey: secretKey # Key given to the secret to be created on the cluster\n remoteRef: \n key: myGitlabVariable # Key of the variable on Gitlab\n
"},{"location":"provider/gitlab-variables/#using-datafrom","title":"Using DataFrom","text":"DataFrom can be used to get a variable as a JSON string and attempt to parse it.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: gitlab-external-secret-example\nspec:\n refreshInterval: 1h\n\n secretStoreRef:\n kind: SecretStore\n name: gitlab-secret-store # Must match SecretStore on the cluster\n\n target:\n name: gitlab-secret-to-create # Name for the secret to be created on the cluster\n creationPolicy: Owner\n\n # each secret name in the KV will be used as the secret key in the SECRET k8s target object\n dataFrom:\n - extract:\n key: \"myJsonVariable\" # Key of the variable on Gitlab\n
"},{"location":"provider/gitlab-variables/#getting-the-kubernetes-secret","title":"Getting the Kubernetes secret","text":"The operator will fetch the project variable and inject it as a Kind=Secret
.
kubectl get secret gitlab-secret-to-create -o jsonpath='{.data.secretKey}' | base64 -d\n
"},{"location":"provider/google-secrets-manager/","title":"Google Cloud Secret Manager","text":""},{"location":"provider/google-secrets-manager/#google-cloud-secret-manager","title":"Google Cloud Secret Manager","text":"External Secrets Operator integrates with GCP Secret Manager for secret management.
"},{"location":"provider/google-secrets-manager/#authentication","title":"Authentication","text":""},{"location":"provider/google-secrets-manager/#workload-identity","title":"Workload Identity","text":"Your Google Kubernetes Engine (GKE) applications can consume GCP services like Secrets Manager without using static, long-lived authentication tokens. This is our recommended approach of handling credentials in GCP. ESO offers two options for integrating with GKE workload identity: pod-based workload identity and using service accounts directly. Before using either way you need to create a service account - this is covered below.
"},{"location":"provider/google-secrets-manager/#creating-workload-identity-service-accounts","title":"Creating Workload Identity Service Accounts","text":"You can find the documentation for Workload Identity here. We will walk you through how to navigate it here.
Search the document for this editable values and change them to your values: Note: If you have installed ESO, a serviceaccount has already been created. You can either patch the existing external-secrets
SA or create a new one that fits your needs.
CLUSTER_NAME
: The name of your cluster PROJECT_ID
: Your project ID (not your Project number nor your Project name) K8S_NAMESPACE
: For us following these steps here it will be es
, but this will be the namespace where you deployed the external-secrets operator KSA_NAME
: external-secrets (if you are not creating a new one to attach to the deployment) GSA_NAME
: external-secrets for simplicity, or something else if you have to follow different naming conventions for cloud resources ROLE_NAME
: should be roles/secretmanager.secretAccessor
- so you make the pod only be able to access secrets on Secret Manager
"},{"location":"provider/google-secrets-manager/#using-service-accounts-directly","title":"Using Service Accounts directly","text":"Let's assume you have created a service account correctly and attached a appropriate workload identity. It should roughly look like this:
apiVersion: v1\nkind: ServiceAccount\nmetadata:\n name: external-secrets\n namespace: es\n annotations:\n iam.gke.io/gcp-service-account: example-team-a@my-project.iam.gserviceaccount.com\n
You can reference this particular ServiceAccount in a SecretStore
or ClusterSecretStore
. It's important that you also set the projectID
, clusterLocation
and clusterName
. The Namespace on the serviceAccountRef
is ignored when using a SecretStore
resource. This is needed to isolate the namespaces properly.
When filling clusterLocation
parameter keep in mind if it is Regional or Zonal cluster.
apiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\n name: gcp-store\nspec:\n provider:\n gcpsm:\n projectID: alphabet-123\n auth:\n workloadIdentity:\n # name of the cluster Location, region or zone\n clusterLocation: europe-central2\n # name of the GKE cluster\n clusterName: alpha-cluster-42\n # projectID of the cluster (if omitted defaults to spec.provider.gcpsm.projectID)\n clusterProjectID: my-cluster-project\n # reference the sa from above\n serviceAccountRef:\n name: team-a\n namespace: team-a\n
You need to give the Google service account the roles/iam.serviceAccountTokenCreator
role so it can generate a service account token for you (not necessary in the Pod-based Workload Identity bellow)
"},{"location":"provider/google-secrets-manager/#using-pod-based-workload-identity","title":"Using Pod-based Workload Identity","text":"You can attach a Workload Identity directly to the ESO pod. ESO then has access to all the APIs defined in the attached service account policy. You attach the workload identity by (1) creating a service account with a attached workload identity (described above) and (2) using this particular service account in the pod's serviceAccountName
field.
For this example we will assume that you installed ESO using helm and that you named the chart installation external-secrets
and the namespace where it lives es
like:
helm install external-secrets external-secrets/external-secrets --namespace es\n
Then most of the resources would have this name, the important one here being the k8s service account attached to the external-secrets operator deployment:
# ...\n containers:\n - image: ghcr.io/external-secrets/external-secrets:vVERSION\n name: external-secrets\n ports:\n - containerPort: 8080\n protocol: TCP\n restartPolicy: Always\n schedulerName: default-scheduler\n serviceAccount: external-secrets\n serviceAccountName: external-secrets # <--- here\n
The pod now has the identity. Now you need to configure the SecretStore
. You just need to set the projectID
, all other fields can be omitted.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: gcp-store\nspec:\n provider:\n gcpsm:\n projectID: alphabet-123\n
"},{"location":"provider/google-secrets-manager/#gcp-service-account-authentication","title":"GCP Service Account authentication","text":"You can use GCP Service Account to authenticate with GCP. These are static, long-lived credentials. A GCP Service Account is a JSON file that needs to be stored in a Kind=Secret
. ESO will use that Secret to authenticate with GCP. See here how you manage GCP Service Accounts. After creating a GCP Service account go to IAM & Admin
web UI, click ADD ANOTHER ROLE
button, add Secret Manager Secret Accessor
role to this service account. The Secret Manager Secret Accessor
role is required to access secrets.
apiVersion: v1\nkind: Secret\nmetadata:\n name: gcpsm-secret\n labels:\n type: gcpsm\ntype: Opaque\nstringData:\n secret-access-credentials: |-\n {\n \"type\": \"service_account\",\n \"project_id\": \"external-secrets-operator\",\n \"private_key_id\": \"\",\n \"private_key\": \"-----BEGIN PRIVATE KEY-----\\nA key\\n-----END PRIVATE KEY-----\\n\",\n \"client_email\": \"test-service-account@external-secrets-operator.iam.gserviceaccount.com\",\n \"client_id\": \"client ID\",\n \"auth_uri\": \"https://accounts.google.com/o/oauth2/auth\",\n \"token_uri\": \"https://oauth2.googleapis.com/token\",\n \"auth_provider_x509_cert_url\": \"https://www.googleapis.com/oauth2/v1/certs\",\n \"client_x509_cert_url\": \"https://www.googleapis.com/robot/v1/metadata/x509/test-service-account%40external-secrets-operator.iam.gserviceaccount.com\"\n }\n
"},{"location":"provider/google-secrets-manager/#update-secret-store","title":"Update secret store","text":"Be sure the gcpsm
provider is listed in the Kind=SecretStore
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: gcp-store\n namespace: example\nspec:\n provider:\n gcpsm: # gcpsm provider\n auth:\n secretRef:\n secretAccessKeySecretRef:\n name: gcpsm-secret # secret name containing SA key\n key: secret-access-credentials # key name containing SA key\n projectID: alphabet-123 # name of Google Cloud project\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
for SecretAccessKeyRef
with the namespace of the secret that we just created.
"},{"location":"provider/google-secrets-manager/#creating-external-secret","title":"Creating external secret","text":"To create a kubernetes secret from the GCP Secret Manager secret a Kind=ExternalSecret
is needed.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: database-credentials\nspec:\n refreshInterval: 1h # rate SecretManager pulls GCPSM\n secretStoreRef:\n kind: SecretStore\n name: gcp-store # name of the SecretStore (or kind specified)\n target:\n name: database-credentials # name of the k8s Secret to be created\n creationPolicy: Owner\n data:\n - secretKey: database_username\n remoteRef:\n key: database_username # name of the GCPSM secret key\n - secretKey: database_password\n remoteRef:\n key: database_password # name of the GCPSM secret key\n
The operator will fetch the GCP Secret Manager secret and inject it as a Kind=Secret
kubectl get secret secret-to-be-created -n <namespace> -o jsonpath='{.data.dev-secret-test}' | base64 -d\n
"},{"location":"provider/hashicorp-vault/","title":"HashiCorp Vault","text":""},{"location":"provider/hashicorp-vault/#hashicorp-vault","title":"Hashicorp Vault","text":"External Secrets Operator integrates with HashiCorp Vault for secret management.
The KV Secrets Engine is the only one supported by this provider. For other secrets engines, please refer to the Vault Generator.
"},{"location":"provider/hashicorp-vault/#example","title":"Example","text":"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\nkind: SecretStore\nmetadata:\n name: vault-backend\nspec:\n provider:\n vault:\n server: \"http://my.vault.server:8200\"\n path: \"secret\"\n # Version is the Vault KV secret engine version.\n # This can be either \"v1\" or \"v2\", defaults to \"v2\"\n version: \"v2\"\n auth:\n # points to a secret that contains a vault token\n # https://www.vaultproject.io/docs/auth/token\n tokenSecretRef:\n name: \"vault-token\"\n key: \"token\"\n---\napiVersion: v1\nkind: Secret\nmetadata:\n name: vault-token\ndata:\n token: cm9vdA== # \"root\"\n
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\n
Can check kv version using following and check for Options
column, it should indicate [version:2]:
vault secrets list -detailed\n
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\nkind: ExternalSecret\nmetadata:\n name: vault-example\nspec:\n refreshInterval: \"15s\"\n secretStoreRef:\n name: vault-backend\n kind: SecretStore\n target:\n name: example-sync\n data:\n - secretKey: foobar\n remoteRef:\n key: foo\n property: my-value\n\n # metadataPolicy to fetch all the labels in JSON format\n - secretKey: tags\n remoteRef:\n metadataPolicy: Fetch\n key: foo\n\n # metadataPolicy to fetch a specific label (dev) from the source secret\n - secretKey: developer\n remoteRef:\n metadataPolicy: Fetch\n key: foo\n property: dev\n\n---\n# will create a secret with:\nkind: Secret\nmetadata:\n name: example-sync\ndata:\n foobar: czNjcjN0\n
Keep in mind that fetching the labels with metadataPolicy: Fetch
only works with KV sercrets engine version v2.
"},{"location":"provider/hashicorp-vault/#fetching-raw-values","title":"Fetching Raw Values","text":"You can fetch all key/value pairs for a given path If you leave the remoteRef.property
empty. This returns the json-encoded secret value for that path.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: vault-example\nspec:\n # ...\n data:\n - secretKey: foobar\n remoteRef:\n key: /dev/package.json\n
"},{"location":"provider/hashicorp-vault/#nested-values","title":"Nested Values","text":"Vault supports nested key/value pairs. You can specify a gjson expression at remoteRef.property
to get a nested value.
Given the following secret - assume its path is /dev/config
:
{\n \"foo\": {\n \"nested\": {\n \"bar\": \"mysecret\"\n }\n }\n}\n
You can set the remoteRef.property
to point to the nested key using a gjson expression.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: vault-example\nspec:\n # ...\n data:\n - secretKey: foobar\n remoteRef:\n key: /dev/config\n property: foo.nested.bar\n---\n# creates a secret with:\n# foobar=mysecret\n
If you would set the remoteRef.property
to just foo
then you would get the json-encoded value of that property: {\"nested\":{\"bar\":\"mysecret\"}}
.
"},{"location":"provider/hashicorp-vault/#multiple-nested-values","title":"Multiple nested Values","text":"You can extract multiple keys from a nested secret using dataFrom
.
Given the following secret - assume its path is /dev/config
:
{\n \"foo\": {\n \"nested\": {\n \"bar\": \"mysecret\",\n \"baz\": \"bang\"\n }\n }\n}\n
You can set the remoteRef.property
to point to the nested key using a gjson expression.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: vault-example\nspec:\n # ...\n dataFrom:\n - extract:\n key: /dev/config\n property: foo.nested\n
That results in a secret with these values:
bar=mysecret\nbaz=bang\n
"},{"location":"provider/hashicorp-vault/#getting-multiple-secrets","title":"Getting multiple secrets","text":"You can extract multiple secrets from Hashicorp vault by using dataFrom.Find
Currently, dataFrom.Find
allows users to fetch secret names that match a given regexp pattern, or fetch secrets whose custom_metadata
tags match a predefined set.
Warning
The way hashicorp Vault currently allows LIST operations is through the existence of a secret metadata. If you delete the secret, you will also need to delete the secret's metadata or this will currently make Find operations fail.
Given the following secret - assume its path is /dev/config
:
{\n \"foo\": {\n \"nested\": {\n \"bar\": \"mysecret\",\n \"baz\": \"bang\"\n }\n }\n}\n
Also consider the following secret has the following custom_metadata
:
{\n \"environment\": \"dev\",\n \"component\": \"app-1\"\n}\n
It is possible to find this secret by all the following possibilities:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: vault-example\nspec:\n # ...\n dataFrom:\n - find: #will return every secret with 'dev' in it (including paths)\n name:\n regexp: dev\n - find: #will return every secret matching environment:dev tags from dev/ folder and beyond\n tags:\n environment: dev\n
will generate a secret with: {\n \"dev_config\":\"{\\\"foo\\\":{\\\"nested\\\":{\\\"bar\\\":\\\"mysecret\\\",\\\"baz\\\":\\\"bang\\\"}}}\"\n}\n
Currently, Find
operations are recursive throughout a given vault folder, starting on provider.Path
definition. It is recommended to narrow down the scope of search by setting a find.path
variable. This is also useful to automatically reduce the resulting secret key names:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: vault-example\nspec:\n # ...\n dataFrom:\n - find: #will return every secret from dev/ folder\n path: dev\n name:\n regexp: \".*\"\n - find: #will return every secret matching environment:dev tags from dev/ folder\n path: dev\n tags:\n environment: dev\n
Will generate a secret with: {\n \"config\":\"{\\\"foo\\\": {\\\"nested\\\": {\\\"bar\\\": \\\"mysecret\\\",\\\"baz\\\": \\\"bang\\\"}}}\"\n}\n
"},{"location":"provider/hashicorp-vault/#authentication","title":"Authentication","text":"We support five different modes for authentication: token-based, appRole, kubernetes-native, ldap, userPass, jwt/oidc, awsAuth and tlsCert, each one comes with it's own trade-offs. Depending on the authentication method you need to adapt your environment.
If you're using Vault namespaces, you can authenticate into one namespace and use the vault token against a different namespace, if desired.
"},{"location":"provider/hashicorp-vault/#token-based-authentication","title":"Token-based authentication","text":"A static token is stored in a Kind=Secret
and is used to authenticate with vault.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: vault-backend\n namespace: example\nspec:\n provider:\n vault:\n server: \"https://vault.acme.org\"\n path: \"secret\"\n version: \"v2\"\n auth:\n # points to a secret that contains a vault token\n # https://www.vaultproject.io/docs/auth/token\n tokenSecretRef:\n name: \"my-secret\"\n key: \"vault-token\"\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in tokenSecretRef
with the namespace where the secret resides."},{"location":"provider/hashicorp-vault/#approle-authentication-example","title":"AppRole authentication example","text":"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/v1beta1\nkind: SecretStore\nmetadata:\n name: vault-backend\n namespace: example\nspec:\n provider:\n vault:\n server: \"https://vault.acme.org\"\n path: \"secret\"\n version: \"v2\"\n auth:\n # VaultAppRole authenticates with Vault using the\n # App Role auth mechanism\n # https://www.vaultproject.io/docs/auth/approle\n appRole:\n # Path where the App Role authentication backend is mounted\n path: \"approle\"\n # RoleID configured in the App Role authentication backend\n roleId: \"db02de05-fa39-4855-059b-67221c5c2f63\"\n # Reference to a key in a K8 Secret that contains the App Role SecretId\n secretRef:\n name: \"my-secret\"\n key: \"secret-id\"\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in secretRef
with the namespace where the secret resides."},{"location":"provider/hashicorp-vault/#kubernetes-authentication","title":"Kubernetes authentication","text":"Kubernetes-native authentication has three options of obtaining credentials for vault:
- by using a service account jwt referenced in
serviceAccountRef
- by using the jwt from a
Kind=Secret
referenced by the secretRef
- by using transient credentials from the mounted service account token within the external-secrets operator
Vault validates the service account token by using the TokenReview API. \u26a0\ufe0f You have to bind the system:auth-delegator
ClusterRole to the service account that is used for authentication. Please follow the Vault documentation.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: vault-backend\n namespace: example\nspec:\n provider:\n vault:\n server: \"https://vault.acme.org\"\n path: \"secret\"\n version: \"v2\"\n auth:\n # Authenticate against Vault using a Kubernetes ServiceAccount\n # token stored in a Secret.\n # https://www.vaultproject.io/docs/auth/kubernetes\n kubernetes:\n # Path where the Kubernetes authentication backend is mounted in Vault\n mountPath: \"kubernetes\"\n # A required field containing the Vault Role to assume.\n role: \"demo\"\n # Optional service account field containing the name\n # of a kubernetes ServiceAccount\n serviceAccountRef:\n name: \"my-sa\"\n # Optional secret field containing a Kubernetes ServiceAccount JWT\n # used for authenticating with Vault\n secretRef:\n name: \"my-secret\"\n key: \"vault\"\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in serviceAccountRef
or in secretRef
, if used."},{"location":"provider/hashicorp-vault/#ldap-authentication","title":"LDAP authentication","text":"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/v1beta1\nkind: SecretStore\nmetadata:\n name: vault-backend\n namespace: example\nspec:\n provider:\n vault:\n server: \"https://vault.acme.org\"\n path: \"secret\"\n version: \"v2\"\n auth:\n # VaultLdap authenticates with Vault using the LDAP auth mechanism\n # https://www.vaultproject.io/docs/auth/ldap\n ldap:\n # Path where the LDAP authentication backend is mounted\n path: \"ldap\"\n # LDAP username\n username: \"username\"\n secretRef:\n name: \"my-secret\"\n key: \"ldap-password\"\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in secretRef
with the namespace where the secret resides."},{"location":"provider/hashicorp-vault/#userpass-authentication","title":"UserPass authentication","text":"UserPass 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/v1beta1\nkind: SecretStore\nmetadata:\n name: vault-backend\n namespace: example\nspec:\n provider:\n vault:\n server: \"https://vault.acme.org\"\n path: \"secret\"\n version: \"v2\"\n auth:\n # VaultUserPass authenticates with Vault using the UserPass auth mechanism\n # https://www.vaultproject.io/docs/auth/userpass\n userPass:\n # Path where the UserPass authentication backend is mounted\n path: \"userpass\"\n username: \"username\"\n secretRef:\n name: \"my-secret\"\n key: \"password\"\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in secretRef
with the namespace where the secret resides."},{"location":"provider/hashicorp-vault/#jwtoidc-authentication","title":"JWT/OIDC authentication","text":"JWT/OIDC uses either a JWT token stored in a Kind=Secret
and referenced by the secretRef
or a temporary Kubernetes service account token retrieved via the TokenRequest
API. Optionally a role
field can be defined in a Kind=SecretStore
or Kind=ClusterSecretStore
resource.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: vault-backend\n namespace: example\nspec:\n provider:\n vault:\n server: \"https://vault.acme.org\"\n path: \"secret\"\n version: \"v2\"\n auth:\n # VaultJwt authenticates with Vault using the JWT/OIDC auth mechanism\n # https://www.vaultproject.io/docs/auth/jwt\n jwt:\n # Path where the JWT authentication backend is mounted\n path: \"jwt\"\n # JWT role configured in a Vault server, optional.\n role: \"vault-jwt-role\"\n\n # Retrieve JWT token from a Kubernetes secret\n secretRef:\n name: \"my-secret\"\n key: \"jwt-token\"\n\n # ... or retrieve a Kubernetes service account token via the `TokenRequest` API\n kubernetesServiceAccountToken:\n serviceAccountRef:\n name: \"my-sa\"\n # `audiences` defaults to `[\"vault\"]` it not supplied\n audiences:\n - vault\n # `expirationSeconds` defaults to 10 minutes if not supplied\n expirationSeconds: 600\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in secretRef
with the namespace where the secret resides."},{"location":"provider/hashicorp-vault/#aws-iam-authentication","title":"AWS IAM authentication","text":"AWS IAM uses either a set of AWS Programmatic access credentials stored in a Kind=Secret
and referenced by the secretRef
or by getting the authentication token from an IRSA enabled service account
"},{"location":"provider/hashicorp-vault/#tls-certificates-authentication","title":"TLS certificates authentication","text":"TLS certificates auth method allows authentication using SSL/TLS client certificates which are either signed by a CA or self-signed. SSL/TLS client certificates are defined as having an ExtKeyUsage extension with the usage set to either ClientAuth or Any.
"},{"location":"provider/hashicorp-vault/#mutual-authentication-mtls","title":"Mutual authentication (mTLS)","text":"Under specific compliance requirements, the Vault server can be set up to enforce mutual authentication from clients across all APIs by configuring the server with tls_require_and_verify_client_cert = true
. This configuration differs fundamentally from the TLS certificates auth method. While the TLS certificates auth method allows the issuance of a Vault token through the /v1/auth/cert/login
API, the mTLS configuration solely focuses on TLS transport layer authentication and lacks any authorization-related capabilities. It's important to note that the Vault token must still be included in the request, following any of the supported authentication methods mentioned earlier.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: vault-backend\n namespace: example\nspec:\n provider:\n vault:\n server: \"https://vault.acme.org\"\n path: \"secret\"\n version: \"v2\"\n\n # client TLS related configuration\n caBundle: \"...\"\n tls:\n clientCert:\n name: \"my-cert-secret\"\n key: \"tls.crt\"\n secretRef:\n name: \"my-cert-secret\"\n key: \"tls.key\"\n\n # the authentication methods are not really related to the client TLS configuration\n auth:\n ...\n
"},{"location":"provider/hashicorp-vault/#access-key-id-secret-access-key","title":"Access Key ID & Secret Access Key","text":"You can store Access Key ID & Secret Access Key in a Kind=Secret
and reference it from a SecretStore.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: vault-backend-aws-iam\nspec:\n provider:\n vault:\n server: \"http://my.vault.server:8200\"\n path: secret\n version: v2\n namespace: <vault_namespace>\n auth:\n iam:\n # Path where the AWS auth method is enabled in Vault, e.g: \"aws/\". Defaults to aws\n path: aws\n # AWS Region. Defaults to us-east-1\n region: us-east-1\n # optional: assume role before fetching secrets\n role: arn:aws:iam::1234567890:role/role-a\n # Vault Role. In vault, a role describes an identity with a set of permissions, groups, or policies you want to attach a user of the secrets engine\n vaultRole: vault-role-for-aws-iam-auth\n # Optional. Placeholder to supply header X-Vault-AWS-IAM-Server-ID. It is an additional (optional) header used by Vault IAM auth method to mitigate against different types of replay attacks. More details here: https://developer.hashicorp.com/vault/docs/auth/aws\n vaultAwsIamServerID: example-vaultAwsIamServerID\n secretRef: #Use this method when you have static AWS creds.\n accessKeyIDSecretRef:\n name: vault-iam-creds-secret\n key: access-key\n secretAccessKeySecretRef:\n name: vault-iam-creds-secret\n key: secret-access-key\n sessionTokenSecretRef:\n name: vault-iam-creds-secret\n key: secret-session-token\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in accessKeyIDSecretRef
, secretAccessKeySecretRef
with the namespaces where the secrets reside.
"},{"location":"provider/hashicorp-vault/#eks-service-account-credentials","title":"EKS Service Account credentials","text":"This feature lets you use short-lived service account tokens to authenticate with AWS. You must have Service Account Volume Projection enabled - it is by default on EKS. See EKS guide on how to set up IAM roles for service accounts.
The big advantage of this approach is that ESO runs without any credentials.
apiVersion: v1\nkind: ServiceAccount\nmetadata:\n annotations:\n eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/my-irsa-enabled-role\n name: my-serviceaccount\n namespace: default\n
Reference the service account from above in the Secret Store:
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: vault-backend-aws-iam\nspec:\n provider:\n vault:\n server: \"http://my.vault.server:8200\"\n path: secret\n version: v2\n namespace: <vault_namespace>\n auth:\n iam:\n # Path where the AWS auth method is enabled in Vault, e.g: \"aws/\". Defaults to aws\n path: aws\n # AWS Region. Defaults to us-east-1\n region: us-east-1\n # Vault Role. In vault, a role describes an identity with a set of permissions, groups, or policies you want to attach a user of the secrets engine\n vaultRole: vault-role-for-aws-iam-auth\n # Optional. Placeholder to supply header X-Vault-AWS-IAM-Server-ID. It is an additional (optional) header used by Vault IAM auth method to mitigate against different types of replay attacks. More details here: https://developer.hashicorp.com/vault/docs/auth/aws\n vaultAwsIamServerID: example-vaultAwsIamServerID\n jwt:\n serviceAccountRef:\n name: my-serviceaccount #Provide service account with IRSA enabled\n
"},{"location":"provider/hashicorp-vault/#controllers-pod-identity","title":"Controller's Pod Identity","text":"This is basicially a zero-configuration authentication approach that inherits the credentials from the controller's pod identity
This approach assumes that appropriate IRSA setup is done controller's pod (i.e. IRSA enabled IAM role is created appropriately and controller's service account is annotated appropriately with the annotation \"eks.amazonaws.com/role-arn\" to enable IRSA)
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: vault-backend-aws-iam\nspec:\n provider:\n vault:\n server: \"http://my.vault.server:8200\"\n path: secret\n version: v2\n namespace: <vault_namespace>\n auth:\n iam:\n # Path where the AWS auth method is enabled in Vault, e.g: \"aws/\". Defaults to aws\n path: aws\n # AWS Region. Defaults to us-east-1\n region: us-east-1\n # Vault Role. In vault, a role describes an identity with a set of permissions, groups, or policies you want to attach a user of the secrets engine\n vaultRole: vault-role-for-aws-iam-auth\n # Optional. Placeholder to supply header X-Vault-AWS-IAM-Server-ID. It is an additional (optional) header used by Vault IAM auth method to mitigate against different types of replay attacks. More details here: https://developer.hashicorp.com/vault/docs/auth/aws\n vaultAwsIamServerID: example-vaultAwsIamServerID\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
for serviceAccountRef
with the namespace where the service account resides.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: vault-backend\n namespace: example\nspec:\n provider:\n vault:\n server: \"https://vault.acme.org\"\n path: \"secret\"\n version: \"v2\"\n auth:\n # VaultJwt authenticates with Vault using the JWT/OIDC auth mechanism\n # https://www.vaultproject.io/docs/auth/jwt\n jwt:\n # Path where the JWT authentication backend is mounted\n path: \"jwt\"\n # JWT role configured in a Vault server, optional.\n role: \"vault-jwt-role\"\n\n # Retrieve JWT token from a Kubernetes secret\n secretRef:\n name: \"my-secret\"\n key: \"jwt-token\"\n\n # ... or retrieve a Kubernetes service account token via the `TokenRequest` API\n kubernetesServiceAccountToken:\n serviceAccountRef:\n name: \"my-sa\"\n # `audiences` defaults to `[\"vault\"]` it not supplied\n audiences:\n - vault\n # `expirationSeconds` defaults to 10 minutes if not supplied\n expirationSeconds: 600\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in secretRef
with the namespace where the secret resides."},{"location":"provider/hashicorp-vault/#pushsecret","title":"PushSecret","text":"Vault supports PushSecret features which allow you to sync a given Kubernetes secret key into a Hashicorp vault secret. To do so, it is expected that the secret key is a valid JSON object or that the property
attribute has been specified under the remoteRef
. To use PushSecret, you need to give create
, read
and update
permissions to the path where you want to push secrets for both data
and metadata
of the secret. Use it with care!
Note
Since Vault KV v1 API is not supported with storing secrets metadata, PushSecret will add a custom_metadata
map to each secret in Vault that he will manage. It means pushing secret keys named custom_metadata
is not supported with Vault KV v1.
Here is an example of how to set up PushSecret
:
apiVersion: v1\nkind: Secret\nmetadata:\n name: source-secret\n namespace: default\nstringData:\n source-key1: \"{\\\"foo\\\":\\\"bar\\\"}\" # Needs to be a JSON\n source-key2: bar # Could be a plain string\n---\napiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\n name: pushsecret-example\n namespace: default\nspec:\n refreshInterval: 10s\n secretStoreRefs:\n - name: vault-secretstore\n kind: SecretStore\n selector:\n secret:\n name: source-secret\n data:\n - match:\n secretKey: source-key1\n remoteRef:\n remoteKey: vault/secret1\n - match:\n secretKey: source-key2\n remoteRef:\n remoteKey: vault/secret2\n property: foo\n
Note that in this example, we are generating two secrets in the target vault with the same structure but using different input formats.
"},{"location":"provider/hashicorp-vault/#vault-enterprise","title":"Vault Enterprise","text":""},{"location":"provider/hashicorp-vault/#eventual-consistency-and-performance-standby-nodes","title":"Eventual Consistency and Performance Standby Nodes","text":"When using Vault Enterprise with performance standby nodes, any follower can handle read requests immediately after the provider has authenticated. Since Vault becomes eventually consistent in this mode, these requests can fail if the login has not yet propagated to each server's local state.
Below are two different solutions to this scenario. You'll need to review them and pick the best fit for your environment and Vault configuration.
"},{"location":"provider/hashicorp-vault/#vault-namespaces","title":"Vault Namespaces","text":"Vault namespaces are an enterprise feature that support multi-tenancy. You can specify a vault namespace using the namespace
property when you define a SecretStore:
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: vault-backend\nspec:\n provider:\n vault:\n server: \"http://my.vault.server:8200\"\n # See https://www.vaultproject.io/docs/enterprise/namespaces\n namespace: \"ns1\"\n path: \"secret\"\n version: \"v2\"\n auth:\n # ...\n
"},{"location":"provider/hashicorp-vault/#authenticating-into-a-different-namespace","title":"Authenticating into a different namespace","text":"In some situations your authentication backend may be in one namespace, and your secrets in another. You can authenticate into one namespace, and use that token against another, by setting provider.vault.namespace
and provider.vault.auth.namespace
to different values. If provider.vault.auth.namespace
is unset but provider.vault.namespace
is, it will default to the provider.vault.namespace
value.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: vault-backend\nspec:\n provider:\n vault:\n server: \"http://my.vault.server:8200\"\n # See https://www.vaultproject.io/docs/enterprise/namespaces\n namespace: \"app-team\"\n path: \"secret\"\n version: \"v2\"\n auth:\n namespace: \"kubernetes-team\"\n # ...\n
"},{"location":"provider/hashicorp-vault/#read-your-writes","title":"Read Your Writes","text":"Vault 1.10.0 and later encodes information in the token to detect the case when a server is behind. If a Vault server does not have information about the provided token, Vault returns a 412 error so clients know to retry.
A method supported in versions Vault 1.7 and later is to utilize the X-Vault-Index
header returned on all write requests (including logins). Passing this header back on subsequent requests instructs the Vault client to retry the request until the server has an index greater than or equal to that returned with the last write. Obviously though, this has a performance hit because the read is blocked until the follower's local state has caught up.
"},{"location":"provider/hashicorp-vault/#forward-inconsistent","title":"Forward Inconsistent","text":"Vault also supports proxying inconsistent requests to the current cluster leader for immediate read-after-write consistency.
Vault 1.10.0 and later support a replication configuration that detects when forwarding should occur and does it transparently to the client.
In Vault 1.7 forwarding can be achieved by setting the X-Vault-Inconsistent
header to forward-active-node
. By default, this behavior is disabled and must be explicitly enabled in the server's replication configuration.
"},{"location":"provider/ibm-secrets-manager/","title":"IBM Secrets Manager","text":""},{"location":"provider/ibm-secrets-manager/#ibm-cloud-secret-manager","title":"IBM Cloud Secret Manager","text":"External Secrets Operator integrates with IBM Cloud Secret Manager for secret management.
"},{"location":"provider/ibm-secrets-manager/#authentication","title":"Authentication","text":"We support API key and trusted profile container authentication for this provider.
"},{"location":"provider/ibm-secrets-manager/#api-key-secret","title":"API key secret","text":"To generate your key (for test purposes we are going to generate from your user), first got to your (Access IAM) page:
On the left, click \"API Keys\", then click on \"Create\"
Pick a name and description for your key:
You have created a key. Press the eyeball to show the key. Copy or save it because keys can't be displayed or downloaded twice.
Create a secret containing your apiKey:
kubectl create secret generic ibm-secret --from-literal=apiKey='API_KEY_VALUE'\n
"},{"location":"provider/ibm-secrets-manager/#trusted-profile-container-auth","title":"Trusted Profile Container Auth","text":"To create the trusted profile, first got to your (Access IAM) page:
On the left, click \"Access groups\":
Pick a name and description for your group:
Click on \"Access\", and then on \"Assign\":
Click on \"Assign Access\", select \"IAM services\", and pick \"Secrets Manager\" from the pick-list:
Scope to \"All resources\" or \"Resources based on selected attributes\":
Select the \"SecretsReader\" service access policy:
Click \"Add\" and \"Assign\" to save the access group.
Next, on the left, click \"Trusted profiles\":
Press \"Create\" and pick a name and description for your profile:
Scope the profile's access.
The compute service type will be \"Red Hat OpenShift on IBM Cloud\". Additional restriction can be configured based on cloud or cluster metadata, or if \"Specific resources\" is selected, restriction to a specific cluster.
Click \"Add\" next to the previously created access group and then \"Create\", to associate the necessary service permissions.
To use the container-based authentication, it is necessary to map the API server serviceAccountToken
auth token to the \"external-secrets\" and \"external-secrets-webhook\" deployment descriptors. Example below:
...\nspec:\n ...\n template:\n ...\n spec:\n containers:\n ...\n volumeMounts:\n - mountPath: /var/run/secrets/tokens\n name: sa-token\n ...\n volumes:\n - name: sa-token\n projected:\n defaultMode: 420\n sources:\n - serviceAccountToken:\n audience: iam\n expirationSeconds: 3600\n path: sa-token\n...\n
"},{"location":"provider/ibm-secrets-manager/#update-secret-store","title":"Update secret store","text":"Be sure the ibm
provider is listed in the Kind=SecretStore
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: ibm-store\nspec:\n provider:\n ibm:\n serviceUrl: \"https://<SECRETS_MANAGER_ID>.<REGION>.secrets-manager.appdomain.cloud\"\n auth:\n containerAuth:\n profile: \"test container auth profile\"\n tokenLocation: \"/var/run/secrets/tokens/sa-token\"\n iamEndpoint: \"https://iam.cloud.ibm.com\"\n secretRef:\n secretApiKeySecretRef:\n name: ibm-secret\n key: apiKey\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in secretApiKeySecretRef
with the namespace where the secret resides. NOTE: Only secretApiKeySecretRef
or containerAuth
should be specified, depending on authentication method being used.
To find your serviceURL
, under your Secrets Manager resource, go to \"Endpoints\" on the left.
See here for a list of publicly available endpoints.
"},{"location":"provider/ibm-secrets-manager/#secret-types","title":"Secret Types","text":"We support the following secret types of IBM Secrets Manager:
arbitrary
username_password
iam_credentials
service_credentials
imported_cert
public_cert
private_cert
kv
To define the type of secret you would like to sync you need to prefix the secret id with the desired type. If the secret type is not specified it is defaulted to arbitrary
:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: ibm-sample\nspec:\n # [...]\n data:\n - secretKey: test\n remoteRef:\n # defaults to type=arbitrary\n key: xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n - secretKey: usr_pass\n remoteRef:\n key: username_password/yyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy\n property: username\n - secretKey: iam_cred\n remoteRef:\n key: iam_credentials/zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz\n - secretKey: srv_cred\n remoteRef:\n key: service_credentials/zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz\n - secretKey: imp_cert\n remoteRef:\n key: imported_cert/zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz\n property: certificate\n - secretKey: pub_cert\n remoteRef:\n key: public_cert/zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz\n property: certificate\n - secretKey: prvt_cert\n remoteRef:\n key: private_cert/zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz\n property: certificate\n - secretKey: kv_without_key\n remoteRef:\n key: kv/zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz\n - secretKey: kv_key\n remoteRef:\n key: kv/zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz\n property: 'keyid'\n - secretKey: kv_key_with_path\n remoteRef:\n key: kv/zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz\n property: 'key.path'\n
The behavior for the different secret types is as following:
"},{"location":"provider/ibm-secrets-manager/#arbitrary","title":"arbitrary","text":" remoteRef
retrieves a string from secrets manager and sets it for specified secretKey
dataFrom
retrieves a string from secrets manager and tries to parse it as JSON object setting the key:values pairs in resulting Kubernetes secret if successful
"},{"location":"provider/ibm-secrets-manager/#username_password","title":"username_password","text":" remoteRef
requires a property
to be set for either username
or password
to retrieve respective fields from the secrets manager secret and set in specified secretKey
dataFrom
retrieves both username
and password
fields from the secrets manager secret and sets appropriate key:value pairs in the resulting Kubernetes secret
"},{"location":"provider/ibm-secrets-manager/#iam_credentials","title":"iam_credentials","text":" remoteRef
retrieves an apikey from secrets manager and sets it for specified secretKey
dataFrom
retrieves an apikey from secrets manager and sets it for the apikey
Kubernetes secret key
"},{"location":"provider/ibm-secrets-manager/#service_credentials","title":"service_credentials","text":" remoteRef
retrieves the credentials object from secrets manager and sets it for specified secretKey
dataFrom
retrieves the credential object as a map from secrets manager and sets appropriate key:value pairs in the resulting Kubernetes secret
"},{"location":"provider/ibm-secrets-manager/#imported_cert-public_cert-and-private_cert","title":"imported_cert, public_cert, and private_cert","text":" remoteRef
requires a property
to be set for either certificate
, private_key
or intermediate
to retrieve respective fields from the secrets manager secret and set in specified secretKey
dataFrom
retrieves all certificate
, private_key
and intermediate
fields from the secrets manager secret and sets appropriate key:value pairs in the resulting Kubernetes secret
"},{"location":"provider/ibm-secrets-manager/#kv","title":"kv","text":" - An optional
property
field can be set to remoteRef
to select requested key from the KV secret. If not set, the entire secret will be returned dataFrom
retrieves a string from secrets manager and tries to parse it as JSON object setting the key:values pairs in resulting Kubernetes secret if successful. It could be either used with the methods Extract
to extract multiple key/value pairs from one secret (with optional property
field being supported as well) Find
to find secrets based on tags or regular expressions and allows finding multiple external secrets and map them into a single Kubernetes secret
{\n \"key1\": \"val1\",\n \"key2\": \"val2\",\n \"key3\": {\n \"keyA\": \"valA\",\n \"keyB\": \"valB\"\n },\n \"special.key\": \"special-content\"\n}\n
data:\n- secretKey: key3_keyB\n remoteRef:\n key: 'kv/aaaaa-bbbb-cccc-dddd-eeeeee'\n property: 'key3.keyB'\n- secretKey: special_key\n remoteRef:\n key: 'kv/aaaaa-bbbb-cccc-dddd-eeeeee'\n property: 'special.key'\n- secretKey: key_all\n remoteRef:\n key: 'kv/aaaaa-bbbb-cccc-dddd-eeeeee'\n
dataFrom:\n - extract:\n key: 'kv/fffff-gggg-iiii-dddd-eeeeee' #mandatory\n decodingStrategy: Base64 #optional\n
dataFrom:\n - find:\n name: #matches any secret name ending in foo-bar\n regexp: \"key\" #assumption that secrets are stored like /comp/key1, key2/trigger, and comp/trigger/keygen within the secret manager\n - find:\n tags: #matches any secrets with the following metadata labels\n environment: \"dev\"\n application: \"BFF\"\n
results in
data:\n # secrets from data\n key3_keyB: ... #valB\n special_key: ... #special-content\n key_all: ... #{\"key1\":\"val1\",\"key2\":\"val2\", ...\"special.key\":\"special-content\"}\n\n # secrets from dataFrom with extract method\n keyA: ... #1st key-value pair from JSON object\n keyB: ... #2nd key-value pair from JSON object\n keyC: ... #3rd key-value pair from JSON object\n\n # secrets from dataFrom with find regex method\n _comp_key1: ... #secret value for /comp/key1\n key2_trigger: ... #secret value for key2/trigger\n _comp_trigger_keygen: ... #secret value for comp/trigger/keygen\n\n # secrets from dataFrom with find tags method\n bffA: ...\n bffB: ...\n bffC: ...\n
"},{"location":"provider/ibm-secrets-manager/#creating-external-secret","title":"Creating external secret","text":"To create a kubernetes secret from the IBM Secrets Manager, a Kind=ExternalSecret
is needed. Below example creates a kubernetes secret based on ID of the secret in Secrets Manager.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: database-credentials\nspec:\n refreshInterval: 60m\n secretStoreRef:\n name: ibm-store\n kind: SecretStore\n target:\n name: database-credentials\n creationPolicy: Owner\n data:\n - secretKey: username\n remoteRef:\n key: username_password/<SECRET_ID>\n property: username\n - secretKey: password\n remoteRef:\n key: username_password/<SECRET_ID>\n property: password\n
Alternatively, the secret name along with its secret group name can be specified instead of secret ID to fetch the secret.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: database-credentials\nspec:\n refreshInterval: 60m\n secretStoreRef:\n name: ibm-store\n kind: SecretStore\n target:\n name: database-credentials\n creationPolicy: Owner\n data:\n - secretKey: username\n remoteRef:\n key: <SECRET_GROUP_NAME>/username_password/<SECRET_NAME>\n property: username\n - secretKey: password\n remoteRef:\n key: <SECRET_GROUP_NAME>/username_password/<SECRET_NAME>\n property: password\n
"},{"location":"provider/ibm-secrets-manager/#getting-the-kubernetes-secret","title":"Getting the Kubernetes secret","text":"The operator will fetch the IBM Secret Manager secret and inject it as a Kind=Secret
kubectl get secret secret-to-be-created -n <namespace> | -o jsonpath='{.data.test}' | base64 -d\n
"},{"location":"provider/ibm-secrets-manager/#populating-the-kubernetes-secret-with-metadata-from-ibm-secrets-manager-provider","title":"Populating the Kubernetes secret with metadata from IBM Secrets Manager Provider","text":"ESO can add metadata while creating or updating a Kubernetes secret to be reflected in its labels or annotations. The metadata could be any of the fields that are supported and returned in the response by IBM Secrets Manager.
In order for the user to opt in to adding metadata to secret, an existing optional field spec.dataFrom.extract.metadataPolicy
can be set to Fetch
, its default value being None
. In addition to this, templating provided be ESO can be leveraged to specify the key-value pairs of the resultant secrets' labels and annotation.
In order for the required metadata to be populated in the Kubernetes secret, combination of below should be provided in the External Secrets resource: 1. The required metadata should be specified under template.metadata.labels
or template.metadata.annotations
. 2. The required secret data should be specified under template.data
. 3. The spec.dataFrom.extract should be specified with details of the Secrets Manager secret with spec.dataFrom.extract.metadataPolicy
set to Fetch
. Below is an example, where secret_id
and updated_at
are the metadata of a secret in IBM Secrets Manager:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: database-credentials\n namespace: external-secrets\nspec:\n dataFrom:\n - extract:\n key: username_password/<SECRET_ID>\n metadataPolicy: Fetch # leveraging optional parameter, defaults to None\n secretKey: username\n secretStoreRef:\n kind: SecretStore\n name: ibm-store\n target:\n name: database-credentials\n template:\n engineVersion: v2\n data:\n secret: \"{{ .password }}\"\n metadata:\n annotations:\n secret_id: \"{{ .id }}\" # adding metadata key whose value would be added to the secret as a label\n updated_at: \"{{ .updated_at }}\"\n
While the secret is being reconciled, it will have the secret data along with the required annotations. Below is the example of the secret after reconciliation:
apiVersion: v1\ndata:\n secret: OHE0MFV5MGhQb2FmRjZTOGVva3dPQjRMeVZXeXpWSDlrSWgyR1BiVDZTMyc=\nimmutable: false\nkind: Secret\nmetadata:\n annotations:\n reconcile.external-secrets.io/data-hash: 02217008d13ed228e75cf6d26fe74324\n creationTimestamp: \"2023-05-04T08:41:24Z\"\n secret_id: \"1234\"\n updated_at: 2023-05-04T08:57:19Z\n name: database-credentials\n namespace: external-secrets\n ownerReferences:\n - apiVersion: external-secrets.io/v1beta1\n blockOwnerDeletion: true\n controller: true\n kind: ExternalSecret\n name: database-credentials\n uid: c2a018e7-1ac3-421b-bd3b-d9497204f843\n #resourceVersion: \"1803567\" #immutable for a user\n #uid: f5dff604-611b-4d41-9d65-b860c61a0b8d #immutable for a user\ntype: Opaque\n
"},{"location":"provider/keeper-security/","title":"Keeper Security","text":""},{"location":"provider/keeper-security/#keeper-security","title":"Keeper Security","text":"External Secrets Operator integrates with Keeper Security for secret management by using Keeper Secrets Manager.
"},{"location":"provider/keeper-security/#authentication","title":"Authentication","text":""},{"location":"provider/keeper-security/#secrets-manager-configuration-smc","title":"Secrets Manager Configuration (SMC)","text":"KSM can authenticate using One Time Access Token or Secret Manager Configuration. In order to work with External Secret Operator we need to configure a Secret Manager Configuration.
"},{"location":"provider/keeper-security/#creating-secrets-manager-configuration","title":"Creating Secrets Manager Configuration","text":"You can find the documentation for the Secret Manager Configuration creation here. Make sure you add the proper permissions to your device in order to be able to read and write secrets
Once you have created your SMC, you will get a config.json file or a base64 json encoded string containing the following keys:
hostname
clientId
privateKey
serverPublicKeyId
appKey
appOwnerPublicKey
This base64 encoded jsong string will be required to create your secretStores
"},{"location":"provider/keeper-security/#important-note-about-this-documentation","title":"Important note about this documentation","text":"The KepeerSecurity calls the entries in vaults 'Records'. These docs use the same term.
"},{"location":"provider/keeper-security/#update-secret-store","title":"Update secret store","text":"Be sure the keepersecurity
provider is listed in the Kind=SecretStore
---\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: keeper\nspec:\n provider:\n keepersecurity:\n authRef: # Refer to a kubernetes secret which holds the base64 encoded json string for the configuration\n name: keeper-configuration\n key: auth\n folderID: 1qdsiewFW-U # Folder ID where the secrets can be pushed. It requires write permissions\n
NOTE 1: folderID
target the folder ID where the secrets should be pushed to. It requires write permissions within the folder
NOTE 2: In case of a ClusterSecretStore
, Be sure to provide namespace
for SecretAccessKeyRef
with the namespace of the secret that we just created.
"},{"location":"provider/keeper-security/#external-secrets","title":"External Secrets","text":""},{"location":"provider/keeper-security/#behavior","title":"Behavior","text":" - How a Record is equated to an ExternalSecret:
remoteRef.key
is equated to a Record's ID remoteRef.property
is equated to one of the following options: - Fields: Record's field's Type
- CustomFields: Record's field's Label
- Files: Record's file's Name
- If empty, defaults to the complete Record in JSON format
remoteRef.version
is currently not supported.
dataFrom
: find.path
is currently not supported. find.name.regexp
is equated to one of the following options: - Fields: Record's field's Type
- CustomFields: Record's field's Label
- Files: Record's file's Name
find.tags
are not supported at this time.
NOTE: For complex types, like name, phone, bankAccount, which does not match with a single string value, external secrets will return the complete json string. Use the json template functions to decode.
"},{"location":"provider/keeper-security/#creating-external-secret","title":"Creating external secret","text":"To create a kubernetes secret from Keeper Secret Manager secret a Kind=ExternalSecret
is needed.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example\nspec:\n refreshInterval: 1h # rate SecretManager pulls KeeperSrucity\n secretStoreRef:\n kind: SecretStore\n name: example # name of the SecretStore (or kind specified)\n target:\n name: secret-to-be-created # name of the k8s Secret to be created\n creationPolicy: Owner\n dataFrom:\n - extract:\n key: OqPt3Vd37My7G8rTb-8Q # ID of the Keeper Record\n---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: regcred\n namespace: external-secrets\nspec:\n refreshInterval: 1m\n secretStoreRef:\n name: keeper\n kind: ClusterSecretStore\n target:\n name: regcred\n creationPolicy: Owner\n template:\n engineVersion: v2\n type: kubernetes.io/dockerconfigjson\n data:\n .dockerconfigjson: \"{\\\"auths\\\":{\\\"registry.example.com\\\":{\\\"username\\\":\\\"{{ .username }}\\\",\\\"password\\\":\\\"{{ .password }}\\\",\\\"auth\\\":\\\"{{(printf \\\"%s:%s\\\" .username .password) | b64enc }}\\\"}}}\"\n data:\n - secretKey: username\n remoteRef:\n key: OqPt3Vd37My7G8rTb-8Q\n property: login\n - secretKey: password\n remoteRef:\n key: OqPt3Vd37My7G8rTb-8Q\n property: password\n---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: config\n namespace: external-secrets\nspec:\n refreshInterval: 1m\n secretStoreRef:\n name: keeper\n kind: ClusterSecretStore\n target:\n name: credentials\n creationPolicy: Owner\n template:\n engineVersion: v2\n data:\n username: \"{{ .login }}\"\n password: \"{{ .password }}\"\n data:\n - secretKey: login\n remoteRef:\n key: OqPt3Vd37My7G8rTb-8Q\n property: login\n - secretKey: password\n remoteRef:\n key: OqPt3Vd37My7G8rTb-8Q\n property: password\n---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example\nspec:\n refreshInterval: 1h # rate SecretManager pulls KeeperSrucity\n secretStoreRef:\n kind: SecretStore\n name: example # name of the SecretStore (or kind specified)\n target:\n name: secret-to-be-created # name of the k8s Secret to be created\n creationPolicy: Owner\n template:\n engineVersion: v2\n data:\n username: \"{{ (fromJson .name).first }} {{ (fromJson .name).middle }} {{ (fromJson .name).last }}\" # decode json string into vars\n dataFrom:\n - extract:\n key: OqPt3Vd37My7G8rTb-8Q # ID of the Keeper Record\n
The operator will fetch the Keeper Secret Manager secret and inject it as a Kind=Secret
kubectl get secret secret-to-be-created -n <namespace> | -o jsonpath='{.data.dev-secret-test}' | base64 -d\n
"},{"location":"provider/keeper-security/#limitations","title":"Limitations","text":"There are some limitations using this provider.
- Keeper Secret Manager does not work with
General
Records types nor legacy non-typed records - Using tags
find.tags
is not supported by KSM - Using path
find.path
is not supported at the moment
"},{"location":"provider/keeper-security/#push-secrets","title":"Push Secrets","text":"Push Secret will only work with a custom KeeperSecurity Record type ExternalSecret
"},{"location":"provider/keeper-security/#behavior_1","title":"Behavior","text":" selector
: secret.name
: name of the kubernetes secret to be pushed data.match
: secretKey
: key on the selected secret to be pushed remoteRef.remoteKey
: Secret and key to be created on the remote provider - Format: SecretName/SecretKey
"},{"location":"provider/keeper-security/#creating-push-secret","title":"Creating push secret","text":"To create a Keeper Security record from kubernetes a Kind=PushSecret
is needed.
apiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\n name: example\nspec:\n secretStoreRefs:\n - name: keeper\n kind: SecretStore\n refreshInterval: \"1h\"\n deletionPolicy: Delete\n selector:\n secret:\n name: secret-name # k8s secret to be pushed\n data:\n - match:\n secretKey: secret-key # k8s key within the secret to be pushed\n remoteRef:\n remoteKey: remote-secret-name/remote-secret-key # This will create a record called \"remote-secret-name\" with a key \"remote-secret-key\"\n
"},{"location":"provider/keeper-security/#limitations_1","title":"Limitations","text":" - Only possible to push one key per secret at the moment
- If the record with the selected name exists but the key does not exists the record can not be updated. See Ability to add custom fields to existing secret #17
"},{"location":"provider/kubernetes/","title":"Kubernetes","text":"External Secrets Operator allows to retrieve secrets from a Kubernetes Cluster - this can be either a remote cluster or the local one where the operator runs in.
A SecretStore
points to a specific namespace in the target Kubernetes Cluster. You are able to retrieve all secrets from that particular namespace given you have the correct set of RBAC permissions.
The SecretStore
reconciler checks if you have read access for secrets in that namespace using SelfSubjectRulesReview
. See below on how to set that up properly.
"},{"location":"provider/kubernetes/#external-secret-spec","title":"External Secret Spec","text":"This provider supports the use of the Property
field. With it you point to the key of the remote secret. If you leave it empty it will json encode all key/value pairs.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: database-credentials\nspec:\n refreshInterval: 1h\n secretStoreRef:\n kind: SecretStore\n name: k8s-store # name of the SecretStore (or kind specified)\n target:\n name: database-credentials # name of the k8s Secret to be created\n data:\n - secretKey: username\n remoteRef:\n key: database-credentials\n property: username\n\n - secretKey: password\n remoteRef:\n key: database-credentials\n property: password\n\n # metadataPolicy to fetch all the labels and annotations in JSON format\n - secretKey: tags\n remoteRef:\n metadataPolicy: Fetch\n key: database-credentials\n\n # metadataPolicy to fetch all the labels in JSON format\n - secretKey: labels\n remoteRef:\n metadataPolicy: Fetch\n key: database-credentials\n property: labels\n\n # metadataPolicy to fetch a specific label (dev) from the source secret\n - secretKey: developer\n remoteRef:\n metadataPolicy: Fetch\n key: database-credentials\n property: labels.dev\n
"},{"location":"provider/kubernetes/#find-by-tag-name","title":"find by tag & name","text":"You can fetch secrets based on labels or names matching a regexp:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: fetch-tls-and-nginx\nspec:\n refreshInterval: 1h\n secretStoreRef:\n kind: SecretStore\n name: k8s-store\n target:\n name: fetch-tls-and-nginx\n dataFrom:\n - find:\n name:\n # match secret name with regexp\n regexp: \"tls-.*\"\n - find:\n tags:\n # fetch secrets based on label combination\n app: \"nginx\"\n
"},{"location":"provider/kubernetes/#target-api-server-configuration","title":"Target API-Server Configuration","text":"The servers url
can be omitted and defaults to kubernetes.default
. You have to provide a CA certificate in order to connect to the API Server securely. For your convenience, each namespace has a ConfigMap kube-root-ca.crt
that contains the CA certificate of the internal API Server (see RootCAConfigMap
feature gate). Use that if you want to connect to the same API server. If you want to connect to a remote API Server you need to fetch it and store it inside the cluster as ConfigMap or Secret. You may also define it inline as base64 encoded value using the caBundle
property.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: k8s-store-default-ns\nspec:\n provider:\n kubernetes:\n # with this, the store is able to pull only from `default` namespace\n remoteNamespace: default\n server:\n url: \"https://myapiserver.tld\"\n caProvider:\n type: ConfigMap\n name: kube-root-ca.crt\n key: ca.crt\n
"},{"location":"provider/kubernetes/#authentication","title":"Authentication","text":"It's possible to authenticate against the Kubernetes API using client certificates, a bearer token or service account. The operator enforces that exactly one authentication method is used. You can not use the service account that is mounted inside the operator, this is by design to avoid reading secrets across namespaces.
NOTE: SelfSubjectRulesReview
permission is required in order to validation work properly. Please use the following role as reference:
apiVersion: rbac.authorization.k8s.io/v1\nkind: Role\nmetadata:\n namespace: default\n name: eso-store-role\nrules:\n- apiGroups: [\"\"]\n resources:\n - secrets\n verbs:\n - get\n - list\n - watch\n- apiGroups:\n - authorization.k8s.io\n resources:\n - selfsubjectrulesreviews\n verbs:\n - create\n
"},{"location":"provider/kubernetes/#authenticating-with-bearertoken","title":"Authenticating with BearerToken","text":"Create a Kubernetes secret with a client token. There are many ways to acquire such a token, please refer to the Kubernetes Authentication docs.
apiVersion: v1\nkind: Secret\nmetadata:\n name: my-token\ndata:\n token: \"....\"\n
Create a SecretStore: The auth
section indicates that the type token
will be used for authentication, it includes the path to fetch the token. Set remoteNamespace
to the name of the namespace where your target secrets reside.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: k8s-store-token-auth\nspec:\n provider:\n kubernetes:\n # with this, the store is able to pull only from `default` namespace\n remoteNamespace: default\n server:\n # ...\n auth:\n token:\n bearerToken:\n name: my-token\n key: token\n
"},{"location":"provider/kubernetes/#authenticating-with-serviceaccount","title":"Authenticating with ServiceAccount","text":"Create a Kubernetes Service Account, please refer to the Service Account Tokens Documentation on how they work and how to create them.
$ kubectl create serviceaccount my-store\n
This Service Account needs permissions to read Secret
and create SelfSubjectRulesReview
resources. Please see the above role.
$ kubectl create rolebinding my-store --role=eso-store-role --serviceaccount=default:my-store\n
Create a SecretStore: the auth
section indicates that the type serviceAccount
will be used for authentication.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: k8s-store-sa-auth\nspec:\n provider:\n kubernetes:\n # with this, the store is able to pull only from `default` namespace\n remoteNamespace: default\n server:\n # ...\n auth:\n serviceAccount:\n name: \"my-store\"\n
"},{"location":"provider/kubernetes/#authenticating-with-client-certificates","title":"Authenticating with Client Certificates","text":"Create a Kubernetes secret which contains the client key and certificate. See Generate Certificates Documentations on how to create them.
$ kubectl create secret tls tls-secret --cert=path/to/tls.cert --key=path/to/tls.key\n
Reference the tls-secret
in the SecretStore
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: k8s-store-cert-auth\nspec:\n provider:\n kubernetes:\n # with this, the store is able to pull only from `default` namespace\n remoteNamespace: default\n server:\n # ...\n auth:\n cert:\n clientCert:\n name: \"tls-secret\"\n key: \"tls.crt\"\n clientKey:\n name: \"tls-secret\"\n key: \"tls.key\"\n
"},{"location":"provider/kubernetes/#pushsecret","title":"PushSecret","text":"The PushSecret functionality facilitates the replication of a Kubernetes Secret from one namespace or cluster to another. This feature proves useful in scenarios where you need to share sensitive information, such as credentials or configuration data, across different parts of your infrastructure.
To configure the PushSecret resource, you need to specify the following parameters:
-
Selector: Specify the selector that identifies the source Secret to be replicated. This selector allows you to target the specific Secret you want to share.
-
SecretKey: Set the SecretKey parameter to indicate the key within the source Secret that you want to replicate. This ensures that only the relevant information is shared.
-
RemoteRef.Property: In addition to the above parameters, the Kubernetes provider requires you to set the remoteRef.property
field. This field specifies the key of the remote Secret resource where the replicated value should be stored.
Here's an example:
apiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\n name: example\nspec:\n refreshInterval: 10s\n secretStoreRefs:\n - name: k8s-store-remote-ns\n kind: SecretStore\n selector:\n secret:\n name: pokedex-credentials\n data:\n - match:\n secretKey: best-pokemon\n remoteRef:\n remoteKey: remote-best-pokemon\n property: best-pokemon\n
To utilize the PushSecret feature effectively, the referenced SecretStore
requires specific permissions on the target cluster. In particular it requires create
, read
, update
and delete
permissions on the Secret resource:
apiVersion: rbac.authorization.k8s.io/v1\nkind: Role\nmetadata:\n namespace: remote\n name: eso-store-push-role\nrules:\n- apiGroups: [\"\"]\n resources:\n - secrets\n verbs:\n - get\n - list\n - watch\n - create\n - update\n - patch\n - delete\n- apiGroups:\n - authorization.k8s.io\n resources:\n - selfsubjectrulesreviews\n verbs:\n - create\n
"},{"location":"provider/kubernetes/#implementation-considerations","title":"Implementation Considerations","text":"When utilizing the PushSecret feature and configuring the permissions for the SecretStore, consider the following:
-
RBAC Configuration: Ensure that the Role-Based Access Control (RBAC) configuration for the SecretStore grants the appropriate permissions for creating, reading, and updating resources in the target cluster.
-
Least Privilege Principle: Adhere to the principle of least privilege when assigning permissions to the SecretStore. Only provide the minimum required permissions to accomplish the desired synchronization between Secrets.
-
Namespace or Cluster Scope: Depending on your specific requirements, configure the SecretStore to operate at the desired scope, whether it is limited to a specific namespace or encompasses the entire cluster. Consider the security and access control implications of your chosen scope.
"},{"location":"provider/onboardbase/","title":"Onboardbase","text":""},{"location":"provider/onboardbase/#onboardbase-secret-management","title":"Onboardbase Secret Management","text":"Sync secrets from Onboardbase to Kubernetes using the External Secrets Operator.
"},{"location":"provider/onboardbase/#authentication","title":"Authentication","text":""},{"location":"provider/onboardbase/#get-an-onboardbase-api-key","title":"Get an Onboardbase API Key.","text":"Create the Onboardbase API by opening the organization tab under your account settings:
And view them under the team name in your Account settings
Create an Onboardbase API secret with your API Key and Passcode value:
HISTIGNORE='*kubectl*' \\\n kubectl create secret generic onboardbase-auth-secret \\\n --from-literal=API_KEY=*****VZYKYJNMMEMK***** \\\n --from-literal=PASSCODE=api-key-passcode\n
Then to create a generic SecretStore
:
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: onboardbase-external-secret-store\nspec:\n provider:\n onboardbase:\n project: project-name # can be altered from here\n environment: development # can be altered from here\n auth:\n apiKey:\n name: onboardbase-auth-secret\n key: onboardbase-api-key \n passcode:\n name: onboardbase-auth-secret\n key: onboardbase-passcode\n
"},{"location":"provider/onboardbase/#use-cases","title":"Use Cases","text":"The below operations are possible with the Onboardbase provider:
- Fetch
- Fetch all
- Filter
Let's explore each use case using a fictional auth-api
Onboardbase project.
"},{"location":"provider/onboardbase/#1-fetch","title":"1. Fetch","text":"To sync one or more individual secrets:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: service-name-secrets\nspec:\n refreshInterval: 10m\n secretStoreRef:\n name: onboardbase-external-secret-store\n kind: SecretStore\n target:\n name: service-name-secrets\n data:\n - secretKey: DATABASE_URI\n remoteRef: \n key: DATABASE_URI\n
"},{"location":"provider/onboardbase/#2-fetch-all","title":"2. Fetch all","text":"To sync every secret from a config:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: service-name-secrets\nspec:\n refreshInterval: 10m\n secretStoreRef:\n name: onboardbase-external-secret-store\n kind: SecretStore\n target:\n name: service-name-secrets\n dataFrom:\n - find:\n name:\n regexp: .*\n
"},{"location":"provider/onboardbase/#3-filter","title":"3. Filter","text":"To filter secrets by path
(path prefix), name
(regular expression) or a combination of both:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: service-name-secrets\nspec:\n refreshInterval: 10m\n secretStoreRef:\n name: onboardbase-external-secret-store\n kind: SecretStore\n target:\n name: service-name-secrets\n dataFrom:\n - find:\n path: DATABASE_\n
"},{"location":"provider/oracle-vault/","title":"Oracle Vault","text":""},{"location":"provider/oracle-vault/#oracle-vault","title":"Oracle Vault","text":"External Secrets Operator integrates with OCI API to sync secret on the Oracle Vault to secrets held on the Kubernetes cluster.
"},{"location":"provider/oracle-vault/#authentication","title":"Authentication","text":"Specify the authenticating principal with principalType
, using UserPrincipal
, InstancePrincipal
, or Workload
as values. If principalType
or auth
are not set, the operator defaults to instance principal for authentication.
For user principal, userOCID, tenancyOCID, fingerprint and private key are required. The fingerprint and key file should be supplied in the secret with the rest being provided in the secret store.
See url for what region you you are accessing.
Select tenancy in the top right to see your user OCID as shown below.
Select your user in the top right to see your user OCID as shown below.
"},{"location":"provider/oracle-vault/#service-account-key-authentication","title":"Service account key authentication","text":"Create a secret containing your private key and fingerprint:
apiVersion: v1\nkind: Secret\nmetadata:\n name: oracle-secret\n labels: \n type: oracle\ntype: Opaque\nstringData:\n privateKey: \n fingerprint: \n
Your fingerprint will be attatched to your API key, once it has been generated. Found on the same page as the user OCID.
Once you click \"Add API Key\" you will be shown the following, where you can download the RSA key in the necessary PEM format for API requests. This will automatically generate a fingerprint.
"},{"location":"provider/oracle-vault/#update-secret-store","title":"Update secret store","text":"Be sure the oracle
provider is listed in the Kind=SecretStore
.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: example-instance-principal\nspec:\n provider:\n oracle:\n vault: # The vault OCID\n region: # The vault region\n principalType: InstancePrincipal\n\n---\n\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: example-workload-identity\nspec:\n provider:\n oracle:\n vault: # The vault OCID\n region: # The vault region\n principalType: Workload\n\n---\n\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: example-auth\nspec:\n provider:\n oracle:\n vault: # The vault OCID\n region: # The vault region\n principalType: UserPrincipal\n auth:\n user: # A user OCID\n tenancy: # A user's tenancy\n secretRef:\n privatekey:\n name: oracle-secret\n key: privateKey\n fingerprint:\n name: oracle-secret\n key: fingerprint\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in privatekey
and fingerprint
with the namespaces where the secrets reside.
"},{"location":"provider/oracle-vault/#creating-external-secret","title":"Creating external secret","text":"To create a kubernetes secret from the Oracle Cloud Interface secret aKind=ExternalSecret
is needed.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example\nspec:\n refreshInterval: 0.03m\n secretStoreRef:\n kind: SecretStore\n name: example # Must match SecretStore on the cluster\n target:\n name: secret-to-be-created # Name for the secret on the cluster\n creationPolicy: Owner\n dataFrom:\n - extract:\n key: the-secret-name\n
"},{"location":"provider/oracle-vault/#getting-the-kubernetes-secret","title":"Getting the Kubernetes secret","text":"The operator will fetch the project variable and inject it as a Kind=Secret
.
kubectl get secret oracle-secret-to-create -o jsonpath='{.data.dev-secret-test}' | base64 -d\n
"},{"location":"provider/oracle-vault/#pushsecrets-and-retrieving-multiple-secrets","title":"PushSecrets and retrieving multiple secrets.","text":"When using PushSecrets, the compartment OCID and encryption key OCID must be specified in the Oracle SecretStore. You can find your compartment and encrpytion key OCIDs in the OCI console.
If retrieving multiple secrets by tag or regex, only the compartment OCID must be specified.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: example-instance-principal\nspec:\n provider:\n oracle:\n vault: # The vault OCID\n compartment: # The compartment OCID where the vault is located. Required when using PushSecrets or retrieving multiple secrets.\n encryptionKey: # The OCID of the master encryption key that will be used for PushSecret encryption. Must exist in the vault, required when using PushSecrets.\n principalType: Workload\n
"},{"location":"provider/passbolt/","title":"Passbolt","text":"External Secrets Operator integrates with Passbolt API to sync Passbolt to secrets held on the Kubernetes cluster.
"},{"location":"provider/passbolt/#creating-a-passbolt-secret-store","title":"Creating a Passbolt secret store","text":"Be sure the passbolt
provider is listed in the Kind=SecretStore
and auth and host are set. The API requires a password and private key provided in a secret.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: passbolt\nspec:\n provider:\n passbolt:\n host: https://passbolt.passbolt.svc.cluster.local\n auth:\n passwordSecretRef:\n key: password\n name: passbolt-credentials\n privateKeySecretRef:\n key: privateKey\n name: passbolt-credentials\n
"},{"location":"provider/passbolt/#creating-an-external-secret","title":"Creating an external secret","text":"To sync a Passbolt secret to a Kubernetes secret, a Kind=ExternalSecret
is needed. By default the secret contains name, username, uri, password and description.
To only select a single property add the property
key.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: passbolt-example-simple\nspec:\n refreshInterval: \"15s\"\n secretStoreRef:\n name: passbolt\n kind: SecretStore\n target:\n name: passbolt-example\n data:\n - secretKey: full_secret\n remoteRef:\n key: e22487a8-feb8-4591-95aa-14b193930cb4 # Replace with ID of exising Passbolt secret\n - secretKey: password_only\n remoteRef:\n key: e22487a8-feb8-4591-95aa-14b193930cb4 # Replace with ID of exising Passbolt secret\n property: password # You can limit the secret to only display one property\n
The above external secret will lead to the creation of a secret in the following form:
apiVersion: v1\nkind: Secret\nmetadata:\n name: passbolt-example\ndata:\n full_secret: '{\"name\":\"passbolt-secret\",\"username\":\"some-username\",\"password\":\"supersecretpassword\",\"uri\":\"passbolt.com\",\"description\":\"some description\"}'\n password_only: supersecretpassword\ntype: Opaque\n
"},{"location":"provider/passbolt/#finding-a-secret-by-name","title":"Finding a secret by name","text":"Instead of retrieving secrets by ID you can also use dataFrom
to search for secrets by name.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: passbolt-example\nspec:\n refreshInterval: \"15s\"\n secretStoreRef:\n name: passbolt\n kind: SecretStore\n target:\n name: passbolt-example\n dataFrom:\n - find:\n name:\n regexp: \".*\"\n
"},{"location":"provider/pulumi/","title":"Pulumi ESC","text":""},{"location":"provider/pulumi/#pulumi-esc","title":"Pulumi ESC","text":"Sync environments, configs and secrets from Pulumi ESC to Kubernetes using the External Secrets Operator.
"},{"location":"provider/pulumi/#authentication","title":"Authentication","text":"Pulumi Access Tokens are recommended to access Pulumi ESC.
"},{"location":"provider/pulumi/#creating-a-secretstore","title":"Creating a SecretStore","text":"A Pulumi SecretStore can be created by specifying the organization
and environment
and referencing a Kubernetes secret containing the accessToken
.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: secret-store\nspec:\n provider:\n pulumi:\n organization: <NAME_OF_THE_ORGANIZATION>\n environment: <NAME_OF_THE_ENVIRONMENT>\n accessToken:\n secretRef:\n name: <NAME_OF_KUBE_SECRET>\n key: <KEY_IN_KUBE_SECRET>\n
If required, the API URL (apiUrl
) can be customized as well. If not specified, the default value is https://api.pulumi.com
.
"},{"location":"provider/pulumi/#referencing-secrets","title":"Referencing Secrets","text":"Secrets can be referenced by defining the key
containing the JSON path to the secret. Pulumi ESC secrets are internally organized as a JSON object.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: secret\nspec:\n refreshInterval: 5m\n secretStoreRef:\n kind: SecretStore\n name: secret-store\n data:\n - secretKey: <KEY_IN_KUBE_SECRET>\n remoteRef:\n key: <PULUMI_PATH_SYNTAX>\n
Note: key
is not following the JSON Path syntax, but rather the Pulumi path syntax.
"},{"location":"provider/pulumi/#examples","title":"Examples","text":" - root
- root.nested
- root[\"nested\"]
- root.double.nest
- root[\"double\"].nest
- root[\"double\"][\"nest\"]
- root.array[0]
- root.array[100]
- root.array[0].nested
- root.array[0][1].nested
- root.nested.array[0].double[1]
- root[\"key with \\\"escaped\\\" quotes\"]
- root[\"key with a .\"]
- [\"root key with \\\"escaped\\\" quotes\"].nested
- [\"root key with a .\"][100]
- root.array[*].field
- root.array[\"*\"].field
See Pulumi's documentation for more information.
"},{"location":"provider/scaleway/","title":"Scaleway","text":""},{"location":"provider/scaleway/#scaleway-secret-manager","title":"Scaleway Secret Manager","text":"External Secrets Operator integrates with Scaleway's Secret Manager.
"},{"location":"provider/scaleway/#creating-a-secretstore","title":"Creating a SecretStore","text":"You need an api key (access key + secret key) to authenticate with the secret manager. Both access and secret keys can be specified either directly in the config, or by referencing a kubernetes secret.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: secret-store\nspec:\n provider:\n scaleway:\n region: <REGION>\n projectId: <PROJECT_UUID>\n accessKey:\n value: <ACCESS_KEY>\n secretKey:\n secretRef:\n name: <NAME_OF_KUBE_SECRET>\n key: <KEY_IN_KUBE_SECRET>\n
"},{"location":"provider/scaleway/#referencing-secrets","title":"Referencing Secrets","text":"Secrets can be referenced by name, id or path, using the prefixes \"name:\"
, \"id:\"
and \"path:\"
respectively.
A PushSecret resource can only use a name reference.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: secret\nspec:\n refreshInterval: 20s\n secretStoreRef:\n kind: SecretStore\n name: secret-store\n data:\n - secretKey: <KEY_IN_KUBE_SECRET>\n remoteRef:\n key: id:<SECRET_UUID>\n version: latest_enabled\n
"},{"location":"provider/senhasegura-dsm/","title":"senhasegura DevOps Secrets Management (DSM)","text":""},{"location":"provider/senhasegura-dsm/#senhasegura-devops-secrets-management-dsm","title":"senhasegura DevOps Secrets Management (DSM)","text":"External Secrets Operator integrates with senhasegura DevOps Secrets Management (DSM) module to sync application secrets to secrets held on the Kubernetes cluster.
"},{"location":"provider/senhasegura-dsm/#authentication","title":"Authentication","text":"Authentication in senhasegura uses DevOps Secrets Management (DSM) application authorization schema
You need to create an Kubernetes Secret with desired auth parameters, for example:
Instructions to setup authorizations and secrets in senhasegura DSM can be found at senhasegura docs for DSM and senhasegura YouTube channel
---\napiVersion: v1\nkind: Secret\nmetadata:\n name: senhasegura-dsm-auth\nstringData:\n CLIENT_SECRET: \"CHANGEME\"\n
"},{"location":"provider/senhasegura-dsm/#examples","title":"Examples","text":"To sync secrets between senhasegura and Kubernetes with External Secrets, we need to define an SecretStore or ClusterSecretStore resource with senhasegura provider, setting authentication in DSM module with Secret defined before
"},{"location":"provider/senhasegura-dsm/#secretstore","title":"SecretStore","text":"---\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: senhasegura\nspec:\n provider:\n senhasegura:\n url: \"https://senhasegura.changeme.com\"\n module: DSM # Select senhasegura DSM module to sync secrets\n auth:\n clientId: \"CHANGEME\"\n clientSecretSecretRef:\n name: senhasegura-dsm-auth\n key: CLIENT_SECRET\n ignoreSslCertificate: false # Optional\n
"},{"location":"provider/senhasegura-dsm/#clustersecretstore","title":"ClusterSecretStore","text":"---\napiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\n name: senhasegura\nspec:\n provider:\n senhasegura:\n url: \"https://senhasegura.changeme.com\"\n module: DSM # Select senhasegura DSM module to sync secrets\n auth:\n clientId: \"CHANGEME\"\n clientSecretSecretRef:\n name: senhasegura-dsm-auth\n key: CLIENT_SECRET\n namespace: senhasegura # Namespace of Secret \"senhasegura-dsm-auth\"\n ignoreSslCertificate: false # Optional\n
"},{"location":"provider/senhasegura-dsm/#syncing-secrets","title":"Syncing secrets","text":"In examples below, consider that three secrets (api-settings, db-settings and hsm-settings) are defined in senhasegura DSM
**Secret Identifier: ** api-settings
Secret data:
URL=https://example.com/api/example\nTOKEN=example-token-value\n
**Secret Identifier: ** db-settings
Secret data:
DB_HOST='db.example'\nDB_PORT='5432'\nDB_USERNAME='example'\nDB_PASSWORD='example'\n
**Secret Identifier: ** hsm-settings
Secret data:
HSM_ADDRESS='hsm.example'\nHSM_PORT='9223'\n
"},{"location":"provider/senhasegura-dsm/#sync-dsm-secrets-using-secret-identifiers","title":"Sync DSM secrets using Secret Identifiers","text":"You can fetch all key/value pairs for a given secret identifier If you leave the remoteRef.property empty. This returns the json-encoded secret value for that path.
If you only need a specific key, you can select it using remoteRef.property as the key name.
In this method, you can overwrites data name in Kubernetes Secret object (e.g API_SETTINGS and API_SETTINGS_TOKEN)
---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example-secret\nspec:\n refreshInterval: \"30s\"\n secretStoreRef:\n name: senhasegura\n kind: SecretStore\n target:\n name: example-secret\n data:\n # Define API_SETTINGS Kubernetes Secret key, with json-encoded values from senhasegura secret with identifier \"api-settings\"\n - secretKey: API_SETTINGS\n remoteRef:\n key: api-settings # Secret Identifier in senhasegura\n # Define API_SETTINGS_TOKEN Kubernetes Secret key, with single secret key (TOKEN) from senhasegura as string\n - secretKey: API_SETTINGS_TOKEN\n remoteRef:\n key: api-settings # Secret Identifier in senhasegura\n property: TOKEN # Optional, Key name within secret\n
Kubernetes Secret will be create with follow .data.X
API_SETTINGS='[{\"TOKEN\":\"example-token-value\",\"URL\":\"https://example.com/api/example\"}]'\nAPI_SETTINGS_TOKEN='example-token-value'\n
"},{"location":"provider/senhasegura-dsm/#sync-dsm-secrets-using-secret-identifiers-with-automatically-name-assignments","title":"Sync DSM secrets using Secret Identifiers with automatically name assignments","text":"If your app requires multiples secrets, it is not required to create multiple ExternalSecret resources, you can aggregate secrets using a single ExternalSecret resource
In this method, every secret data in senhasegura creates an Kubernetes Secret .data.X
field
---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example-secret\nspec:\n refreshInterval: \"30s\"\n secretStoreRef:\n name: senhasegura\n kind: SecretStore\n target:\n name: example-secret\n dataFrom:\n # Define Kubernetes Secret key with any k/v pair in senhasegura Secret with identifier \"api-settings\" or \"db-settings\"\n - extract:\n key: api-settings\n - extract:\n key: db-settings\n
Kubernetes Secret will be create with follow .data.X
URL='https://example.com/api/example'\nTOKEN='example-token-value'\nDB_HOST='db.example'\nDB_PORT='5432'\nDB_USERNAME='example'\nDB_PASSWORD='example'\n
"},{"location":"provider/webhook/","title":"Webhook","text":""},{"location":"provider/webhook/#generic-webhook","title":"Generic Webhook","text":"External Secrets Operator can integrate with simple web apis by specifying the endpoint
"},{"location":"provider/webhook/#example","title":"Example","text":"First, create a SecretStore with a webhook backend. We'll use a static user/password root
:
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: webhook-backend\nspec:\n provider:\n webhook:\n url: \"http://httpbin.org/get?parameter={{ .remoteRef.key }}\"\n result:\n jsonPath: \"$.args.parameter\"\n headers:\n Content-Type: application/json\n Authorization: Basic {{ print .auth.username \":\" .auth.password | b64enc }}\n secrets:\n - name: auth\n secretRef:\n name: webhook-credentials\n---\napiVersion: v1\nkind: Secret\nmetadata:\n name: webhook-credentials\ndata:\n username: dGVzdA== # \"test\"\n password: dGVzdA== # \"test\"\n
NB: This is obviously not practical because it just returns the key as the result, but it shows how it works
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in all secrets
references with the namespaces where the secrets reside.
Now create an ExternalSecret that uses the above SecretStore:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: webhook-example\nspec:\n refreshInterval: \"15s\"\n secretStoreRef:\n name: webhook-backend\n kind: SecretStore\n target:\n name: example-sync\n data:\n - secretKey: foobar\n remoteRef:\n key: secret\n---\n# will create a secret with:\nkind: Secret\nmetadata:\n name: example-sync\ndata:\n foobar: c2VjcmV0\n
"},{"location":"provider/webhook/#limitations","title":"Limitations","text":"Webhook does not support authorization, other than what can be sent by generating http headers
Note
If a webhook endpoint for a given ExternalSecret
returns a 404 status code, the secret is considered to have been deleted. This will trigger the deletionPolicy
set on the ExternalSecret
.
"},{"location":"provider/webhook/#templating","title":"Templating","text":"Generic WebHook provider uses the templating engine to generate the API call. It can be used in the url, headers, body and result.jsonPath fields.
The provider inserts the secret to be retrieved in the object named remoteRef
.
In addition, secrets can be added as named objects, for example to use in authorization headers. Each secret has a name
property which determines the name of the object in the templating engine.
"},{"location":"provider/webhook/#all-parameters","title":"All Parameters","text":"apiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\n name: statervault\nspec:\n provider:\n webhook:\n # Url to call. Use templating engine to fill in the request parameters\n url: <url>\n # http method, defaults to GET\n method: <method>\n # Timeout in duration (1s, 1m, etc)\n timeout: 1s\n result:\n # [jsonPath](https://jsonpath.com) syntax, which also can be templated\n jsonPath: <jsonPath>\n # Map of headers, can be templated\n headers:\n <Header-Name>: <header contents>\n # Body to sent as request, can be templated (optional)\n body: <body>\n # List of secrets to expose to the templating engine\n secrets:\n # Use this name to refer to this secret in templating, above\n - name: <name>\n secretRef:\n namespace: <namespace> # Only used in ClusterSecretStores\n name: <name>\n # Add CAs here for the TLS handshake\n caBundle: <base64 encoded cabundle>\n caProvider:\n type: Secret or ConfigMap\n name: <name of secret or configmap>\n namespace: <namespace> # Only used in ClusterSecretStores\n key: <key inside secret>\n
"},{"location":"provider/webhook/#webhook-as-generators","title":"Webhook as generators","text":"You can also leverage webhooks as generators, following the same syntax. The only difference is that the webhook generator needs its source secrets to be labeled, as opposed to webhook secretstores. Please see the generator-webhook documentation for more information.
"},{"location":"provider/yandex-certificate-manager/","title":"Yandex Certificate Manager","text":""},{"location":"provider/yandex-certificate-manager/#yandex-certificate-manager","title":"Yandex Certificate Manager","text":"External Secrets Operator integrates with Yandex Certificate Manager for secret management.
"},{"location":"provider/yandex-certificate-manager/#prerequisites","title":"Prerequisites","text":" - External Secrets Operator installed
- Yandex.Cloud CLI installed
"},{"location":"provider/yandex-certificate-manager/#authentication","title":"Authentication","text":"At the moment, authorized key authentication is only supported:
- Create a service account in Yandex.Cloud:
yc iam service-account create --name eso-service-account\n
- Create an authorized key for the service account and save it to
authorized-key.json
file: yc iam key create \\\n --service-account-name eso-service-account \\\n --output authorized-key.json\n
- Create a k8s secret containing the authorized key saved above:
kubectl create secret generic yc-auth --from-file=authorized-key=authorized-key.json\n
- Create a SecretStore pointing to
yc-auth
k8s secret: apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: secret-store\nspec:\n provider:\n yandexcertificatemanager:\n auth:\n authorizedKeySecretRef:\n name: yc-auth\n key: authorized-key\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in all authorizedKeySecretRef
with the namespace where the secret resides.
"},{"location":"provider/yandex-certificate-manager/#creating-external-secret","title":"Creating external secret","text":"To make External Secrets Operator sync a k8s secret with a Certificate Manager certificate:
- Create a Certificate Manager certificate (follow the instructions), if not already created.
- Assign the
certificate-manager.certificates.downloader
role for accessing the certificate content to the service account used for authentication (*****
is the certificate ID): yc cm certificate add-access-binding \\\n --id ***** \\\n --service-account-name eso-service-account \\\n --role certificate-manager.certificates.downloader\n
Run the following command to ensure that the correct access binding has been added: yc cm certificate list-access-bindings --id *****\n
- Create an ExternalSecret pointing to
secret-store
and the certificate in Certificate Manager: apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: external-secret\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: secret-store\n kind: SecretStore\n target:\n name: k8s-secret # the target k8s secret name\n template:\n type: kubernetes.io/tls\n data:\n - secretKey: tls.crt # the target k8s secret key\n remoteRef:\n key: ***** # the certificate ID\n property: chain\n - secretKey: tls.key # the target k8s secret key\n remoteRef:\n key: ***** # the certificate ID\n property: privateKey\n
The following property values are possible: chain
\u2013 to fetch PEM-encoded certificate chain privateKey
\u2013 to fetch PEM-encoded private key chainAndPrivateKey
or missing property \u2013 to fetch both chain and private key
The operator will fetch the Yandex Certificate Manager certificate and inject it as a Kind=Secret
kubectl get secret k8s-secret -ojson | jq '.\"data\".\"tls.crt\"' -r | base64 --decode\nkubectl get secret k8s-secret -ojson | jq '.\"data\".\"tls.key\"' -r | base64 --decode\n
"},{"location":"provider/yandex-lockbox/","title":"Yandex Lockbox","text":""},{"location":"provider/yandex-lockbox/#yandex-lockbox","title":"Yandex Lockbox","text":"External Secrets Operator integrates with Yandex Lockbox for secret management.
"},{"location":"provider/yandex-lockbox/#prerequisites","title":"Prerequisites","text":" - External Secrets Operator installed
- Yandex.Cloud CLI installed
"},{"location":"provider/yandex-lockbox/#authentication","title":"Authentication","text":"At the moment, authorized key authentication is only supported:
- Create a service account in Yandex.Cloud:
yc iam service-account create --name eso-service-account\n
- Create an authorized key for the service account and save it to
authorized-key.json
file: yc iam key create \\\n --service-account-name eso-service-account \\\n --output authorized-key.json\n
- Create a k8s secret containing the authorized key saved above:
kubectl create secret generic yc-auth --from-file=authorized-key=authorized-key.json\n
- Create a SecretStore pointing to
yc-auth
k8s secret: apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: secret-store\nspec:\n provider:\n yandexlockbox:\n auth:\n authorizedKeySecretRef:\n name: yc-auth\n key: authorized-key\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in all authorizedKeySecretRef
with the namespace where the secret resides.
"},{"location":"provider/yandex-lockbox/#creating-external-secret","title":"Creating external secret","text":"To make External Secrets Operator sync a k8s secret with a Lockbox secret:
- Create a Lockbox secret, if not already created:
yc lockbox secret create \\\n --name lockbox-secret \\\n --payload '[{\"key\": \"password\",\"textValue\": \"p@$$w0rd\"}]'\n
- Assign the
lockbox.payloadViewer
role for accessing the lockbox-secret
payload to the service account used for authentication: yc lockbox secret add-access-binding \\\n --name lockbox-secret \\\n --service-account-name eso-service-account \\\n --role lockbox.payloadViewer\n
Run the following command to ensure that the correct access binding has been added: yc lockbox secret list-access-bindings --name lockbox-secret\n
- Create an ExternalSecret pointing to
secret-store
and lockbox-secret
: apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: external-secret\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: secret-store\n kind: SecretStore\n target:\n name: k8s-secret # the target k8s secret name\n data:\n - secretKey: password # the target k8s secret key\n remoteRef:\n key: ***** # ID of lockbox-secret\n property: password # (optional) payload entry key of lockbox-secret\n
The operator will fetch the Yandex Lockbox secret and inject it as a Kind=Secret
kubectl get secret k8s-secret -n <namespace> | -o jsonpath='{.data.password}' | base64 -d\n
"},{"location":"snippets/provider-aws-access/","title":"Provider aws access","text":""},{"location":"snippets/provider-aws-access/#aws-authentication","title":"AWS Authentication","text":""},{"location":"snippets/provider-aws-access/#controllers-pod-identity","title":"Controller's Pod Identity","text":"Note: If you are using Parameter Store replace service: SecretsManager
with service: ParameterStore
in all examples below.
This is basicially a zero-configuration authentication method that inherits the credentials from the runtime environment using the aws sdk default credential chain.
You can attach a role to the pod using IRSA, kiam or kube2iam. When no other authentication method is configured in the Kind=Secretstore
this role is used to make all API calls against AWS Secrets Manager or SSM Parameter Store.
Based on the Pod's identity you can do a sts:assumeRole
before fetching the secrets to limit access to certain keys in your provider. This is optional.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: team-b-store\nspec:\n provider:\n aws:\n service: SecretsManager\n region: eu-central-1\n # optional: do a sts:assumeRole before fetching secrets\n role: team-b\n
"},{"location":"snippets/provider-aws-access/#access-key-id-secret-access-key","title":"Access Key ID & Secret Access Key","text":"You can store Access Key ID & Secret Access Key in a Kind=Secret
and reference it from a SecretStore.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: team-b-store\nspec:\n provider:\n aws:\n service: SecretsManager\n region: eu-central-1\n # optional: assume role before fetching secrets\n role: team-b\n auth:\n secretRef:\n accessKeyIDSecretRef:\n name: awssm-secret\n key: access-key\n secretAccessKeySecretRef:\n name: awssm-secret\n key: secret-access-key\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in accessKeyIDSecretRef
, secretAccessKeySecretRef
with the namespaces where the secrets reside.
"},{"location":"snippets/provider-aws-access/#eks-service-account-credentials","title":"EKS Service Account credentials","text":"This feature lets you use short-lived service account tokens to authenticate with AWS. You must have Service Account Volume Projection enabled - it is by default on EKS. See EKS guide on how to set up IAM roles for service accounts.
The big advantage of this approach is that ESO runs without any credentials.
apiVersion: v1\nkind: ServiceAccount\nmetadata:\n annotations:\n eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/team-a\n name: my-serviceaccount\n namespace: default\n
Reference the service account from above in the Secret Store:
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: secretstore-sample\nspec:\n provider:\n aws:\n service: SecretsManager\n region: eu-central-1\n auth:\n jwt:\n serviceAccountRef:\n name: my-serviceaccount\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
for serviceAccountRef
with the namespace where the service account resides.
"},{"location":"snippets/provider-aws-access/#custom-endpoints","title":"Custom Endpoints","text":"You can define custom AWS endpoints if you want to use regional, vpc or custom endpoints. See List of endpoints for Secrets Manager, Secure Systems Manager and Security Token Service.
Use the following environment variables to point the controller to your custom endpoints. Note: All resources managed by this controller are affected.
ENV VAR DESCRIPTION AWS_SECRETSMANAGER_ENDPOINT Endpoint for the Secrets Manager Service. The controller uses this endpoint to fetch secrets from AWS Secrets Manager. AWS_SSM_ENDPOINT Endpoint for the AWS Secure Systems Manager. The controller uses this endpoint to fetch secrets from SSM Parameter Store. AWS_STS_ENDPOINT Endpoint for the Security Token Service. The controller uses this endpoint when creating a session and when doing assumeRole
or assumeRoleWithWebIdentity
calls."}]}
\ No newline at end of file
+{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Introduction","text":"External Secrets Operator is a Kubernetes operator that integrates external secret management systems like AWS Secrets Manager, HashiCorp Vault, Google Secrets Manager, Azure Key Vault, IBM Cloud Secrets Manager, CyberArk Conjur and many more. The operator reads information from external APIs and automatically injects the values into a Kubernetes Secret.
"},{"location":"#what-is-the-goal-of-external-secrets-operator","title":"What is the goal of External Secrets Operator?","text":"The goal of External Secrets Operator is to synchronize secrets from external APIs into Kubernetes. 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.
"},{"location":"#where-to-get-started","title":"Where to get started","text":"To get started, please read through API overview this should give you a high-level overview to understand the API and use-cases. After that please follow one of our guides to get a jump start using the operator. See our getting started guide for installation instructions.
For a complete reference of the API types please refer to our API Reference.
"},{"location":"#how-to-get-involved","title":"How to get involved","text":"This project is driven by its users and contributors, and we welcome everybody to get involved. Join our meetings, open issues or ask questions in Slack. The success of this project depends on your input: No contribution is too small - even opinions matter!
How to get involved:
- Bi-weekly Development Meeting every odd week at 8:00 PM Berlin Time on Wednesday (agenda, jitsi call)
- Kubernetes Slack #external-secrets
- Contributing Process
- Twitter
"},{"location":"#kicked-off-by","title":"Kicked off by","text":""},{"location":"#sponsored-by","title":"Sponsored by","text":""},{"location":"eso-blogs/","title":"ESO Blogs","text":"A list of blogs written by people all over the community. Feel free to let us know if you are writing about ESO at some place! We would be happy to mention you here!
"},{"location":"eso-blogs/#comparing-external-secrets-operator-with-secret-storage-csi-as-kubernetes-external-secrets-is-deprecated","title":"Comparing External Secrets Operator with Secret Storage CSI as Kubernetes External Secrets is Deprecated","text":"@riddle writes about choosing ESO when comparing with Secret Store CSI Driver in their specific use case. They show us the relevant differences between the projects when looking at their scenario and requirements while integrating with ArgoCD. Comparing External Secrets Operator with Secret Storage CSI as Kubernetes External Secrets is Deprecated
"},{"location":"eso-blogs/#tutorial-getting-started-with-external-secrets-operator-on-kubernetes-using-aws-secrets-manager","title":"Tutorial: Getting Started with External Secrets Operator on Kubernetes using AWS Secrets Manager","text":"Puru writes about getting started using ESO with AWS Secrets Manager. He uses illustrations to explain ESO to new users and get's you to quickly start using ESO, as article is easy to follow along. Getting Started with External Secrets Operator on Kubernetes using AWS Secrets Manager
"},{"location":"eso-blogs/#tutorial-how-to-set-external-secrets-with-azure-keyvault","title":"Tutorial: How to Set External-Secrets with Azure KeyVault","text":"Gustavo writes about how to setup ESO with Azure Key Vault and adds an guide on how to make it a bit more secure with OPA (Open Policy Agent). How to Set External-Secrets with Azure KeyVault
"},{"location":"eso-blogs/#tutorial-how-to-set-external-secrets-with-gcp-secret-manager","title":"Tutorial: How to Set External-Secrets with GCP Secret Manager","text":"Gustavo writes about how to setup ESO with GCP Secret Manager. He also shows you how to make a simple multi tenant setup with a ClusterSecretStore. How to Set External-Secrets with GCP Secret Manager
"},{"location":"eso-blogs/#tutorial-how-to-set-external-secrets-with-hashicorp-vault","title":"Tutorial: How to Set External-Secrets with Hashicorp Vault","text":"Gustavo writes about how to setup ESO with Hashicorp Vault. He also shows you how to make this scale with multiple replicas of the operator and leader election enabled to lead balance handling synchronization work. How to Set External-Secrets with Hashicorp Vault
"},{"location":"eso-blogs/#tutorial-how-to-set-external-secrets-with-aws","title":"Tutorial: How to Set External-Secrets with AWS","text":"Gustavo writes about how to setup ESO with AWS Secrets Manager. He also shows you how to limit access and give granular permissions with better policies and roles for your service accounts to use. How to Set External-Secrets with AWS
"},{"location":"eso-blogs/#tutorial-how-to-set-external-secrets-with-ibm-secrets-manager","title":"Tutorial: How to Set External-Secrets with IBM Secrets Manager","text":"In this multi-articles series, Xavier writes about how to setup ESO with IBM Secrets Manager using the web user-interface. Xavier also shares how it is integrated into his pipeline scripts. How to Set External-Secrets with IBM Secrets Manager
"},{"location":"eso-blogs/#kubernetes-hardening-tutorial-part-2-network","title":"Kubernetes Hardening Tutorial Part 2: Network","text":"Tiexin Guo Writes about Kubernetes hardening in this series of blogs. He mentions ESO as one of the convenient options when dealing with secrets in Kubernetes, and how to use it with AWS Secret Manager using AWS credentials. Kubernetes Hardening Tutorial Part 2: Network
"},{"location":"eso-blogs/#tutorial-how-to-manage-secrets-in-openshift-using-vault-and-external-secrets-operator","title":"Tutorial: How to manage secrets in OpenShift using Vault and External Secrets Operator","text":"Balkrishna Pandey published a video tutorial and a blog post on integrating HashiCorp Vault and External Secret Operator (ESO) to manage application secrets on OpenShift Cluster. In this blog, he demonstrates the strength of the ClusterSecretStore
functionality, a cluster scoped SecretStore and is global to the Cluster that all ExternalSecrets
can reference from all namespaces.
"},{"location":"eso-blogs/#tutorial-leverage-aws-secrets-stores-from-eks-fargate-with-external-secrets-operator","title":"Tutorial: Leverage AWS secrets stores from EKS Fargate with External Secrets Operator","text":"In this AWS Containers blog post, Ryan writes about how to leverage External Secret Operator with an EKS Fargate cluster using IAM Roles for Service Accounts (IRSA). This setup supports the requirements of Fargate based workloads. Leverage AWS secrets stores from EKS Fargate with External Secrets Operator
"},{"location":"eso-blogs/#cloud-native-secret-management-with-external-secrets-operator","title":"Cloud Native Secret Management with External Secrets Operator","text":"Emin writes about what problems ESO can solve and how to setup ESO on an Amazon EKS Cluster with integrations for AWS Secrets Manager using IAM Roles for Service Accounts (IRSA). In this blog post, there is also a GitHub repository with example codes for everyone to follow this demonstration.
"},{"location":"eso-blogs/#external-secrets-operator-integration-with-hashicorp-vault","title":"External Secrets Operator Integration with HashiCorp Vault","text":"Emin writes about integration between External Secrets Operator and HashiCorp Vault with a demonstration on installing ESO and Vault on a Kubernetes Cluster and configuration of the permissions and other integration parts.
"},{"location":"eso-blogs/#reversing-the-workflow-with-external-secrets-operators-push-secret-feature","title":"Reversing the Workflow with External Secrets Operator\u2019s Push Secret Feature","text":"Emin writes about the Push Secret feature of ESO and how this new feature reverse the workflow of ESO by pushing Kubernetes secrets to external secret management providers.
"},{"location":"eso-blogs/#gcp-secret-manager-with-self-hosted-kubernetes","title":"GCP Secret Manager with self-hosted Kubernetes","text":"Jacek writes about bringing GCP secrets to on-premises cluster through External Secrets Operator intergration with workload identity.
"},{"location":"eso-demos/","title":"ESO Demos","text":"A list of demos given by people going through simple setups with ESO. Feel free to let us know if you have a demo that you want to include here!
"},{"location":"eso-demos/#manage-kubernetes-secrets-with-external-secrets-operator-on-devops-toolkit","title":"Manage Kubernetes Secrets With External Secrets Operator on DevOps Toolkit","text":"Viktor Farvik shows us how to use ESO with GCP provider and explores a simple workflow with the project.
"},{"location":"eso-demos/#managing-kubernetes-secrets-comparing-external-secrets-operator-and-secrets-store-csi-driver","title":"Managing Kubernetes Secrets: Comparing External Secrets Operator and Secrets Store CSI Driver","text":"Kim Schlesinger and Daniel Hix show us how to install and use both projects, comparing their features and limitations in different situations.
"},{"location":"eso-demos/#gcp-sm-aws-sm-azure-key-vault-demo","title":"GCP SM + AWS SM + Azure Key Vault Demo","text":"This was an old demo going through an old version of ESO. Most of it is still valid, but beware of CRD and breaking change differences.
"},{"location":"eso-demos/#how-to-manage-secrets-in-openshift-using-vault-and-external-secrets-operator","title":"How to manage secrets in OpenShift using Vault and External Secrets Operator","text":"Balkrishna Pandey shows us here how to use ClusterSecretStore and how to integrate ESO with Hashicorp Vault on Openshift.
"},{"location":"eso-demos/#managing-sensitive-data-in-kubernetes-with-sealed-secrets-and-external-secrets-operator-eso","title":"Managing Sensitive Data in Kubernetes with Sealed Secrets and External Secrets Operator (ESO)","text":"Lukonde Mwila demonstrates how ESO works and how to fetch secrets from AWS Secrets Manager into your Kubernetes cluster.
"},{"location":"eso-demos/#external-secrets-operator-a-cloud-native-way-to-manage-your-secrets","title":"External Secrets Operator: A Cloud Native way to manage your secrets","text":"Charl Klein gives an overview of the external secrets project, and a walkthrough of getting ESO up and running with Azure Key Vault
"},{"location":"eso-talks/","title":"ESO Talks","text":"A list of talks given by people at conferences and events. Feel free to let us know if you are talking about ESO at some place! We would be happy to mention you here!
"},{"location":"eso-talks/#kubernetes-community-days-uk","title":"Kubernetes Community Days UK","text":""},{"location":"eso-talks/#cncf-community-groups-canada","title":"CNCF Community Groups Canada","text":""},{"location":"eso-talks/#container-days-hamburg","title":"Container Days Hamburg","text":""},{"location":"eso-talks/#kubernetes-community-days-uk-2022","title":"Kubernetes Community Days UK - 2022","text":""},{"location":"eso-talks/#aws-containers-from-the-couch","title":"AWS Containers from the Couch","text":""},{"location":"eso-talks/#fosdem-23-containers-devroom","title":"FOSDEM '23 (Containers devroom)","text":"FOSDEM '23 (Containers devroom)
"},{"location":"eso-talks/#form3-tech-podcast-building-and-maintaining-external-secrets-operator","title":"Form3 .tech Podcast - Building and maintaining External Secrets Operator","text":"Podcast and Blog
"},{"location":"eso-talks/#enlightning-exploring-external-secrets-operator","title":"\u26a1\ufe0f Enlightning - Exploring External Secrets Operator","text":""},{"location":"eso-talks/#kubecon-eu-23-protecting-your-crown-jewels-with-external-secrets-operator","title":"KubeCon EU '23 - Protecting Your Crown Jewels with External Secrets Operator","text":""},{"location":"provider-passworddepot/","title":"Password Depot","text":"External Secrets Operator integrates with Password Depot API to sync Password Depot to secrets held on the Kubernetes cluster.
"},{"location":"provider-passworddepot/#authentication","title":"Authentication","text":"The API requires a username and password.
apiVersion: v1\nkind: Secret\nmetadata:\n name: password-depot-secret\n labels: \n type: password-depot\ntype: Opaque \nstringData:\n username: the-username-for-password-depot\n password: the secret password\n
"},{"location":"provider-passworddepot/#update-secret-store","title":"Update secret store","text":"Be sure the passworddepot
provider is listed in the Kind=SecretStore
and host and database are set.
apiVersion: external-secrets.io/v1alpha1\nkind: ClusterSecretStore\nmetadata:\n name: external-secrets-store\nspec:\n\n # provider field contains the configuration to access the provider\n # which contains the secret exactly one provider must be configured.\n provider:\n\n passworddepot:\n host: host-of-password-depot # port is 8714 by default\n database: \"password depot database name\"\n auth:\n SecretRef:\n credentials:\n name: password-depot-secret\n namespace: external-secrets\n
"},{"location":"provider-passworddepot/#creating-external-secret","title":"Creating external secret","text":"To sync a Password Depot variable to a secret on the Kubernetes cluster, a Kind=ExternalSecret
is needed.
apiVersion: external-secrets.io/v1alpha1\nkind: ExternalSecret\nmetadata:\n name: passworddepot-external-secret-example\nspec:\n refreshInterval: 1h\n\n secretStoreRef:\n kind: SecretStore\n name: passworddepot-secret-store # Must match SecretStore on the cluster\n\n target:\n name: passworddepot-secret-to-create # Name for the secret to be created on the cluster\n creationPolicy: Owner\n\n data:\n - secretKey: username # Key given to the secret to be created on the cluster\n remoteRef: \n key: Production.mySecret\n property: login # field named in passworddepot\n
"},{"location":"provider-passworddepot/#using-datafrom","title":"Using DataFrom","text":"DataFrom can be used to get a variable as a JSON string and attempt to parse it.
apiVersion: external-secrets.io/v1alpha1\nkind: ExternalSecret\nmetadata:\n name: passworddepot-external-secret-example\nspec:\n refreshInterval: 1h\n\n secretStoreRef:\n kind: SecretStore\n name: passworddepot-secret-store # Must match SecretStore on the cluster\n\n target:\n name: passworddepot-secret-to-create # Name for the secret to be created on the cluster\n creationPolicy: Owner\n\n # each property in the secret will be used as the secret key in the SECRET k8s target object\n dataFrom:\n - key: \"Production.mySecret\" # Key of the secret\n
"},{"location":"provider-passworddepot/#getting-the-kubernetes-secret","title":"Getting the Kubernetes secret","text":"The operator will fetch the project variable and inject it as a Kind=Secret
.
kubectl get secret passworddepot-secret-to-create -o jsonpath='{.data.secretKey}' | base64 -d\n
"},{"location":"spec/","title":"API specification","text":"Packages:
- external-secrets.io/v1beta1
"},{"location":"spec/#external-secrets.io/v1beta1","title":"external-secrets.io/v1beta1","text":"
Package v1beta1 contains resources for external-secrets
Resource Types:
"},{"location":"spec/#external-secrets.io/v1beta1.AWSAuth","title":"AWSAuth","text":" (Appears on: AWSProvider)
AWSAuth tells the controller how to do authentication with aws. Only one of secretRef or jwt can be specified. if none is specified the controller will load credentials using the aws sdk defaults.
Field Description secretRef
AWSAuthSecretRef (Optional) jwt
AWSJWTAuth (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.AWSAuthSecretRef","title":"AWSAuthSecretRef","text":" (Appears on: AWSAuth)
AWSAuthSecretRef holds secret references for AWS credentials both AccessKeyID and SecretAccessKey must be defined in order to properly authenticate.
Field Description accessKeyIDSecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector The AccessKeyID is used for authentication
secretAccessKeySecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector The SecretAccessKey is used for authentication
sessionTokenSecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector The SessionToken used for authentication This must be defined if AccessKeyID and SecretAccessKey are temporary credentials see: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html
"},{"location":"spec/#external-secrets.io/v1beta1.AWSJWTAuth","title":"AWSJWTAuth","text":" (Appears on: AWSAuth)
Authenticate against AWS using service account tokens.
Field Description serviceAccountRef
github.com/external-secrets/external-secrets/apis/meta/v1.ServiceAccountSelector"},{"location":"spec/#external-secrets.io/v1beta1.AWSProvider","title":"AWSProvider","text":" (Appears on: SecretStoreProvider)
AWSProvider configures a store to sync secrets with AWS.
Field Description service
AWSServiceType Service defines which service should be used to fetch the secrets
auth
AWSAuth (Optional) Auth defines the information necessary to authenticate against AWS if not set aws sdk will infer credentials from your environment see: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials
role
string (Optional) Role is a Role ARN which the SecretManager provider will assume
region
string AWS Region to be used for the provider
"},{"location":"spec/#external-secrets.io/v1beta1.AWSServiceType","title":"AWSServiceType (string
alias)","text":" (Appears on: AWSProvider)
AWSServiceType is a enum that defines the service/API that is used to fetch the secrets.
Value Description \"ParameterStore\"
AWSServiceParameterStore is the AWS SystemsManager ParameterStore. see: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html
\"SecretsManager\"
AWSServiceSecretsManager is the AWS SecretsManager. see: https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html
"},{"location":"spec/#external-secrets.io/v1alpha1.AlibabaAuth","title":"AlibabaAuth","text":" (Appears on: AlibabaProvider)
AlibabaAuth contains a secretRef for credentials.
Field Description secretRef
AlibabaAuthSecretRef"},{"location":"spec/#external-secrets.io/v1alpha1.AlibabaAuthSecretRef","title":"AlibabaAuthSecretRef","text":" (Appears on: AlibabaAuth)
AlibabaAuthSecretRef holds secret references for Alibaba credentials.
Field Description accessKeyIDSecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector The AccessKeyID is used for authentication
accessKeySecretSecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector The AccessKeySecret is used for authentication
"},{"location":"spec/#external-secrets.io/v1alpha1.AlibabaProvider","title":"AlibabaProvider","text":" (Appears on: SecretStoreProvider)
AlibabaProvider configures a store to sync secrets using the Alibaba Secret Manager provider.
Field Description auth
AlibabaAuth endpoint
string (Optional) regionID
string Alibaba Region to be used for the provider
"},{"location":"spec/#external-secrets.io/v1alpha1.AzureKVAuth","title":"AzureKVAuth","text":" (Appears on: AkeylessProvider)
Field Description secretRef
AkeylessAuthSecretRef (Optional) Reference to a Secret that contains the details to authenticate with Akeyless.
kubernetesAuth
AkeylessKubernetesAuth (Optional) Kubernetes authenticates with Akeyless by passing the ServiceAccount token stored in the named Secret resource.
"},{"location":"spec/#external-secrets.io/v1beta1.AkeylessAuthSecretRef","title":"AkeylessAuthSecretRef","text":" (Appears on: AkeylessAuth)
AkeylessAuthSecretRef AKEYLESS_ACCESS_TYPE_PARAM: AZURE_OBJ_ID OR GCP_AUDIENCE OR ACCESS_KEY OR KUB_CONFIG_NAME.
Field Description accessID
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector The SecretAccessID is used for authentication
accessType
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector accessTypeParam
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector"},{"location":"spec/#external-secrets.io/v1alpha1.CAProvider","title":"CAProvider","text":" (Appears on: VaultProvider)
Defines a location to fetch the cert for the vault provider from.
Field Description type
CAProviderType The type of provider to use such as \u201cSecret\u201d, or \u201cConfigMap\u201d.
name
string The name of the object located at the provider type.
key
string The key the value inside of the provider type to use, only used with \u201cSecret\u201d type
namespace
string The namespace the Provider type is in.
"},{"location":"spec/#external-secrets.io/v1alpha1.CAProviderType","title":"CAProviderType (string
alias)","text":" (Appears on: CAProvider)
Value Description \"ConfigMap\"
\"Secret\"
"},{"location":"spec/#external-secrets.io/v1alpha1.ClusterSecretStore","title":"ClusterSecretStore","text":" (Appears on: AkeylessAuth)
Authenticate with Kubernetes ServiceAccount token stored.
Field Description accessID
string the Akeyless Kubernetes auth-method access-id
k8sConfName
string Kubernetes-auth configuration name in Akeyless-Gateway
serviceAccountRef
github.com/external-secrets/external-secrets/apis/meta/v1.ServiceAccountSelector (Optional) Optional service account field containing the name of a kubernetes ServiceAccount. If the service account is specified, the service account secret token JWT will be used for authenticating with Akeyless. If the service account selector is not supplied, the secretRef will be used instead.
secretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) Optional secret field containing a Kubernetes ServiceAccount JWT used for authenticating with Akeyless. If a name is specified without a key, token
is the default. If one is not specified, the one bound to the controller will be used.
"},{"location":"spec/#external-secrets.io/v1beta1.AkeylessProvider","title":"AkeylessProvider","text":" (Appears on: SecretStoreProvider)
AkeylessProvider Configures an store to sync secrets using Akeyless KV.
Field Description akeylessGWApiURL
string Akeyless GW API Url from which the secrets to be fetched from.
authSecretRef
AkeylessAuth Auth configures how the operator authenticates with Akeyless.
"},{"location":"spec/#external-secrets.io/v1beta1.AlibabaAuth","title":"AlibabaAuth","text":" (Appears on: AlibabaProvider)
AlibabaAuth contains a secretRef for credentials.
Field Description secretRef
AlibabaAuthSecretRef"},{"location":"spec/#external-secrets.io/v1beta1.AlibabaAuthSecretRef","title":"AlibabaAuthSecretRef","text":" (Appears on: AlibabaAuth)
AlibabaAuthSecretRef holds secret references for Alibaba credentials.
Field Description accessKeyIDSecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector The AccessKeyID is used for authentication
accessKeySecretSecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector The AccessKeySecret is used for authentication
"},{"location":"spec/#external-secrets.io/v1beta1.AlibabaProvider","title":"AlibabaProvider","text":" (Appears on: SecretStoreProvider)
AlibabaProvider configures a store to sync secrets using the Alibaba Secret Manager provider.
Field Description auth
AlibabaAuth endpoint
string (Optional) regionID
string Alibaba Region to be used for the provider
"},{"location":"spec/#external-secrets.io/v1beta1.AzureAuthType","title":"AzureAuthType (string
alias)","text":" (Appears on: AzureKVProvider)
AuthType describes how to authenticate to the Azure Keyvault Only one of the following auth types may be specified. If none of the following auth type is specified, the default one is ServicePrincipal.
Value Description \"ManagedIdentity\"
Using Managed Identity to authenticate. Used with aad-pod-identity installed in the cluster.
\"ServicePrincipal\"
Using service principal to authenticate, which needs a tenantId, a clientId and a clientSecret.
\"WorkloadIdentity\"
Using Workload Identity service accounts to authenticate.
"},{"location":"spec/#external-secrets.io/v1beta1.AzureEnvironmentType","title":"AzureEnvironmentType (string
alias)","text":" (Appears on: AzureKVProvider)
AzureEnvironmentType specifies the Azure cloud environment endpoints to use for connecting and authenticating with Azure. By default it points to the public cloud AAD endpoint. The following endpoints are available, also see here: https://github.com/Azure/go-autorest/blob/main/autorest/azure/environments.go#L152 PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud
Value Description \"ChinaCloud\"
\"GermanCloud\"
\"PublicCloud\"
\"USGovernmentCloud\"
"},{"location":"spec/#external-secrets.io/v1beta1.AzureKVAuth","title":"AzureKVAuth","text":" (Appears on: AzureKVProvider)
Configuration used to authenticate with Azure.
Field Description clientId
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) The Azure clientId of the service principle used for authentication.
clientSecret
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) The Azure ClientSecret of the service principle used for authentication.
"},{"location":"spec/#external-secrets.io/v1beta1.AzureKVProvider","title":"AzureKVProvider","text":" (Appears on: SecretStoreProvider)
Configures an store to sync secrets using Azure KV.
Field Description authType
AzureAuthType (Optional) Auth type defines how to authenticate to the keyvault service. Valid values are: - \u201cServicePrincipal\u201d (default): Using a service principal (tenantId, clientId, clientSecret) - \u201cManagedIdentity\u201d: Using Managed Identity assigned to the pod (see aad-pod-identity)
vaultUrl
string Vault Url from which the secrets to be fetched from.
tenantId
string (Optional) TenantID configures the Azure Tenant to send requests to. Required for ServicePrincipal auth type.
environmentType
AzureEnvironmentType EnvironmentType specifies the Azure cloud environment endpoints to use for connecting and authenticating with Azure. By default it points to the public cloud AAD endpoint. The following endpoints are available, also see here: https://github.com/Azure/go-autorest/blob/main/autorest/azure/environments.go#L152 PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud
authSecretRef
AzureKVAuth (Optional) Auth configures how the operator authenticates with Azure. Required for ServicePrincipal auth type.
serviceAccountRef
github.com/external-secrets/external-secrets/apis/meta/v1.ServiceAccountSelector (Optional) ServiceAccountRef specified the service account that should be used when authenticating with WorkloadIdentity.
identityId
string (Optional) If multiple Managed Identity is assigned to the pod, you can select the one to be used
"},{"location":"spec/#external-secrets.io/v1beta1.CAProvider","title":"CAProvider","text":" (Appears on: KubernetesServer, VaultProvider)
Used to provide custom certificate authority (CA) certificates for a secret store. The CAProvider points to a Secret or ConfigMap resource that contains a PEM-encoded certificate.
Field Description type
CAProviderType The type of provider to use such as \u201cSecret\u201d, or \u201cConfigMap\u201d.
name
string The name of the object located at the provider type.
key
string The key where the CA certificate can be found in the Secret or ConfigMap.
namespace
string (Optional) The namespace the Provider type is in. Can only be defined when used in a ClusterSecretStore.
"},{"location":"spec/#external-secrets.io/v1beta1.CAProviderType","title":"CAProviderType (string
alias)","text":" (Appears on: CAProvider)
Value Description \"ConfigMap\"
\"Secret\"
"},{"location":"spec/#external-secrets.io/v1beta1.CertAuth","title":"CertAuth","text":" (Appears on: KubernetesAuth)
Field Description clientCert
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector clientKey
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector"},{"location":"spec/#external-secrets.io/v1beta1.ClusterExternalSecret","title":"ClusterExternalSecret","text":"
ClusterExternalSecret is the Schema for the clusterexternalsecrets API.
Field Description metadata
Kubernetes meta/v1.ObjectMeta Refer to the Kubernetes API documentation for the fields of the metadata
field. spec
ClusterExternalSecretSpec externalSecretSpec
ExternalSecretSpec The spec for the ExternalSecrets to be created
externalSecretName
string (Optional) The name of the external secrets to be created defaults to the name of the ClusterExternalSecret
namespaceSelector
Kubernetes meta/v1.LabelSelector The labels to select by to find the Namespaces to create the ExternalSecrets in.
refreshTime
Kubernetes meta/v1.Duration The time in which the controller should reconcile it\u2019s objects and recheck namespaces for labels.
status
ClusterExternalSecretStatus"},{"location":"spec/#external-secrets.io/v1beta1.ClusterExternalSecretConditionType","title":"ClusterExternalSecretConditionType (string
alias)","text":" (Appears on: ClusterExternalSecretStatusCondition)
Value Description \"NotReady\"
\"PartiallyReady\"
\"Ready\"
"},{"location":"spec/#external-secrets.io/v1beta1.ClusterExternalSecretNamespaceFailure","title":"ClusterExternalSecretNamespaceFailure","text":" (Appears on: ClusterExternalSecretStatus)
ClusterExternalSecretNamespaceFailure represents a failed namespace deployment and it\u2019s reason.
Field Description namespace
string Namespace is the namespace that failed when trying to apply an ExternalSecret
reason
string (Optional) Reason is why the ExternalSecret failed to apply to the namespace
immutable
bool (Optional) Immutable defines if the final secret will be immutable
"},{"location":"spec/#external-secrets.io/v1beta1.ClusterExternalSecretSpec","title":"ClusterExternalSecretSpec","text":" (Appears on: ClusterExternalSecret)
ClusterExternalSecretSpec defines the desired state of ClusterExternalSecret.
Field Description externalSecretSpec
ExternalSecretSpec The spec for the ExternalSecrets to be created
externalSecretName
string (Optional) The name of the external secrets to be created defaults to the name of the ClusterExternalSecret
namespaceSelector
Kubernetes meta/v1.LabelSelector The labels to select by to find the Namespaces to create the ExternalSecrets in.
refreshTime
Kubernetes meta/v1.Duration The time in which the controller should reconcile it\u2019s objects and recheck namespaces for labels.
"},{"location":"spec/#external-secrets.io/v1beta1.ClusterExternalSecretStatus","title":"ClusterExternalSecretStatus","text":" (Appears on: ClusterExternalSecret)
ClusterExternalSecretStatus defines the observed state of ClusterExternalSecret.
Field Description failedNamespaces
[]ClusterExternalSecretNamespaceFailure (Optional) Failed namespaces are the namespaces that failed to apply an ExternalSecret
provisionedNamespaces
[]string (Optional) ProvisionedNamespaces are the namespaces where the ClusterExternalSecret has secrets
conditions
[]ClusterExternalSecretStatusCondition (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.ClusterExternalSecretStatusCondition","title":"ClusterExternalSecretStatusCondition","text":" (Appears on: ClusterExternalSecretStatus)
Field Description type
ClusterExternalSecretConditionType status
Kubernetes core/v1.ConditionStatus message
string (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.ClusterSecretStore","title":"ClusterSecretStore","text":"
ClusterSecretStore represents a secure external location for storing secrets, which can be referenced as part of storeRef
fields.
Field Description metadata
Kubernetes meta/v1.ObjectMeta Refer to the Kubernetes API documentation for the fields of the metadata
field. spec
SecretStoreSpec controller
string (Optional) Used to select the correct KES controller (think: ingress.ingressClassName) The KES controller is instantiated with a specific controller name and filters ES based on this property
provider
SecretStoreProvider Used to configure the provider. Only one provider may be set
retrySettings
SecretStoreRetrySettings (Optional) Used to configure http retries if failed
refreshInterval
int (Optional) Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
conditions
[]ClusterSecretStoreCondition (Optional) Used to constraint a ClusterSecretStore to specific namespaces. Relevant only to ClusterSecretStore
status
SecretStoreStatus"},{"location":"spec/#external-secrets.io/v1beta1.ClusterSecretStoreCondition","title":"ClusterSecretStoreCondition","text":" (Appears on: SecretStoreSpec)
ClusterSecretStoreCondition describes a condition by which to choose namespaces to process ExternalSecrets in for a ClusterSecretStore instance.
Field Description namespaceSelector
Kubernetes meta/v1.LabelSelector (Optional) Choose namespace using a labelSelector
namespaces
[]string Choose namespaces by name
"},{"location":"spec/#external-secrets.io/v1beta1.DopplerAuth","title":"DopplerAuth","text":" (Appears on: DopplerProvider)
Field Description secretRef
DopplerAuthSecretRef"},{"location":"spec/#external-secrets.io/v1beta1.DopplerAuthSecretRef","title":"DopplerAuthSecretRef","text":" (Appears on: DopplerAuth)
Field Description dopplerToken
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector The DopplerToken is used for authentication. See https://docs.doppler.com/reference/api#authentication for auth token types. The Key attribute defaults to dopplerToken if not specified.
"},{"location":"spec/#external-secrets.io/v1beta1.DopplerProvider","title":"DopplerProvider","text":" (Appears on: SecretStoreProvider)
DopplerProvider configures a store to sync secrets using the Doppler provider. Project and Config are required if not using a Service Token.
Field Description auth
DopplerAuth Auth configures how the Operator authenticates with the Doppler API
project
string (Optional) Doppler project (required if not using a Service Token)
config
string (Optional) Doppler config (required if not using a Service Token)
nameTransformer
string (Optional) Environment variable compatible name transforms that change secret names to a different format
format
string (Optional) Format enables the downloading of secrets as a file (string)
"},{"location":"spec/#external-secrets.io/v1alpha1.OracleAuth","title":"OracleAuth","text":" (Appears on: OracleProvider)
Field Description secretRef
OracleSecretRef SecretRef to pass through sensitive information.
"},{"location":"spec/#external-secrets.io/v1alpha1.OracleProvider","title":"OracleProvider","text":" (Appears on: SecretStoreProvider)
Configures an store to sync secrets using a Oracle Vault backend.
Field Description auth
OracleAuth Auth configures how secret-manager authenticates with the Oracle Vault.
user
string User is an access OCID specific to the account.
tenancy
string projectID is an access token specific to the secret.
region
string projectID is an access token specific to the secret.
"},{"location":"spec/#external-secrets.io/v1alpha1.OracleSecretRef","title":"OracleSecretRef","text":" (Appears on: OracleAuth)
Field Description privatekey
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector The Access Token is used for authentication
fingerprint
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector projectID is an access token specific to the secret.
"},{"location":"spec/#external-secrets.io/v1alpha1.PasswordDepotAuth","title":"PasswordDepotAuth","text":" (Appears on: PasswordDepotProvider)
Field Description SecretRef
PasswordDepotSecretRef"},{"location":"spec/#external-secrets.io/v1alpha1.PasswordDepotProvider","title":"PasswordDepotProvider","text":" (Appears on: SecretStoreProvider)
Configures a store to sync secrets with a Password Depot instance.
Field Description host
string URL configures the Password Depot instance URL.
database
string Database to use as source
auth
PasswordDepotAuth Auth configures how secret-manager authenticates with a Password Depot instance.
"},{"location":"spec/#external-secrets.io/v1alpha1.PasswordDepotSecretRef","title":"PasswordDepotSecretRef","text":" (Appears on: PasswordDepotAuth)
Field Description credentials
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector Username / Password is used for authentication.
"},{"location":"spec/#external-secrets.io/v1alpha1.SecretStore","title":"SecretStore","text":"
ExternalSecret is the Schema for the external-secrets API.
Field Description metadata
Kubernetes meta/v1.ObjectMeta Refer to the Kubernetes API documentation for the fields of the metadata
field. spec
ExternalSecretSpec secretStoreRef
SecretStoreRef (Optional) target
ExternalSecretTarget (Optional) refreshInterval
Kubernetes meta/v1.Duration RefreshInterval is the amount of time before the values are read again from the SecretStore provider Valid time units are \u201cns\u201d, \u201cus\u201d (or \u201c\u00b5s\u201d), \u201cms\u201d, \u201cs\u201d, \u201cm\u201d, \u201ch\u201d May be set to zero to fetch and create it once. Defaults to 1h.
data
[]ExternalSecretData (Optional) Data defines the connection between the Kubernetes Secret keys and the Provider data
dataFrom
[]ExternalSecretDataFromRemoteRef (Optional) DataFrom is used to fetch all properties from a specific Provider data If multiple entries are specified, the Secret keys are merged in the specified order
status
ExternalSecretStatus"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretConditionType","title":"ExternalSecretConditionType (string
alias)","text":" (Appears on: ExternalSecretStatusCondition)
Value Description \"Deleted\"
\"Ready\"
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretConversionStrategy","title":"ExternalSecretConversionStrategy (string
alias)","text":" (Appears on: ExternalSecretDataRemoteRef, ExternalSecretFind)
Value Description \"Default\"
\"Unicode\"
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretCreationPolicy","title":"ExternalSecretCreationPolicy (string
alias)","text":" (Appears on: ExternalSecretTarget)
ExternalSecretCreationPolicy defines rules on how to create the resulting Secret.
Value Description \"Merge\"
Merge does not create the Secret, but merges the data fields to the Secret.
\"None\"
None does not create a Secret (future use with injector).
\"Orphan\"
Orphan creates the Secret and does not set the ownerReference. I.e. it will be orphaned after the deletion of the ExternalSecret.
\"Owner\"
Owner creates the Secret and sets .metadata.ownerReferences to the ExternalSecret resource.
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretData","title":"ExternalSecretData","text":" (Appears on: ExternalSecretSpec)
ExternalSecretData defines the connection between the Kubernetes Secret key (spec.data.) and the Provider data. Field Description secretKey
string
SecretKey defines the key in which the controller stores the value. This is the key in the Kind=Secret
remoteRef
ExternalSecretDataRemoteRef RemoteRef points to the remote secret and defines which secret (version/property/..) to fetch.
sourceRef
SourceRef SourceRef allows you to override the source from which the value will pulled from.
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretDataFromRemoteRef","title":"ExternalSecretDataFromRemoteRef","text":" (Appears on: ExternalSecretSpec)
Field Description extract
ExternalSecretDataRemoteRef (Optional) Used to extract multiple key/value pairs from one secret Note: Extract does not support sourceRef.Generator or sourceRef.GeneratorRef.
find
ExternalSecretFind (Optional) Used to find secrets based on tags or regular expressions Note: Find does not support sourceRef.Generator or sourceRef.GeneratorRef.
rewrite
[]ExternalSecretRewrite (Optional) Used to rewrite secret Keys after getting them from the secret Provider Multiple Rewrite operations can be provided. They are applied in a layered order (first to last)
sourceRef
SourceRef SourceRef points to a store or generator which contains secret values ready to use. Use this in combination with Extract or Find pull values out of a specific SecretStore. When sourceRef points to a generator Extract or Find is not supported. The generator returns a static map of values
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretDataRemoteRef","title":"ExternalSecretDataRemoteRef","text":" (Appears on: ExternalSecretData, ExternalSecretDataFromRemoteRef)
ExternalSecretDataRemoteRef defines Provider data location.
Field Description key
string Key is the key used in the Provider, mandatory
metadataPolicy
ExternalSecretMetadataPolicy (Optional) Policy for fetching tags/labels from provider secrets, possible options are Fetch, None. Defaults to None
property
string (Optional) Used to select a specific property of the Provider value (if a map), if supported
version
string (Optional) Used to select a specific version of the Provider value, if supported
conversionStrategy
ExternalSecretConversionStrategy (Optional) Used to define a conversion Strategy
decodingStrategy
ExternalSecretDecodingStrategy (Optional) Used to define a decoding Strategy
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretDecodingStrategy","title":"ExternalSecretDecodingStrategy (string
alias)","text":" (Appears on: ExternalSecretDataRemoteRef, ExternalSecretFind)
Value Description \"Auto\"
\"Base64\"
\"Base64URL\"
\"None\"
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretDeletionPolicy","title":"ExternalSecretDeletionPolicy (string
alias)","text":" (Appears on: ExternalSecretTarget)
ExternalSecretDeletionPolicy defines rules on how to delete the resulting Secret.
Value Description \"Delete\"
Delete deletes the secret if all provider secrets are deleted. If a secret gets deleted on the provider side and is not accessible anymore this is not considered an error and the ExternalSecret does not go into SecretSyncedError status.
\"Merge\"
Merge removes keys in the secret, but not the secret itself. If a secret gets deleted on the provider side and is not accessible anymore this is not considered an error and the ExternalSecret does not go into SecretSyncedError status.
\"Retain\"
Retain will retain the secret if all provider secrets have been deleted. If a provider secret does not exist the ExternalSecret gets into the SecretSyncedError status.
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretFind","title":"ExternalSecretFind","text":" (Appears on: ExternalSecretDataFromRemoteRef)
Field Description path
string (Optional) A root path to start the find operations.
name
FindName (Optional) Finds secrets based on the name.
tags
map[string]string (Optional) Find secrets based on tags.
conversionStrategy
ExternalSecretConversionStrategy (Optional) Used to define a conversion Strategy
decodingStrategy
ExternalSecretDecodingStrategy (Optional) Used to define a decoding Strategy
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretMetadataPolicy","title":"ExternalSecretMetadataPolicy (string
alias)","text":" (Appears on: ExternalSecretDataRemoteRef)
Value Description \"Fetch\"
\"None\"
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretRewrite","title":"ExternalSecretRewrite","text":" (Appears on: ExternalSecretDataFromRemoteRef)
Field Description regexp
ExternalSecretRewriteRegexp (Optional) Used to rewrite with regular expressions. The resulting key will be the output of a regexp.ReplaceAll operation.
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretRewriteRegexp","title":"ExternalSecretRewriteRegexp","text":" (Appears on: ExternalSecretRewrite)
Field Description source
string Used to define the regular expression of a re.Compiler.
target
string Used to define the target pattern of a ReplaceAll operation.
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretSpec","title":"ExternalSecretSpec","text":" (Appears on: ClusterExternalSecretSpec, ExternalSecret)
ExternalSecretSpec defines the desired state of ExternalSecret.
Field Description secretStoreRef
SecretStoreRef (Optional) target
ExternalSecretTarget (Optional) refreshInterval
Kubernetes meta/v1.Duration RefreshInterval is the amount of time before the values are read again from the SecretStore provider Valid time units are \u201cns\u201d, \u201cus\u201d (or \u201c\u00b5s\u201d), \u201cms\u201d, \u201cs\u201d, \u201cm\u201d, \u201ch\u201d May be set to zero to fetch and create it once. Defaults to 1h.
data
[]ExternalSecretData (Optional) Data defines the connection between the Kubernetes Secret keys and the Provider data
dataFrom
[]ExternalSecretDataFromRemoteRef (Optional) DataFrom is used to fetch all properties from a specific Provider data If multiple entries are specified, the Secret keys are merged in the specified order
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretStatus","title":"ExternalSecretStatus","text":" (Appears on: ExternalSecret)
Field Description refreshTime
Kubernetes meta/v1.Time refreshTime is the time and date the external secret was fetched and the target secret updated
syncedResourceVersion
string SyncedResourceVersion keeps track of the last synced version
conditions
[]ExternalSecretStatusCondition (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretStatusCondition","title":"ExternalSecretStatusCondition","text":" (Appears on: ExternalSecretStatus)
Field Description type
ExternalSecretConditionType status
Kubernetes core/v1.ConditionStatus reason
string (Optional) message
string (Optional) lastTransitionTime
Kubernetes meta/v1.Time (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretTarget","title":"ExternalSecretTarget","text":" (Appears on: ExternalSecretSpec)
ExternalSecretTarget defines the Kubernetes Secret to be created There can be only one target per ExternalSecret.
Field Description name
string (Optional) Name defines the name of the Secret resource to be managed This field is immutable Defaults to the .metadata.name of the ExternalSecret resource
creationPolicy
ExternalSecretCreationPolicy (Optional) CreationPolicy defines rules on how to create the resulting Secret Defaults to \u2018Owner\u2019
deletionPolicy
ExternalSecretDeletionPolicy (Optional) DeletionPolicy defines rules on how to delete the resulting Secret Defaults to \u2018Retain\u2019
template
ExternalSecretTemplate (Optional) Template defines a blueprint for the created Secret resource.
immutable
bool (Optional) Immutable defines if the final secret will be immutable
"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretTemplate","title":"ExternalSecretTemplate","text":" (Appears on: ExternalSecretTarget)
ExternalSecretTemplate defines a blueprint for the created Secret resource. we can not use native corev1.Secret, it will have empty ObjectMeta values: https://github.com/kubernetes-sigs/controller-tools/issues/448
Field Description type
Kubernetes core/v1.SecretType (Optional) engineVersion
TemplateEngineVersion metadata
ExternalSecretTemplateMetadata (Optional) data
map[string]string (Optional) templateFrom
[]TemplateFrom (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretTemplateMetadata","title":"ExternalSecretTemplateMetadata","text":" (Appears on: ExternalSecretTemplate)
ExternalSecretTemplateMetadata defines metadata fields for the Secret blueprint.
Field Description annotations
map[string]string (Optional) labels
map[string]string (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretValidator","title":"ExternalSecretValidator","text":""},{"location":"spec/#external-secrets.io/v1beta1.FakeProvider","title":"FakeProvider","text":" (Appears on: SecretStoreProvider)
FakeProvider configures a fake provider that returns static values.
Field Description data
[]FakeProviderData"},{"location":"spec/#external-secrets.io/v1beta1.FakeProviderData","title":"FakeProviderData","text":" (Appears on: FakeProvider)
Field Description key
string value
string valueMap
map[string]string version
string"},{"location":"spec/#external-secrets.io/v1beta1.FindName","title":"FindName","text":" (Appears on: ExternalSecretFind)
Field Description regexp
string (Optional) Finds secrets base
"},{"location":"spec/#external-secrets.io/v1beta1.GCPSMAuth","title":"GCPSMAuth","text":" (Appears on: GCPSMProvider)
Field Description secretRef
GCPSMAuthSecretRef (Optional) workloadIdentity
GCPWorkloadIdentity (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.GCPSMAuthSecretRef","title":"GCPSMAuthSecretRef","text":" (Appears on: GCPSMAuth)
Field Description secretAccessKeySecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) The SecretAccessKey is used for authentication
"},{"location":"spec/#external-secrets.io/v1beta1.GCPSMProvider","title":"GCPSMProvider","text":" (Appears on: SecretStoreProvider)
GCPSMProvider Configures a store to sync secrets using the GCP Secret Manager provider.
Field Description auth
GCPSMAuth (Optional) Auth defines the information necessary to authenticate against GCP
projectID
string ProjectID project where secret is located
"},{"location":"spec/#external-secrets.io/v1beta1.GCPWorkloadIdentity","title":"GCPWorkloadIdentity","text":" (Appears on: GCPSMAuth)
Field Description serviceAccountRef
github.com/external-secrets/external-secrets/apis/meta/v1.ServiceAccountSelector clusterLocation
string clusterName
string clusterProjectID
string"},{"location":"spec/#external-secrets.io/v1beta1.GeneratorRef","title":"GeneratorRef","text":" (Appears on: SourceRef)
GeneratorRef points to a generator custom resource.
Field Description apiVersion
string Specify the apiVersion of the generator resource
kind
string Specify the Kind of the resource, e.g. Password, ACRAccessToken etc.
name
string Specify the name of the generator resource
"},{"location":"spec/#external-secrets.io/v1beta1.GenericStore","title":"GenericStore","text":"
GenericStore is a common interface for interacting with ClusterSecretStore or a namespaced SecretStore.
"},{"location":"spec/#external-secrets.io/v1beta1.GenericStoreValidator","title":"GenericStoreValidator","text":""},{"location":"spec/#external-secrets.io/v1beta1.GitlabAuth","title":"GitlabAuth","text":" (Appears on: GitlabProvider)
Field Description SecretRef
GitlabSecretRef"},{"location":"spec/#external-secrets.io/v1beta1.GitlabProvider","title":"GitlabProvider","text":" (Appears on: SecretStoreProvider)
Configures a store to sync secrets with a GitLab instance.
Field Description url
string URL configures the GitLab instance URL. Defaults to https://gitlab.com/.
auth
GitlabAuth Auth configures how secret-manager authenticates with a GitLab instance.
projectID
string ProjectID specifies a project where secrets are located.
inheritFromGroups
bool InheritFromGroups specifies whether parent groups should be discovered and checked for secrets.
groupIDs
[]string GroupIDs specify, which gitlab groups to pull secrets from. Group secrets are read from left to right followed by the project variables.
environment
string Environment environment_scope of gitlab CI/CD variables (Please see https://docs.gitlab.com/ee/ci/environments/#create-a-static-environment on how to create environments)
"},{"location":"spec/#external-secrets.io/v1beta1.GitlabSecretRef","title":"GitlabSecretRef","text":" (Appears on: GitlabAuth)
Field Description accessToken
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector AccessToken is used for authentication.
"},{"location":"spec/#external-secrets.io/v1beta1.IBMAuth","title":"IBMAuth","text":" (Appears on: IBMProvider)
Field Description secretRef
IBMAuthSecretRef containerAuth
IBMAuthContainerAuth"},{"location":"spec/#external-secrets.io/v1beta1.IBMAuthContainerAuth","title":"IBMAuthContainerAuth","text":" (Appears on: IBMAuth)
IBM Container-based auth with IAM Trusted Profile.
Field Description profile
string the IBM Trusted Profile
tokenLocation
string Location the token is mounted on the pod
iamEndpoint
string"},{"location":"spec/#external-secrets.io/v1beta1.IBMAuthSecretRef","title":"IBMAuthSecretRef","text":" (Appears on: IBMAuth)
Field Description secretApiKeySecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector The SecretAccessKey is used for authentication
"},{"location":"spec/#external-secrets.io/v1beta1.IBMProvider","title":"IBMProvider","text":" (Appears on: SecretStoreProvider)
Configures an store to sync secrets using a IBM Cloud Secrets Manager backend.
Field Description auth
IBMAuth Auth configures how secret-manager authenticates with the IBM secrets manager.
serviceUrl
string ServiceURL is the Endpoint URL that is specific to the Secrets Manager service instance
"},{"location":"spec/#external-secrets.io/v1beta1.KubernetesAuth","title":"KubernetesAuth","text":" (Appears on: KubernetesProvider)
Field Description cert
CertAuth (Optional) has both clientCert and clientKey as secretKeySelector
token
TokenAuth (Optional) use static token to authenticate with
serviceAccount
github.com/external-secrets/external-secrets/apis/meta/v1.ServiceAccountSelector (Optional) points to a service account that should be used for authentication
"},{"location":"spec/#external-secrets.io/v1beta1.KubernetesProvider","title":"KubernetesProvider","text":" (Appears on: SecretStoreProvider)
Configures a store to sync secrets with a Kubernetes instance.
Field Description server
KubernetesServer configures the Kubernetes server Address.
auth
KubernetesAuth Auth configures how secret-manager authenticates with a Kubernetes instance.
remoteNamespace
string (Optional) Remote namespace to fetch the secrets from
"},{"location":"spec/#external-secrets.io/v1beta1.KubernetesServer","title":"KubernetesServer","text":" (Appears on: KubernetesProvider)
Field Description url
string (Optional) configures the Kubernetes server Address.
caBundle
[]byte (Optional) CABundle is a base64-encoded CA certificate
caProvider
CAProvider (Optional) see: https://external-secrets.io/v0.4.1/spec/#external-secrets.io/v1alpha1.CAProvider
"},{"location":"spec/#external-secrets.io/v1beta1.NoSecretError","title":"NoSecretError","text":"
NoSecretError shall be returned when a GetSecret can not find the desired secret. This is used for deletionPolicy.
"},{"location":"spec/#external-secrets.io/v1beta1.OnePasswordAuth","title":"OnePasswordAuth","text":" (Appears on: OnePasswordProvider)
OnePasswordAuth contains a secretRef for credentials.
Field Description secretRef
OnePasswordAuthSecretRef"},{"location":"spec/#external-secrets.io/v1beta1.OnePasswordAuthSecretRef","title":"OnePasswordAuthSecretRef","text":" (Appears on: OnePasswordAuth)
OnePasswordAuthSecretRef holds secret references for 1Password credentials.
Field Description connectTokenSecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector The ConnectToken is used for authentication to a 1Password Connect Server.
"},{"location":"spec/#external-secrets.io/v1beta1.OnePasswordProvider","title":"OnePasswordProvider","text":" (Appears on: SecretStoreProvider)
OnePasswordProvider configures a store to sync secrets using the 1Password Secret Manager provider.
Field Description auth
OnePasswordAuth Auth defines the information necessary to authenticate against OnePassword Connect Server
connectHost
string ConnectHost defines the OnePassword Connect Server to connect to
vaults
map[string]int Vaults defines which OnePassword vaults to search in which order
"},{"location":"spec/#external-secrets.io/v1beta1.OracleAuth","title":"OracleAuth","text":" (Appears on: OracleProvider)
Field Description tenancy
string Tenancy is the tenancy OCID where user is located.
user
string User is an access OCID specific to the account.
secretRef
OracleSecretRef SecretRef to pass through sensitive information.
"},{"location":"spec/#external-secrets.io/v1beta1.OracleProvider","title":"OracleProvider","text":" (Appears on: SecretStoreProvider)
Configures an store to sync secrets using a Oracle Vault backend.
Field Description region
string Region is the region where vault is located.
vault
string Vault is the vault\u2019s OCID of the specific vault where secret is located.
auth
OracleAuth (Optional) Auth configures how secret-manager authenticates with the Oracle Vault. If empty, use the instance principal, otherwise the user credentials specified in Auth.
"},{"location":"spec/#external-secrets.io/v1beta1.OracleSecretRef","title":"OracleSecretRef","text":" (Appears on: OracleAuth)
Field Description privatekey
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector PrivateKey is the user\u2019s API Signing Key in PEM format, used for authentication.
fingerprint
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector Fingerprint is the fingerprint of the API private key.
"},{"location":"spec/#external-secrets.io/v1beta1.Provider","title":"Provider","text":"
Provider is a common interface for interacting with secret backends.
"},{"location":"spec/#external-secrets.io/v1beta1.SecretStore","title":"SecretStore","text":"
SecretStore represents a secure external location for storing secrets, which can be referenced as part of storeRef
fields.
Field Description metadata
Kubernetes meta/v1.ObjectMeta Refer to the Kubernetes API documentation for the fields of the metadata
field. spec
SecretStoreSpec controller
string (Optional) Used to select the correct KES controller (think: ingress.ingressClassName) The KES controller is instantiated with a specific controller name and filters ES based on this property
provider
SecretStoreProvider Used to configure the provider. Only one provider may be set
retrySettings
SecretStoreRetrySettings (Optional) Used to configure http retries if failed
refreshInterval
int (Optional) Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
conditions
[]ClusterSecretStoreCondition (Optional) Used to constraint a ClusterSecretStore to specific namespaces. Relevant only to ClusterSecretStore
status
SecretStoreStatus"},{"location":"spec/#external-secrets.io/v1beta1.SecretStoreConditionType","title":"SecretStoreConditionType (string
alias)","text":" (Appears on: SecretStoreStatusCondition)
Value Description \"Ready\"
"},{"location":"spec/#external-secrets.io/v1beta1.SecretStoreProvider","title":"SecretStoreProvider","text":" (Appears on: SecretStoreSpec)
SecretStoreProvider contains the provider-specific configuration.
Field Description aws
AWSProvider (Optional) AWS configures this store to sync secrets using AWS Secret Manager provider
azurekv
AzureKVProvider (Optional) AzureKV configures this store to sync secrets using Azure Key Vault provider
akeyless
AkeylessProvider (Optional) Akeyless configures this store to sync secrets using Akeyless Vault provider
vault
VaultProvider (Optional) Vault configures this store to sync secrets using Hashi provider
gcpsm
GCPSMProvider (Optional) GCPSM configures this store to sync secrets using Google Cloud Platform Secret Manager provider
oracle
OracleProvider (Optional) Oracle configures this store to sync secrets using Oracle Vault provider
ibm
IBMProvider (Optional) IBM configures this store to sync secrets using IBM Cloud provider
yandexcertificatemanager
YandexCertificateManagerProvider (Optional) YandexCertificateManager configures this store to sync secrets using Yandex Certificate Manager provider
yandexlockbox
YandexLockboxProvider (Optional) YandexLockbox configures this store to sync secrets using Yandex Lockbox provider
gitlab
GitlabProvider (Optional) GitLab configures this store to sync secrets using GitLab Variables provider
alibaba
AlibabaProvider (Optional) Alibaba configures this store to sync secrets using Alibaba Cloud provider
onepassword
OnePasswordProvider (Optional) OnePassword configures this store to sync secrets using the 1Password Cloud provider
webhook
WebhookProvider (Optional) Webhook configures this store to sync secrets using a generic templated webhook
kubernetes
KubernetesProvider (Optional) Kubernetes configures this store to sync secrets using a Kubernetes cluster provider
fake
FakeProvider (Optional) Fake configures a store with static key/value pairs
senhasegura
SenhaseguraProvider (Optional) Senhasegura configures this store to sync secrets using senhasegura provider
doppler
DopplerProvider (Optional) Doppler configures this store to sync secrets using the Doppler provider
"},{"location":"spec/#external-secrets.io/v1beta1.SecretStoreRef","title":"SecretStoreRef","text":" (Appears on: ExternalSecretSpec, SourceRef)
SecretStoreRef defines which SecretStore to fetch the ExternalSecret data.
Field Description name
string Name of the SecretStore resource
kind
string (Optional) Kind of the SecretStore resource (SecretStore or ClusterSecretStore) Defaults to SecretStore
"},{"location":"spec/#external-secrets.io/v1beta1.SecretStoreRetrySettings","title":"SecretStoreRetrySettings","text":" (Appears on: SecretStoreSpec)
Field Description maxRetries
int32 retryInterval
string"},{"location":"spec/#external-secrets.io/v1beta1.SecretStoreSpec","title":"SecretStoreSpec","text":" (Appears on: ClusterSecretStore, SecretStore)
SecretStoreSpec defines the desired state of SecretStore.
Field Description controller
string (Optional) Used to select the correct KES controller (think: ingress.ingressClassName) The KES controller is instantiated with a specific controller name and filters ES based on this property
provider
SecretStoreProvider Used to configure the provider. Only one provider may be set
retrySettings
SecretStoreRetrySettings (Optional) Used to configure http retries if failed
refreshInterval
int (Optional) Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
conditions
[]ClusterSecretStoreCondition (Optional) Used to constraint a ClusterSecretStore to specific namespaces. Relevant only to ClusterSecretStore
"},{"location":"spec/#external-secrets.io/v1beta1.SecretStoreStatus","title":"SecretStoreStatus","text":" (Appears on: ClusterSecretStore, SecretStore)
SecretStoreStatus defines the observed state of the SecretStore.
Field Description conditions
[]SecretStoreStatusCondition (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.SecretStoreStatusCondition","title":"SecretStoreStatusCondition","text":" (Appears on: SecretStoreStatus)
Field Description type
SecretStoreConditionType status
Kubernetes core/v1.ConditionStatus reason
string (Optional) message
string (Optional) lastTransitionTime
Kubernetes meta/v1.Time (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.SecretsClient","title":"SecretsClient","text":"
SecretsClient provides access to secrets.
"},{"location":"spec/#external-secrets.io/v1beta1.SenhaseguraAuth","title":"SenhaseguraAuth","text":" (Appears on: SenhaseguraProvider)
SenhaseguraAuth tells the controller how to do auth in senhasegura.
Field Description clientId
string clientSecretSecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector"},{"location":"spec/#external-secrets.io/v1beta1.SenhaseguraModuleType","title":"SenhaseguraModuleType (string
alias)","text":" (Appears on: SenhaseguraProvider)
SenhaseguraModuleType enum defines senhasegura target module to fetch secrets
Value Description \"DSM\"
SenhaseguraModuleDSM is the senhasegura DevOps Secrets Management module\nsee: https://senhasegura.com/devops\n
"},{"location":"spec/#external-secrets.io/v1beta1.SenhaseguraProvider","title":"SenhaseguraProvider","text":" (Appears on: SecretStoreProvider)
SenhaseguraProvider setup a store to sync secrets with senhasegura.
Field Description url
string URL of senhasegura
module
SenhaseguraModuleType Module defines which senhasegura module should be used to get secrets
auth
SenhaseguraAuth Auth defines parameters to authenticate in senhasegura
ignoreSslCertificate
bool IgnoreSslCertificate defines if SSL certificate must be ignored
"},{"location":"spec/#external-secrets.io/v1beta1.SourceRef","title":"SourceRef","text":" (Appears on: ExternalSecretData, ExternalSecretDataFromRemoteRef)
SourceRef allows you to override the source from which the secret will be pulled from. You can define at maximum one property.
Field Description storeRef
SecretStoreRef (Optional) generatorRef
GeneratorRef (Optional) GeneratorRef points to a generator custom resource in
"},{"location":"spec/#external-secrets.io/v1beta1.TemplateEngineVersion","title":"TemplateEngineVersion (string
alias)","text":" (Appears on: ExternalSecretTemplate)
Value Description \"v1\"
\"v2\"
"},{"location":"spec/#external-secrets.io/v1beta1.TemplateFrom","title":"TemplateFrom","text":" (Appears on: ExternalSecretTemplate)
Field Description configMap
TemplateRef secret
TemplateRef scope
TemplateScope (Optional) target
TemplateTarget (Optional) literal
string (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.TemplateRef","title":"TemplateRef","text":" (Appears on: TemplateFrom)
Field Description name
string items
[]TemplateRefItem"},{"location":"spec/#external-secrets.io/v1beta1.TemplateRefItem","title":"TemplateRefItem","text":" (Appears on: TemplateRef)
Field Description key
string"},{"location":"spec/#external-secrets.io/v1beta1.TemplateScope","title":"TemplateScope (string
alias)","text":" (Appears on: TemplateFrom)
Value Description \"KeysAndValues\"
\"Values\"
"},{"location":"spec/#external-secrets.io/v1beta1.TemplateTarget","title":"TemplateTarget (string
alias)","text":" (Appears on: TemplateFrom)
Value Description \"Annotations\"
\"Data\"
\"Labels\"
\"StringData\"
"},{"location":"spec/#external-secrets.io/v1beta1.TokenAuth","title":"TokenAuth","text":" (Appears on: KubernetesAuth)
Field Description bearerToken
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector"},{"location":"spec/#external-secrets.io/v1beta1.ValidationResult","title":"ValidationResult (byte
alias)","text":"Value Description 2
Error indicates that there is a misconfiguration.
0
Ready indicates that the client is configured correctly and can be used.
1
Unknown indicates that the client can be used but information is missing and it can not be validated.
"},{"location":"spec/#external-secrets.io/v1beta1.VaultAppRole","title":"VaultAppRole","text":" (Appears on: VaultAuth)
VaultAppRole authenticates with Vault using the App Role auth mechanism, with the role and secret stored in a Kubernetes Secret resource.
Field Description path
string Path where the App Role authentication backend is mounted in Vault, e.g: \u201capprole\u201d
roleId
string RoleID configured in the App Role authentication backend when setting up the authentication backend in Vault.
secretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector Reference to a key in a Secret that contains the App Role secret used to authenticate with Vault. The key
field must be specified and denotes which entry within the Secret resource is used as the app role secret.
"},{"location":"spec/#external-secrets.io/v1beta1.VaultAuth","title":"VaultAuth","text":" (Appears on: VaultProvider)
VaultAuth is the configuration used to authenticate with a Vault server. Only one of tokenSecretRef
, appRole
, kubernetes
, ldap
, userPass
, jwt
or cert
can be specified.
Field Description tokenSecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) TokenSecretRef authenticates with Vault by presenting a token.
appRole
VaultAppRole (Optional) AppRole authenticates with Vault using the App Role auth mechanism, with the role and secret stored in a Kubernetes Secret resource.
kubernetes
VaultKubernetesAuth (Optional) Kubernetes authenticates with Vault by passing the ServiceAccount token stored in the named Secret resource to the Vault server.
ldap
VaultLdapAuth (Optional) Ldap authenticates with Vault by passing username/password pair using the LDAP authentication method
userPass
VaultUserPassAuth (Optional) UserPass authenticates with Vault by passing username/password pair using the userPass authentication method
jwt
VaultJwtAuth (Optional) Jwt authenticates with Vault by passing role and JWT token using the JWT/OIDC authentication method
cert
VaultCertAuth (Optional) Cert authenticates with TLS Certificates by passing client certificate, private key and ca certificate Cert authentication method
"},{"location":"spec/#external-secrets.io/v1beta1.VaultCertAuth","title":"VaultCertAuth","text":" (Appears on: VaultAuth)
VaultJwtAuth authenticates with Vault using the JWT/OIDC authentication method, with the role name and token stored in a Kubernetes Secret resource.
Field Description clientCert
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) ClientCert is a certificate to authenticate using the Cert Vault authentication method
secretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector SecretRef to a key in a Secret resource containing client private key to authenticate with Vault using the Cert authentication method
"},{"location":"spec/#external-secrets.io/v1beta1.VaultJwtAuth","title":"VaultJwtAuth","text":" (Appears on: VaultAuth)
VaultJwtAuth authenticates with Vault using the JWT/OIDC authentication method, with the role name and a token stored in a Kubernetes Secret resource or a Kubernetes service account token retrieved via TokenRequest
.
Field Description path
string Path where the JWT authentication backend is mounted in Vault, e.g: \u201cjwt\u201d
role
string (Optional) Role is a JWT role to authenticate using the JWT/OIDC Vault authentication method
secretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) Optional SecretRef that refers to a key in a Secret resource containing JWT token to authenticate with Vault using the JWT/OIDC authentication method.
kubernetesServiceAccountToken
VaultKubernetesServiceAccountTokenAuth (Optional) Optional ServiceAccountToken specifies the Kubernetes service account for which to request a token for with the TokenRequest
API.
"},{"location":"spec/#external-secrets.io/v1beta1.VaultKVStoreVersion","title":"VaultKVStoreVersion (string
alias)","text":" (Appears on: VaultProvider)
Value Description \"v1\"
\"v2\"
"},{"location":"spec/#external-secrets.io/v1beta1.VaultKubernetesAuth","title":"VaultKubernetesAuth","text":" (Appears on: VaultAuth)
Authenticate against Vault using a Kubernetes ServiceAccount token stored in a Secret.
Field Description mountPath
string Path where the Kubernetes authentication backend is mounted in Vault, e.g: \u201ckubernetes\u201d
serviceAccountRef
github.com/external-secrets/external-secrets/apis/meta/v1.ServiceAccountSelector (Optional) Optional service account field containing the name of a kubernetes ServiceAccount. If the service account is specified, the service account secret token JWT will be used for authenticating with Vault. If the service account selector is not supplied, the secretRef will be used instead.
secretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) Optional secret field containing a Kubernetes ServiceAccount JWT used for authenticating with Vault. If a name is specified without a key, token
is the default. If one is not specified, the one bound to the controller will be used.
role
string A required field containing the Vault Role to assume. A Role binds a Kubernetes ServiceAccount with a set of Vault policies.
"},{"location":"spec/#external-secrets.io/v1beta1.VaultKubernetesServiceAccountTokenAuth","title":"VaultKubernetesServiceAccountTokenAuth","text":" (Appears on: VaultJwtAuth)
VaultKubernetesServiceAccountTokenAuth authenticates with Vault using a temporary Kubernetes service account token retrieved by the TokenRequest
API.
Field Description oracle
OracleProvider (Optional) Oracle configures this store to sync secrets using Oracle Vault provider
ibm
github.com/external-secrets/external-secrets/apis/meta/v1.ServiceAccountSelector Service account field containing the name of a kubernetes ServiceAccount.
audiences
[]string (Optional) Optional audiences field that will be used to request a temporary Kubernetes service account token for the service account referenced by serviceAccountRef
. Defaults to a single audience vault
it not specified. Deprecated: use serviceAccountRef.Audiences instead
expirationSeconds
int64 (Optional) Optional expiration time in seconds that will be used to request a temporary Kubernetes service account token for the service account referenced by serviceAccountRef
. Deprecated: this will be removed in the future. Defaults to 10 minutes.
alibaba
AlibabaProvider (Optional) Alibaba configures this store to sync secrets using Alibaba Cloud provider
passworddepot
PasswordDepotProvider (Optional) PasswordDepot configures this store to sync secrets using PasswordDepot provider
"},{"location":"spec/#external-secrets.io/v1beta1.VaultLdapAuth","title":"VaultLdapAuth","text":" (Appears on: VaultAuth)
VaultLdapAuth authenticates with Vault using the LDAP authentication method, with the username and password stored in a Kubernetes Secret resource.
Field Description path
string Path where the LDAP authentication backend is mounted in Vault, e.g: \u201cldap\u201d
username
string Username is a LDAP user name used to authenticate using the LDAP Vault authentication method
secretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector SecretRef to a key in a Secret resource containing password for the LDAP user used to authenticate with Vault using the LDAP authentication method
"},{"location":"spec/#external-secrets.io/v1beta1.VaultUserPassAuth","title":"VaultUserPassAuth","text":" (Appears on: VaultAuth)
VaultUserPassAuth authenticates with Vault using the UserPass authentication method, with the username and password stored in a Kubernetes Secret resource.
Field Description path
string Path where the UserPass authentication backend is mounted in Vault, e.g: \u201cuserpass\u201d
username
string Username is a user name used to authenticate using the UserPass Vault authentication method
secretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector SecretRef to a key in a Secret resource containing password for the user used to authenticate with Vault using the UserPass authentication method
"},{"location":"spec/#external-secrets.io/v1beta1.VaultProvider","title":"VaultProvider","text":" (Appears on: SecretStoreProvider)
Configures an store to sync secrets using a HashiCorp Vault KV backend.
Field Description auth
VaultAuth Auth configures how secret-manager authenticates with the Vault server.
server
string Server is the connection address for the Vault server, e.g: \u201chttps://vault.example.com:8200\u201d.
path
string (Optional) Path is the mount path of the Vault KV backend endpoint, e.g: \u201csecret\u201d. The v2 KV secret engine version specific \u201c/data\u201d path suffix for fetching secrets from Vault is optional and will be appended if not present in specified path.
version
VaultKVStoreVersion Version is the Vault KV secret engine version. This can be either \u201cv1\u201d or \u201cv2\u201d. Version defaults to \u201cv2\u201d.
namespace
string (Optional) Name of the vault namespace. Namespaces is a set of features within Vault Enterprise that allows Vault environments to support Secure Multi-tenancy. e.g: \u201cns1\u201d. More about namespaces can be found here https://www.vaultproject.io/docs/enterprise/namespaces
caBundle
[]byte (Optional) PEM encoded CA bundle used to validate Vault server certificate. Only used if the Server URL is using HTTPS protocol. This parameter is ignored for plain HTTP protocol connection. If not set the system root certificates are used to validate the TLS connection.
caProvider
CAProvider (Optional) The provider for the CA bundle to use to validate Vault server certificate.
readYourWrites
bool (Optional) ReadYourWrites ensures isolated read-after-write semantics by providing discovered cluster replication states in each request. More information about eventual consistency in Vault can be found here https://www.vaultproject.io/docs/enterprise/consistency
forwardInconsistent
bool (Optional) ForwardInconsistent tells Vault to forward read-after-write requests to the Vault leader instead of simply retrying within a loop. This can increase performance if the option is enabled serverside. https://www.vaultproject.io/docs/configuration/replication#allow_forwarding_via_header
"},{"location":"spec/#external-secrets.io/v1beta1.WebhookCAProvider","title":"WebhookCAProvider","text":" (Appears on: WebhookProvider)
Defines a location to fetch the cert for the webhook provider from.
Field Description type
WebhookCAProviderType The type of provider to use such as \u201cSecret\u201d, or \u201cConfigMap\u201d.
name
string The name of the object located at the provider type.
key
string The key the value inside of the provider type to use, only used with \u201cSecret\u201d type
namespace
string (Optional) The namespace the Provider type is in.
"},{"location":"spec/#external-secrets.io/v1beta1.WebhookCAProviderType","title":"WebhookCAProviderType (string
alias)","text":" (Appears on: WebhookCAProvider)
Value Description \"ConfigMap\"
\"Secret\"
"},{"location":"spec/#external-secrets.io/v1beta1.WebhookProvider","title":"WebhookProvider","text":" (Appears on: SecretStoreProvider)
AkeylessProvider Configures an store to sync secrets using Akeyless KV.
Field Description method
string Webhook Method
url
string Webhook url to call
headers
map[string]string (Optional) Headers
body
string (Optional) Body
timeout
Kubernetes meta/v1.Duration (Optional) Timeout
result
WebhookResult Result formatting
secrets
[]WebhookSecret (Optional) Secrets to fill in templates These secrets will be passed to the templating function as key value pairs under the given name
caBundle
[]byte (Optional) PEM encoded CA bundle used to validate webhook server certificate. Only used if the Server URL is using HTTPS protocol. This parameter is ignored for plain HTTP protocol connection. If not set the system root certificates are used to validate the TLS connection.
caProvider
WebhookCAProvider (Optional) The provider for the CA bundle to use to validate webhook server certificate.
"},{"location":"spec/#external-secrets.io/v1beta1.WebhookResult","title":"WebhookResult","text":" (Appears on: WebhookProvider)
Field Description jsonPath
string (Optional) Json path of return value
"},{"location":"spec/#external-secrets.io/v1beta1.WebhookSecret","title":"WebhookSecret","text":" (Appears on: WebhookProvider)
Field Description name
string Name of this secret in templates
secretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector Secret ref to fill in credentials
"},{"location":"spec/#external-secrets.io/v1beta1.YandexCertificateManagerAuth","title":"YandexCertificateManagerAuth","text":" (Appears on: YandexCertificateManagerProvider)
Field Description authorizedKeySecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) The authorized key used for authentication
"},{"location":"spec/#external-secrets.io/v1beta1.YandexCertificateManagerCAProvider","title":"YandexCertificateManagerCAProvider","text":" (Appears on: YandexCertificateManagerProvider)
Field Description certSecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector"},{"location":"spec/#external-secrets.io/v1beta1.YandexCertificateManagerProvider","title":"YandexCertificateManagerProvider","text":" (Appears on: SecretStoreProvider)
YandexCertificateManagerProvider Configures a store to sync secrets using the Yandex Certificate Manager provider.
Field Description apiEndpoint
string (Optional) Yandex.Cloud API endpoint (e.g. \u2018api.cloud.yandex.net:443\u2019)
auth
YandexCertificateManagerAuth Auth defines the information necessary to authenticate against Yandex Certificate Manager
caProvider
YandexCertificateManagerCAProvider (Optional) The provider for the CA bundle to use to validate Yandex.Cloud server certificate.
"},{"location":"spec/#external-secrets.io/v1beta1.YandexLockboxAuth","title":"YandexLockboxAuth","text":" (Appears on: YandexLockboxProvider)
Field Description authorizedKeySecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) The authorized key used for authentication
caProvider
CAProvider (Optional) The provider for the CA bundle to use to validate Vault server certificate.
"},{"location":"spec/#external-secrets.io/v1beta1.YandexLockboxCAProvider","title":"YandexLockboxCAProvider","text":" (Appears on: YandexLockboxProvider)
Field Description certSecretRef
github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector"},{"location":"spec/#external-secrets.io/v1beta1.YandexLockboxProvider","title":"YandexLockboxProvider","text":" (Appears on: SecretStoreProvider)
YandexLockboxProvider Configures a store to sync secrets using the Yandex Lockbox provider.
Field Description apiEndpoint
string (Optional) Yandex.Cloud API endpoint (e.g. \u2018api.cloud.yandex.net:443\u2019)
auth
YandexLockboxAuth Auth defines the information necessary to authenticate against Yandex Lockbox
caProvider
YandexLockboxCAProvider (Optional) The provider for the CA bundle to use to validate Yandex.Cloud server certificate.
Generated with gen-crd-api-reference-docs
.
"},{"location":"api/clusterexternalsecret/","title":"ClusterExternalSecret","text":"The ClusterExternalSecret
is a cluster scoped resource that can be used to manage ExternalSecret
resources in specific namespaces.
With namespaceSelector
you can select namespaces in which the ExternalSecret should be created. If there is a conflict with an existing resource the controller will error out.
"},{"location":"api/clusterexternalsecret/#example","title":"Example","text":"Below is an example of the ClusterExternalSecret
in use.
apiVersion: external-secrets.io/v1beta1\nkind: ClusterExternalSecret\nmetadata:\n name: \"hello-world\"\nspec:\n # The name to be used on the ExternalSecrets\n externalSecretName: \"hello-world-es\"\n\n # This is a basic label selector to select the namespaces to deploy ExternalSecrets to.\n # you can read more about them here https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#resources-that-support-set-based-requirements\n namespaceSelector:\n matchLabels: \n cool: label\n\n # How often the ClusterExternalSecret should reconcile itself\n # This will decide how often to check and make sure that the ExternalSecrets exist in the matching namespaces\n refreshTime: \"1m\"\n\n # This is the spec of the ExternalSecrets to be created\n # The content of this was taken from our ExternalSecret example\n externalSecretSpec:\n secretStoreRef:\n name: secret-store-name\n kind: SecretStore\n\n refreshInterval: \"1h\"\n target:\n name: my-secret\n creationPolicy: 'Merge'\n template:\n type: kubernetes.io/dockerconfigjson\n\n metadata:\n annotations: {}\n labels: {}\n data:\n config.yml: |\n endpoints:\n - https://{{ .data.user }}:{{ .data.password }}@api.exmaple.com\n templateFrom:\n - configMap:\n name: alertmanager\n items:\n - key: alertmanager.yaml\n data:\n - secretKey: secret-key-to-be-managed\n remoteRef:\n key: provider-key\n version: provider-key-version\n property: provider-key-property\n dataFrom:\n - key: provider-key\n version: provider-key-version\n property: provider-key-property\n\nstatus:\n # This will list any namespaces where the creation of the ExternalSecret failed\n # This will not list any issues with the ExternalSecrets, you will have to check the\n # ExternalSecrets to see any issues with them.\n failedNamespaces:\n - namespace: \"matching-ns-1\"\n # This is one of the possible messages, and likely the most common\n reason: \"external secret already exists in namespace\"\n\n # You can find all matching and successfully deployed namespaces here\n provisionedNamespaces:\n - \"matching-ns-3\"\n - \"matching-ns-2\"\n\n # The condition can be Ready, PartiallyReady, or NotReady \n # PartiallyReady would indicate an error in 1 or more namespaces\n # NotReady would indicate errors in all namespaces meaning all ExternalSecrets resulted in errors\n conditions:\n - type: PartiallyReady\n status: \"True\"\n lastTransitionTime: \"2022-01-12T12:33:02Z\"\n
"},{"location":"api/clustersecretstore/","title":"ClusterSecretStore","text":"The ClusterSecretStore
is a cluster scoped SecretStore that can be referenced by all ExternalSecrets
from all namespaces. Use it to offer a central gateway to your secret backend.
"},{"location":"api/clustersecretstore/#example","title":"Example","text":"For a full list of supported fields see spec or dig into our guides.
apiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\n name: example\nspec:\n # Used to select the correct ESO controller (think: ingress.ingressClassName)\n # The ESO controller is instantiated with a specific controller name\n # and filters ES based on this property\n # Optional\n controller: dev\n\n # provider field contains the configuration to access the provider\n # which contains the secret exactly one provider must be configured.\n provider:\n # (1): AWS Secrets Manager\n # aws configures this store to sync secrets using AWS Secret Manager provider\n aws:\n service: SecretsManager\n # Role is a Role ARN which the SecretManager provider will assume\n role: iam-role\n # AWS Region to be used for the provider\n region: eu-central-1\n # Auth defines the information necessary to authenticate against AWS\n auth:\n # Getting the accessKeyID and secretAccessKey from an already created Kubernetes Secret\n secretRef:\n accessKeyIDSecretRef:\n name: awssm-secret\n key: access-key\n secretAccessKeySecretRef:\n name: awssm-secret\n key: secret-access-key\n # IAM roles for service accounts\n # https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-technical-overview.html\n jwt:\n serviceAccountRef:\n name: my-serviceaccount\n namespace: sa-namespace\n\n vault:\n server: \"https://vault.acme.org\"\n # Path is the mount path of the Vault KV backend endpoint\n # Used as a path prefix for the external secret key\n path: \"secret\"\n # Version is the Vault KV secret engine version.\n # This can be either \"v1\" or \"v2\", defaults to \"v2\"\n version: \"v2\"\n # vault enterprise namespace: https://www.vaultproject.io/docs/enterprise/namespaces\n namespace: \"a-team\"\n # base64 encoded string of certificate\n caBundle: \"...\"\n # Instead of caBundle you can also specify a caProvider\n # this will retrieve the cert from a Secret or ConfigMap\n caProvider:\n # Can be Secret or ConfigMap\n type: \"Secret\"\n # namespace is mandatory for ClusterSecretStore and not relevant for SecretStore\n namespace: \"my-cert-secret-namespace\"\n name: \"my-cert-secret\"\n key: \"cert-key\"\n auth:\n # static token: https://www.vaultproject.io/docs/auth/token\n tokenSecretRef:\n name: \"my-secret\"\n namespace: \"secret-admin\"\n key: \"vault-token\"\n\n # AppRole auth: https://www.vaultproject.io/docs/auth/approle\n appRole:\n path: \"approle\"\n roleId: \"db02de05-fa39-4855-059b-67221c5c2f63\"\n secretRef:\n name: \"my-secret\"\n namespace: \"secret-admin\"\n key: \"vault-token\"\n\n # Kubernetes auth: https://www.vaultproject.io/docs/auth/kubernetes\n kubernetes:\n mountPath: \"kubernetes\"\n role: \"demo\"\n # Optional service account reference\n serviceAccountRef:\n name: \"my-sa\"\n namespace: \"secret-admin\"\n # Optional secret field containing a Kubernetes ServiceAccount JWT\n # used for authenticating with Vault\n secretRef:\n name: \"my-secret\"\n namespace: \"secret-admin\"\n key: \"vault\"\n\n # (2): GCP Secret Manager\n gcpsm:\n # Auth defines the information necessary to authenticate against GCP by getting\n # the credentials from an already created Kubernetes Secret.\n auth:\n secretRef:\n secretAccessKeySecretRef:\n name: gcpsm-secret\n key: secret-access-credentials\n namespace: example\n projectID: myproject\n\n # (3): Kubernetes provider\n kubernetes:\n server:\n url: \"https://myapiserver.tld\"\n caProvider:\n type: Secret\n name: my-cluster-secrets\n namespace: example\n key: ca.crt\n auth:\n serviceAccount:\n name: \"example-sa\"\n namespace: \"example\"\n\n # (4): Oracle provider\n oracle:\n # The vault OCID\n vault: ocid1.vault.oc1.eu-frankfurt-1.aaa1aaaaaaaaa.aaaaaaaaaaaaaa1aaaaaaa111aaaaaaaaaaaaaaaa\n # The vault region\n region: eu-frankfurt-1\n auth:\n # The user OCID\n user: ocid1.user.oc1..aaa1aaaaaaaaa.aaaaaaaaaaaaaa1aaaaaaa111aaaaaaaaaaaaaaaa\n # The tenancy OCID\n tenancy: ocid1.tenancy.oc1..aaa1aaaaaaaaa.aaaaaaaaaaaaaa1aaaaaaa111aaaaaaaaaaaaaaaa\n secretRef:\n privatekey:\n # The secret that contains your privatekey\n name: oci-secret-name\n key: privateKey\n namespace: example-namespace\n fingerprint:\n # The secret that contains your fingerprint\n name: oci-secret-name\n key: fingerprint\n namespace: example-namespace\n\n # (TODO): add more provider examples here\n\n # Conditions about namespaces in which the ClusterSecretStore is usable for ExternalSecrets\n conditions:\n # Options are namespaceSelector, or namespaces\n - namespaceSelector:\n matchLabels:\n my.namespace.io/some-label: \"value\" # Only namespaces with that label will work\n\n - namespaces:\n - \"namespace-a\"\n - \"namespace-b\"\n\n # conditions needs only one of the conditions to meet for the CSS to be usable in the namespace.\n\nstatus:\n # Standard condition schema\n conditions:\n # SecretStore ready condition indicates the given store is in ready\n # state and able to referenced by ExternalSecrets\n # If the `status` of this condition is `False`, ExternalSecret controllers\n # should prevent attempts to fetch secrets\n - type: Ready\n status: \"False\"\n reason: \"ConfigError\"\n message: \"SecretStore validation failed\"\n lastTransitionTime: \"2019-08-12T12:33:02Z\"\n
"},{"location":"api/components/","title":"Components","text":""},{"location":"api/components/#overview","title":"Overview","text":"Exernal Secrets comes with three components: Core Controller
, Webhook
and Cert Controller
.
This is due to the need to implement conversion webhooks in order to convert custom resources between api versions and to provide a ValidatingWebhook for the ExternalSecret
and SecretStore
resources.
These features are optional but highly recommended. You can disable them with helm chart values certController.create=false
and webhook.create=false
.
"},{"location":"api/components/#tls-bootstrap","title":"TLS Bootstrap","text":"Cert-controller is responsible for (1) generating TLS credentials which will be used by the webhook component and (2) injecting the certificate as caBundle
into Kind=CustomResourceDefinition
for conversion webhooks and Kind=ValidatingWebhookConfiguration
for validating admission webhook. The TLS credentials are stored in a Kind=Secret
which is consumed by the webhook.
"},{"location":"api/controller-options/","title":"Controller Options","text":"The external-secrets binary includes three components: core controller
, certcontroller
and webook
.
"},{"location":"api/controller-options/#core-controller-flags","title":"Core Controller Flags","text":"The core controller is invoked without a subcommand and can be configured with the following flags:
Name Type Default Description --client-burst
int uses rest client default (10) Maximum Burst allowed to be passed to rest.Client --client-qps
float32 uses rest client default (5) QPS configuration to be passed to rest.Client --concurrent
int 1 The number of concurrent reconciles. --controller-class
string default The controller is instantiated with a specific controller name and filters ES based on this property --enable-cluster-external-secret-reconciler
boolean true Enables the cluster external secret reconciler. --enable-cluster-store-reconciler
boolean true Enables the cluster store reconciler. --enable-push-secret-reconciler
boolean true Enables the push secret reconciler. --enable-secrets-caching
boolean false Enables the secrets caching for external-secrets pod. --enable-configmaps-caching
boolean false Enables the ConfigMap caching for external-secrets pod. --enable-flood-gate
boolean true Enable flood gate. External secret will be reconciled only if the ClusterStore or Store have an healthy or unknown state. --enable-extended-metric-labels
boolean true Enable recommended kubernetes annotations as labels in metrics. --enable-leader-election
boolean false Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager. --experimental-enable-aws-session-cache
boolean false Enable experimental AWS session cache. External secret will reuse the AWS session without creating a new one on each request. --help
help for external-secrets --loglevel
string info loglevel to use, one of: debug, info, warn, error, dpanic, panic, fatal --metrics-addr
string :8080 The address the metric endpoint binds to. --namespace
string - watch external secrets scoped in the provided namespace only. ClusterSecretStore can be used but only work if it doesn't reference resources from other namespaces --store-requeue-interval
duration 5m0s Default Time duration between reconciling (Cluster)SecretStores"},{"location":"api/controller-options/#cert-controller-flags","title":"Cert Controller Flags","text":"Name Type Default Descripton --crd-requeue-interval
duration 5m0s Time duration between reconciling CRDs for new certs --enable-leader-election
boolean false Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager. --healthz-addr
string :8081 The address the health endpoint binds to. --help
help for certcontroller --loglevel
string info loglevel to use, one of: debug, info, warn, error, dpanic, panic, fatal --metrics-addr
string :8080 The address the metric endpoint binds to. --secret-name
string external-secrets-webhook Secret to store certs for webhook --secret-namespace
string default namespace of the secret to store certs --service-name
string external-secrets-webhook Webhook service name --service-namespace
string default Webhook service namespace"},{"location":"api/controller-options/#webhook-flags","title":"Webhook Flags","text":"Name Type Default Description --cert-dir
string /tmp/k8s-webhook-server/serving-certs path to check for certs --check-interval
duration 5m0s certificate check interval --dns-name
string localhost DNS name to validate certificates with --healthz-addr
string :8081 The address the health endpoint binds to. --help
help for webhook --loglevel
string info loglevel to use, one of: debug, info, warn, error, dpanic, panic, fatal --lookahead-interval
duration 2160h0m0s (90d) certificate check interval --metrics-addr
string :8080 The address the metric endpoint binds to. --port
number 10250 Port number that the webhook server will serve. --tls-ciphers
string comma separated list of tls ciphers allowed. This does not apply to TLS 1.3 as the ciphers are selected automatically. The order of this list does not give preference to the ciphers, the ordering is done automatically. Full lists of available ciphers can be found at https://pkg.go.dev/crypto/tls#pkg-constants. E.g. 'TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256' --tls-min-version
string 1.2 minimum version of TLS supported."},{"location":"api/externalsecret/","title":"ExternalSecret","text":"The ExternalSecret
describes what data should be fetched, how the data should be transformed and saved as a Kind=Secret
:
- tells the operator what secrets should be synced by using
spec.data
to explicitly sync individual keys or use spec.dataFrom
to get all values from the external API. - you can specify how the secret should look like by specifying a
spec.target.template
"},{"location":"api/externalsecret/#template","title":"Template","text":"When the controller reconciles the ExternalSecret
it will use the spec.template
as a blueprint to construct a new Kind=Secret
. You can use golang templates to define the blueprint and use template functions to transform secret values. You can also pull in ConfigMaps
that contain golang-template data using templateFrom
. See advanced templating for details.
"},{"location":"api/externalsecret/#update-behavior","title":"Update Behavior","text":"The Kind=Secret
is updated when:
- the
spec.refreshInterval
has passed and is not 0
- the
ExternalSecret
's labels
or annotations
are changed - the
ExternalSecret
's spec
has been changed
You can trigger a secret refresh by using kubectl or any other kubernetes api client:
kubectl annotate es my-es force-sync=$(date +%s) --overwrite\n
"},{"location":"api/externalsecret/#features","title":"Features","text":"Individual features are described in the Guides section:
- Find many secrets / Extract from structured data
- Templating
- Using Generators
- Secret Ownership and Deletion
- Key Rewriting
- Decoding Strategy
"},{"location":"api/externalsecret/#example","title":"Example","text":"Take a look at an annotated example to understand the design behind the ExternalSecret
.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: \"hello-world\"\n\n # labels and annotations are copied over to the\n # secret that will be created\n labels:\n acme.org/owned-by: \"q-team\"\n annotations:\n acme.org/sha: 1234\n\nspec:\n\n # Optional, SecretStoreRef defines the default SecretStore to use when fetching the secret data.\n secretStoreRef:\n name: aws-store\n kind: SecretStore # or ClusterSecretStore\n\n # RefreshInterval is the amount of time before the values reading again from the SecretStore provider\n # Valid time units are \"ns\", \"us\" (or \"\u00b5s\"), \"ms\", \"s\", \"m\", \"h\" (from time.ParseDuration)\n # May be set to zero to fetch and create it once\n refreshInterval: \"1h\"\n\n # the target describes the secret that shall be created\n # there can only be one target per ExternalSecret\n target:\n\n # The secret name of the resource\n # Defaults to .metadata.name of the ExternalSecret\n # It is immutable\n name: application-config\n\n # Enum with values: 'Owner', 'Merge', or 'None'\n # Default value of 'Owner'\n # Owner creates the secret and sets .metadata.ownerReferences of the resource\n # Merge does not create the secret, but merges in the data fields to the secret\n # None does not create a secret (future use with injector)\n creationPolicy: 'Merge'\n\n # DeletionPolicy defines how/when to delete the Secret in Kubernetes\n # if the provider secret gets deleted.\n # Valid values are Delete, Merge, Retain\n deletionPolicy: \"Retain\"\n\n # Specify a blueprint for the resulting Kind=Secret\n template:\n type: kubernetes.io/dockerconfigjson # or TLS...\n\n metadata:\n annotations: {}\n labels: {}\n\n # Use inline templates to construct your desired config file that contains your secret\n data:\n config.yml: |\n database:\n connection: postgres://{{ .username }}:{{ .password }}@{{ .database_host }}:5432/payments\n\n # Uses an existing template from configmap\n # Secret is fetched, merged and templated within the referenced configMap data\n # It does not update the configmap, it creates a secret with: data[\"alertmanager.yml\"] = ...result...\n templateFrom:\n - configMap:\n name: application-config-tmpl\n items:\n - key: config.yml\n\n # Data defines the connection between the Kubernetes Secret keys and the Provider data\n data:\n - secretKey: username\n remoteRef:\n key: database-credentials\n version: v1\n property: username\n decodingStrategy: None # can be None, Base64, Base64URL or Auto\n\n # define the source of the secret. Can be a SecretStore or a Generator kind\n sourceRef:\n # point to a SecretStore that should be used to fetch a secret.\n # must be defined if no spec.secretStoreRef is defined.\n storeRef:\n name: aws-secretstore\n kind: ClusterSecretStore\n\n # Used to fetch all properties from the Provider key\n # If multiple dataFrom are specified, secrets are merged in the specified order\n # Can be defined using sourceRef.generatorRef or extract / find\n # Both use cases are exemplified below\n dataFrom:\n - sourceRef:\n generatorRef:\n apiVersion: generators.external-secrets.io/v1alpha1\n kind: ECRAuthorizationToken\n name: \"my-ecr\"\n #Or\n dataFrom:\n - extract:\n key: database-credentials\n version: v1\n property: data\n conversionStrategy: Default\n decodingStrategy: Auto\n rewrite:\n - regexp:\n source: \"exp-(.*?)-ression\"\n target: \"rewriting-${1}-with-groups\"\n - find:\n path: path-to-filter\n source: \"exp-(.*?)-ression\"\n target: \"rewriting-${1}-with-groups\"\n name:\n regexp: \".*foobar.*\"\n tags:\n foo: bar\n conversionStrategy: Unicode\n decodingStrategy: Base64\n rewrite:\n - regexp:\n source: \"foo\"\n target: \"bar\"\n\nstatus:\n # refreshTime is the time and date the external secret was fetched and\n # the target secret updated\n refreshTime: \"2019-08-12T12:33:02Z\"\n # Standard condition schema\n conditions:\n # ExternalSecret ready condition indicates the secret is ready for use.\n # This is defined as:\n # - The target secret exists\n # - The target secret has been refreshed within the last refreshInterval\n # - The target secret content is up-to-date based on any target templates\n - type: Ready\n status: \"True\" # False if last refresh was not successful\n reason: \"SecretSynced\"\n message: \"Secret was synced\"\n lastTransitionTime: \"2019-08-12T12:33:02Z\"\n
"},{"location":"api/metrics/","title":"Metrics","text":"The External Secrets Operator exposes its Prometheus metrics in the /metrics
path. To enable it, set the serviceMonitor.enabled
Helm flag to true
.
If you are using a different monitoring tool that also needs a /metrics
endpoint, you can set the metrics.service.enabled
Helm flag to true
. In addition you can also set webhook.metrics.service.enabled
and certController.metrics.service.enabled
to scrape the other components.
The Operator has the controller-runtime metrics inherited from kubebuilder plus some custom metrics with a resource name prefix, such as externalsecret_
.
"},{"location":"api/metrics/#cluster-external-secret-metrics","title":"Cluster External Secret Metrics","text":"Name Type Description clusterexternalsecret_status_condition
Gauge The status condition of a specific Cluster External Secret clusterexternalsecret_reconcile_duration
Gauge The duration time to reconcile the Cluster External Secret"},{"location":"api/metrics/#external-secret-metrics","title":"External Secret Metrics","text":"Name Type Description externalsecret_provider_api_calls_count
Counter Number of API calls made to an upstream secret provider API. The metric provides a provider
, call
and status
labels. externalsecret_sync_calls_total
Counter Total number of the External Secret sync calls externalsecret_sync_calls_error
Counter Total number of the External Secret sync errors externalsecret_status_condition
Gauge The status condition of a specific External Secret externalsecret_reconcile_duration
Gauge The duration time to reconcile the External Secret"},{"location":"api/metrics/#cluster-secret-store-metrics","title":"Cluster Secret Store Metrics","text":"Name Type Description clustersecretstore_status_condition
Gauge The status condition of a specific Cluster Secret Store clustersecretstore_reconcile_duration
Gauge The duration time to reconcile the Cluster Secret Store"},{"location":"api/metrics/#secret-store-metrics","title":"Secret Store Metrics","text":"Name Type Description secretstore_status_condition
Gauge The status condition of a specific Secret Store secretstore_reconcile_duration
Gauge The duration time to reconcile the Secret Store"},{"location":"api/metrics/#controller-runtime-metrics","title":"Controller Runtime Metrics","text":"See the kubebuilder documentation on the default exported metrics by controller-runtime.
"},{"location":"api/metrics/#dashboard","title":"Dashboard","text":"We provide a Grafana Dashboard that gives you an overview of External Secrets Operator:
"},{"location":"api/metrics/#service-level-indicators-and-alerts","title":"Service Level Indicators and Alerts","text":"We find the following Service Level Indicators (SLIs) useful when operating ESO. They should give you a good starting point and hints to develop your own Service Level Objectives (SLOs).
"},{"location":"api/metrics/#webhook-http-status-codes","title":"Webhook HTTP Status Codes","text":"The webhook HTTP status code indicates that a HTTP Request was answered successfully or not. If the Webhook pod is not able to serve the requests properly then that failure may cascade down to the controller or any other user of kube-apiserver
.
SLI Example: request error percentage.
sum(increase(controller_runtime_webhook_requests_total{service=~\"external-secrets.*\",code=\"500\"}[1m]))\n/\nsum(increase(controller_runtime_webhook_requests_total{service=~\"external-secrets.*\"}[1m]))\n
"},{"location":"api/metrics/#webhook-http-request-latency","title":"Webhook HTTP Request Latency","text":"If the webhook server is not able to respond in time then that may cause a timeout at the client. This failure may cascade down to the controller or any other user of kube-apiserver
.
SLI Example: p99 across all webhook requests.
histogram_quantile(0.99,\n sum(rate(controller_runtime_webhook_latency_seconds_bucket{service=~\"external-secrets.*\"}[5m])) by (le)\n)\n
"},{"location":"api/metrics/#controller-workqueue-depth","title":"Controller Workqueue Depth","text":"If the workqueue depth is > 0 for a longer period of time then this is an indicator for the controller not being able to reconcile resources in time. I.e. delivery of secret updates is delayed.
Note: when a controller is restarted, then queue length = total number of resources
. Make sure to measure the time it takes for the controller to fully reconcile all secrets after a restart. In large clusters this may take a while, make sure to define an acceptable timeframe to fully reconcile all resources.
sum(\n workqueue_depth{service=~\"external-secrets.*\"}\n) by (name)\n
"},{"location":"api/metrics/#controller-reconcile-latency","title":"Controller Reconcile Latency","text":"The controller should be able to reconcile resources within a reasonable timeframe. When latency is high secret delivery may impacted.
SLI Example: p99 across all controllers.
histogram_quantile(0.99,\n sum(rate(controller_runtime_reconcile_time_seconds_bucket{service=~\"external-secrets.*\"}[5m])) by (le)\n)\n
"},{"location":"api/metrics/#controller-reconcile-error","title":"Controller Reconcile Error","text":"The controller should be able to reconcile resources without errors. When errors occurr secret delivery may be impacted which could cascade down to the secret consuming applications.
sum(increase(\n controller_runtime_reconcile_total{service=~\"external-secrets.*\",controller=~\"$controller\",result=\"error\"}[1m])\n) by (result)\n
"},{"location":"api/pushsecret/","title":"PushSecret","text":"The PushSecret
is namespaced and it describes what data should be pushed to the secret provider.
- tells the operator what secrets should be pushed by using
spec.selector
. - you can specify what secret keys should be pushed by using
spec.data
. - you can also template the resulting property values using templating.
apiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\n name: pushsecret-example # Customisable\n namespace: default # Same of the SecretStores\nspec:\n updatePolicy: Replace # Policy to overwrite existing secrets in the provider on sync\n deletionPolicy: Delete # the provider' secret will be deleted if the PushSecret is deleted\n refreshInterval: 10s # Refresh interval for which push secret will reconcile\n secretStoreRefs: # A list of secret stores to push secrets to\n - name: aws-parameterstore\n kind: SecretStore\n selector:\n secret:\n name: pokedex-credentials # Source Kubernetes secret to be pushed\n template:\n metadata:\n annotations: { }\n labels: { }\n data:\n best-pokemon: \"{{ .best-pokemon | toString | upper }} is the really best!\"\n # Uses an existing template from configmap\n # Secret is fetched, merged and templated within the referenced configMap data\n # It does not update the configmap, it creates a secret with: data[\"alertmanager.yml\"] = ...result...\n templateFrom:\n - configMap:\n name: application-config-tmpl\n items:\n - key: config.yml\n data:\n - conversionStrategy: None # Also supports the ReverseUnicode strategy\n match:\n secretKey: best-pokemon # Source Kubernetes secret key to be pushed\n remoteRef:\n remoteKey: my-first-parameter # Remote reference (where the secret is going to be pushed)\n
"},{"location":"api/pushsecret/#templating","title":"Templating","text":"When the controller reconciles the PushSecret
it will use the spec.template
as a blueprint to construct a new property. You can use golang templates to define the blueprint and use template functions to transform the defined properties. You can also pull in ConfigMaps
that contain golang-template data using templateFrom
. See advanced templating for details.
"},{"location":"api/secretstore/","title":"SecretStore","text":"The SecretStore
is namespaced and specifies how to access the external API. The SecretStore maps to exactly one instance of an external API.
By design, SecretStores are bound to a namespace and can not reference resources across namespaces. If you want to design cross-namespace SecretStores you must use ClusterSecretStores which do not have this limitation.
"},{"location":"api/secretstore/#example","title":"Example","text":"For a full list of supported fields see spec or dig into our guides.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: example\n namespace: example-ns\nspec:\n\n # Used to select the correct ESO controller (think: ingress.ingressClassName)\n # The ESO controller is instantiated with a specific controller name\n # and filters ES based on this property\n # Optional\n controller: dev\n\n # You can specify retry settings for the http connection\n # these fields allow you to set a maxRetries before failure, and\n # an interval between the retries.\n # Current supported providers: AWS, Hashicorp Vault, IBM\n retrySettings:\n maxRetries: 5\n retryInterval: \"10s\"\n\n # provider field contains the configuration to access the provider\n # which contains the secret exactly one provider must be configured.\n provider:\n\n # (1): AWS Secrets Manager\n # aws configures this store to sync secrets using AWS Secret Manager provider\n aws:\n service: SecretsManager\n # Role is a Role ARN which the SecretManager provider will assume\n role: iam-role\n # AWS Region to be used for the provider\n region: eu-central-1\n # Auth defines the information necessary to authenticate against AWS by\n # getting the accessKeyID and secretAccessKey from an already created Kubernetes Secret\n auth:\n secretRef:\n accessKeyIDSecretRef:\n name: awssm-secret\n key: access-key\n secretAccessKeySecretRef:\n name: awssm-secret\n key: secret-access-key\n\n # (2) Hashicorp Vault\n vault:\n server: \"https://vault.acme.org\"\n # Path is the mount path of the Vault KV backend endpoint\n # Used as a path prefix for the external secret key\n path: \"secret\"\n # Version is the Vault KV secret engine version.\n # This can be either \"v1\" or \"v2\", defaults to \"v2\"\n version: \"v2\"\n # vault enterprise namespace: https://www.vaultproject.io/docs/enterprise/namespaces\n namespace: \"a-team\"\n # base64 encoded string of certificate\n caBundle: \"...\"\n # Instead of caBundle you can also specify a caProvider\n # this will retrieve the cert from a Secret or ConfigMap\n caProvider:\n # Can be Secret or ConfigMap\n type: \"Secret\"\n name: \"my-cert-secret\"\n key: \"cert-key\"\n # client side related TLS communication, when the Vault server requires mutual authentication\n tls:\n clientCert:\n namespace: ...\n name: \"my-cert-secret\"\n key: \"tls.crt\"\n secretRef:\n namespace: ...\n name: \"my-cert-secret\"\n key: \"tls.key\"\n\n auth:\n # static token: https://www.vaultproject.io/docs/auth/token\n tokenSecretRef:\n name: \"my-secret\"\n key: \"vault-token\"\n\n # AppRole auth: https://www.vaultproject.io/docs/auth/approle\n appRole:\n path: \"approle\"\n roleId: \"db02de05-fa39-4855-059b-67221c5c2f63\"\n secretRef:\n name: \"my-secret\"\n key: \"vault-token\"\n\n # Kubernetes auth: https://www.vaultproject.io/docs/auth/kubernetes\n kubernetes:\n mountPath: \"kubernetes\"\n role: \"demo\"\n # Optional service account reference\n serviceAccountRef:\n name: \"my-sa\"\n # Optional secret field containing a Kubernetes ServiceAccount JWT\n # used for authenticating with Vault\n secretRef:\n name: \"my-secret\"\n key: \"vault\"\n\n # TLS certificates auth method: https://developer.hashicorp.com/vault/docs/auth/cert\n cert:\n clientCert:\n namespace: ...\n name: \"my-cert-secret\"\n key: \"tls.crt\"\n secretRef:\n namespace: ...\n name: \"my-cert-secret\"\n key: \"tls.key\"\n\n # (3): GCP Secret Manager\n gcpsm:\n # Auth defines the information necessary to authenticate against GCP by getting\n # the credentials from an already created Kubernetes Secret.\n auth:\n secretRef:\n secretAccessKeySecretRef:\n name: gcpsm-secret\n key: secret-access-credentials\n projectID: myproject\n # (TODO): add more provider examples here\n\nstatus:\n # Standard condition schema\n conditions:\n # SecretStore ready condition indicates the given store is in ready\n # state and able to referenced by ExternalSecrets\n # If the `status` of this condition is `False`, ExternalSecret controllers\n # should prevent attempts to fetch secrets\n - type: Ready\n status: \"False\"\n reason: \"ConfigError\"\n message: \"SecretStore validation failed\"\n lastTransitionTime: \"2019-08-12T12:33:02Z\"\n
"},{"location":"api/spec/","title":"API specification","text":"Packages:
- external-secrets.io/v1beta1
"},{"location":"api/spec/#external-secrets.io/v1beta1","title":"external-secrets.io/v1beta1","text":"
Package v1beta1 contains resources for external-secrets
Resource Types:
"},{"location":"api/spec/#external-secrets.io/v1beta1.AWSAuth","title":"AWSAuth","text":" (Appears on: AWSProvider)
AWSAuth tells the controller how to do authentication with aws. Only one of secretRef or jwt can be specified. if none is specified the controller will load credentials using the aws sdk defaults.
Field Description secretRef
AWSAuthSecretRef (Optional) jwt
AWSJWTAuth (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.AWSAuthSecretRef","title":"AWSAuthSecretRef","text":" (Appears on: AWSAuth)
AWSAuthSecretRef holds secret references for AWS credentials both AccessKeyID and SecretAccessKey must be defined in order to properly authenticate.
Field Description accessKeyIDSecretRef
External Secrets meta/v1.SecretKeySelector The AccessKeyID is used for authentication
secretAccessKeySecretRef
External Secrets meta/v1.SecretKeySelector The SecretAccessKey is used for authentication
sessionTokenSecretRef
External Secrets meta/v1.SecretKeySelector The SessionToken used for authentication This must be defined if AccessKeyID and SecretAccessKey are temporary credentials see: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html
"},{"location":"api/spec/#external-secrets.io/v1beta1.AWSJWTAuth","title":"AWSJWTAuth","text":" (Appears on: AWSAuth)
Authenticate against AWS using service account tokens.
Field Description serviceAccountRef
External Secrets meta/v1.ServiceAccountSelector"},{"location":"api/spec/#external-secrets.io/v1beta1.AWSProvider","title":"AWSProvider","text":" (Appears on: SecretStoreProvider)
AWSProvider configures a store to sync secrets with AWS.
Field Description service
AWSServiceType Service defines which service should be used to fetch the secrets
auth
AWSAuth (Optional) Auth defines the information necessary to authenticate against AWS if not set aws sdk will infer credentials from your environment see: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials
role
string (Optional) Role is a Role ARN which the provider will assume
region
string AWS Region to be used for the provider
additionalRoles
[]string (Optional) AdditionalRoles is a chained list of Role ARNs which the provider will sequentially assume before assuming the Role
externalID
string AWS External ID set on assumed IAM roles
sessionTags
[]*github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1.Tag (Optional) AWS STS assume role session tags
secretsManager
SecretsManager (Optional) SecretsManager defines how the provider behaves when interacting with AWS SecretsManager
transitiveTagKeys
[]*string (Optional) AWS STS assume role transitive session tags. Required when multiple rules are used with the provider
"},{"location":"api/spec/#external-secrets.io/v1beta1.AWSServiceType","title":"AWSServiceType (string
alias)","text":" (Appears on: AWSProvider)
AWSServiceType is a enum that defines the service/API that is used to fetch the secrets.
Value Description \"ParameterStore\"
AWSServiceParameterStore is the AWS SystemsManager ParameterStore service. see: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html
\"SecretsManager\"
AWSServiceSecretsManager is the AWS SecretsManager service. see: https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html
"},{"location":"api/spec/#external-secrets.io/v1beta1.AkeylessAuth","title":"AkeylessAuth","text":" (Appears on: AkeylessProvider)
Field Description secretRef
AkeylessAuthSecretRef (Optional) Reference to a Secret that contains the details to authenticate with Akeyless.
kubernetesAuth
AkeylessKubernetesAuth (Optional) Kubernetes authenticates with Akeyless by passing the ServiceAccount token stored in the named Secret resource.
"},{"location":"api/spec/#external-secrets.io/v1beta1.AkeylessAuthSecretRef","title":"AkeylessAuthSecretRef","text":" (Appears on: AkeylessAuth)
AkeylessAuthSecretRef AKEYLESS_ACCESS_TYPE_PARAM: AZURE_OBJ_ID OR GCP_AUDIENCE OR ACCESS_KEY OR KUB_CONFIG_NAME.
Field Description accessID
External Secrets meta/v1.SecretKeySelector The SecretAccessID is used for authentication
accessType
External Secrets meta/v1.SecretKeySelector accessTypeParam
External Secrets meta/v1.SecretKeySelector"},{"location":"api/spec/#external-secrets.io/v1beta1.AkeylessKubernetesAuth","title":"AkeylessKubernetesAuth","text":" (Appears on: AkeylessAuth)
Authenticate with Kubernetes ServiceAccount token stored.
Field Description accessID
string the Akeyless Kubernetes auth-method access-id
k8sConfName
string Kubernetes-auth configuration name in Akeyless-Gateway
serviceAccountRef
External Secrets meta/v1.ServiceAccountSelector (Optional) Optional service account field containing the name of a kubernetes ServiceAccount. If the service account is specified, the service account secret token JWT will be used for authenticating with Akeyless. If the service account selector is not supplied, the secretRef will be used instead.
secretRef
External Secrets meta/v1.SecretKeySelector (Optional) Optional secret field containing a Kubernetes ServiceAccount JWT used for authenticating with Akeyless. If a name is specified without a key, token
is the default. If one is not specified, the one bound to the controller will be used.
"},{"location":"api/spec/#external-secrets.io/v1beta1.AkeylessProvider","title":"AkeylessProvider","text":" (Appears on: SecretStoreProvider)
AkeylessProvider Configures an store to sync secrets using Akeyless KV.
Field Description akeylessGWApiURL
string Akeyless GW API Url from which the secrets to be fetched from.
authSecretRef
AkeylessAuth Auth configures how the operator authenticates with Akeyless.
caBundle
[]byte (Optional) PEM/base64 encoded CA bundle used to validate Akeyless Gateway certificate. Only used if the AkeylessGWApiURL URL is using HTTPS protocol. If not set the system root certificates are used to validate the TLS connection.
caProvider
CAProvider (Optional) The provider for the CA bundle to use to validate Akeyless Gateway certificate.
"},{"location":"api/spec/#external-secrets.io/v1beta1.AlibabaAuth","title":"AlibabaAuth","text":" (Appears on: AlibabaProvider)
AlibabaAuth contains a secretRef for credentials.
Field Description secretRef
AlibabaAuthSecretRef (Optional) rrsa
AlibabaRRSAAuth (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.AlibabaAuthSecretRef","title":"AlibabaAuthSecretRef","text":" (Appears on: AlibabaAuth)
AlibabaAuthSecretRef holds secret references for Alibaba credentials.
Field Description accessKeyIDSecretRef
External Secrets meta/v1.SecretKeySelector The AccessKeyID is used for authentication
accessKeySecretSecretRef
External Secrets meta/v1.SecretKeySelector The AccessKeySecret is used for authentication
"},{"location":"api/spec/#external-secrets.io/v1beta1.AlibabaProvider","title":"AlibabaProvider","text":" (Appears on: SecretStoreProvider)
AlibabaProvider configures a store to sync secrets using the Alibaba Secret Manager provider.
Field Description auth
AlibabaAuth regionID
string Alibaba Region to be used for the provider
"},{"location":"api/spec/#external-secrets.io/v1beta1.AlibabaRRSAAuth","title":"AlibabaRRSAAuth","text":" (Appears on: AlibabaAuth)
Authenticate against Alibaba using RRSA.
Field Description oidcProviderArn
string oidcTokenFilePath
string roleArn
string sessionName
string"},{"location":"api/spec/#external-secrets.io/v1beta1.AzureAuthType","title":"AzureAuthType (string
alias)","text":" (Appears on: AzureKVProvider)
AuthType describes how to authenticate to the Azure Keyvault Only one of the following auth types may be specified. If none of the following auth type is specified, the default one is ServicePrincipal.
Value Description \"ManagedIdentity\"
Using Managed Identity to authenticate. Used with aad-pod-identity installed in the cluster.
\"ServicePrincipal\"
Using service principal to authenticate, which needs a tenantId, a clientId and a clientSecret.
\"WorkloadIdentity\"
Using Workload Identity service accounts to authenticate.
"},{"location":"api/spec/#external-secrets.io/v1beta1.AzureEnvironmentType","title":"AzureEnvironmentType (string
alias)","text":" (Appears on: AzureKVProvider)
AzureEnvironmentType specifies the Azure cloud environment endpoints to use for connecting and authenticating with Azure. By default it points to the public cloud AAD endpoint. The following endpoints are available, also see here: https://github.com/Azure/go-autorest/blob/main/autorest/azure/environments.go#L152 PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud
Value Description \"ChinaCloud\"
\"GermanCloud\"
\"PublicCloud\"
\"USGovernmentCloud\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.AzureKVAuth","title":"AzureKVAuth","text":" (Appears on: AzureKVProvider)
Configuration used to authenticate with Azure.
Field Description clientId
External Secrets meta/v1.SecretKeySelector (Optional) The Azure clientId of the service principle or managed identity used for authentication.
tenantId
External Secrets meta/v1.SecretKeySelector (Optional) The Azure tenantId of the managed identity used for authentication.
clientSecret
External Secrets meta/v1.SecretKeySelector (Optional) The Azure ClientSecret of the service principle used for authentication.
"},{"location":"api/spec/#external-secrets.io/v1beta1.AzureKVProvider","title":"AzureKVProvider","text":" (Appears on: SecretStoreProvider)
Configures an store to sync secrets using Azure KV.
Field Description authType
AzureAuthType (Optional) Auth type defines how to authenticate to the keyvault service. Valid values are: - \u201cServicePrincipal\u201d (default): Using a service principal (tenantId, clientId, clientSecret) - \u201cManagedIdentity\u201d: Using Managed Identity assigned to the pod (see aad-pod-identity)
vaultUrl
string Vault Url from which the secrets to be fetched from.
tenantId
string (Optional) TenantID configures the Azure Tenant to send requests to. Required for ServicePrincipal auth type. Optional for WorkloadIdentity.
environmentType
AzureEnvironmentType EnvironmentType specifies the Azure cloud environment endpoints to use for connecting and authenticating with Azure. By default it points to the public cloud AAD endpoint. The following endpoints are available, also see here: https://github.com/Azure/go-autorest/blob/main/autorest/azure/environments.go#L152 PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud
authSecretRef
AzureKVAuth (Optional) Auth configures how the operator authenticates with Azure. Required for ServicePrincipal auth type. Optional for WorkloadIdentity.
serviceAccountRef
External Secrets meta/v1.ServiceAccountSelector (Optional) ServiceAccountRef specified the service account that should be used when authenticating with WorkloadIdentity.
identityId
string (Optional) If multiple Managed Identity is assigned to the pod, you can select the one to be used
"},{"location":"api/spec/#external-secrets.io/v1beta1.CAProvider","title":"CAProvider","text":" (Appears on: AkeylessProvider, ConjurProvider, KubernetesServer, VaultProvider)
Used to provide custom certificate authority (CA) certificates for a secret store. The CAProvider points to a Secret or ConfigMap resource that contains a PEM-encoded certificate.
Field Description type
CAProviderType The type of provider to use such as \u201cSecret\u201d, or \u201cConfigMap\u201d.
name
string The name of the object located at the provider type.
key
string The key where the CA certificate can be found in the Secret or ConfigMap.
namespace
string (Optional) The namespace the Provider type is in. Can only be defined when used in a ClusterSecretStore.
"},{"location":"api/spec/#external-secrets.io/v1beta1.CAProviderType","title":"CAProviderType (string
alias)","text":" (Appears on: CAProvider)
Value Description \"ConfigMap\"
\"Secret\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.CertAuth","title":"CertAuth","text":" (Appears on: KubernetesAuth)
Field Description clientCert
External Secrets meta/v1.SecretKeySelector clientKey
External Secrets meta/v1.SecretKeySelector"},{"location":"api/spec/#external-secrets.io/v1beta1.ChefAuth","title":"ChefAuth","text":" (Appears on: ChefProvider)
ChefAuth contains a secretRef for credentials.
Field Description secretRef
ChefAuthSecretRef"},{"location":"api/spec/#external-secrets.io/v1beta1.ChefAuthSecretRef","title":"ChefAuthSecretRef","text":" (Appears on: ChefAuth)
ChefAuthSecretRef holds secret references for chef server login credentials.
Field Description privateKeySecretRef
External Secrets meta/v1.SecretKeySelector SecretKey is the Signing Key in PEM format, used for authentication.
"},{"location":"api/spec/#external-secrets.io/v1beta1.ChefProvider","title":"ChefProvider","text":" (Appears on: SecretStoreProvider)
ChefProvider configures a store to sync secrets using basic chef server connection credentials.
Field Description auth
ChefAuth Auth defines the information necessary to authenticate against chef Server
username
string UserName should be the user ID on the chef server
serverUrl
string ServerURL is the chef server URL used to connect to. If using orgs you should include your org in the url and terminate the url with a \u201c/\u201d
"},{"location":"api/spec/#external-secrets.io/v1beta1.ClusterExternalSecret","title":"ClusterExternalSecret","text":"
ClusterExternalSecret is the Schema for the clusterexternalsecrets API.
Field Description metadata
Kubernetes meta/v1.ObjectMeta Refer to the Kubernetes API documentation for the fields of the metadata
field. spec
ClusterExternalSecretSpec externalSecretSpec
ExternalSecretSpec The spec for the ExternalSecrets to be created
externalSecretName
string (Optional) The name of the external secrets to be created defaults to the name of the ClusterExternalSecret
externalSecretMetadata
ExternalSecretMetadata (Optional) The metadata of the external secrets to be created
namespaceSelector
Kubernetes meta/v1.LabelSelector (Optional) The labels to select by to find the Namespaces to create the ExternalSecrets in. Deprecated: Use NamespaceSelectors instead.
namespaceSelectors
[]*k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector (Optional) A list of labels to select by to find the Namespaces to create the ExternalSecrets in. The selectors are ORed.
namespaces
[]string (Optional) Choose namespaces by name. This field is ORed with anything that NamespaceSelectors ends up choosing.
refreshTime
Kubernetes meta/v1.Duration The time in which the controller should reconcile its objects and recheck namespaces for labels.
status
ClusterExternalSecretStatus"},{"location":"api/spec/#external-secrets.io/v1beta1.ClusterExternalSecretConditionType","title":"ClusterExternalSecretConditionType (string
alias)","text":" (Appears on: ClusterExternalSecretStatusCondition)
Value Description \"Ready\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.ClusterExternalSecretNamespaceFailure","title":"ClusterExternalSecretNamespaceFailure","text":" (Appears on: ClusterExternalSecretStatus)
ClusterExternalSecretNamespaceFailure represents a failed namespace deployment and it\u2019s reason.
Field Description namespace
string Namespace is the namespace that failed when trying to apply an ExternalSecret
reason
string (Optional) Reason is why the ExternalSecret failed to apply to the namespace
"},{"location":"api/spec/#external-secrets.io/v1beta1.ClusterExternalSecretSpec","title":"ClusterExternalSecretSpec","text":" (Appears on: ClusterExternalSecret)
ClusterExternalSecretSpec defines the desired state of ClusterExternalSecret.
Field Description externalSecretSpec
ExternalSecretSpec The spec for the ExternalSecrets to be created
externalSecretName
string (Optional) The name of the external secrets to be created defaults to the name of the ClusterExternalSecret
externalSecretMetadata
ExternalSecretMetadata (Optional) The metadata of the external secrets to be created
namespaceSelector
Kubernetes meta/v1.LabelSelector (Optional) The labels to select by to find the Namespaces to create the ExternalSecrets in. Deprecated: Use NamespaceSelectors instead.
namespaceSelectors
[]*k8s.io/apimachinery/pkg/apis/meta/v1.LabelSelector (Optional) A list of labels to select by to find the Namespaces to create the ExternalSecrets in. The selectors are ORed.
namespaces
[]string (Optional) Choose namespaces by name. This field is ORed with anything that NamespaceSelectors ends up choosing.
refreshTime
Kubernetes meta/v1.Duration The time in which the controller should reconcile its objects and recheck namespaces for labels.
"},{"location":"api/spec/#external-secrets.io/v1beta1.ClusterExternalSecretStatus","title":"ClusterExternalSecretStatus","text":" (Appears on: ClusterExternalSecret)
ClusterExternalSecretStatus defines the observed state of ClusterExternalSecret.
Field Description externalSecretName
string ExternalSecretName is the name of the ExternalSecrets created by the ClusterExternalSecret
failedNamespaces
[]ClusterExternalSecretNamespaceFailure (Optional) Failed namespaces are the namespaces that failed to apply an ExternalSecret
provisionedNamespaces
[]string (Optional) ProvisionedNamespaces are the namespaces where the ClusterExternalSecret has secrets
conditions
[]ClusterExternalSecretStatusCondition (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.ClusterExternalSecretStatusCondition","title":"ClusterExternalSecretStatusCondition","text":" (Appears on: ClusterExternalSecretStatus)
Field Description type
ClusterExternalSecretConditionType status
Kubernetes core/v1.ConditionStatus message
string (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.ClusterSecretStore","title":"ClusterSecretStore","text":"
ClusterSecretStore represents a secure external location for storing secrets, which can be referenced as part of storeRef
fields.
Field Description metadata
Kubernetes meta/v1.ObjectMeta Refer to the Kubernetes API documentation for the fields of the metadata
field. spec
SecretStoreSpec controller
string (Optional) Used to select the correct ESO controller (think: ingress.ingressClassName) The ESO controller is instantiated with a specific controller name and filters ES based on this property
provider
SecretStoreProvider Used to configure the provider. Only one provider may be set
retrySettings
SecretStoreRetrySettings (Optional) Used to configure http retries if failed
refreshInterval
int (Optional) Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
conditions
[]ClusterSecretStoreCondition (Optional) Used to constraint a ClusterSecretStore to specific namespaces. Relevant only to ClusterSecretStore
status
SecretStoreStatus"},{"location":"api/spec/#external-secrets.io/v1beta1.ClusterSecretStoreCondition","title":"ClusterSecretStoreCondition","text":" (Appears on: SecretStoreSpec)
ClusterSecretStoreCondition describes a condition by which to choose namespaces to process ExternalSecrets in for a ClusterSecretStore instance.
Field Description namespaceSelector
Kubernetes meta/v1.LabelSelector (Optional) Choose namespace using a labelSelector
namespaces
[]string Choose namespaces by name
"},{"location":"api/spec/#external-secrets.io/v1beta1.ConjurAPIKey","title":"ConjurAPIKey","text":" (Appears on: ConjurAuth)
Field Description account
string userRef
External Secrets meta/v1.SecretKeySelector apiKeyRef
External Secrets meta/v1.SecretKeySelector"},{"location":"api/spec/#external-secrets.io/v1beta1.ConjurAuth","title":"ConjurAuth","text":" (Appears on: ConjurProvider)
Field Description apikey
ConjurAPIKey (Optional) jwt
ConjurJWT (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.ConjurJWT","title":"ConjurJWT","text":" (Appears on: ConjurAuth)
Field Description account
string serviceID
string The conjur authn jwt webservice id
hostId
string (Optional) Optional HostID for JWT authentication. This may be used depending on how the Conjur JWT authenticator policy is configured.
secretRef
External Secrets meta/v1.SecretKeySelector (Optional) Optional SecretRef that refers to a key in a Secret resource containing JWT token to authenticate with Conjur using the JWT authentication method.
serviceAccountRef
External Secrets meta/v1.ServiceAccountSelector (Optional) Optional ServiceAccountRef specifies the Kubernetes service account for which to request a token for with the TokenRequest
API.
"},{"location":"api/spec/#external-secrets.io/v1beta1.ConjurProvider","title":"ConjurProvider","text":" (Appears on: SecretStoreProvider)
Field Description url
string caBundle
string (Optional) caProvider
CAProvider (Optional) auth
ConjurAuth"},{"location":"api/spec/#external-secrets.io/v1beta1.DelineaProvider","title":"DelineaProvider","text":" (Appears on: SecretStoreProvider)
See https://github.com/DelineaXPM/dsv-sdk-go/blob/main/vault/vault.go.
Field Description clientId
DelineaProviderSecretRef ClientID is the non-secret part of the credential.
clientSecret
DelineaProviderSecretRef ClientSecret is the secret part of the credential.
tenant
string Tenant is the chosen hostname / site name.
urlTemplate
string (Optional) URLTemplate If unset, defaults to \u201chttps://%s.secretsvaultcloud.%s/v1/%s%s\u201d.
tld
string (Optional) TLD is based on the server location that was chosen during provisioning. If unset, defaults to \u201ccom\u201d.
"},{"location":"api/spec/#external-secrets.io/v1beta1.DelineaProviderSecretRef","title":"DelineaProviderSecretRef","text":" (Appears on: DelineaProvider)
Field Description value
string (Optional) Value can be specified directly to set a value without using a secret.
secretRef
External Secrets meta/v1.SecretKeySelector (Optional) SecretRef references a key in a secret that will be used as value.
"},{"location":"api/spec/#external-secrets.io/v1beta1.DopplerAuth","title":"DopplerAuth","text":" (Appears on: DopplerProvider)
Field Description secretRef
DopplerAuthSecretRef"},{"location":"api/spec/#external-secrets.io/v1beta1.DopplerAuthSecretRef","title":"DopplerAuthSecretRef","text":" (Appears on: DopplerAuth)
Field Description dopplerToken
External Secrets meta/v1.SecretKeySelector The DopplerToken is used for authentication. See https://docs.doppler.com/reference/api#authentication for auth token types. The Key attribute defaults to dopplerToken if not specified.
"},{"location":"api/spec/#external-secrets.io/v1beta1.DopplerProvider","title":"DopplerProvider","text":" (Appears on: SecretStoreProvider)
DopplerProvider configures a store to sync secrets using the Doppler provider. Project and Config are required if not using a Service Token.
Field Description auth
DopplerAuth Auth configures how the Operator authenticates with the Doppler API
project
string (Optional) Doppler project (required if not using a Service Token)
config
string (Optional) Doppler config (required if not using a Service Token)
nameTransformer
string (Optional) Environment variable compatible name transforms that change secret names to a different format
format
string (Optional) Format enables the downloading of secrets as a file (string)
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecret","title":"ExternalSecret","text":"
ExternalSecret is the Schema for the external-secrets API.
Field Description metadata
Kubernetes meta/v1.ObjectMeta Refer to the Kubernetes API documentation for the fields of the metadata
field. spec
ExternalSecretSpec secretStoreRef
SecretStoreRef (Optional) target
ExternalSecretTarget (Optional) refreshInterval
Kubernetes meta/v1.Duration RefreshInterval is the amount of time before the values are read again from the SecretStore provider Valid time units are \u201cns\u201d, \u201cus\u201d (or \u201c\u00b5s\u201d), \u201cms\u201d, \u201cs\u201d, \u201cm\u201d, \u201ch\u201d May be set to zero to fetch and create it once. Defaults to 1h.
data
[]ExternalSecretData (Optional) Data defines the connection between the Kubernetes Secret keys and the Provider data
dataFrom
[]ExternalSecretDataFromRemoteRef (Optional) DataFrom is used to fetch all properties from a specific Provider data If multiple entries are specified, the Secret keys are merged in the specified order
status
ExternalSecretStatus"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretConditionType","title":"ExternalSecretConditionType (string
alias)","text":" (Appears on: ExternalSecretStatusCondition)
Value Description \"Deleted\"
\"Ready\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretConversionStrategy","title":"ExternalSecretConversionStrategy (string
alias)","text":" (Appears on: ExternalSecretDataRemoteRef, ExternalSecretFind)
Value Description \"Default\"
\"Unicode\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretCreationPolicy","title":"ExternalSecretCreationPolicy (string
alias)","text":" (Appears on: ExternalSecretTarget)
ExternalSecretCreationPolicy defines rules on how to create the resulting Secret.
Value Description \"Merge\"
Merge does not create the Secret, but merges the data fields to the Secret.
\"None\"
None does not create a Secret (future use with injector).
\"Orphan\"
Orphan creates the Secret and does not set the ownerReference. I.e. it will be orphaned after the deletion of the ExternalSecret.
\"Owner\"
Owner creates the Secret and sets .metadata.ownerReferences to the ExternalSecret resource.
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretData","title":"ExternalSecretData","text":" (Appears on: ExternalSecretSpec)
ExternalSecretData defines the connection between the Kubernetes Secret key (spec.data.) and the Provider data. Field Description secretKey
string
SecretKey defines the key in which the controller stores the value. This is the key in the Kind=Secret
remoteRef
ExternalSecretDataRemoteRef RemoteRef points to the remote secret and defines which secret (version/property/..) to fetch.
sourceRef
StoreSourceRef SourceRef allows you to override the source from which the value will pulled from.
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretDataFromRemoteRef","title":"ExternalSecretDataFromRemoteRef","text":" (Appears on: ExternalSecretSpec)
Field Description extract
ExternalSecretDataRemoteRef (Optional) Used to extract multiple key/value pairs from one secret Note: Extract does not support sourceRef.Generator or sourceRef.GeneratorRef.
find
ExternalSecretFind (Optional) Used to find secrets based on tags or regular expressions Note: Find does not support sourceRef.Generator or sourceRef.GeneratorRef.
rewrite
[]ExternalSecretRewrite (Optional) Used to rewrite secret Keys after getting them from the secret Provider Multiple Rewrite operations can be provided. They are applied in a layered order (first to last)
sourceRef
StoreGeneratorSourceRef SourceRef points to a store or generator which contains secret values ready to use. Use this in combination with Extract or Find pull values out of a specific SecretStore. When sourceRef points to a generator Extract or Find is not supported. The generator returns a static map of values
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretDataRemoteRef","title":"ExternalSecretDataRemoteRef","text":" (Appears on: ExternalSecretData, ExternalSecretDataFromRemoteRef)
ExternalSecretDataRemoteRef defines Provider data location.
Field Description key
string Key is the key used in the Provider, mandatory
metadataPolicy
ExternalSecretMetadataPolicy (Optional) Policy for fetching tags/labels from provider secrets, possible options are Fetch, None. Defaults to None
property
string (Optional) Used to select a specific property of the Provider value (if a map), if supported
version
string (Optional) Used to select a specific version of the Provider value, if supported
conversionStrategy
ExternalSecretConversionStrategy (Optional) Used to define a conversion Strategy
decodingStrategy
ExternalSecretDecodingStrategy (Optional) Used to define a decoding Strategy
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretDecodingStrategy","title":"ExternalSecretDecodingStrategy (string
alias)","text":" (Appears on: ExternalSecretDataRemoteRef, ExternalSecretFind)
Value Description \"Auto\"
\"Base64\"
\"Base64URL\"
\"None\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretDeletionPolicy","title":"ExternalSecretDeletionPolicy (string
alias)","text":" (Appears on: ExternalSecretTarget)
ExternalSecretDeletionPolicy defines rules on how to delete the resulting Secret.
Value Description \"Delete\"
Delete deletes the secret if all provider secrets are deleted. If a secret gets deleted on the provider side and is not accessible anymore this is not considered an error and the ExternalSecret does not go into SecretSyncedError status.
\"Merge\"
Merge removes keys in the secret, but not the secret itself. If a secret gets deleted on the provider side and is not accessible anymore this is not considered an error and the ExternalSecret does not go into SecretSyncedError status.
\"Retain\"
Retain will retain the secret if all provider secrets have been deleted. If a provider secret does not exist the ExternalSecret gets into the SecretSyncedError status.
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretFind","title":"ExternalSecretFind","text":" (Appears on: ExternalSecretDataFromRemoteRef)
Field Description path
string (Optional) A root path to start the find operations.
name
FindName (Optional) Finds secrets based on the name.
tags
map[string]string (Optional) Find secrets based on tags.
conversionStrategy
ExternalSecretConversionStrategy (Optional) Used to define a conversion Strategy
decodingStrategy
ExternalSecretDecodingStrategy (Optional) Used to define a decoding Strategy
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretMetadata","title":"ExternalSecretMetadata","text":" (Appears on: ClusterExternalSecretSpec)
ExternalSecretMetadata defines metadata fields for the ExternalSecret generated by the ClusterExternalSecret.
Field Description annotations
map[string]string (Optional) labels
map[string]string (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretMetadataPolicy","title":"ExternalSecretMetadataPolicy (string
alias)","text":" (Appears on: ExternalSecretDataRemoteRef)
Value Description \"Fetch\"
\"None\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretRewrite","title":"ExternalSecretRewrite","text":" (Appears on: ExternalSecretDataFromRemoteRef)
Field Description regexp
ExternalSecretRewriteRegexp (Optional) Used to rewrite with regular expressions. The resulting key will be the output of a regexp.ReplaceAll operation.
transform
ExternalSecretRewriteTransform (Optional) Used to apply string transformation on the secrets. The resulting key will be the output of the template applied by the operation.
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretRewriteRegexp","title":"ExternalSecretRewriteRegexp","text":" (Appears on: ExternalSecretRewrite)
Field Description source
string Used to define the regular expression of a re.Compiler.
target
string Used to define the target pattern of a ReplaceAll operation.
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretRewriteTransform","title":"ExternalSecretRewriteTransform","text":" (Appears on: ExternalSecretRewrite)
Field Description template
string Used to define the template to apply on the secret name. .value
will specify the secret name in the template.
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretSpec","title":"ExternalSecretSpec","text":" (Appears on: ClusterExternalSecretSpec, ExternalSecret)
ExternalSecretSpec defines the desired state of ExternalSecret.
Field Description secretStoreRef
SecretStoreRef (Optional) target
ExternalSecretTarget (Optional) refreshInterval
Kubernetes meta/v1.Duration RefreshInterval is the amount of time before the values are read again from the SecretStore provider Valid time units are \u201cns\u201d, \u201cus\u201d (or \u201c\u00b5s\u201d), \u201cms\u201d, \u201cs\u201d, \u201cm\u201d, \u201ch\u201d May be set to zero to fetch and create it once. Defaults to 1h.
data
[]ExternalSecretData (Optional) Data defines the connection between the Kubernetes Secret keys and the Provider data
dataFrom
[]ExternalSecretDataFromRemoteRef (Optional) DataFrom is used to fetch all properties from a specific Provider data If multiple entries are specified, the Secret keys are merged in the specified order
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretStatus","title":"ExternalSecretStatus","text":" (Appears on: ExternalSecret)
Field Description refreshTime
Kubernetes meta/v1.Time refreshTime is the time and date the external secret was fetched and the target secret updated
syncedResourceVersion
string SyncedResourceVersion keeps track of the last synced version
conditions
[]ExternalSecretStatusCondition (Optional) binding
Kubernetes core/v1.LocalObjectReference Binding represents a servicebinding.io Provisioned Service reference to the secret
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretStatusCondition","title":"ExternalSecretStatusCondition","text":" (Appears on: ExternalSecretStatus)
Field Description type
ExternalSecretConditionType status
Kubernetes core/v1.ConditionStatus reason
string (Optional) message
string (Optional) lastTransitionTime
Kubernetes meta/v1.Time (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretTarget","title":"ExternalSecretTarget","text":" (Appears on: ExternalSecretSpec)
ExternalSecretTarget defines the Kubernetes Secret to be created There can be only one target per ExternalSecret.
Field Description name
string (Optional) Name defines the name of the Secret resource to be managed This field is immutable Defaults to the .metadata.name of the ExternalSecret resource
creationPolicy
ExternalSecretCreationPolicy (Optional) CreationPolicy defines rules on how to create the resulting Secret Defaults to \u2018Owner\u2019
deletionPolicy
ExternalSecretDeletionPolicy (Optional) DeletionPolicy defines rules on how to delete the resulting Secret Defaults to \u2018Retain\u2019
template
ExternalSecretTemplate (Optional) Template defines a blueprint for the created Secret resource.
immutable
bool (Optional) Immutable defines if the final secret will be immutable
"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretTemplate","title":"ExternalSecretTemplate","text":" (Appears on: ExternalSecretTarget)
ExternalSecretTemplate defines a blueprint for the created Secret resource. we can not use native corev1.Secret, it will have empty ObjectMeta values: https://github.com/kubernetes-sigs/controller-tools/issues/448
Field Description type
Kubernetes core/v1.SecretType (Optional) engineVersion
TemplateEngineVersion EngineVersion specifies the template engine version that should be used to compile/execute the template specified in .data and .templateFrom[].
metadata
ExternalSecretTemplateMetadata (Optional) mergePolicy
TemplateMergePolicy data
map[string]string (Optional) templateFrom
[]TemplateFrom (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretTemplateMetadata","title":"ExternalSecretTemplateMetadata","text":" (Appears on: ExternalSecretTemplate)
ExternalSecretTemplateMetadata defines metadata fields for the Secret blueprint.
Field Description annotations
map[string]string (Optional) labels
map[string]string (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretValidator","title":"ExternalSecretValidator","text":""},{"location":"api/spec/#external-secrets.io/v1beta1.FakeProvider","title":"FakeProvider","text":" (Appears on: SecretStoreProvider)
FakeProvider configures a fake provider that returns static values.
Field Description data
[]FakeProviderData"},{"location":"api/spec/#external-secrets.io/v1beta1.FakeProviderData","title":"FakeProviderData","text":" (Appears on: FakeProvider)
Field Description key
string value
string valueMap
map[string]string Deprecated: ValueMap is deprecated and is intended to be removed in the future, use the value
field instead.
version
string"},{"location":"api/spec/#external-secrets.io/v1beta1.FindName","title":"FindName","text":" (Appears on: ExternalSecretFind)
Field Description regexp
string (Optional) Finds secrets base
"},{"location":"api/spec/#external-secrets.io/v1beta1.FortanixProvider","title":"FortanixProvider","text":" (Appears on: SecretStoreProvider)
Field Description apiUrl
string APIURL is the URL of SDKMS API. Defaults to sdkms.fortanix.com
.
apiKey
FortanixProviderSecretRef APIKey is the API token to access SDKMS Applications.
"},{"location":"api/spec/#external-secrets.io/v1beta1.FortanixProviderSecretRef","title":"FortanixProviderSecretRef","text":" (Appears on: FortanixProvider)
Field Description secretRef
External Secrets meta/v1.SecretKeySelector SecretRef is a reference to a secret containing the SDKMS API Key.
"},{"location":"api/spec/#external-secrets.io/v1beta1.GCPSMAuth","title":"GCPSMAuth","text":" (Appears on: GCPSMProvider)
Field Description secretRef
GCPSMAuthSecretRef (Optional) workloadIdentity
GCPWorkloadIdentity (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.GCPSMAuthSecretRef","title":"GCPSMAuthSecretRef","text":" (Appears on: GCPSMAuth)
Field Description secretAccessKeySecretRef
External Secrets meta/v1.SecretKeySelector (Optional) The SecretAccessKey is used for authentication
"},{"location":"api/spec/#external-secrets.io/v1beta1.GCPSMProvider","title":"GCPSMProvider","text":" (Appears on: SecretStoreProvider)
GCPSMProvider Configures a store to sync secrets using the GCP Secret Manager provider.
Field Description auth
GCPSMAuth (Optional) Auth defines the information necessary to authenticate against GCP
projectID
string ProjectID project where secret is located
"},{"location":"api/spec/#external-secrets.io/v1beta1.GCPWorkloadIdentity","title":"GCPWorkloadIdentity","text":" (Appears on: GCPSMAuth)
Field Description serviceAccountRef
External Secrets meta/v1.ServiceAccountSelector clusterLocation
string clusterName
string clusterProjectID
string"},{"location":"api/spec/#external-secrets.io/v1beta1.GeneratorRef","title":"GeneratorRef","text":" (Appears on: StoreGeneratorSourceRef, StoreSourceRef)
GeneratorRef points to a generator custom resource.
Field Description apiVersion
string Specify the apiVersion of the generator resource
kind
string Specify the Kind of the resource, e.g. Password, ACRAccessToken etc.
name
string Specify the name of the generator resource
"},{"location":"api/spec/#external-secrets.io/v1beta1.GenericStore","title":"GenericStore","text":"
GenericStore is a common interface for interacting with ClusterSecretStore or a namespaced SecretStore.
"},{"location":"api/spec/#external-secrets.io/v1beta1.GenericStoreValidator","title":"GenericStoreValidator","text":""},{"location":"api/spec/#external-secrets.io/v1beta1.GitlabAuth","title":"GitlabAuth","text":" (Appears on: GitlabProvider)
Field Description SecretRef
GitlabSecretRef"},{"location":"api/spec/#external-secrets.io/v1beta1.GitlabProvider","title":"GitlabProvider","text":" (Appears on: SecretStoreProvider)
Configures a store to sync secrets with a GitLab instance.
Field Description url
string URL configures the GitLab instance URL. Defaults to https://gitlab.com/.
auth
GitlabAuth Auth configures how secret-manager authenticates with a GitLab instance.
projectID
string ProjectID specifies a project where secrets are located.
inheritFromGroups
bool InheritFromGroups specifies whether parent groups should be discovered and checked for secrets.
groupIDs
[]string GroupIDs specify, which gitlab groups to pull secrets from. Group secrets are read from left to right followed by the project variables.
environment
string Environment environment_scope of gitlab CI/CD variables (Please see https://docs.gitlab.com/ee/ci/environments/#create-a-static-environment on how to create environments)
"},{"location":"api/spec/#external-secrets.io/v1beta1.GitlabSecretRef","title":"GitlabSecretRef","text":" (Appears on: GitlabAuth)
Field Description accessToken
External Secrets meta/v1.SecretKeySelector AccessToken is used for authentication.
"},{"location":"api/spec/#external-secrets.io/v1beta1.IBMAuth","title":"IBMAuth","text":" (Appears on: IBMProvider)
Field Description secretRef
IBMAuthSecretRef containerAuth
IBMAuthContainerAuth"},{"location":"api/spec/#external-secrets.io/v1beta1.IBMAuthContainerAuth","title":"IBMAuthContainerAuth","text":" (Appears on: IBMAuth)
IBM Container-based auth with IAM Trusted Profile.
Field Description profile
string the IBM Trusted Profile
tokenLocation
string Location the token is mounted on the pod
iamEndpoint
string"},{"location":"api/spec/#external-secrets.io/v1beta1.IBMAuthSecretRef","title":"IBMAuthSecretRef","text":" (Appears on: IBMAuth)
Field Description secretApiKeySecretRef
External Secrets meta/v1.SecretKeySelector The SecretAccessKey is used for authentication
"},{"location":"api/spec/#external-secrets.io/v1beta1.IBMProvider","title":"IBMProvider","text":" (Appears on: SecretStoreProvider)
Configures an store to sync secrets using a IBM Cloud Secrets Manager backend.
Field Description auth
IBMAuth Auth configures how secret-manager authenticates with the IBM secrets manager.
serviceUrl
string ServiceURL is the Endpoint URL that is specific to the Secrets Manager service instance
"},{"location":"api/spec/#external-secrets.io/v1beta1.KeeperSecurityProvider","title":"KeeperSecurityProvider","text":" (Appears on: SecretStoreProvider)
KeeperSecurityProvider Configures a store to sync secrets using Keeper Security.
Field Description authRef
External Secrets meta/v1.SecretKeySelector folderID
string"},{"location":"api/spec/#external-secrets.io/v1beta1.KubernetesAuth","title":"KubernetesAuth","text":" (Appears on: KubernetesProvider)
Field Description cert
CertAuth (Optional) has both clientCert and clientKey as secretKeySelector
token
TokenAuth (Optional) use static token to authenticate with
serviceAccount
External Secrets meta/v1.ServiceAccountSelector (Optional) points to a service account that should be used for authentication
"},{"location":"api/spec/#external-secrets.io/v1beta1.KubernetesProvider","title":"KubernetesProvider","text":" (Appears on: SecretStoreProvider)
Configures a store to sync secrets with a Kubernetes instance.
Field Description server
KubernetesServer configures the Kubernetes server Address.
auth
KubernetesAuth Auth configures how secret-manager authenticates with a Kubernetes instance.
remoteNamespace
string (Optional) Remote namespace to fetch the secrets from
"},{"location":"api/spec/#external-secrets.io/v1beta1.KubernetesServer","title":"KubernetesServer","text":" (Appears on: KubernetesProvider)
Field Description url
string (Optional) configures the Kubernetes server Address.
caBundle
[]byte (Optional) CABundle is a base64-encoded CA certificate
caProvider
CAProvider (Optional) see: https://external-secrets.io/v0.4.1/spec/#external-secrets.io/v1alpha1.CAProvider
"},{"location":"api/spec/#external-secrets.io/v1beta1.NoSecretError","title":"NoSecretError","text":"
NoSecretError shall be returned when a GetSecret can not find the desired secret. This is used for deletionPolicy.
"},{"location":"api/spec/#external-secrets.io/v1beta1.OnboardbaseAuthSecretRef","title":"OnboardbaseAuthSecretRef","text":" (Appears on: OnboardbaseProvider)
OnboardbaseAuthSecretRef holds secret references for onboardbase API Key credentials.
Field Description apiKeyRef
External Secrets meta/v1.SecretKeySelector OnboardbaseAPIKey is the APIKey generated by an admin account. It is used to recognize and authorize access to a project and environment within onboardbase
passcodeRef
External Secrets meta/v1.SecretKeySelector OnboardbasePasscode is the passcode attached to the API Key
"},{"location":"api/spec/#external-secrets.io/v1beta1.OnboardbaseProvider","title":"OnboardbaseProvider","text":" (Appears on: SecretStoreProvider)
OnboardbaseProvider configures a store to sync secrets using the Onboardbase provider. Project and Config are required if not using a Service Token.
Field Description auth
OnboardbaseAuthSecretRef Auth configures how the Operator authenticates with the Onboardbase API
apiHost
string APIHost use this to configure the host url for the API for selfhosted installation, default is https://public.onboardbase.com/api/v1/
project
string Project is an onboardbase project that the secrets should be pulled from
environment
string Environment is the name of an environmnent within a project to pull the secrets from
"},{"location":"api/spec/#external-secrets.io/v1beta1.OnePasswordAuth","title":"OnePasswordAuth","text":" (Appears on: OnePasswordProvider)
OnePasswordAuth contains a secretRef for credentials.
Field Description secretRef
OnePasswordAuthSecretRef"},{"location":"api/spec/#external-secrets.io/v1beta1.OnePasswordAuthSecretRef","title":"OnePasswordAuthSecretRef","text":" (Appears on: OnePasswordAuth)
OnePasswordAuthSecretRef holds secret references for 1Password credentials.
Field Description connectTokenSecretRef
External Secrets meta/v1.SecretKeySelector The ConnectToken is used for authentication to a 1Password Connect Server.
"},{"location":"api/spec/#external-secrets.io/v1beta1.OnePasswordProvider","title":"OnePasswordProvider","text":" (Appears on: SecretStoreProvider)
OnePasswordProvider configures a store to sync secrets using the 1Password Secret Manager provider.
Field Description auth
OnePasswordAuth Auth defines the information necessary to authenticate against OnePassword Connect Server
connectHost
string ConnectHost defines the OnePassword Connect Server to connect to
vaults
map[string]int Vaults defines which OnePassword vaults to search in which order
"},{"location":"api/spec/#external-secrets.io/v1beta1.OracleAuth","title":"OracleAuth","text":" (Appears on: OracleProvider)
Field Description tenancy
string Tenancy is the tenancy OCID where user is located.
user
string User is an access OCID specific to the account.
secretRef
OracleSecretRef SecretRef to pass through sensitive information.
"},{"location":"api/spec/#external-secrets.io/v1beta1.OraclePrincipalType","title":"OraclePrincipalType (string
alias)","text":" (Appears on: OracleProvider)
Value Description \"InstancePrincipal\"
InstancePrincipal represents a instance principal.
\"UserPrincipal\"
UserPrincipal represents a user principal.
\"Workload\"
WorkloadPrincipal represents a workload principal.
"},{"location":"api/spec/#external-secrets.io/v1beta1.OracleProvider","title":"OracleProvider","text":" (Appears on: SecretStoreProvider)
Configures an store to sync secrets using a Oracle Vault backend.
Field Description region
string Region is the region where vault is located.
vault
string Vault is the vault\u2019s OCID of the specific vault where secret is located.
compartment
string (Optional) Compartment is the vault compartment OCID. Required for PushSecret
encryptionKey
string (Optional) EncryptionKey is the OCID of the encryption key within the vault. Required for PushSecret
principalType
OraclePrincipalType (Optional) The type of principal to use for authentication. If left blank, the Auth struct will determine the principal type. This optional field must be specified if using workload identity.
auth
OracleAuth (Optional) Auth configures how secret-manager authenticates with the Oracle Vault. If empty, use the instance principal, otherwise the user credentials specified in Auth.
serviceAccountRef
External Secrets meta/v1.ServiceAccountSelector (Optional) ServiceAccountRef specified the service account that should be used when authenticating with WorkloadIdentity.
"},{"location":"api/spec/#external-secrets.io/v1beta1.OracleSecretRef","title":"OracleSecretRef","text":" (Appears on: OracleAuth)
Field Description privatekey
External Secrets meta/v1.SecretKeySelector PrivateKey is the user\u2019s API Signing Key in PEM format, used for authentication.
fingerprint
External Secrets meta/v1.SecretKeySelector Fingerprint is the fingerprint of the API private key.
"},{"location":"api/spec/#external-secrets.io/v1beta1.PassboltAuth","title":"PassboltAuth","text":" (Appears on: PassboltProvider)
Passbolt contains a secretRef for the passbolt credentials.
Field Description passwordSecretRef
External Secrets meta/v1.SecretKeySelector privateKeySecretRef
External Secrets meta/v1.SecretKeySelector"},{"location":"api/spec/#external-secrets.io/v1beta1.PassboltProvider","title":"PassboltProvider","text":" (Appears on: SecretStoreProvider)
Field Description auth
PassboltAuth Auth defines the information necessary to authenticate against Passbolt Server
host
string Host defines the Passbolt Server to connect to
"},{"location":"api/spec/#external-secrets.io/v1beta1.PasswordDepotAuth","title":"PasswordDepotAuth","text":" (Appears on: PasswordDepotProvider)
Field Description secretRef
PasswordDepotSecretRef"},{"location":"api/spec/#external-secrets.io/v1beta1.PasswordDepotProvider","title":"PasswordDepotProvider","text":" (Appears on: SecretStoreProvider)
Configures a store to sync secrets with a Password Depot instance.
Field Description host
string URL configures the Password Depot instance URL.
database
string Database to use as source
auth
PasswordDepotAuth Auth configures how secret-manager authenticates with a Password Depot instance.
"},{"location":"api/spec/#external-secrets.io/v1beta1.PasswordDepotSecretRef","title":"PasswordDepotSecretRef","text":" (Appears on: PasswordDepotAuth)
Field Description credentials
External Secrets meta/v1.SecretKeySelector (Optional) Username / Password is used for authentication.
"},{"location":"api/spec/#external-secrets.io/v1beta1.Provider","title":"Provider","text":"
Provider is a common interface for interacting with secret backends.
"},{"location":"api/spec/#external-secrets.io/v1beta1.PulumiProvider","title":"PulumiProvider","text":" (Appears on: SecretStoreProvider)
Field Description apiUrl
string APIURL is the URL of the Pulumi API.
accessToken
PulumiProviderSecretRef AccessToken is the access tokens to sign in to the Pulumi Cloud Console.
organization
string Organization are a space to collaborate on shared projects and stacks. To create a new organization, visit https://app.pulumi.com/ and click \u201cNew Organization\u201d.
environment
string Environment are YAML documents composed of static key-value pairs, programmatic expressions, dynamically retrieved values from supported providers including all major clouds, and other Pulumi ESC environments. To create a new environment, visit https://www.pulumi.com/docs/esc/environments/ for more information.
"},{"location":"api/spec/#external-secrets.io/v1beta1.PulumiProviderSecretRef","title":"PulumiProviderSecretRef","text":" (Appears on: PulumiProvider)
Field Description secretRef
External Secrets meta/v1.SecretKeySelector SecretRef is a reference to a secret containing the Pulumi API token.
"},{"location":"api/spec/#external-secrets.io/v1beta1.PushSecretData","title":"PushSecretData","text":"
PushSecretData is an interface to allow using v1alpha1.PushSecretData content in Provider registered in v1beta1.
"},{"location":"api/spec/#external-secrets.io/v1beta1.PushSecretRemoteRef","title":"PushSecretRemoteRef","text":"
PushSecretRemoteRef is an interface to allow using v1alpha1.PushSecretRemoteRef in Provider registered in v1beta1.
"},{"location":"api/spec/#external-secrets.io/v1beta1.ScalewayProvider","title":"ScalewayProvider","text":" (Appears on: SecretStoreProvider)
Field Description apiUrl
string (Optional) APIURL is the url of the api to use. Defaults to https://api.scaleway.com
region
string Region where your secrets are located: https://developers.scaleway.com/en/quickstart/#region-and-zone
projectId
string ProjectID is the id of your project, which you can find in the console: https://console.scaleway.com/project/settings
accessKey
ScalewayProviderSecretRef AccessKey is the non-secret part of the api key.
secretKey
ScalewayProviderSecretRef SecretKey is the non-secret part of the api key.
"},{"location":"api/spec/#external-secrets.io/v1beta1.ScalewayProviderSecretRef","title":"ScalewayProviderSecretRef","text":" (Appears on: ScalewayProvider)
Field Description value
string (Optional) Value can be specified directly to set a value without using a secret.
secretRef
External Secrets meta/v1.SecretKeySelector (Optional) SecretRef references a key in a secret that will be used as value.
"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStore","title":"SecretStore","text":"
SecretStore represents a secure external location for storing secrets, which can be referenced as part of storeRef
fields.
Field Description metadata
Kubernetes meta/v1.ObjectMeta Refer to the Kubernetes API documentation for the fields of the metadata
field. spec
SecretStoreSpec controller
string (Optional) Used to select the correct ESO controller (think: ingress.ingressClassName) The ESO controller is instantiated with a specific controller name and filters ES based on this property
provider
SecretStoreProvider Used to configure the provider. Only one provider may be set
retrySettings
SecretStoreRetrySettings (Optional) Used to configure http retries if failed
refreshInterval
int (Optional) Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
conditions
[]ClusterSecretStoreCondition (Optional) Used to constraint a ClusterSecretStore to specific namespaces. Relevant only to ClusterSecretStore
status
SecretStoreStatus"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStoreCapabilities","title":"SecretStoreCapabilities (string
alias)","text":" (Appears on: SecretStoreStatus)
SecretStoreCapabilities defines the possible operations a SecretStore can do.
Value Description \"ReadOnly\"
\"ReadWrite\"
\"WriteOnly\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStoreConditionType","title":"SecretStoreConditionType (string
alias)","text":" (Appears on: SecretStoreStatusCondition)
Value Description \"Ready\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStoreProvider","title":"SecretStoreProvider","text":" (Appears on: SecretStoreSpec)
SecretStoreProvider contains the provider-specific configuration.
Field Description aws
AWSProvider (Optional) AWS configures this store to sync secrets using AWS Secret Manager provider
azurekv
AzureKVProvider (Optional) AzureKV configures this store to sync secrets using Azure Key Vault provider
akeyless
AkeylessProvider (Optional) Akeyless configures this store to sync secrets using Akeyless Vault provider
vault
VaultProvider (Optional) Vault configures this store to sync secrets using Hashi provider
gcpsm
GCPSMProvider (Optional) GCPSM configures this store to sync secrets using Google Cloud Platform Secret Manager provider
oracle
OracleProvider (Optional) Oracle configures this store to sync secrets using Oracle Vault provider
ibm
IBMProvider (Optional) IBM configures this store to sync secrets using IBM Cloud provider
yandexcertificatemanager
YandexCertificateManagerProvider (Optional) YandexCertificateManager configures this store to sync secrets using Yandex Certificate Manager provider
yandexlockbox
YandexLockboxProvider (Optional) YandexLockbox configures this store to sync secrets using Yandex Lockbox provider
gitlab
GitlabProvider (Optional) GitLab configures this store to sync secrets using GitLab Variables provider
alibaba
AlibabaProvider (Optional) Alibaba configures this store to sync secrets using Alibaba Cloud provider
onepassword
OnePasswordProvider (Optional) OnePassword configures this store to sync secrets using the 1Password Cloud provider
webhook
WebhookProvider (Optional) Webhook configures this store to sync secrets using a generic templated webhook
kubernetes
KubernetesProvider (Optional) Kubernetes configures this store to sync secrets using a Kubernetes cluster provider
fake
FakeProvider (Optional) Fake configures a store with static key/value pairs
senhasegura
SenhaseguraProvider (Optional) Senhasegura configures this store to sync secrets using senhasegura provider
scaleway
ScalewayProvider (Optional) Scaleway
doppler
DopplerProvider (Optional) Doppler configures this store to sync secrets using the Doppler provider
onboardbase
OnboardbaseProvider (Optional) Onboardbase configures this store to sync secrets using the Onboardbase provider
keepersecurity
KeeperSecurityProvider (Optional) KeeperSecurity configures this store to sync secrets using the KeeperSecurity provider
conjur
ConjurProvider (Optional) Conjur configures this store to sync secrets using conjur provider
delinea
DelineaProvider (Optional) Delinea DevOps Secrets Vault https://docs.delinea.com/online-help/products/devops-secrets-vault/current
chef
ChefProvider (Optional) Chef configures this store to sync secrets with chef server
pulumi
PulumiProvider (Optional) Pulumi configures this store to sync secrets using the Pulumi provider
fortanix
FortanixProvider (Optional) Fortanix configures this store to sync secrets using the Fortanix provider
passworddepot
PasswordDepotProvider (Optional) passbolt
PassboltProvider (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStoreRef","title":"SecretStoreRef","text":" (Appears on: ExternalSecretSpec, StoreGeneratorSourceRef, StoreSourceRef)
SecretStoreRef defines which SecretStore to fetch the ExternalSecret data.
Field Description name
string Name of the SecretStore resource
kind
string (Optional) Kind of the SecretStore resource (SecretStore or ClusterSecretStore) Defaults to SecretStore
"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStoreRetrySettings","title":"SecretStoreRetrySettings","text":" (Appears on: SecretStoreSpec)
Field Description maxRetries
int32 retryInterval
string"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStoreSpec","title":"SecretStoreSpec","text":" (Appears on: ClusterSecretStore, SecretStore)
SecretStoreSpec defines the desired state of SecretStore.
Field Description controller
string (Optional) Used to select the correct ESO controller (think: ingress.ingressClassName) The ESO controller is instantiated with a specific controller name and filters ES based on this property
provider
SecretStoreProvider Used to configure the provider. Only one provider may be set
retrySettings
SecretStoreRetrySettings (Optional) Used to configure http retries if failed
refreshInterval
int (Optional) Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.
conditions
[]ClusterSecretStoreCondition (Optional) Used to constraint a ClusterSecretStore to specific namespaces. Relevant only to ClusterSecretStore
"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStoreStatus","title":"SecretStoreStatus","text":" (Appears on: ClusterSecretStore, SecretStore)
SecretStoreStatus defines the observed state of the SecretStore.
Field Description conditions
[]SecretStoreStatusCondition (Optional) capabilities
SecretStoreCapabilities (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStoreStatusCondition","title":"SecretStoreStatusCondition","text":" (Appears on: SecretStoreStatus)
Field Description type
SecretStoreConditionType status
Kubernetes core/v1.ConditionStatus reason
string (Optional) message
string (Optional) lastTransitionTime
Kubernetes meta/v1.Time (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretsClient","title":"SecretsClient","text":"
SecretsClient provides access to secrets.
"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretsManager","title":"SecretsManager","text":" (Appears on: AWSProvider)
SecretsManager defines how the provider behaves when interacting with AWS SecretsManager. Some of these settings are only applicable to controlling how secrets are deleted, and hence only apply to PushSecret (and only when deletionPolicy is set to Delete).
Field Description forceDeleteWithoutRecovery
bool (Optional) Specifies whether to delete the secret without any recovery window. You can\u2019t use both this parameter and RecoveryWindowInDays in the same call. If you don\u2019t use either, then by default Secrets Manager uses a 30 day recovery window. see: https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_DeleteSecret.html#SecretsManager-DeleteSecret-request-ForceDeleteWithoutRecovery
recoveryWindowInDays
int64 (Optional) The number of days from 7 to 30 that Secrets Manager waits before permanently deleting the secret. You can\u2019t use both this parameter and ForceDeleteWithoutRecovery in the same call. If you don\u2019t use either, then by default Secrets Manager uses a 30 day recovery window. see: https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_DeleteSecret.html#SecretsManager-DeleteSecret-request-RecoveryWindowInDays
"},{"location":"api/spec/#external-secrets.io/v1beta1.SenhaseguraAuth","title":"SenhaseguraAuth","text":" (Appears on: SenhaseguraProvider)
SenhaseguraAuth tells the controller how to do auth in senhasegura.
Field Description clientId
string clientSecretSecretRef
External Secrets meta/v1.SecretKeySelector"},{"location":"api/spec/#external-secrets.io/v1beta1.SenhaseguraModuleType","title":"SenhaseguraModuleType (string
alias)","text":" (Appears on: SenhaseguraProvider)
SenhaseguraModuleType enum defines senhasegura target module to fetch secrets
Value Description \"DSM\"
SenhaseguraModuleDSM is the senhasegura DevOps Secrets Management module\nsee: https://senhasegura.com/devops\n
"},{"location":"api/spec/#external-secrets.io/v1beta1.SenhaseguraProvider","title":"SenhaseguraProvider","text":" (Appears on: SecretStoreProvider)
SenhaseguraProvider setup a store to sync secrets with senhasegura.
Field Description url
string URL of senhasegura
module
SenhaseguraModuleType Module defines which senhasegura module should be used to get secrets
auth
SenhaseguraAuth Auth defines parameters to authenticate in senhasegura
ignoreSslCertificate
bool IgnoreSslCertificate defines if SSL certificate must be ignored
"},{"location":"api/spec/#external-secrets.io/v1beta1.StoreGeneratorSourceRef","title":"StoreGeneratorSourceRef","text":" (Appears on: ExternalSecretDataFromRemoteRef)
StoreGeneratorSourceRef allows you to override the source from which the secret will be pulled from. You can define at maximum one property.
Field Description storeRef
SecretStoreRef (Optional) generatorRef
GeneratorRef (Optional) GeneratorRef points to a generator custom resource.
"},{"location":"api/spec/#external-secrets.io/v1beta1.StoreSourceRef","title":"StoreSourceRef","text":" (Appears on: ExternalSecretData)
StoreSourceRef allows you to override the SecretStore source from which the secret will be pulled from. You can define at maximum one property.
Field Description storeRef
SecretStoreRef (Optional) generatorRef
GeneratorRef GeneratorRef points to a generator custom resource.
Deprecated: The generatorRef is not implemented in .data[]. this will be removed with v1.
"},{"location":"api/spec/#external-secrets.io/v1beta1.Tag","title":"Tag","text":"Field Description key
string value
string"},{"location":"api/spec/#external-secrets.io/v1beta1.TemplateEngineVersion","title":"TemplateEngineVersion (string
alias)","text":" (Appears on: ExternalSecretTemplate)
Value Description \"v1\"
\"v2\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.TemplateFrom","title":"TemplateFrom","text":" (Appears on: ExternalSecretTemplate)
Field Description configMap
TemplateRef secret
TemplateRef target
TemplateTarget (Optional) literal
string (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.TemplateMergePolicy","title":"TemplateMergePolicy (string
alias)","text":" (Appears on: ExternalSecretTemplate)
Value Description \"Merge\"
\"Replace\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.TemplateRef","title":"TemplateRef","text":" (Appears on: TemplateFrom)
Field Description name
string items
[]TemplateRefItem"},{"location":"api/spec/#external-secrets.io/v1beta1.TemplateRefItem","title":"TemplateRefItem","text":" (Appears on: TemplateRef)
Field Description key
string templateAs
TemplateScope"},{"location":"api/spec/#external-secrets.io/v1beta1.TemplateScope","title":"TemplateScope (string
alias)","text":" (Appears on: TemplateRefItem)
Value Description \"KeysAndValues\"
\"Values\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.TemplateTarget","title":"TemplateTarget (string
alias)","text":" (Appears on: TemplateFrom)
Value Description \"Annotations\"
\"Data\"
\"Labels\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.TokenAuth","title":"TokenAuth","text":" (Appears on: KubernetesAuth)
Field Description bearerToken
External Secrets meta/v1.SecretKeySelector"},{"location":"api/spec/#external-secrets.io/v1beta1.ValidationResult","title":"ValidationResult (byte
alias)","text":"Value Description 2
Error indicates that there is a misconfiguration.
0
Ready indicates that the client is configured correctly and can be used.
1
Unknown indicates that the client can be used but information is missing and it can not be validated.
"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultAppRole","title":"VaultAppRole","text":" (Appears on: VaultAuth)
VaultAppRole authenticates with Vault using the App Role auth mechanism, with the role and secret stored in a Kubernetes Secret resource.
Field Description path
string Path where the App Role authentication backend is mounted in Vault, e.g: \u201capprole\u201d
roleId
string (Optional) RoleID configured in the App Role authentication backend when setting up the authentication backend in Vault.
roleRef
External Secrets meta/v1.SecretKeySelector (Optional) Reference to a key in a Secret that contains the App Role ID used to authenticate with Vault. The key
field must be specified and denotes which entry within the Secret resource is used as the app role id.
secretRef
External Secrets meta/v1.SecretKeySelector Reference to a key in a Secret that contains the App Role secret used to authenticate with Vault. The key
field must be specified and denotes which entry within the Secret resource is used as the app role secret.
"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultAuth","title":"VaultAuth","text":" (Appears on: VaultProvider)
VaultAuth is the configuration used to authenticate with a Vault server. Only one of tokenSecretRef
, appRole
, kubernetes
, ldap
, userPass
, jwt
or cert
can be specified. A namespace to authenticate against can optionally be specified.
Field Description namespace
string (Optional) Name of the vault namespace to authenticate to. This can be different than the namespace your secret is in. Namespaces is a set of features within Vault Enterprise that allows Vault environments to support Secure Multi-tenancy. e.g: \u201cns1\u201d. More about namespaces can be found here https://www.vaultproject.io/docs/enterprise/namespaces This will default to Vault.Namespace field if set, or empty otherwise
tokenSecretRef
External Secrets meta/v1.SecretKeySelector (Optional) TokenSecretRef authenticates with Vault by presenting a token.
appRole
VaultAppRole (Optional) AppRole authenticates with Vault using the App Role auth mechanism, with the role and secret stored in a Kubernetes Secret resource.
kubernetes
VaultKubernetesAuth (Optional) Kubernetes authenticates with Vault by passing the ServiceAccount token stored in the named Secret resource to the Vault server.
ldap
VaultLdapAuth (Optional) Ldap authenticates with Vault by passing username/password pair using the LDAP authentication method
jwt
VaultJwtAuth (Optional) Jwt authenticates with Vault by passing role and JWT token using the JWT/OIDC authentication method
cert
VaultCertAuth (Optional) Cert authenticates with TLS Certificates by passing client certificate, private key and ca certificate Cert authentication method
iam
VaultIamAuth (Optional) Iam authenticates with vault by passing a special AWS request signed with AWS IAM credentials AWS IAM authentication method
userPass
VaultUserPassAuth (Optional) UserPass authenticates with Vault by passing username/password pair
"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultAwsAuth","title":"VaultAwsAuth","text":"
VaultAwsAuth tells the controller how to do authentication with aws. Only one of secretRef or jwt can be specified. if none is specified the controller will try to load credentials from its own service account assuming it is IRSA enabled.
Field Description secretRef
VaultAwsAuthSecretRef (Optional) jwt
VaultAwsJWTAuth (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultAwsAuthSecretRef","title":"VaultAwsAuthSecretRef","text":" (Appears on: VaultAwsAuth, VaultIamAuth)
VaultAWSAuthSecretRef holds secret references for AWS credentials both AccessKeyID and SecretAccessKey must be defined in order to properly authenticate.
Field Description accessKeyIDSecretRef
External Secrets meta/v1.SecretKeySelector The AccessKeyID is used for authentication
secretAccessKeySecretRef
External Secrets meta/v1.SecretKeySelector The SecretAccessKey is used for authentication
sessionTokenSecretRef
External Secrets meta/v1.SecretKeySelector The SessionToken used for authentication This must be defined if AccessKeyID and SecretAccessKey are temporary credentials see: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html
"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultAwsJWTAuth","title":"VaultAwsJWTAuth","text":" (Appears on: VaultAwsAuth, VaultIamAuth)
Authenticate against AWS using service account tokens.
Field Description serviceAccountRef
External Secrets meta/v1.ServiceAccountSelector"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultCertAuth","title":"VaultCertAuth","text":" (Appears on: VaultAuth)
VaultJwtAuth authenticates with Vault using the JWT/OIDC authentication method, with the role name and token stored in a Kubernetes Secret resource.
Field Description clientCert
External Secrets meta/v1.SecretKeySelector (Optional) ClientCert is a certificate to authenticate using the Cert Vault authentication method
secretRef
External Secrets meta/v1.SecretKeySelector SecretRef to a key in a Secret resource containing client private key to authenticate with Vault using the Cert authentication method
"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultClientTLS","title":"VaultClientTLS","text":" (Appears on: VaultProvider)
VaultClientTLS is the configuration used for client side related TLS communication, when the Vault server requires mutual authentication.
Field Description certSecretRef
External Secrets meta/v1.SecretKeySelector CertSecretRef is a certificate added to the transport layer when communicating with the Vault server. If no key for the Secret is specified, external-secret will default to \u2018tls.crt\u2019.
keySecretRef
External Secrets meta/v1.SecretKeySelector KeySecretRef to a key in a Secret resource containing client private key added to the transport layer when communicating with the Vault server. If no key for the Secret is specified, external-secret will default to \u2018tls.key\u2019.
"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultIamAuth","title":"VaultIamAuth","text":" (Appears on: VaultAuth)
VaultIamAuth authenticates with Vault using the Vault\u2019s AWS IAM authentication method. Refer: https://developer.hashicorp.com/vault/docs/auth/aws
Field Description path
string Path where the AWS auth method is enabled in Vault, e.g: \u201caws\u201d
region
string AWS region
role
string This is the AWS role to be assumed before talking to vault
vaultRole
string Vault Role. In vault, a role describes an identity with a set of permissions, groups, or policies you want to attach a user of the secrets engine
externalID
string AWS External ID set on assumed IAM roles
vaultAwsIamServerID
string X-Vault-AWS-IAM-Server-ID is an additional header used by Vault IAM auth method to mitigate against different types of replay attacks. More details here: https://developer.hashicorp.com/vault/docs/auth/aws
secretRef
VaultAwsAuthSecretRef (Optional) Specify credentials in a Secret object
jwt
VaultAwsJWTAuth (Optional) Specify a service account with IRSA enabled
"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultJwtAuth","title":"VaultJwtAuth","text":" (Appears on: VaultAuth)
VaultJwtAuth authenticates with Vault using the JWT/OIDC authentication method, with the role name and a token stored in a Kubernetes Secret resource or a Kubernetes service account token retrieved via TokenRequest
.
Field Description path
string Path where the JWT authentication backend is mounted in Vault, e.g: \u201cjwt\u201d
role
string (Optional) Role is a JWT role to authenticate using the JWT/OIDC Vault authentication method
secretRef
External Secrets meta/v1.SecretKeySelector (Optional) Optional SecretRef that refers to a key in a Secret resource containing JWT token to authenticate with Vault using the JWT/OIDC authentication method.
kubernetesServiceAccountToken
VaultKubernetesServiceAccountTokenAuth (Optional) Optional ServiceAccountToken specifies the Kubernetes service account for which to request a token for with the TokenRequest
API.
"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultKVStoreVersion","title":"VaultKVStoreVersion (string
alias)","text":" (Appears on: VaultProvider)
Value Description \"v1\"
\"v2\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultKubernetesAuth","title":"VaultKubernetesAuth","text":" (Appears on: VaultAuth)
Authenticate against Vault using a Kubernetes ServiceAccount token stored in a Secret.
Field Description mountPath
string Path where the Kubernetes authentication backend is mounted in Vault, e.g: \u201ckubernetes\u201d
serviceAccountRef
External Secrets meta/v1.ServiceAccountSelector (Optional) Optional service account field containing the name of a kubernetes ServiceAccount. If the service account is specified, the service account secret token JWT will be used for authenticating with Vault. If the service account selector is not supplied, the secretRef will be used instead.
secretRef
External Secrets meta/v1.SecretKeySelector (Optional) Optional secret field containing a Kubernetes ServiceAccount JWT used for authenticating with Vault. If a name is specified without a key, token
is the default. If one is not specified, the one bound to the controller will be used.
role
string A required field containing the Vault Role to assume. A Role binds a Kubernetes ServiceAccount with a set of Vault policies.
"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultKubernetesServiceAccountTokenAuth","title":"VaultKubernetesServiceAccountTokenAuth","text":" (Appears on: VaultJwtAuth)
VaultKubernetesServiceAccountTokenAuth authenticates with Vault using a temporary Kubernetes service account token retrieved by the TokenRequest
API.
Field Description serviceAccountRef
External Secrets meta/v1.ServiceAccountSelector Service account field containing the name of a kubernetes ServiceAccount.
audiences
[]string (Optional) Optional audiences field that will be used to request a temporary Kubernetes service account token for the service account referenced by serviceAccountRef
. Defaults to a single audience vault
it not specified. Deprecated: use serviceAccountRef.Audiences instead
expirationSeconds
int64 (Optional) Optional expiration time in seconds that will be used to request a temporary Kubernetes service account token for the service account referenced by serviceAccountRef
. Deprecated: this will be removed in the future. Defaults to 10 minutes.
"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultLdapAuth","title":"VaultLdapAuth","text":" (Appears on: VaultAuth)
VaultLdapAuth authenticates with Vault using the LDAP authentication method, with the username and password stored in a Kubernetes Secret resource.
Field Description path
string Path where the LDAP authentication backend is mounted in Vault, e.g: \u201cldap\u201d
username
string Username is a LDAP user name used to authenticate using the LDAP Vault authentication method
secretRef
External Secrets meta/v1.SecretKeySelector SecretRef to a key in a Secret resource containing password for the LDAP user used to authenticate with Vault using the LDAP authentication method
"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultProvider","title":"VaultProvider","text":" (Appears on: SecretStoreProvider)
Configures an store to sync secrets using a HashiCorp Vault KV backend.
Field Description auth
VaultAuth Auth configures how secret-manager authenticates with the Vault server.
server
string Server is the connection address for the Vault server, e.g: \u201chttps://vault.example.com:8200\u201d.
path
string (Optional) Path is the mount path of the Vault KV backend endpoint, e.g: \u201csecret\u201d. The v2 KV secret engine version specific \u201c/data\u201d path suffix for fetching secrets from Vault is optional and will be appended if not present in specified path.
version
VaultKVStoreVersion Version is the Vault KV secret engine version. This can be either \u201cv1\u201d or \u201cv2\u201d. Version defaults to \u201cv2\u201d.
namespace
string (Optional) Name of the vault namespace. Namespaces is a set of features within Vault Enterprise that allows Vault environments to support Secure Multi-tenancy. e.g: \u201cns1\u201d. More about namespaces can be found here https://www.vaultproject.io/docs/enterprise/namespaces
caBundle
[]byte (Optional) PEM encoded CA bundle used to validate Vault server certificate. Only used if the Server URL is using HTTPS protocol. This parameter is ignored for plain HTTP protocol connection. If not set the system root certificates are used to validate the TLS connection.
tls
VaultClientTLS (Optional) The configuration used for client side related TLS communication, when the Vault server requires mutual authentication. Only used if the Server URL is using HTTPS protocol. This parameter is ignored for plain HTTP protocol connection. It\u2019s worth noting this configuration is different from the \u201cTLS certificates auth method\u201d, which is available under the auth.cert
section.
caProvider
CAProvider (Optional) The provider for the CA bundle to use to validate Vault server certificate.
readYourWrites
bool (Optional) ReadYourWrites ensures isolated read-after-write semantics by providing discovered cluster replication states in each request. More information about eventual consistency in Vault can be found here https://www.vaultproject.io/docs/enterprise/consistency
forwardInconsistent
bool (Optional) ForwardInconsistent tells Vault to forward read-after-write requests to the Vault leader instead of simply retrying within a loop. This can increase performance if the option is enabled serverside. https://www.vaultproject.io/docs/configuration/replication#allow_forwarding_via_header
"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultUserPassAuth","title":"VaultUserPassAuth","text":" (Appears on: VaultAuth)
VaultUserPassAuth authenticates with Vault using UserPass authentication method, with the username and password stored in a Kubernetes Secret resource.
Field Description path
string Path where the UserPassword authentication backend is mounted in Vault, e.g: \u201cuser\u201d
username
string Username is a user name used to authenticate using the UserPass Vault authentication method
secretRef
External Secrets meta/v1.SecretKeySelector SecretRef to a key in a Secret resource containing password for the user used to authenticate with Vault using the UserPass authentication method
"},{"location":"api/spec/#external-secrets.io/v1beta1.WebhookCAProvider","title":"WebhookCAProvider","text":" (Appears on: WebhookProvider)
Defines a location to fetch the cert for the webhook provider from.
Field Description type
WebhookCAProviderType The type of provider to use such as \u201cSecret\u201d, or \u201cConfigMap\u201d.
name
string The name of the object located at the provider type.
key
string The key the value inside of the provider type to use, only used with \u201cSecret\u201d type
namespace
string (Optional) The namespace the Provider type is in.
"},{"location":"api/spec/#external-secrets.io/v1beta1.WebhookCAProviderType","title":"WebhookCAProviderType (string
alias)","text":" (Appears on: WebhookCAProvider)
Value Description \"ConfigMap\"
\"Secret\"
"},{"location":"api/spec/#external-secrets.io/v1beta1.WebhookProvider","title":"WebhookProvider","text":" (Appears on: SecretStoreProvider)
AkeylessProvider Configures an store to sync secrets using Akeyless KV.
Field Description method
string Webhook Method
url
string Webhook url to call
headers
map[string]string (Optional) Headers
body
string (Optional) Body
timeout
Kubernetes meta/v1.Duration (Optional) Timeout
result
WebhookResult Result formatting
secrets
[]WebhookSecret (Optional) Secrets to fill in templates These secrets will be passed to the templating function as key value pairs under the given name
caBundle
[]byte (Optional) PEM encoded CA bundle used to validate webhook server certificate. Only used if the Server URL is using HTTPS protocol. This parameter is ignored for plain HTTP protocol connection. If not set the system root certificates are used to validate the TLS connection.
caProvider
WebhookCAProvider (Optional) The provider for the CA bundle to use to validate webhook server certificate.
"},{"location":"api/spec/#external-secrets.io/v1beta1.WebhookResult","title":"WebhookResult","text":" (Appears on: WebhookProvider)
Field Description jsonPath
string (Optional) Json path of return value
"},{"location":"api/spec/#external-secrets.io/v1beta1.WebhookSecret","title":"WebhookSecret","text":" (Appears on: WebhookProvider)
Field Description name
string Name of this secret in templates
secretRef
External Secrets meta/v1.SecretKeySelector Secret ref to fill in credentials
"},{"location":"api/spec/#external-secrets.io/v1beta1.YandexCertificateManagerAuth","title":"YandexCertificateManagerAuth","text":" (Appears on: YandexCertificateManagerProvider)
Field Description authorizedKeySecretRef
External Secrets meta/v1.SecretKeySelector (Optional) The authorized key used for authentication
"},{"location":"api/spec/#external-secrets.io/v1beta1.YandexCertificateManagerCAProvider","title":"YandexCertificateManagerCAProvider","text":" (Appears on: YandexCertificateManagerProvider)
Field Description certSecretRef
External Secrets meta/v1.SecretKeySelector"},{"location":"api/spec/#external-secrets.io/v1beta1.YandexCertificateManagerProvider","title":"YandexCertificateManagerProvider","text":" (Appears on: SecretStoreProvider)
YandexCertificateManagerProvider Configures a store to sync secrets using the Yandex Certificate Manager provider.
Field Description apiEndpoint
string (Optional) Yandex.Cloud API endpoint (e.g. \u2018api.cloud.yandex.net:443\u2019)
folderID
string (Optional) If provided sets the ability to get secrets by its name in the specified folder
auth
YandexCertificateManagerAuth Auth defines the information necessary to authenticate against Yandex Certificate Manager
caProvider
YandexCertificateManagerCAProvider (Optional) The provider for the CA bundle to use to validate Yandex.Cloud server certificate.
"},{"location":"api/spec/#external-secrets.io/v1beta1.YandexLockboxAuth","title":"YandexLockboxAuth","text":" (Appears on: YandexLockboxProvider)
Field Description authorizedKeySecretRef
External Secrets meta/v1.SecretKeySelector (Optional) The authorized key used for authentication
"},{"location":"api/spec/#external-secrets.io/v1beta1.YandexLockboxCAProvider","title":"YandexLockboxCAProvider","text":" (Appears on: YandexLockboxProvider)
Field Description certSecretRef
External Secrets meta/v1.SecretKeySelector"},{"location":"api/spec/#external-secrets.io/v1beta1.YandexLockboxProvider","title":"YandexLockboxProvider","text":" (Appears on: SecretStoreProvider)
YandexLockboxProvider Configures a store to sync secrets using the Yandex Lockbox provider.
Field Description apiEndpoint
string (Optional) Yandex.Cloud API endpoint (e.g. \u2018api.cloud.yandex.net:443\u2019)
folderID
string (Optional) If provided sets the ability to get secrets by its name in the specified folder
auth
YandexLockboxAuth Auth defines the information necessary to authenticate against Yandex Lockbox
caProvider
YandexLockboxCAProvider (Optional) The provider for the CA bundle to use to validate Yandex.Cloud server certificate.
Generated with gen-crd-api-reference-docs
.
"},{"location":"api/generator/","title":"Index","text":"Generators allow you to generate values. See Generators Guide
"},{"location":"api/generator/acr/","title":"Azure Container Registry","text":"The Azure Container Registry (ACR) generator creates a short-lived refresh or access token for accessing ACR. The token is generated for a particular ACR registry defined in spec.registry
.
"},{"location":"api/generator/acr/#output-keys-and-values","title":"Output Keys and Values","text":"Key Description username username for the docker login
command password password for the docker login
command"},{"location":"api/generator/acr/#authentication","title":"Authentication","text":"You must choose one out of three authentication mechanisms:
- service principal
- managed identity
- workload identity
The generated token will inherit the permissions from the assigned policy. I.e. when you assign a read-only policy all generated tokens will be read-only. You must assign a Azure RBAC role, such as AcrPush
or AcrPull
to the service principal in order to be able to authenticate with the Azure container registry API.
You can scope tokens to a particular repository using spec.scope
.
"},{"location":"api/generator/acr/#scope","title":"Scope","text":"First, an Azure Active Directory access token is obtained with the desired authentication method. This AAD access token will be used to authenticate against ACR to issue a refresh token or access token. If spec.scope
if it is defined it obtains an ACR access token. If spec.scope
is missing it obtains an ACR refresh token:
- access tokens are scoped to a specific repository or action (pull,push)
- refresh tokens can are scoped to whatever policy is attached to the identity that creates the acr refresh token
The Scope grammar is defined in the Docker Registry spec. Note: You can not use a wildcards in the scope parameter, you can match exactly one repository and defined multiple actions like pull
or push
.
Example scopes:
repository:my-repository:pull,push\nrepository:my-repository:pull\n
"},{"location":"api/generator/acr/#example-manifest","title":"Example Manifest","text":"apiVersion: generators.external-secrets.io/v1alpha1\nkind: ACRAccessToken\nmetadata:\n name: my-azurecr\nspec:\n tenantId: 11111111-2222-3333-4444-111111111111\n registry: example.azurecr.io\n\n # optional; scope token down to a single repository/action\n # if set, it will generate an access token instead of an refresh token.\n scope: \"repository:foo:pull,push\"\n\n # Specify Azure cloud type, defaults to PublicCloud.\n # This is used for authenticating with Azure Active Directory.\n # available options: PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud\n environmentType: \"PublicCloud\"\n\n # choose one authentication method\n auth:\n\n # option 1: point to a secret that contains a client-id and client-secret\n servicePrincipal:\n secretRef:\n clientSecret:\n name: az-secret\n key: clientsecret\n clientId:\n name: az-secret\n key: clientid\n\n # option 2:\n managedIdentity:\n identityId: \"xxxxx\"\n\n # option 3:\n workloadIdentity:\n # note: you can reference service accounts across namespaces.\n serviceAccountRef:\n name: \"my-service-account\"\n audiences: []\n
Example ExternalSecret
that references the ACR generator:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: azurecr-credentials\nspec:\n dataFrom:\n - sourceRef:\n generatorRef:\n apiVersion: generators.external-secrets.io/v1alpha1\n kind: ACRAccessToken\n name: my-azurecr\n refreshInterval: 12h\n target:\n name: azurecr-credentials\n template:\n type: kubernetes.io/dockerconfigjson\n data:\n .dockerconfigjson: |\n {\n \"auths\": {\n \"myregistry.azurecr.io\": {\n \"username\": \"{{ .username }}\",\n \"identitytoken\": \"{{ .password }}\"\n }\n }\n }\n
"},{"location":"api/generator/ecr/","title":"AWS Elastic Container Registry","text":"ECRAuthorizationTokenSpec uses the GetAuthorizationToken API to retrieve an authorization token. The authorization token is valid for 12 hours. For more information, see registry authentication in the Amazon Elastic Container Registry User Guide.
"},{"location":"api/generator/ecr/#output-keys-and-values","title":"Output Keys and Values","text":"Key Description username username for the docker login
command. password password for the docker login
command. proxy_endpoint The registry URL to use for this authorization token in a docker login
command. expires_at time when token expires in UNIX time (seconds since January 1, 1970 UTC)."},{"location":"api/generator/ecr/#authentication","title":"Authentication","text":"You can choose from three authentication mechanisms:
- static credentials using
spec.auth.secretRef
- point to a IRSA Service Account with
spec.auth.jwt
- use credentials from the SDK default credentials chain from the controller environment
"},{"location":"api/generator/ecr/#example-manifest","title":"Example Manifest","text":"apiVersion: generators.external-secrets.io/v1alpha1\nkind: ECRAuthorizationToken\nmetadata:\n name: ecr-gen\nspec:\n\n # specify aws region (mandatory)\n region: eu-west-1\n\n # assume role with the given authentication credentials\n role: \"my-role\"\n\n # choose an authentication strategy\n # if no auth strategy is defined it falls back to using\n # credentials from the environment of the controller.\n auth:\n\n # 1: static credentials\n # point to a secret that contains static credentials\n # like AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY\n secretRef:\n accessKeyIDSecretRef:\n name: \"my-aws-creds\"\n key: \"key-id\"\n secretAccessKeySecretRef:\n name: \"my-aws-creds\"\n key: \"access-secret\"\n\n # option 2: IAM Roles for Service Accounts\n # point to a service account that should be used\n # that is configured for IAM Roles for Service Accounts (IRSA)\n jwt:\n serviceAccountRef:\n name: \"oci-token-sync\"\n
Example ExternalSecret
that references the ECR generator:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: \"ecr-secret\"\nspec:\n refreshInterval: \"1h\"\n target:\n name: ecr-secret\n dataFrom:\n - sourceRef:\n generatorRef:\n apiVersion: generators.external-secrets.io/v1alpha1\n kind: ECRAuthorizationToken\n name: \"ecr-gen\"\n
"},{"location":"api/generator/fake/","title":"Fake","text":"The Fake generator provides hard-coded key/value pairs. The intended use is just for debugging and testing. The key/value pairs defined in spec.data
is returned as-is.
"},{"location":"api/generator/fake/#example-manifest","title":"Example Manifest","text":"apiVersion: generators.external-secrets.io/v1alpha1\nkind: Fake\nmetadata:\n name: fake-key\nspec:\n data:\n foo: bar\n baz: bang\n
Example ExternalSecret
that references the Fake generator:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: \"fake\"\nspec:\n refreshInterval: \"30m\"\n target:\n name: fake\n dataFrom:\n - sourceRef:\n generatorRef:\n apiVersion: generators.external-secrets.io/v1alpha1\n kind: Fake\n name: \"fake-key\"\n
"},{"location":"api/generator/gcr/","title":"Google Container Registry","text":"GCRAccessToken creates a GCP Access token that can be used to authenticate with GCR in order to pull OCI images. You won't need any extra permissions to request for a token, but the token would only work against a GCR if the token requester (service Account or WI) has the appropriate access
You must specify the spec.projectID
in which GCR is located.
"},{"location":"api/generator/gcr/#output-keys-and-values","title":"Output Keys and Values","text":"Key Description username username for the docker login
command. password password for the docker login
command. expiry time when token expires in UNIX time (seconds since January 1, 1970 UTC)."},{"location":"api/generator/gcr/#authentication","title":"Authentication","text":""},{"location":"api/generator/gcr/#workload-identity","title":"Workload Identity","text":"Use spec.auth.workloadIdentity
to point to a Service Account that has Workload Identity enabled. For details see GCP Secret Manager.
"},{"location":"api/generator/gcr/#gcp-service-account","title":"GCP Service Account","text":"Use spec.auth.secretRef
to point to a Secret that contains a GCP Service Account. For details see GCP Secret Manager.
"},{"location":"api/generator/gcr/#example-manifest","title":"Example Manifest","text":"apiVersion: generators.external-secrets.io/v1alpha1\nkind: GCRAccessToken\nmetadata:\n name: gcr-gen\nspec:\n # project where gcr lives in\n projectID: \"\"\n\n # choose authentication strategy\n auth:\n # option 1: workload identity\n workloadIdentity:\n # point to the workload identity\n # service account\n serviceAccountRef:\n name: \"\"\n audiences: []\n # the cluster can live in a different project or location\n # use the following fields to configure where the cluster lives\n clusterLocation: \"\"\n clusterName: \"\"\n clusterProjectID: \"\"\n\n\n # option 2: GCP service account\n secretRef:\n secretAccessKeySecretRef:\n name: \"\"\n key: \"\"\n
Example ExternalSecret
that references the GCR generator:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: \"gcr-token\"\nspec:\n refreshInterval: \"30m\"\n target:\n name: gcr-token\n dataFrom:\n - sourceRef:\n generatorRef:\n apiVersion: generators.external-secrets.io/v1alpha1\n kind: GCRAccessToken\n name: \"gcr-gen\"\n
"},{"location":"api/generator/password/","title":"Password","text":"The Password generator provides random passwords that you can feed into your applications. It uses lower and uppercase alphanumeric characters as well as symbols. Please see below for the symbols in use.
Passwords are completely randomized
It is possible that we may generate passwords that don't match the expected character set from your application.
"},{"location":"api/generator/password/#output-keys-and-values","title":"Output Keys and Values","text":"Key Description password the generated password"},{"location":"api/generator/password/#parameters","title":"Parameters","text":"You can influence the behavior of the generator by providing the following args
Key Default Description length 24 Length of the password to be generated. digits 25% of the length Specify the number of digits in the generated password. symbols 25% of the length Specify the number of symbol characters in the generated. symbolCharacters ~!@#$%^&*()_+`-={}|[]\\:\"<>?,./ Specify the character set that should be used when generating the password. noUpper false disable uppercase characters. allowRepeat false allow repeating characters."},{"location":"api/generator/password/#example-manifest","title":"Example Manifest","text":"apiVersion: generators.external-secrets.io/v1alpha1\nkind: Password\nmetadata:\n name: my-password\nspec:\n length: 42\n digits: 5\n symbols: 5\n symbolCharacters: \"-_$@\"\n noUpper: false\n allowRepeat: true\n
Example ExternalSecret
that references the Password generator:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: \"password\"\nspec:\n refreshInterval: \"30m\"\n target:\n name: password-secret\n dataFrom:\n - sourceRef:\n generatorRef:\n apiVersion: generators.external-secrets.io/v1alpha1\n kind: Password\n name: \"my-password\"\n
Which will generate a Kind=Secret
with a key called 'password' that may look like:
RMngCHKtZ@@h@3aja$WZDuDVhkCkN48JBa9OF8jH$R\nVB$pX8SSUMIlk9K8g@XxJAhGz$0$ktbJ1ArMukg-bD\nHi$-aK_3Rrrw1Pj9-sIpPZuk5abvEDJlabUYUcS$9L\n
With default values you would get something like:
2Cp=O*&8x6sdwM!<74G_gUz5\n-MS`e#n24K|h5A<&6q9Yv7Cj\nZRv-k!y6x/V\"29:43aErSf$1\nVk9*mwXE30Q+>H?lY$5I64_q\n
"},{"location":"api/generator/vault/","title":"Vault Dynamic Secret","text":"The VaultDynamicSecret
Generator provides an interface to HashiCorp Vault's Secrets engines. Specifically, it enables obtaining dynamic secrets not covered by the HashiCorp Vault provider.
Any Vault authentication method supported by the provider can be used here (provider
block of the spec).
All secrets engines should be supported by providing matching path
, method
and parameters
values to the Generator spec (see example below).
Exact output keys and values depend on the Vault secret engine used; nested values are stored into the resulting Secret in JSON format.
"},{"location":"api/generator/vault/#example-manifest","title":"Example manifest","text":"apiVersion: generators.external-secrets.io/v1alpha1\nkind: VaultDynamicSecret\nmetadata:\n name: \"pki-example\"\nspec:\n path: \"/pki/issue/example-dot-com\"\n method: \"POST\"\n parameters:\n common_name: \"localhost\"\n ip_sans: \"127.0.0.1,127.0.0.11\"\n provider:\n server: \"http://vault.default.svc.cluster.local:8200\"\n auth:\n kubernetes:\n mountPath: \"kubernetes\"\n role: \"external-secrets-operator\"\n serviceAccountRef:\n name: \"default\"\n
Example ExternalSecret
that references the Vault generator:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: \"pki-example-com\"\nspec:\n refreshInterval: \"768h\"\n target:\n name: pki-example-com\n dataFrom:\n - sourceRef:\n generatorRef:\n apiVersion: generators.external-secrets.io/v1alpha1\n kind: VaultDynamicSecret\n name: \"pki-example\"\n
"},{"location":"api/generator/webhook/","title":"Webhook","text":"The Webhook generator is very similar to SecretStore generator, and provides a way to use external systems to generate sensitive information.
"},{"location":"api/generator/webhook/#output-keys-and-values","title":"Output Keys and Values","text":"Webhook calls are expected to produce valid JSON objects. All keys within that JSON object will be exported as keys to the kubernetes Secret.
"},{"location":"api/generator/webhook/#example-manifest","title":"Example Manifest","text":"apiVersion: generators.external-secrets.io/v1alpha1\nkind: Webhook\nmetadata:\n name: webhook\nspec:\n url: \"http://httpbin.org/get?parameter={{ .auth.param }}\"\n result:\n jsonPath: \"$.args\"\n headers:\n Content-Type: application/json\n Authorization: Basic {{ print .auth.username \":\" .auth.password | b64enc }}\n secrets:\n - name: auth\n secretRef:\n name: webhook-credentials\n---\napiVersion: v1\nkind: Secret\nmetadata:\n name: webhook-credentials\n labels:\n generators.external-secrets.io/type: webhook #Needed to allow webhook to use this secret\ndata:\n username: dGVzdA== # \"test\"\n password: dGVzdA== # \"test\"\n param: dGVzdA== # \"test\"\n
Example ExternalSecret
that references the Webhook generator using an internal Secret
:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: \"webhook\"\nspec:\n refreshInterval: \"30m\"\n target:\n name: webhook-secret\n dataFrom:\n - sourceRef:\n generatorRef:\n apiVersion: generators.external-secrets.io/v1alpha1\n kind: Webhook\n name: \"webhook\"\n
This will generate a kubernetes secret with the following values:
parameter: test\n
"},{"location":"contributing/coc/","title":"Code of Conduct","text":""},{"location":"contributing/coc/#our-pledge","title":"Our Pledge","text":"We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
"},{"location":"contributing/coc/#our-standards","title":"Our Standards","text":"Examples of behavior that contributes to a positive environment for our community include:
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
- Focusing on what is best not just for us as individuals, but for the overall community
Examples of unacceptable behavior include:
- The use of sexualized language or imagery, and sexual attention or advances of any kind
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email address, without their explicit permission
- Other conduct which could reasonably be considered inappropriate in a professional setting
"},{"location":"contributing/coc/#enforcement-responsibilities","title":"Enforcement Responsibilities","text":"Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
"},{"location":"contributing/coc/#scope","title":"Scope","text":"This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
"},{"location":"contributing/coc/#enforcement","title":"Enforcement","text":"Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at cncf-ExternalSecretsOp-maintainers@lists.cncf.io. All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the reporter of any incident.
"},{"location":"contributing/coc/#enforcement-guidelines","title":"Enforcement Guidelines","text":"Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
"},{"location":"contributing/coc/#1-correction","title":"1. Correction","text":"Community Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
Consequence: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
"},{"location":"contributing/coc/#2-warning","title":"2. Warning","text":"Community Impact: A violation through a single incident or series of actions.
Consequence: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
"},{"location":"contributing/coc/#3-temporary-ban","title":"3. Temporary Ban","text":"Community Impact: A serious violation of community standards, including sustained inappropriate behavior.
Consequence: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
"},{"location":"contributing/coc/#4-permanent-ban","title":"4. Permanent Ban","text":"Community Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
Consequence: A permanent ban from any sort of public interaction within the community.
"},{"location":"contributing/coc/#attribution","title":"Attribution","text":"This Code of Conduct is adapted from the Contributor Covenant, version 2.0, available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by Mozilla's code of conduct enforcement ladder.
For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.
"},{"location":"contributing/devguide/","title":"Developer guide","text":""},{"location":"contributing/devguide/#getting-started","title":"Getting Started","text":"You must have a working Go environment and then clone the repo:
git clone https://github.com/external-secrets/external-secrets.git\ncd external-secrets\n
Note: many of the make
commands use yq, version 4.2X.X or higher.
Our helm chart is tested using helm-unittest
. You will need it to run tests locally if you modify the helm chart. Install it with the following command:
$ helm plugin install https://github.com/helm-unittest/helm-unittest\n
"},{"location":"contributing/devguide/#building-testing","title":"Building & Testing","text":"The project uses the make
build system. It'll run code generators, tests and static code analysis.
Building the operator binary and docker image:
make build\nmake docker.build IMAGE_NAME=external-secrets IMAGE_TAG=latest\n
Run tests and lint the code:
make test\nmake lint # OR\ndocker run --rm -v $(pwd):/app -w /app golangci/golangci-lint:v1.49.0 golangci-lint run\n
Build the documentation:
make docs\n
"},{"location":"contributing/devguide/#using-tilt","title":"Using Tilt","text":"Tilt can be used to develop external-secrets. Tilt will hot-reload changes to the code and replace the running binary in the container using a process manager of its own.
To run tilt, download the utility for your operating system and run make tilt-up
. This will do two things: - downloads tilt for the current OS and ARCH under bin/tilt
- make manifest files of your current changes and place them under ./bin/deploy/manifests/external-secrets.yaml
- run tilt with tilt run
Hit space
and you can observe all the pods starting up and track their output in the tilt UI.
"},{"location":"contributing/devguide/#installing","title":"Installing","text":"To install the External Secret Operator into a Kubernetes Cluster run:
helm repo add external-secrets https://charts.external-secrets.io\nhelm repo update\nhelm install external-secrets external-secrets/external-secrets\n
You can alternatively run the controller on your host system for development purposes:
make crds.install\nmake run\n
To remove the CRDs run:
make crds.uninstall\n
If you need to test some other k8s integrations and need the operator to be deployed to the actual cluster while developing, you can use the following workflow:
# Start a local K8S cluster with KinD\nkind create cluster --name external-secrets\n\nexport TAG=$(make docker.tag)\nexport IMAGE=$(make docker.imagename)\n\n# Build docker image\nmake docker.build\n\n# Load docker image into local kind cluster\nkind load docker-image $IMAGE:$TAG --name external-secrets\n\n# (Optional) Pull the image from GitHub Repo to copy into kind\n# docker pull ghcr.io/external-secrets/external-secrets:v0.8.2\n# kind load docker-image ghcr.io/external-secrets/external-secrets:v0.8.2 -n external-secrets\n# export TAG=v0.8.2\n\n# Update helm charts and install to KinD cluster\nmake helm.generate\nhelm upgrade --install external-secrets ./deploy/charts/external-secrets/ \\\n--set image.repository=$IMAGE --set image.tag=$TAG \\\n--set webhook.image.repository=$IMAGE --set webhook.image.tag=$TAG \\\n--set certController.image.repository=$IMAGE --set certController.image.tag=$TAG\n\n\n# Command to delete the cluster when done\n# kind delete cluster -n external-secrets\n
Contributing Flow
The HOW TO guide for contributing is at the Contributing Process page.
"},{"location":"contributing/devguide/#documentation","title":"Documentation","text":"We use mkdocs material and mike to generate this documentation. See /docs
for the source code and /hack/api-docs
for the build process.
When writing documentation it is advised to run the mkdocs server with livereload:
make docs.serve\n
Run the following command to run a complete build. The rendered assets are available under /site
.
make docs\nmake docs.serve\n
Open http://localhost:8000
in your browser.
Since mike uses a branch to create/update documentation, any docs operation will create a diff on your local gh-pages
branch.
When finished writing/reviewing the docs, clean up your local docs branch changes with git branch -D gh-pages
"},{"location":"contributing/process/","title":"Contributing Process","text":""},{"location":"contributing/process/#project-management","title":"Project Management","text":"The Code, our TODOs and Documentation is maintained on GitHub. All Issues should be opened in that repository. We have a Roadmap to track progress for our road towards GA.
"},{"location":"contributing/process/#issues","title":"Issues","text":"Features, bugs and any issues regarding the documentation should be filed as GitHub Issue in our repository. We use labels like kind/feature
, kind/bug
, area/aws
to organize the issues. Issues labeled good first issue
and help wanted
are especially good for a first contribution. If you want to pick up an issue just leave a comment.
"},{"location":"contributing/process/#submitting-a-pull-request","title":"Submitting a Pull Request","text":"This project uses the well-known pull request process from GitHub. To submit a pull request, fork the repository and push any changes to a branch on the copy, from there a pull request can be made in the main repo. Merging a pull request requires the following steps to be completed before the pull request will be merged:
- ideally, there is an issue that documents the problem or feature in depth.
- code must have a reasonable amount of test coverage
- tests must pass
- PR needs be reviewed and approved
Once these steps are completed the PR will be merged by a code owner. We're using the pull request assignee
feature to track who is responsible for the lifecycle of the PR: review, merging, ping on inactivity, close. We close pull requests or issues if there is no response from the author for a period of time. Feel free to reopen if you want to get back on it.
"},{"location":"contributing/process/#triggering-e2e-tests","title":"Triggering e2e tests","text":"We have an extensive set of e2e tests that test the integration with real cloud provider APIs. Maintainers must trigger these kind of tests manually for PRs that come from forked repositories. These tests run inside a kind
cluster in the GitHub Actions runner:
/ok-to-test sha=xxxxxx\n
"},{"location":"contributing/process/#executing-e2e-tests-locally","title":"Executing e2e tests locally","text":"You have to prepare your shell environment with the necessary variables so the e2e test runner knows what credentials to use. See e2e/run.sh
for the variables that are passed in. If you e.g. want to test AWS integration make sure set all AWS_*
variables mentioned in that file.
Use ginkgo labels to select the tests you want to execute. You have to specify !managed
to ensure that you do not run managed tests.
make test.e2e GINKGO_LABELS='gcp&&!managed'\n
"},{"location":"contributing/process/#managed-kubernetes-e2e-tests","title":"Managed Kubernetes e2e tests","text":"There's another suite of e2e tests that integrate with managed Kubernetes offerings. They create real infrastructure at a cloud provider and deploy the controller into that environment. This is necessary to test the authentication integration (GCP Workload Identity, EKS IRSA...).
These tests are time intensive (~20-45min) and must be triggered manually by a maintainer when a particular provider or authentication mechanism was changed:
/ok-to-test-managed sha=xxxxxx provider=aws\n# or\n/ok-to-test-managed sha=xxxxxx provider=gcp\n# or\n/ok-to-test-managed sha=xxxxxx provider=azure\n
Both tests can run in parallel. Once started they add a dynamic GitHub check integration-managed-(gcp|aws|azure)
to the PR that triggered the test.
"},{"location":"contributing/process/#executing-managed-kubernetes-e2e-tests-locally","title":"Executing Managed Kubernetes e2e tests locally","text":"You have to prepare your shell environment with the necessary variables so the e2e test runner knows what credentials to use. See .github/workflows/e2e-managed.yml
for the variables that are passed in. If you e.g. want to test AWS integration make sure set all variables containing AWS_*
and TF_VAR_AWS_*
mentioned in that file.
Then execute tf.apply.aws
or tf.apply.gcp
to create the infrastructure.
make tf.apply.aws\n
Then run the managed
testsuite. You will need push permissions to the external-secrets ghcr repository. You can set IMAGE_NAME
to control which image registry is used to store the controller and e2e test images in.
You also have to setup a proper Kubeconfig so the e2e test pod gets deployed into the managed cluster.
aws eks update-kubeconfig --name ${AWS_CLUSTER_NAME}\nor\ngcloud container clusters get-credentials ${GCP_GKE_CLUSTER} --region europe-west1-b\n
Use ginkgo labels to select the tests you want to execute.
# you may have to set IMAGE_NAME=docker.io/your-user/external-secrets\nmake test.e2e.managed GINKGO_LABELS='gcp'\n
"},{"location":"contributing/process/#proposal-process","title":"Proposal Process","text":"Before we introduce significant changes to the project we want to gather feedback from the community to ensure that we progress in the right direction before we develop and release big changes. Significant changes include for example:
- creating new custom resources
- proposing breaking changes
- changing the behavior of the controller significantly
Please create a document in the design/
directory based on the template 000-template.md
and fill in your proposal. Open a pull request in draft mode and request feedback. Once the proposal is accepted and the pull request is merged we can create work packages and proceed with the implementation.
"},{"location":"contributing/process/#release-planning","title":"Release Planning","text":"We have a GitHub Project Board where we organize issues on a high level. We group issues by milestone. Once all issues of a given milestone are closed we should prepare a new feature release. Issues of the next milestone have priority over other issues - but that does not mean that no one is allowed to start working on them.
Issues must be manually added to that board (at least for now, see GH Roadmap). Milestones must be assigned manually as well. If no milestone is assigned it is basically a backlog item. It is the responsibility of the maintainers to:
- assign new issues to the GH Project
- add a milestone if needed
- add appropriate labels
If you would like to raise the priority of an issue for whatever reason feel free to comment on the issue or ping a maintainer.
"},{"location":"contributing/process/#support-questions","title":"Support & Questions","text":"Providing support to end users is an important and difficult task. We have three different channels through which support questions arise:
- Kubernetes Slack #external-secrets
- GitHub Discussions
- GitHub Issues
We use labels to identify GitHub Issues. Specifically for managing support cases we use the following labels to identify the state a support case is in:
triage/needs-information
: Indicates an issue needs more information in order to work on it. triage/not-reproducible
: Indicates an issue can not be reproduced as described. triage/support
: Indicates an issue that is a support question.
"},{"location":"contributing/process/#cutting-releases","title":"Cutting Releases","text":"The external-secrets project is released on a as-needed basis. Feel free to open a issue to request a release. Details on how to cut a release can be found in the release page.
"},{"location":"contributing/release/","title":"Release Process","text":"ESO and the ESO Helm Chart have two distinct lifecycles and can be released independently. Helm Chart releases are named external-secrets-x.y.z
.
The external-secrets project is released on a as-needed basis. Feel free to open a issue to request a release.
"},{"location":"contributing/release/#release-eso","title":"Release ESO","text":"When doing a release it's best to start with with the \"Create Release\" issue template, it has a checklist to go over.
\u26a0\ufe0f Note: when releasing multiple versions, make sure to first release the \"old\" version, then the newer version. Otherwise the latest
documentation will point to the older version. Also avoid to release both versions at the same time to avoid race conditions in the CI pipeline (updating docs, GitHub Release, helm chart release).
- Run
Create Release
Action to create a new release, pass in the desired version number to release. - choose the right
branch
to execute the action: use main
when creating a new release. Use release-x.y
when you want to bump a LTS release. - \u26a0\ufe0f make sure that CI on the relevant branch has completed the docker build/push jobs. Otherwise an old image will be promoted.
- GitHub Release, Changelog will be created by the
release.yml
workflow which also promotes the container image. - update Helm Chart, see below
- update OLM bundle, see helm-operator docs
"},{"location":"contributing/release/#release-helm-chart","title":"Release Helm Chart","text":" - Update
version
and/or appVersion
in Chart.yaml
and run make helm.docs helm.update.appversion helm.test.update helm.test
- push to branch and open pr
- run
/ok-to-test-managed
commands for all cloud providers - merge PR if everyhing is green
- CI picks up the new chart version and creates a new GitHub Release for it
- create/merge into release branch
- on a
minor
release: create a new branch release-x.y
- on a
patch
release: merge main into release-x.y
"},{"location":"contributing/release/#release-olm-bundle","title":"Release OLM Bundle","text":"In order to make the latest release available to OperatorHub.io we need to create a bundle and open a PR in the community-operators repository.
To create a bundle first increment the VERSION
in the Makefile as described above. Then run the following commands in the root of the repository:
# clone repo\ngit clone https://github.com/external-secrets/external-secrets-helm-operator\ncd external-secrets-helm-operator\n\n# bump version\nexport VERSION=x.y.z\nsed -i \"s/^VERSION ?= .*/VERSION ?= ${VERSION}/\" Makefile\n\n# prep release\nmake prepare-stable-release ATTACH_IMAGE_DIGESTS=0\n
Check the generated files in the bundle/
directory. If they look good add & commit them, open a PR against this repository. You can always use the OperatorHub.io/preview page to preview the generated CSV.
git status\ngit add .\ngit commit -s -m \"chore: bump version xyz\"\ngit push\n
Once the PR is merged and the image build job on main
has completed, we need create a pull request against both community-operators repositories. There's a make target that does the heavy lifting for you:
make attach-image-digests\nmake bundle-operatorhub\n
This command will add/commit/push and open pull requests in the respective repositories.
"},{"location":"contributing/roadmap/","title":"The road to external-secrets GA","text":"The following external-secret custom resource APIs are considered stable:
ExternalSecret
ClusterExternalSecret
SecretStore
ClusterSecretStore
These CRDs are currently at v1beta1
and are considered production ready. Going forward, breaking changes to these APIs will be accompanied by a conversion mechanism.
We have identified the following areas of work. This is subject to change while we gather feedback. We have a GitHub Project Board where we organize issues and milestones on a high level.
- Conformance testing
- \u2713 end to end testing with ArgoCD and Flux
- \u2713 end to end testing for all project maintained providers
- API enhancements
- consolidate provider fields
- \u2713 dataFrom key rewrites
- provider versioning strategy
- \u2713 pushing secrets to a provider
- Documentation Improvements
- Troubleshooting Guides
- \u2713 FAQ
- \u2713 review multi tenancy docs
- \u2713 security model for infosec teams
- \u2713 security best practices guide
- \u2713 provider specific guides
- Observability
- \u2713 Provide Grafana Dashboard and Prometheus alerts
- \u2713 add provider-level metrics
- Pentest
- \u2713 SBOM
"},{"location":"examples/anchore-engine-credentials/","title":"Getting started","text":"Anchore Engine is an open-source project that provides a centralized service for inspection, analysis, and certification of container images. With Kubernetes, it also brings nice features like preventing unscanned images from being deployed into your clusters
"},{"location":"examples/anchore-engine-credentials/#installing-with-helm","title":"Installing with Helm","text":"There are several parts of the installation that require credentials these being :-
ANCHORE_ADMIN_USERNAME ANCHORE_ADMIN_PASSWORD ANCHORE_DB_PASSWORD db-url db-user postgres-password
Creating the following external secret ensure the credentials are drawn from the backend provider of choice. The example shown here works with Hashicorp Vault and AWS Secrets Manager providers.
"},{"location":"examples/anchore-engine-credentials/#hashicorp-vault","title":"Hashicorp Vault","text":"apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: anchore-access-credentials\n namespace: security\nspec:\n refreshInterval: 1m\n secretStoreRef:\n name: vault-backend\n kind: ClusterSecretStore\n target:\n name: anchore-access-credentials\n template:\n\n data:\n ANCHORE_ADMIN_USERNAME: >-\n {{ printf \"{{ .username | toString }}\" }}\n ANCHORE_ADMIN_PASSWORD: >-\n {{ printf \"{{ .password | toString }}\" }}\n ANCHORE_DB_PASSWORD: >-\n {{ printf \"{{ .dbPassword | toString }}\" }}\n db-url: >-\n {{ printf \"{{ .dbUrl | toString }}\" }}\n db-user: >-\n {{ printf \"{{ .dbUser | toString }}\" }}\n postgres-password: >-\n {{ printf \"{{ .postgresPassword | toString }}\" }}\n\n data:\n - secretKey: password\n remoteRef:\n key: anchore-engine\n property: ANCHORE_ADMIN_PASSWORD\n - secretKey: username\n remoteRef:\n key: anchore-engine\n property: ANCHORE_ADMIN_USERNAME\n - secretKey: dbPassword\n remoteRef:\n key: anchore-engine\n property: ANCHORE_DB_PASSWORD\n - secretKey: dbUrl\n remoteRef:\n key: anchore-engine\n property: db-url\n - secretKey: dbUser\n remoteRef:\n key: anchore-engine\n property: db-user\n - secretKey: postgresPassword\n remoteRef:\n key: anchore-engine\n property: postgres-password\n
"},{"location":"examples/anchore-engine-credentials/#aws-secrets-manager","title":"AWS Secrets Manager","text":"---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: anchore-access-credentials\n namespace: ci\nspec:\n refreshInterval: 1m\n secretStoreRef:\n name: cluster-secrets-store\n kind: ClusterSecretStore\n target:\n name: anchore-access-credentials\n dataFrom:\n - extract:\n key: service/anchore-engine/engineAccess\n
"},{"location":"examples/bitwarden/","title":"Bitwarden support using webhook provider","text":"Bitwarden is an integrated open source password management solution for individuals, teams, and business organizations.
"},{"location":"examples/bitwarden/#how-does-it-work","title":"How does it work?","text":"To make external-secrets compatible with Bitwarden, we need:
- External Secrets Operator >= 0.8.0
- Multiple (Cluster)SecretStores using the webhook provider
- BitWarden CLI image running
bw serve
When you create a new external-secret object, the External Secrets webhook provider will query the Bitwarden CLI pod that is synced with the Bitwarden server.
"},{"location":"examples/bitwarden/#requirements","title":"Requirements","text":" - Bitwarden account (it also works with Vaultwarden!)
- A Kubernetes secret which contains your Bitwarden credentials
- A Docker image running the Bitwarden CLI. You could use
ghcr.io/charlesthomas/bitwarden-cli:2023.12.1
or build your own.
Here is an example of a Dockerfile used to build the image:
FROM debian:sid\n\nENV BW_CLI_VERSION=2023.12.1\n\nRUN apt update && \\\n apt install -y wget unzip && \\\n wget https://github.com/bitwarden/clients/releases/download/cli-v${BW_CLI_VERSION}/bw-linux-${BW_CLI_VERSION}.zip && \\\n unzip bw-linux-${BW_CLI_VERSION}.zip && \\\n chmod +x bw && \\\n mv bw /usr/local/bin/bw && \\\n rm -rfv *.zip\n\nCOPY entrypoint.sh /\n\nCMD [\"/entrypoint.sh\"]\n
And the content of entrypoint.sh
:
#!/bin/bash\n\nset -e\n\nbw config server ${BW_HOST}\n\nexport BW_SESSION=$(bw login ${BW_USER} --passwordenv BW_PASSWORD --raw)\n\nbw unlock --check\n\necho 'Running `bw server` on port 8087'\nbw serve --hostname 0.0.0.0 #--disable-origin-protection\n
"},{"location":"examples/bitwarden/#deploy-bitwarden-credentials","title":"Deploy Bitwarden credentials","text":"apiVersion: v1\ndata:\n BW_HOST: ...\n BW_USERNAME: ...\n BW_PASSWORD: ....\nkind: Secret\nmetadata:\n name: bitwarden-cli\n namespace: bitwarden\ntype: Opaque\n
"},{"location":"examples/bitwarden/#deploy-bitwarden-cli-container","title":"Deploy Bitwarden CLI container","text":"apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: bitwarden-cli\n namespace: bitwarden\n labels:\n app.kubernetes.io/instance: bitwarden-cli\n app.kubernetes.io/name: bitwarden-cli\nspec:\n replicas: 1\n strategy:\n type: Recreate\n selector:\n matchLabels:\n app.kubernetes.io/name: bitwarden-cli\n app.kubernetes.io/instance: bitwarden-cli\n template:\n metadata:\n labels:\n app.kubernetes.io/name: bitwarden-cli\n app.kubernetes.io/instance: bitwarden-cli\n spec:\n containers:\n - name: bitwarden-cli\n image: YOUR_BITWARDEN_CLI_IMAGE\n imagePullPolicy: IfNotPresent\n env:\n - name: BW_HOST\n valueFrom:\n secretKeyRef:\n name: bitwarden-cli\n key: BW_HOST\n - name: BW_USER\n valueFrom:\n secretKeyRef:\n name: bitwarden-cli\n key: BW_USERNAME\n - name: BW_PASSWORD\n valueFrom:\n secretKeyRef:\n name: bitwarden-cli\n key: BW_PASSWORD\n ports:\n - name: http\n containerPort: 8087\n protocol: TCP\n livenessProbe:\n exec:\n command:\n - wget\n - -q\n - http://127.0.0.1:8087/sync?force=true\n - --post-data=''\n initialDelaySeconds: 20\n failureThreshold: 3\n timeoutSeconds: 1\n periodSeconds: 120\n readinessProbe:\n tcpSocket:\n port: 8087\n initialDelaySeconds: 20\n failureThreshold: 3\n timeoutSeconds: 1\n periodSeconds: 10\n startupProbe:\n tcpSocket:\n port: 8087\n initialDelaySeconds: 10\n failureThreshold: 30\n timeoutSeconds: 1\n periodSeconds: 5\n---\napiVersion: v1\nkind: Service\nmetadata:\n name: bitwarden-cli\n namespace: bitwarden\n labels:\n app.kubernetes.io/instance: bitwarden-cli\n app.kubernetes.io/name: bitwarden-cli\n annotations:\nspec:\n type: ClusterIP\n ports:\n - port: 8087\n targetPort: http\n protocol: TCP\n name: http\n selector:\n app.kubernetes.io/name: bitwarden-cli\n app.kubernetes.io/instance: bitwarden-cli\n---\nkind: NetworkPolicy\napiVersion: networking.k8s.io/v1\nmetadata:\n namespace: bitwarden\n name: external-secret-2-bw-cli\nspec:\n podSelector:\n matchLabels:\n app.kubernetes.io/instance: bitwarden-cli\n app.kubernetes.io/name: bitwarden-cli\n ingress:\n - from:\n - podSelector:\n matchLabels:\n app.kubernetes.io/instance: external-secrets\n app.kubernetes.io/name: external-secrets\n
NOTE: Deploying a network policy is recommended since there is no authentication to query the Bitwarden CLI, which means that your secrets are exposed.
NOTE: In this example the Liveness probe is querying /sync to ensure that the Bitwarden CLI is able to connect to the server and is also synchronised. (The secret sync is only every 2 minutes in this example)
"},{"location":"examples/bitwarden/#deploy-clustersecretstores","title":"Deploy (Cluster)SecretStores","text":"There are four possible (Cluster)SecretStores to deploy, each can access different types of fields from an item in the Bitwarden vault. It is not required to deploy them all.
---\napiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\n name: bitwarden-login\nspec:\n provider:\n webhook:\n url: \"http://bitwarden-cli:8087/object/item/{{ .remoteRef.key }}\"\n headers:\n Content-Type: application/json\n result:\n jsonPath: \"$.data.login.{{ .remoteRef.property }}\"\n---\napiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\n name: bitwarden-fields\nspec:\n provider:\n webhook:\n url: \"http://bitwarden-cli:8087/object/item/{{ .remoteRef.key }}\"\n result:\n jsonPath: \"$.data.fields[?@.name==\\\"{{ .remoteRef.property }}\\\"].value\"\n---\napiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\n name: bitwarden-notes\nspec:\n provider:\n webhook:\n url: \"http://bitwarden-cli:8087/object/item/{{ .remoteRef.key }}\"\n result:\n jsonPath: \"$.data.notes\"\n---\napiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\n name: bitwarden-attachments\nspec:\n provider:\n webhook:\n url: \"http://bitwarden-cli:8087/object/attachment/{{ .remoteRef.property }}?itemid={{ .remoteRef.key }}\"\n result: {}\n
"},{"location":"examples/bitwarden/#usage","title":"Usage","text":"(Cluster)SecretStores:
bitwarden-login
: Use to get the username
or password
fields bitwarden-fields
: Use to get custom fields bitwarden-notes
: Use to get notes bitwarden-attachments
: Use to get attachments
remoteRef:
-
key
: ID of a secret, which can be found in the URL itemId
parameter: https://myvault.com/#/vault?type=login&itemId=........-....-....-....-............
s
-
property
: Name of the field to access
username
for the username of a secret (bitwarden-login
SecretStore) password
for the password of a secret (bitwarden-login
SecretStore) name_of_the_custom_field
for any custom field (bitwarden-fields
SecretStore) id_or_name_of_the_attachment
for any attachment (bitwarden-attachment
, SecretStore)
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: my-secrets\n namespace: default\nspec:\n target:\n name: my-secrets\n deletionPolicy: Delete\n template:\n type: Opaque\n data:\n username: |-\n {{ .username }}\n password: |-\n {{ .password }}\n postgres-password: |-\n {{ .postgres_password }}\n postgres-replication-password: |-\n {{ .postgres_replication_password }}\n db_url: |-\n postgresql://{{ .username }}:{{ .password }}@my-postgresql:5432/mydb\n service_account_key: |-\n {{ .service_account_key }}\n ssh_pub_key: |-\n {{ .ssh_pub_key }}\n data:\n - secretKey: username\n sourceRef:\n storeRef:\n name: bitwarden-login\n kind: ClusterSecretStore # or SecretStore\n remoteRef:\n key: aaaabbbb-cccc-dddd-eeee-000011112222\n property: username\n - secretKey: password\n sourceRef:\n storeRef:\n name: bitwarden-login\n kind: ClusterSecretStore # or SecretStore\n remoteRef:\n key: aaaabbbb-cccc-dddd-eeee-000011112222\n property: password\n - secretKey: postgres_password\n sourceRef:\n storeRef:\n name: bitwarden-fields\n kind: ClusterSecretStore # or SecretStore\n remoteRef:\n key: aaaabbbb-cccc-dddd-eeee-000011112222\n property: admin-password\n - secretKey: postgres_replication_password\n sourceRef:\n storeRef:\n name: bitwarden-fields\n kind: ClusterSecretStore # or SecretStore\n remoteRef:\n key: aaaabbbb-cccc-dddd-eeee-000011112222\n property: postgres-replication-password\n - secretKey: service_account_key\n sourceRef:\n storeRef:\n name: bitwarden-notes\n kind: ClusterSecretStore # or SecretStore\n remoteRef:\n key: service_account_key\n - secretKey: ssh_pub_key\n sourceRef:\n storeRef:\n name: bitwarden-attachments\n kind: ClusterSecretStore # or SecretStore\n remoteRef:\n key: aaaabbbb-cccc-dddd-eeee-000011112222\n property: id_rsa.pub\n
"},{"location":"examples/gitops-using-fluxcd/","title":"GitOps using FluxCD (v2)","text":"FluxCD is a GitOps operator for Kubernetes. It synchronizes the status of the cluster from manifests allocated in different repositories (Git or Helm). This approach fits perfectly with External Secrets on clusters which are dynamically created, to get credentials with no manual intervention from the beginning.
"},{"location":"examples/gitops-using-fluxcd/#advantages","title":"Advantages","text":"This approach has several advantages as follows:
- Homogenize environments allowing developers to use the same toolset in Kind in the same way they do in the cloud provider distributions such as EKS or GKE. This accelerates the development
- Reduce security risks, because credentials can be easily obtained, so temptation to store them locally is reduced.
- Application compatibility increase: Applications are deployed in different ways, and sometimes they need to share credentials. This can be done using External Secrets as a wire for them at real time.
- Automation by default oh, come on!
"},{"location":"examples/gitops-using-fluxcd/#the-approach","title":"The approach","text":"FluxCD is composed by several controllers dedicated to manage different custom resources. The most important ones are Kustomization (to clarify, Flux one, not Kubernetes' one) and HelmRelease to deploy using the approaches of the same names.
External Secrets can be deployed using Helm as explained here. The deployment includes the CRDs if enabled on the values.yaml
, but after this, you need to deploy some SecretStore
to start getting credentials from your secrets manager with External Secrets.
The idea of this guide is to deploy the whole stack, using flux, needed by developers not to worry about the credentials, but only about the application and its code.
"},{"location":"examples/gitops-using-fluxcd/#the-problem","title":"The problem","text":"This can sound easy, but External Secrets is deployed using Helm, which is managed by the HelmController, and your custom resources, for example a ClusterSecretStore
and the related Secret
, are often deployed using a kustomization.yaml
, which is deployed by the KustomizeController.
Both controllers manage the resources independently, at different moments, with no possibility to wait each other. This means that we have a wonderful race condition where sometimes the CRs (SecretStore
,ClusterSecretStore
...) tries to be deployed before than the CRDs needed to recognize them.
"},{"location":"examples/gitops-using-fluxcd/#the-solution","title":"The solution","text":"Let's see the conditions to start working on a solution:
- The External Secrets operator is deployed with Helm, and admits disabling the CRDs deployment
- The race condition only affects the deployment of
CustomResourceDefinition
and the CRs needed later - CRDs can be deployed directly from the Git repository of the project using a Flux
Kustomization
- Required CRs can be deployed using a Flux
Kustomization
too, allowing dependency between CRDs and CRs - All previous manifests can be applied with a Kubernetes
kustomization
"},{"location":"examples/gitops-using-fluxcd/#create-the-main-kustomization","title":"Create the main kustomization","text":"To have a better view of things needed later, the first manifest to be created is the kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n# Deploy the Vault access secret\n- namespace.yaml\n- secret-token.yaml\n\n# Deploy the repositories\n- repositories.yaml\n\n# Deploy the CRDs\n- deployment-crds.yaml\n\n# Deploy the operator\n- deployment.yaml\n\n# Deploy default Custom Resources from 'crs' directory\n# INFO: This depends on the CRDs deployment. Will happen after it\n- deployment-crs.yaml\n
"},{"location":"examples/gitops-using-fluxcd/#create-the-secret","title":"Create the secret","text":"To access your secret manager, External Secrets needs some credentials. They are stored inside a Secret, which is intended to be deployed by automation as a good practise. This time, a placeholder called secret-token.yaml
is show as an example:
# The namespace.yaml first\napiVersion: v1\nkind: Namespace\nmetadata:\n name: external-secrets\n
apiVersion: v1\nkind: Secret\nmetadata:\n name: vault-token-global\n namespace: external-secrets\nstringData:\n # This token must be patched by overlays. Not here for security reasons\n token: change-me-placeholder\n
"},{"location":"examples/gitops-using-fluxcd/#creating-the-references-to-repositories","title":"Creating the references to repositories","text":"Create a manifest called repositories.yaml
to store the references to external repositories for Flux
# Reference to Helm repository\napiVersion: source.toolkit.fluxcd.io/v1beta1\nkind: HelmRepository\nmetadata:\n name: external-secrets\n namespace: flux-system\nspec:\n interval: 10m\n url: https://charts.external-secrets.io\n---\napiVersion: source.toolkit.fluxcd.io/v1beta1\nkind: GitRepository\nmetadata:\n name: external-secrets\n namespace: flux-system\nspec:\n interval: 10m\n ref:\n branch: main\n url: http://github.com/external-secrets/external-secrets\n
"},{"location":"examples/gitops-using-fluxcd/#deploy-the-crds","title":"Deploy the CRDs","text":"As mentioned, CRDs can be deployed using the official Helm package, but to solve the race condition, they will be deployed from our git repository using a Kustomization manifest called deployment-crds.yaml
as follows:
---\napiVersion: kustomize.toolkit.fluxcd.io/v1beta2\nkind: Kustomization\nmetadata:\n name: external-secrets-crds\n namespace: flux-system\nspec:\n interval: 10m\n path: ./deploy/crds\n prune: true\n sourceRef:\n kind: GitRepository\n name: external-secrets\n
"},{"location":"examples/gitops-using-fluxcd/#deploy-the-operator","title":"Deploy the operator","text":"The operator is deployed using a HelmRelease manifest to deploy the Helm package, but due to the special race condition, the deployment must be disabled in the values
of the manifest called deployment.yaml
, as follows:
# How to manage values files. Ref: https://fluxcd.io/docs/guides/helmreleases/#refer-to-values-inside-the-chart\n# How to inject values: https://fluxcd.io/docs/guides/helmreleases/#cloud-storage\n---\napiVersion: helm.toolkit.fluxcd.io/v2beta1\nkind: HelmRelease\nmetadata:\n name: external-secrets\n namespace: flux-system\nspec:\n # Override Release name to avoid the pattern Namespace-Release\n # Ref: https://fluxcd.io/docs/components/helm/api/#helm.toolkit.fluxcd.io/v2beta1.HelmRelease\n releaseName: external-secrets\n targetNamespace: external-secrets\n interval: 10m\n chart:\n spec:\n chart: external-secrets\n version: 0.9.4\n sourceRef:\n kind: HelmRepository\n name: external-secrets\n namespace: flux-system\n values:\n installCRDs: false\n\n # Ref: https://fluxcd.io/docs/components/helm/api/#helm.toolkit.fluxcd.io/v2beta1.Install\n install:\n createNamespace: true\n
"},{"location":"examples/gitops-using-fluxcd/#deploy-the-crs","title":"Deploy the CRs","text":"Now, be ready for the arcane magic. Create a Kustomization manifest called deployment-crs.yaml
with the following content:
---\napiVersion: kustomize.toolkit.fluxcd.io/v1beta2\nkind: Kustomization\nmetadata:\n name: external-secrets-crs\n namespace: flux-system\nspec:\n dependsOn:\n - name: external-secrets-crds\n interval: 10m\n path: ./infrastructure/external-secrets/crs\n prune: true\n sourceRef:\n kind: GitRepository\n name: flux-system\n
There are several interesting details to see here, that finally solves the race condition:
- First one is the field
dependsOn
, which points to a previous Kustomization called external-secrets-crds
. This dependency forces this deployment to wait for the other to be ready, before start being deployed. - The reference to the place where to find the CRs
path: ./infrastructure/external-secrets/crs\nsourceRef:\n kind: GitRepository\n name: flux-system\n
Custom Resources will be searched in the relative path ./infrastructure/external-secrets/crs
of the GitRepository called flux-system
, which is a reference to the same repository that FluxCD watches to synchronize the cluster. With fewer words, a reference to itself, but going to another directory called crs
Of course, allocate inside the mentioned path ./infrastructure/external-secrets/crs
, all the desired CRs to be deployed, for example, a manifest clusterSecretStore.yaml
to reach your Hashicorp Vault as follows:
apiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\n name: vault-backend-global\nspec:\n provider:\n vault:\n server: \"https://vault.your-domain.com\"\n path: secret\n version: v2\n auth:\n # points to a secret that contains a vault token\n # https://www.vaultproject.io/docs/auth/token\n tokenSecretRef:\n name: \"vault-token-global\"\n key: \"token\"\n namespace: external-secrets\n
"},{"location":"examples/gitops-using-fluxcd/#results","title":"Results","text":"At the end, the required files tree is shown in the following picture:
"},{"location":"examples/jenkins-kubernetes-credentials/","title":"Getting started","text":"Jenkins is one of the most popular automation servers for continuous integration, automation, scheduling jobs and for generic pipelining. It has an extensive set of plugins that extend or provide additional functionality including the kubernetes credentials plugin. This plugin takes kubernetes secrets and creates Jenkins credentials from them removing the need for manual entry of secrets, local storage and manual secret rotation.
"},{"location":"examples/jenkins-kubernetes-credentials/#examples","title":"Examples","text":"The Jenkins credentials plugin uses labels and annotations on a kubernetes secret to create a Jenkins credential.
The different types of Jenkins credentials that can be created are SecretText, privateSSHKey, UsernamePassword.
"},{"location":"examples/jenkins-kubernetes-credentials/#secrettext","title":"SecretText","text":"Here are some examples of SecretText with the Hashicorp Vault and AWS External Secrets providers:
"},{"location":"examples/jenkins-kubernetes-credentials/#hashicorp-vault","title":"Hashicorp Vault","text":"apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: sonarqube-api-token\n namespace: ci\nspec:\n refreshInterval: 1m\n secretStoreRef:\n name: vault-backend\n kind: ClusterSecretStore\n target:\n name: sonarqube-api-token\n template:\n metadata:\n labels:\n \"jenkins.io/credentials-type\": \"secretText\"\n annotations:\n \"jenkins.io/credentials-description\": \"sonarqube api token\"\n data:\n text: >-\n {{ printf \"{{ .password | toString }}\" }}\n data:\n - secretKey: password\n remoteRef:\n key: jenkins-credentials\n property: sonarqube-api-token\n
"},{"location":"examples/jenkins-kubernetes-credentials/#aws-secrets-manager","title":"AWS Secrets Manager","text":"---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: sonarqube-api-token\n namespace: ci\nspec:\n refreshInterval: 1m\n secretStoreRef:\n name: cluster-secrets-store\n kind: ClusterSecretStore\n target:\n name: sonarqube-api-token\n template:\n metadata:\n labels:\n \"jenkins.io/credentials-type\": \"secretText\"\n annotations:\n \"jenkins.io/credentials-description\": \"Sonar API token\"\n data:\n - secretKey: text\n remoteRef:\n key: service/sonarqube/apiToken\n
"},{"location":"examples/jenkins-kubernetes-credentials/#usernamepassword","title":"UsernamePassword","text":"Here are some examples of UsernamePassword credentials with the Hashicorp Vault and AWS External Secrets providers:
"},{"location":"examples/jenkins-kubernetes-credentials/#hashicorp-vault_1","title":"Hashicorp Vault","text":"apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: harbor-chart-robot\n namespace: ci\nspec:\n refreshInterval: 1m\n secretStoreRef:\n name: vault-backend\n kind: ClusterSecretStore\n target:\n name: harbor-chart-robot\n template:\n metadata:\n labels:\n \"jenkins.io/credentials-type\": \"usernamePassword\"\n annotations:\n \"jenkins.io/credentials-description\": \"harbor chart robot\"\n data:\n username: >-\n {{ printf \"{{ .username | toString }}\" }}\n password: >-\n {{ printf \"{{ .password | toString }}\" }}\n data:\n - secretKey: username\n remoteRef:\n key: my-kv\n property: harbor-chart-robot-username\n - secretKey: password\n remoteRef:\n key: my-kv\n property: harbor-chart-robot-token\n
"},{"location":"examples/jenkins-kubernetes-credentials/#aws-secrets-manager_1","title":"AWS Secrets Manager","text":"---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: harbor-chart-robot\n namespace: ci\nspec:\n refreshInterval: 1m\n secretStoreRef:\n name: cluster-secrets-store\n kind: ClusterSecretStore\n target:\n name: harbor-chart-robot\n template:\n metadata:\n labels:\n \"jenkins.io/credentials-type\": \"usernamePassword\"\n annotations:\n \"jenkins.io/credentials-description\": \"harbor chart robot access\"\n data:\n - secretKey: password\n remoteRef:\n key: service/harbor/chartRobot\n property: password\n - secretKey: username\n remoteRef:\n key: service/harbor/chartRobot\n property: username\n
"},{"location":"examples/jenkins-kubernetes-credentials/#basicsshuserprivatekey","title":"basicSSHUserPrivateKey","text":"Here are some examples of basicSSHUserPrivateKey credentials with the Hashicorp Vault and AWS External Secrets providers:
"},{"location":"examples/jenkins-kubernetes-credentials/#hashicorp-vault_2","title":"Hashicorp Vault","text":"apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: github-ssh-access\n namespace: ci\nspec:\n refreshInterval: 1m\n secretStoreRef:\n name: vault-backend\n kind: ClusterSecretStore\n target:\n name: github-ssh-access\n template:\n metadata:\n labels:\n \"jenkins.io/credentials-type\": \"basicSSHUserPrivateKey\"\n annotations:\n \"jenkins.io/credentials-description\": \"github-ssh-access key\"\n data:\n username: >-\n {{ printf \"{{ .username | toString }}\" }}\n privateKey: >-\n {{ printf \"{{ .privateKey | toString }}\" }}\n data:\n - secretKey: username\n remoteRef:\n key: my-kv\n property: github-ssh-access-username\n - secretKey: privateKey\n remoteRef:\n key: my-kv\n property: github-ssh-access-private-key\n
"},{"location":"examples/jenkins-kubernetes-credentials/#aws-secrets-manager_2","title":"AWS Secrets Manager","text":"---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: github-ssh-access\n namespace: ci\nspec:\n refreshInterval: 1m\n secretStoreRef:\n name: cluster-parameter-store\n kind: ClusterSecretStore\n target:\n name: github-ssh-access\n template:\n metadata:\n labels:\n \"jenkins.io/credentials-type\": \"basicSSHUserPrivateKey\"\n annotations:\n \"jenkins.io/credentials-description\": \"github-ssh-access key\"\n data:\n - secretKey: username\n remoteRef:\n key: /service/github/sshUserPrivateKeyUserName\n - secretKey: privateKey\n remoteRef:\n key: /service/github/sshUserPrivateKey\n
"},{"location":"guides/all-keys-one-secret/","title":"All Keys, One Secret","text":"To get multiple key-values from an external secret, not having to worry about how many, or what these keys are, we have to use the dataFrom field of the ExternalSecret resource, instead of the data field. We will give an example here with the gcp provider (should work with other providers in the same way).
Please follow the authentication and SecretStore steps of the Google Cloud Secrets Manager guide to setup access to your google cloud account first.
Then create a secret in Google Cloud Secret Manager that contains a JSON string with multiple key values like this:
Let's call this secret all-keys-example-secret on Google Cloud.
"},{"location":"guides/all-keys-one-secret/#creating-datafrom-external-secret","title":"Creating dataFrom external secret","text":"Now, when creating our ExternalSecret resource, instead of using the data field, we use the dataFrom field:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example\nspec:\n refreshInterval: 1h # rate SecretManager pulls GCPSM\n secretStoreRef:\n kind: SecretStore\n name: example # name of the SecretStore (or kind specified)\n target:\n name: secret-to-be-created # name of the k8s Secret to be created\n creationPolicy: Owner\n dataFrom:\n - extract:\n key: all-keys-example-secret # name of the GCPSM secret\n
Here, \"example\" is the name of the external secret that will be created in our cluster. Whereas, \"secret-to-be-created\" is the name of Kubernetes secrets that will be created. Note: Since these secrets are namespace-based resources, you can also explicitly specify the \"namespace\" under the \"metadata\" block of the above external secret file. when we use, dataFrom:\n - extract:\n key: all-keys-example-secret\n
We get all the key-value pairs present over the remote secret store (GCP or AWS or Azure) and can pass either all or a few key-values as environment variables. Please note that, \"all-keys-example-secret\" is the name of your secret present on GCP/AWS secrets manager/Azure We can pass a few secrets as env variables as below:
env:\n - name: key1\n valueFrom:\n secretKeyRef:\n name: secret-to-be-created\n key: username\n\n - name: key2\n valueFrom:\n secretKeyRef:\n name: secret-to-be-created\n key: surname\n
Here, \\<key1> and \\ are the names of keys that will be created and passed as env variables. \\<secret-to-be-created>: is the name of your Kubernetes secret created by you. \\<username> and \\: is the particular key in the secrets manager whose value you want to pass. To check both values we can run:
kubectl get secret secret-to-be-created -n <namespace> -o jsonpath='{.data.username}' | base64 -d\nkubectl get secret secret-to-be-created -n <namespace> -o jsonpath='{.data.surname}' | base64 -d\n
Also, if you have a large number of secrets and you want to pass all of them as enviromnent variables, then either you can replicate the above steps in your deployment file for all the keys or you can use the envFrom block as below:
spec:\n containers:\n - command:\n - mkdir abc.sh\n envFrom:\n - secretRef:\n name: secret-to-be-created\n
"},{"location":"guides/common-k8s-secret-types/","title":"A few common k8s secret types examples","text":"Here we will give some examples of how to work with a few common k8s secret types. We will give this examples here with the gcp provider (should work with other providers in the same way). Please also check the guides on Advanced Templating to understand the details.
Please follow the authentication and SecretStore steps of the Google Cloud Secrets Manager guide to setup access to your google cloud account first.
"},{"location":"guides/common-k8s-secret-types/#dockerconfigjson-example","title":"Dockerconfigjson example","text":"First create a secret in Google Cloud Secrets Manager containing your docker config:
Let's call this secret docker-config-example on Google Cloud.
Then create a ExternalSecret resource taking advantage of templating to populate the generated secret:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: dk-cfg-example\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: example\n kind: SecretStore\n target:\n template:\n type: kubernetes.io/dockerconfigjson\n data:\n .dockerconfigjson: \"{{ .mysecret | toString }}\"\n name: secret-to-be-created\n creationPolicy: Owner\n data:\n - secretKey: mysecret\n remoteRef:\n key: docker-config-example\n
For Helm users: since Helm interprets the template above, the ExternalSecret resource can be written this way:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: dk-cfg-example\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: example\n kind: SecretStore\n target:\n template:\n type: kubernetes.io/dockerconfigjson\n engineVersion: v2\n data:\n .dockerconfigjson: \"{{ `{{ .mysecret }}` }}\"\n name: secret-to-be-created\n creationPolicy: Owner\n data:\n - secretKey: mysecret\n remoteRef:\n key: docker-config-example\n
For more information, please see this issue
This will generate a valid dockerconfigjson secret for you to use!
You can get the final value with:
kubectl get secret secret-to-be-created -n <namespace> -o jsonpath=\"{.data.\\.dockerconfigjson}\" | base64 -d\n
Alternately, if you only have the container registry name and password value, you can take advantage of the advanced ExternalSecret templating functions to create the secret:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: dk-cfg-example\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: example\n kind: SecretStore\n target:\n template:\n type: kubernetes.io/dockerconfigjson\n data:\n .dockerconfigjson: '{\"auths\":{\"{{ .registryName | lower }}.{{ .registryHost }}\":{\"username\":\"{{ .registryName }}\",\"password\":\"{{ .password }}\",\"auth\":\"{{ printf \"%s:%s\" .registryName .password | b64enc }}\"}}}'\n data:\n - secretKey: registryName\n remoteRef:\n key: secret/docker-registry-name # \"myRegistry\"\n - secretKey: registryHost\n remoteRef:\n key: secret/docker-registry-host # \"docker.io\"\n - secretKey: password\n remoteRef:\n key: secret/docker-registry-password\n
"},{"location":"guides/common-k8s-secret-types/#tls-cert-example","title":"TLS Cert example","text":"We are assuming here that you already have valid certificates, maybe generated with letsencrypt or any other CA. So to simplify you can use openssl to generate a single secret pkcs12 cert based on your cert.pem and privkey.pen files.
openssl pkcs12 -export -out certificate.p12 -inkey privkey.pem -in cert.pem\n
With a certificate.p12 you can upload it to Google Cloud Secrets Manager:
And now you can create an ExternalSecret that gets it. You will end up with a k8s secret of type tls with pem values.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: template-tls-example\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: example\n kind: SecretStore\n target:\n name: secret-to-be-created\n # this is how the Kind=Secret will look like\n template:\n type: kubernetes.io/tls\n data:\n tls.crt: \"{{ .mysecret | pkcs12cert | pemCertificate }}\"\n tls.key: \"{{ .mysecret | pkcs12key | pemPrivateKey }}\"\n\n data:\n # this is a pkcs12 archive that contains\n # a cert and a private key\n - secretKey: mysecret\n remoteRef:\n key: ssl-certificate-p12-example\n
You can get their values with:
kubectl get secret secret-to-be-created -n <namespace> -o jsonpath=\"{.data.tls\\.crt}\" | base64 -d\nkubectl get secret secret-to-be-created -n <namespace> -o jsonpath=\"{.data.tls\\.key}\" | base64 -d\n
"},{"location":"guides/common-k8s-secret-types/#ssh-auth-example","title":"SSH Auth example","text":"Add the ssh privkey to a new Google Cloud Secrets Manager secret:
And now you can create an ExternalSecret that gets it. You will end up with a k8s secret of type ssh-auth with the privatekey value.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: ssh-auth-example\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: example\n kind: SecretStore\n target:\n name: secret-to-be-created\n template:\n type: kubernetes.io/ssh-auth\n data:\n ssh-privatekey: \"{{ .mysecret | toString }}\"\n name: secret-to-be-created\n creationPolicy: Owner\n data:\n - secretKey: mysecret\n remoteRef:\n key: ssh-priv-key-example\n
You can get the privkey value with:
kubectl get secret secret-to-be-created -n <namespace> -o jsonpath=\"{.data.ssh-privatekey}\" | base64 -d\n
"},{"location":"guides/common-k8s-secret-types/#more-examples","title":"More examples","text":"We need more examples here
Feel free to contribute with our docs and add more examples here!
"},{"location":"guides/controller-class/","title":"Controller Classes","text":"NOTE: this feature is experimental and not highly tested
Controller classes are a property set during the deployment that allows multiple controllers to work in a group of workload. It works by separating which secretStores are going to be attributed to which controller. For the behavior of a single controller, no extra configuration is needed.
"},{"location":"guides/controller-class/#setting-up-controller-class","title":"Setting up Controller Class","text":"In order to deploy the controller with a specific class, install the helm charts specifying the controller class, and create a SecretStore
with the appropriate spec.controller
values:
helm install custom-external-secrets external-secrets/external-secrets --set controllerClass=custom\n
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: controller-custom-example\nspec:\n #define the controller label to the matching value of the deployment\n controller: custom\n #configure provider the same way\n provider:\n vault:\n server: \"http://vault.default:8200\"\n path: \"secret\"\n version: \"v2\"\n auth:\n kubernetes:\n mountPath: \"kubernetes\"\n role: \"demo-role\"\n
Now, any ExternalSecret
bound to this secret store will be evaluated by the operator with the controllerClass custom.
Note: Any SecretStore without spec.controller
set will be considered as valid by any operator, regardless of their respective controllerClasses.
"},{"location":"guides/datafrom-rewrite/","title":"Rewriting Keys in DataFrom","text":"When calling out an ExternalSecret with dataFrom.extract
or dataFrom.find
, it is possible that you end up with a kubernetes secret that has conflicts in the key names, or that you simply want to remove a common path from the secret keys.
In order to do so, it is possible to define a set of rewrite operations using dataFrom.rewrite
. These operations can be stacked, hence allowing complex manipulations of the secret keys.
Rewrite operations are all applied before ConversionStrategy
is applied.
"},{"location":"guides/datafrom-rewrite/#methods","title":"Methods","text":""},{"location":"guides/datafrom-rewrite/#regexp","title":"Regexp","text":"This method implements rewriting through the use of regular expressions. It needs a source
and a target
field. The source field is where the definition of the matching regular expression goes, where the target
field is where the replacing expression goes.
Some considerations about the implementation of Regexp Rewrite:
- The input of a subsequent rewrite operation are the outputs of the previous rewrite.
- If a given set of keys do not match any Rewrite operation, there will be no error. Rather, the original keys will be used.
- If a
source
is not a compilable regexp
expression, an error will be produced and the external secret goes into a error state.
"},{"location":"guides/datafrom-rewrite/#examples","title":"Examples","text":""},{"location":"guides/datafrom-rewrite/#removing-a-common-path-from-find-operations","title":"Removing a common path from find operations","text":"The following ExternalSecret:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example\nspec:\n refreshInterval: 1h\n secretStoreRef:\n kind: SecretStore\n name: backend\n target:\n name: secret-to-be-created\n dataFrom:\n - find:\n path: path/to/my\n name: \n regexp: secrets\n rewrite:\n - regexp:\n source: \"path/to/my/secrets/(.*)\"\n target: \"$1\"\n
Will get all the secrets matching path/to/my/secrets/*
and then rewrite them by removing the common path away. In this example, if we had the following secrets available in the provider:
path/to/my/secrets/username\npath/to/my/secrets/password\n
the output kubernetes secret would be: apiVersion: v1\nkind: Secret\ntype: Opaque\ndata:\n username: ...\n password: ...\n
"},{"location":"guides/datafrom-rewrite/#avoiding-key-collisions","title":"Avoiding key collisions","text":"The following ExternalSecret:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example\nspec:\n refreshInterval: 1h\n secretStoreRef:\n kind: SecretStore\n name: backend\n target:\n name: secret-to-be-created\n dataFrom:\n - extract:\n key: my-secrets-dev\n rewrite:\n - regexp:\n source: \"(.*)\"\n target: \"dev-$1\" \n - extract:\n key: my-secrets-prod\n rewrite:\n - regexp:\n source: \"(.*)\"\n target: \"prod-$1\"\n
Will allow two secrets with the same JSON keys to be imported into a Kubernetes Secret without any conflict. In this example, if we had the following secrets available in the provider: {\n \"my-secrets-dev\": {\n \"password\": \"bar\",\n },\n \"my-secrets-prod\": {\n \"password\": \"safebar\",\n }\n}\n
the output kubernetes secret would be: apiVersion: v1\nkind: Secret\ntype: Opaque\ndata:\n dev_password: YmFy #bar\n prod_password: c2FmZWJhcg== #safebar\n
"},{"location":"guides/datafrom-rewrite/#remove-invalid-characters","title":"Remove invalid characters","text":"The following ExternalSecret:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example\nspec:\n refreshInterval: 1h\n secretStoreRef:\n kind: SecretStore\n name: backend\n target:\n name: secret-to-be-created\n dataFrom:\n - extract:\n key: development\n rewrite:\n - regexp:\n source: \"[^a-zA-Z0-9 -]\"\n target: \"_\"\n
Will remove invalid characters from the secret key. In this example, if we had the following secrets available in the provider: {\n \"development\": {\n \"foo/bar\": \"1111\",\n \"foo$baz\": \"2222\"\n }\n}\n
the output kubernetes secret would be: apiVersion: v1\nkind: Secret\ntype: Opaque\ndata:\n foo_bar: MTExMQ== #1111\n foo_baz: MjIyMg== #2222\n
"},{"location":"guides/datafrom-rewrite/#limitations","title":"Limitations","text":"Regexp Rewrite is based on golang regexp
, which in turns implements RE2
regexp language. There a a series of known limitations to this implementation, such as:
- Lack of ability to do lookaheads or lookbehinds;
- Lack of negation expressions;
- Lack of support for conditional branches;
- Lack of support for possessive repetitions.
A list of compatibility and known limitations considering other commonly used regexp frameworks (such as PCRE and PERL) are listed here.
"},{"location":"guides/decoding-strategy/","title":"Decoding Strategies","text":"The External Secrets Operator has the feature to allow multiple decoding strategies during an object generation.
The decodingStrategy
field allows the user to set the following Decoding Strategies based on their needs. decodingStrategy
can be placed under spec.data.remoteRef
, spec.dataFrom.extract
or spec.dataFrom.find
. It will configure the decoding strategy for that specific operation, leaving others with the default behavior if not set.
"},{"location":"guides/decoding-strategy/#none-default","title":"None (default)","text":"ESO will not try to decode the secret value.
"},{"location":"guides/decoding-strategy/#base64","title":"Base64","text":"ESO will try to decode the secret value using base64 method. If the decoding fails, an error is produced.
"},{"location":"guides/decoding-strategy/#base64url","title":"Base64URL","text":"ESO will try to decode the secret value using base64url method. If the decoding fails, an error is produced.
"},{"location":"guides/decoding-strategy/#auto","title":"Auto","text":"ESO will try to decode using Base64/Base64URL strategies. If the decoding fails, ESO will apply decoding strategy None. No error is produced to the user.
"},{"location":"guides/decoding-strategy/#examples","title":"Examples","text":""},{"location":"guides/decoding-strategy/#setting-decoding-strategy-auto-in-a-datafromextract","title":"Setting Decoding strategy Auto in a DataFrom.Extract","text":"Given that we have the given secret information:
{\n \"name\": \"Gustavo\",\n \"surname\": \"Fring\",\n \"address\":\"aGFwcHkgc3RyZWV0\",\n}\n
if we apply the following dataFrom: spec:\n dataFrom:\n - extract:\n key: my-secret\n decodingStrategy: Auto\n
It will render the following Kubernetes Secret: data:\n name: R3VzdGF2bw== #Gustavo\n surname: RnJpbmc= #Fring\n address: aGFwcHkgc3RyZWV0 #happy street\n
"},{"location":"guides/decoding-strategy/#limitations","title":"Limitations","text":"At this time, decoding Strategy Auto is only trying to check if the original input is valid to perform Base64 operations. This means that some non-encoded secret values might end up being decoded, producing gibberish. This is the case for numbered values like 123456
or some specially crafted string values such as happy/street
.
Note
If you are using decodeStrategy: Auto
and start to see ESO pulling completely wrong secret values into your kubernetes secret, consider changing it to None
to investigate it.
"},{"location":"guides/disable-cluster-features/","title":"Deploying without ClusterSecretStore and ClusterExternalSecret","text":"When deploying External Secrets Operator via Helm chart, the default configuration will install ClusterSecretStore
and ClusterExternalSecret
CRDs and these objects will be processed by the operator.
In order to disable both or one of these features, it is necessary to configure the crds.*
Helm value, as well as the process*
Helm value, as these 2 values are connected.
If you would like to install the operator without ClusterSecretStore
and ClusterExternalSecret
management, you will have to :
- set
crds.createClusterExternalSecret
to false - set
crds.createClusterSecretStore
to false - set
processClusterExternalSecret
to false - set
processClusterStore
to false
Example:
helm install external-secrets external-secrets/external-secrets --set crds.createClusterExternalSecret=false \\\n--set crds.createClusterSecretStore=false \\\n--set processClusterExternalSecret=false \\\n--set processClusterStore=false\n
"},{"location":"guides/generator/","title":"Generators","text":"Generators allow you to generate values. They are used through a ExternalSecret spec.DataFrom
. They are referenced from a custom resource using sourceRef.generatorRef
.
If the External Secret should be refreshed via spec.refreshInterval
the generator produces a map of values with the generator.spec
as input. The generator does not keep track of the produced values. Every invocation produces a new set of values.
These values can be used with the other features like rewrite
or template
. I.e. you can modify, encode, decode, pack the values as needed.
"},{"location":"guides/generator/#reference-custom-resource","title":"Reference Custom Resource","text":"Generators can be defined as a custom resource and re-used across different ExternalSecrets. Every invocation creates a new set of values. I.e. you can not share the same value produced by a generator across different ExternalSecrets
or spec.dataFrom[]
entries.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: \"ecr-token\"\nspec:\n refreshInterval: \"30m\"\n target:\n name: ecr-token\n dataFrom:\n - sourceRef:\n generatorRef:\n apiVersion: generators.external-secrets.io/v1alpha1\n kind: ECRAuthorizationToken\n name: \"my-ecr\"\n
"},{"location":"guides/getallsecrets/","title":"Fetching information from multiple secrets","text":"In some use cases, it might be impractical to bundle all sensitive information into a single secret, or even it is not possible to fully know a given secret name. In such cases, it is possible that a user might need to sync multiple secrets from an external provider into a single Kubernetes Secret. This is possible to be done in external-secrets with the dataFrom.find
option.
Note
The secret's contents as defined in the provider are going to be stored in the kubernetes secret as a single key. Currently, it's possible to apply a decoding Strategy during a find operation, but only at the secret level (e.g. if a secret is a JSON with some B64 encoded data within, decodingStrategy: Auto
would not decode it)
"},{"location":"guides/getallsecrets/#fetching-secrets-matching-a-given-name-pattern","title":"Fetching secrets matching a given name pattern","text":"To fetch multiple secrets matching a name pattern from a common SecretStore you can apply the following manifest:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: find-by-tags\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: secretstore-sample\n kind: SecretStore\n target:\n name: secret-to-be-created\n dataFrom:\n - find:\n name:\n regexp: \"key\"\n
Suppose we contain secrets /path/key1
, key2/path
, and path/to/keyring
with their respective values. The above YAML will produce the following kubernetes Secret:
_path_key1: Cg==\nkey2_path: Cg==\npath_to_keyring: Cg==\n
"},{"location":"guides/getallsecrets/#fetching-secrets-matching-a-set-of-metadata-tags","title":"Fetching secrets matching a set of metadata tags","text":"To fetch multiple secrets matching a name pattern from a common SecretStore you can apply the following manifest:
apiVersion: external-secrets.io/v1beta1 \nkind: ExternalSecret\nmetadata:\n name: find-by-tags\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: secretstore-sample\n kind: SecretStore\n target:\n name: secret-to-be-created\n dataFrom:\n - find:\n tags:\n environment: \"prod\"\n application: \"app-name\"\n
This will match any secrets containing all of the metadata labels in the tags
parameter. At least one tag must be provided in order to allow finding secrets by metadata tags."},{"location":"guides/getallsecrets/#searching-only-in-a-given-path","title":"Searching only in a given path","text":"Some providers support filtering out a find operation only to a given path, instead of the root path. In order to use this feature, you can pass find.path
to filter out these secrets into only this path, instead of the root path.
"},{"location":"guides/getallsecrets/#avoiding-name-conflicts","title":"Avoiding name conflicts","text":"By default, kubernetes Secrets accepts only a given range of characters. Find
operations will automatically replace any not allowed character with a _
. So if we have a given secret a_c
and a/c
would lead to a naming conflict.
If you happen to have a case where a conflict is happening, you can use the rewrite
block to apply a regexp on one of the find operations (for more information please refer to Rewriting Keys from DataFrom).
You can also set dataFrom.find.conversionStrategy: Unicode
to reduce the collistion probability. When using Unicode
, any invalid character will be replaced by its unicode, in the form of _UXXXX_
. In this case, the available kubernetes keys would be a_c
and a_U2215_c
, hence avoiding most of possible conflicts.
PRs welcome
Some providers might not have the implementation needed for fetching multiple secrets. If that's your case, please feel free to contribute!
"},{"location":"guides/introduction/","title":"Guides","text":"The following guides demonstrate use-cases and provide examples of how to use the API. Please pick one of the following guides:
- Multi-Tenancy Design Considerations
- Find multiple secrets & Extract Secret values
- Advanced Templating
- Generating Passwords using generators
- Ownership and Deletion Policy
- Key Rewriting
- Controller Class
- Decoding Strategy
- v1beta1 Migration
- Deploying image from main
- Deploying without cluster features
"},{"location":"guides/multi-tenancy/","title":"Multi Tenancy","text":"External Secrets Operator provides different modes of operation to fulfill organizational needs. This guide outlines the flexibility of ESO and should give you a first impression of how you can employ this operator in your organization.
For a multi-tenant deployment you should first examine your organizational structure:
- what roles (i.e. Application Developers, Cluster Admins, ...) do you have in your organization,
- what responsibilities do they have and
- how does that map to Kubernetes RBAC roles.
Further, you should examine how your external API provider manages access control for your secrets. Can you limit access by secret names (e.g. db/dev/*
)? Or only on a bucket level? Please keep in mind that not all external APIs provide fine-grained access management for secrets.
Note: The following examples should not be considered as best practice but rather as a example to show how to combine different mechanics and techniques for tenant isolation.
"},{"location":"guides/multi-tenancy/#shared-clustersecretstore","title":"Shared ClusterSecretStore","text":"A Cluster Administrator deploys a ClusterSecretStore
(CSS) and manages access to the external API. The CSS is shared by all tenants within the cluster. Application Developers do reference it in a ExternalSecret
but can not create a ClusterSecretStores or SecretStores on their own. Now all application developers have access to all the secrets. You probably want to limit access to certain keys or prefixes that should be used. ESO does not provide a mechanic to limit access to certain keys per namespace. More advanced validation should be done with an Admission Webhook, e.g. with Kyverno or Open Policy Agent).
This setup suites well if you have one central bucket that contains all of your secrets and your Cluster Administrators should manage access to it. This setup is very simple but does not scale very well.
"},{"location":"guides/multi-tenancy/#managed-secretstore-per-namespace","title":"Managed SecretStore per Namespace","text":"Cluster Administrators manage one or multiple SecretStores
per Namespace. Each SecretStore uses it's own role that limits access to a small set of keys. The peculiarity of this is approach is, that access is actually managed by the external API which provides the roles. The Cluster Administrator does just the wiring. This approach may be desirable if you have an external entity - let's call it Secret Administrator - that manages access and lifecycle of the secrets.
"},{"location":"guides/multi-tenancy/#eso-as-a-service","title":"ESO as a Service","text":"Every namespace is self-contained. Application developers manage SecretStore
, ExternalSecret
and secret infrastructure on their own. Cluster Administrators just provide the External Secrets Operator as a service.
This makes sense if application developers should be completely autonomous while a central team provides common services.
"},{"location":"guides/ownership-deletion-policy/","title":"Lifecycle","text":"The External Secrets Operator manages the lifecycle of secrets in Kubernetes. With creationPolicy
and deletionPolicy
you get fine-grained control of its lifecycle.
Creation/Deletion Policy Combinations
Some combinations of creationPolicy/deletionPolicy are not allowed as they would delete existing secrets: - deletionPolicy=Delete
& creationPolicy=Merge
- deletionPolicy=Delete
& creationPolicy=None
- deletionPolicy=Merge
& creationPolicy=None
"},{"location":"guides/ownership-deletion-policy/#creation-policy","title":"Creation Policy","text":"The field spec.target.creationPolicy
defines how the operator creates the a secret.
"},{"location":"guides/ownership-deletion-policy/#owner-default","title":"Owner (default)","text":"The External Secret Operator creates secret and sets the ownerReference
field on the Secret. This secret is subject to garbage collection if the initial ExternalSecret
is absent. If a secret with the same name already exists that is not owned by the controller it will result in a conflict. The operator will just error out, not claiming the ownership.
Secrets with ownerReference
field not found
If the secret exists and the ownerReference field is not found, the controller treats this secret as orphaned. It will take ownership of this secret by adding an ownerReference
field and updating it.
"},{"location":"guides/ownership-deletion-policy/#orphan","title":"Orphan","text":"The operator creates the secret but does not set the ownerReference
on the Secret. That means the Secret will not be subject to garbage collection. If a secret with the same name already exists it will be updated.
"},{"location":"guides/ownership-deletion-policy/#merge","title":"Merge","text":"The operator does not create a secret. Instead, it expects the secret to already exist. Values from the secret provider will be merged into the existing secret. Note: the controller takes ownership of a field even if it is owned by a different entity. Multiple ExternalSecrets can use creationPolicy=Merge
with a single secret as long as the fields don't collide - otherwise you end up in an oscillating state.
"},{"location":"guides/ownership-deletion-policy/#none","title":"None","text":"The operator does not create or update the secret, this is basically a no-op.
"},{"location":"guides/ownership-deletion-policy/#deletion-policy","title":"Deletion Policy","text":"DeletionPolicy defines what should happen if a given secret gets deleted from the provider.
DeletionPolicy is only supported on the specific providers, please refer to our stability/support table.
"},{"location":"guides/ownership-deletion-policy/#retain-default","title":"Retain (default)","text":"Retain will retain the secret if all provider secrets have been deleted. If a provider secret does not exist the ExternalSecret gets into the SecretSyncedError status.
"},{"location":"guides/ownership-deletion-policy/#delete","title":"Delete","text":"Delete deletes the secret if all provider secrets are deleted. If a secret gets deleted on the provider side and is not accessible anymore this is not considered an error and the ExternalSecret does not go into SecretSyncedError status. This is also true for new ExternalSecrets mapping to non-existing secrets in the provider.
"},{"location":"guides/ownership-deletion-policy/#merge_1","title":"Merge","text":"Merge removes keys in the secret, but not the secret itself. If a secret gets deleted on the provider side and is not accessible anymore this is not considered an error and the ExternalSecret does not go into SecretSyncedError status.
"},{"location":"guides/pushsecrets/","title":"Push Secrets","text":"Contrary to what ExternalSecret
does by pulling secrets from secret providers and creating kind=Secret
in your cluster, PushSecret
reads a local kind=Secret
and pushes its content to a secret provider.
The update behavior of PushSecret
is controlled by spec.updatePolicy
. The default policy is Replace
, such that secrets are overwritten in the provider, regardless of whether there already is a secret present in the provider at the given location. If you do not want PushSecret
to overwrite existing secrets in the provider, you can set spec.UpdatePolicy
to IfNotExists
. With this policy, the provider becomes the source of truth. Please note that with using spec.updatePolicy=IfNotExists
it is possible that the secret value referenced by the PushSecret
within the cluster differs from the secret value at the given location in the provider.
By default, the secret created in the secret provided will not be deleted even after deleting the PushSecret
, unless you set spec.deletionPolicy
to Delete
.
apiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\n name: pushsecret-example # Customisable\n namespace: default # Same of the SecretStores\nspec:\n updatePolicy: Replace # Policy to overwrite existing secrets in the provider on sync\n deletionPolicy: Delete # the provider' secret will be deleted if the PushSecret is deleted\n refreshInterval: 10s # Refresh interval for which push secret will reconcile\n secretStoreRefs: # A list of secret stores to push secrets to\n - name: aws-parameterstore\n kind: SecretStore\n selector:\n secret:\n name: pokedex-credentials # Source Kubernetes secret to be pushed\n template:\n metadata:\n annotations: { }\n labels: { }\n data:\n best-pokemon: \"{{ .best-pokemon | toString | upper }} is the really best!\"\n # Uses an existing template from configmap\n # Secret is fetched, merged and templated within the referenced configMap data\n # It does not update the configmap, it creates a secret with: data[\"alertmanager.yml\"] = ...result...\n templateFrom:\n - configMap:\n name: application-config-tmpl\n items:\n - key: config.yml\n data:\n - conversionStrategy: None # Also supports the ReverseUnicode strategy\n match:\n secretKey: best-pokemon # Source Kubernetes secret key to be pushed\n remoteRef:\n remoteKey: my-first-parameter # Remote reference (where the secret is going to be pushed)\n
"},{"location":"guides/pushsecrets/#backup-use-case","title":"Backup use case","text":"An interesting use case for kind=PushSecret
is backing up your current secret from one provider to another one.
Imagine you have your secrets in GCP and you want to back them up in Azure Key Vault. You would then create a SecretStore
for each provider, and an ExternalSecret
to pull the secrets from GCP. This will generate a kind=Secret
in your cluster that you can use as the source of a PushSecret
configured with the Azure SecretStore
.
"},{"location":"guides/pushsecrets/#pushing-the-whole-secret","title":"Pushing the whole secret","text":"There are two ways to push an entire secret without defining all keys individually.
By leaving off the secret key and remote property options.
apiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\n name: pushsecret-example # Customisable\n namespace: default # Same of the SecretStores\nspec:\n deletionPolicy: Delete # the provider' secret will be deleted if the PushSecret is deleted\n refreshInterval: 10s # Refresh interval for which push secret will reconcile\n secretStoreRefs: # A list of secret stores to push secrets to\n - name: aws-parameterstore\n kind: SecretStore\n selector:\n secret:\n name: pokedex-credentials # Source Kubernetes secret to be pushed\n data:\n - match:\n remoteRef:\n remoteKey: my-first-parameter # Remote reference (where the secret is going to be pushed)\n
This will result in all keys being pushed as they are into the remote location.
By leaving off the secret key but setting the remote property option.
apiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\n name: pushsecret-example # Customisable\n namespace: default # Same of the SecretStores\nspec:\n deletionPolicy: Delete # the provider' secret will be deleted if the PushSecret is deleted\n refreshInterval: 10s # Refresh interval for which push secret will reconcile\n secretStoreRefs: # A list of secret stores to push secrets to\n - name: aws-parameterstore\n kind: SecretStore\n selector:\n secret:\n name: pokedex-credentials # Source Kubernetes secret to be pushed\n data:\n - match:\n secretKey: best-pokemon # Source Kubernetes secret key to be pushed\n remoteRef:\n remoteKey: my-first-parameter # Remote reference (where the secret is going to be pushed)\n property: single-value-secret # the property to use to push into\n
This will marshal the entire secret data and push it into this single property as a JSON object.
Warning
This should ONLY be done if the secret data is marshal-able. Values like, binary data cannot be marshaled and will result in error or invalid secret data.
"},{"location":"guides/pushsecrets/#key-conversion-strategy","title":"Key conversion strategy","text":"You can also set data[*].conversionStrategy: ReverseUnicode
to reverse the invalid character replaced by the conversionStrategy: Unicode
configuration in the ExternalSecret
object as documented here.
"},{"location":"guides/security-best-practices/","title":"Security Best Practices","text":"The purpose of this document is to outline a set of best practices for securing the External Secrets Operator (ESO). These practices aim to mitigate the risk of successful attacks against ESO and the Kubernetes cluster it integrates with.
"},{"location":"guides/security-best-practices/#security-functions-and-features","title":"Security Functions and Features","text":""},{"location":"guides/security-best-practices/#1-namespace-isolation","title":"1. Namespace Isolation","text":"To maintain security boundaries, ESO ensures that namespaced resources like SecretStore
and ExternalSecret
are limited to their respective namespaces. The following rules apply:
ExternalSecret
resources must not have cross-namespace references of Kind=SecretStore
or Kind=Secret
resources SecretStore
resources must not have cross-namespace references of Kind=Secret
or others
For cluster-wide resources like ClusterSecretStore
and ClusterExternalSecret
, exercise caution since they have access to Secret resources across all namespaces. Minimize RBAC permissions for administrators and developers to the necessary minimum. If cluster-wide resources are not required, it is recommended to disable them.
"},{"location":"guides/security-best-practices/#2-configure-clustersecretstore-match-conditions","title":"2. Configure ClusterSecretStore match conditions","text":"Utilize the ClusterSecretStore resource to define specific match conditions using namespaceSelector
or an explicit namespaces list. This restricts the usage of the ClusterSecretStore
to a predetermined list of namespaces or a namespace that matches a predefined label. Here's an example:
apiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\n name: fake\nspec:\n conditions:\n - namespaceSelector:\n matchLabels:\n app: frontend\n
"},{"location":"guides/security-best-practices/#3-selectively-disable-reconciliation-of-cluster-wide-resources","title":"3. Selectively Disable Reconciliation of Cluster-Wide Resources","text":"ESO allows you to selectively disable the reconciliation of cluster-wide resources such as ClusterSecretStore
, ClusterExternalSecret
, and PushSecret
. You can disable the installation of CRDs in the Helm chart or disable reconciliation in the core-controller using the following options:
To disable CRD installation:
# disable cluster-wide resources & push secret\ncrds:\n createClusterExternalSecret: false\n createClusterSecretStore: false\n createPushSecret: false\n
To disable reconciliation in the core-controller:
--enable-cluster-external-secret-reconciler\n--enable-cluster-store-reconciler\n
"},{"location":"guides/security-best-practices/#4-implement-namespace-scoped-installation","title":"4. Implement Namespace-Scoped Installation","text":"To further enhance security, consider installing ESO into a specific namespace with restricted access to only that namespace's resources. This prevents access to cluster-wide secrets. Use the following Helm values to scope the controller to a specific namespace:
# If set to true, create scoped RBAC roles under the scoped namespace\n# and implicitly disable cluster stores and cluster external secrets\nscopedRBAC: true\n\n# Specify the namespace where external secrets should be reconciled\nscopedNamespace: my-namespace\n
"},{"location":"guides/security-best-practices/#pod-security","title":"Pod Security","text":"The Pods of the External Secrets Operator have been configured to meet the Pod Security Standards, specifically the restricted profile. This configuration ensures a strong security posture by implementing recommended best practices for hardening Pods, including those outlined in the NSA Kubernetes Hardening Guide.
By adhering to these standards, the External Secrets Operator benefits from a secure and resilient operating environment. The restricted profile has been set as the default configuration since version v0.8.2
, and it is recommended to maintain this setting to align with the principle of least privilege.
"},{"location":"guides/security-best-practices/#role-based-access-control-rbac","title":"Role-Based Access Control (RBAC)","text":"The External Secrets Operator operates with elevated privileges within your Kubernetes cluster, allowing it to read and write to all secrets across all namespaces. It is crucial to properly restrict access to ESO resources such as ExternalSecret
and SecretStore
where necessary. This is particularly important for cluster-scoped resources like ClusterExternalSecret
and ClusterSecretStore
. Unauthorized tampering with these resources by an attacker could lead to unauthorized access to secrets or potential data exfiltration from your system.
In most scenarios, the External Secrets Operator is deployed cluster-wide. However, if you prefer to run it on a per-namespace basis, you can scope it to a specific namespace using the scopedRBAC
and scopedNamespace
options in the helm chart.
To ensure a secure RBAC configuration, consider the following checklist:
- Restrict access to execute shell commands (pods/exec) within the External Secrets Operator Pod.
- Restrict access to (Cluster)ExternalSecret and (Cluster)SecretStore resources.
- Limit access to aggregated ClusterRoles (view/edit/admin) as needed.
- If necessary, deploy ESO with scoped RBAC or within a specific namespace.
By carefully managing RBAC permissions and scoping the External Secrets Operator appropriately, you can enhance the security of your Kubernetes cluster.
"},{"location":"guides/security-best-practices/#network-traffic-and-security","title":"Network Traffic and Security","text":"To ensure a secure network environment, it is recommended to restrict network traffic to and from the External Secrets Operator using NetworkPolicies
or similar mechanisms. By default, the External Secrets Operator does not include pre-defined Network Policies.
To implement network restrictions effectively, consider the following steps:
- Define and apply appropriate NetworkPolicies to limit inbound and outbound traffic for the External Secrets Operator.
- Specify a \"deny all\" policy by default and selectively permit necessary communication based on your specific requirements.
- Restrict access to only the required endpoints and protocols for the External Secrets Operator, such as communication with the Kubernetes API server or external secret providers.
- Regularly review and update the Network Policies to align with changes in your network infrastructure and security requirements.
It is the responsibility of the user to define and configure Network Policies tailored to their specific environment and security needs. By implementing proper network restrictions, you can enhance the overall security posture of the External Secrets Operator within your Kubernetes cluster.
Data Exfiltration Risk
If not configured properly ESO may be used to exfiltrate data out of your cluster. It is advised to create tight NetworkPolicies and use a policy engine such as kyverno to prevent data exfiltration.
"},{"location":"guides/security-best-practices/#outbound-traffic-restrictions","title":"Outbound Traffic Restrictions","text":""},{"location":"guides/security-best-practices/#core-controller","title":"Core Controller","text":"Restrict outbound traffic from the core controller component to the following destinations:
kube-apiserver
: The Kubernetes API server. - Secret provider (e.g., AWS, GCP): Whenever possible, use private endpoints to establish secure and private communication.
"},{"location":"guides/security-best-practices/#webhook","title":"Webhook","text":" - Restrict outbound traffic from the webhook component to the
kube-apiserver
.
"},{"location":"guides/security-best-practices/#cert-controller","title":"Cert Controller","text":" - Restrict outbound traffic from the cert controller component to the
kube-apiserver
.
"},{"location":"guides/security-best-practices/#inbound-traffic-restrictions","title":"Inbound Traffic Restrictions","text":""},{"location":"guides/security-best-practices/#core-controller_1","title":"Core Controller","text":" - Restrict inbound traffic to the core controller component by allowing communication on port
8080
from your monitoring agent.
"},{"location":"guides/security-best-practices/#cert-controller_1","title":"Cert Controller","text":" - Restrict inbound traffic to the cert controller component by allowing communication on port
8080
from your monitoring agent. - Additionally, permit inbound traffic on port
8081
from the kubelet for health check endpoints (healthz/readyz).
"},{"location":"guides/security-best-practices/#webhook_1","title":"Webhook","text":"Restrict inbound traffic to the webhook component as follows:
- Allow communication on port
10250
from the kube-apiserver. - Allow communication on port
8080
from your monitoring agent. - Permit inbound traffic on port
8081
from the kubelet for health check endpoints (healthz/readyz).
"},{"location":"guides/security-best-practices/#policy-engine-best-practices","title":"Policy Engine Best Practices","text":"To enhance the security and enforce specific policies for External Secrets Operator (ESO) resources such as SecretStore and ExternalSecret, it is recommended to utilize a policy engine like Kyverno or OPA Gatekeeper. These policy engines provide a way to define and enforce custom policies that restrict changes made to ESO resources.
Data Exfiltration Risk
ESO could be used to exfiltrate data out of your cluster. You should disable all providers you don't need. Further, you should implement NetworkPolicies
to restrict network access to known entities (see above), to prevent data exfiltration.
Here are some recommendations to consider when configuring your policies:
- Explicitly Deny Unused Providers: Create policies that explicitly deny the usage of secret providers that are not required in your environment. This prevents unauthorized access to unnecessary providers and reduces the attack surface.
- Restrict Access to Secrets: Implement policies that restrict access to secrets based on specific conditions. For example, you can define policies to allow access to secrets only if they have a particular prefix in the
.spec.data[].remoteRef.key
field. This helps ensure that only authorized entities can access sensitive information. - Restrict
ClusterSecretStore
References: Define policies to restrict the usage of ClusterSecretStore references within ExternalSecret resources. This ensures that the resources are properly scoped and prevent potential unauthorized access to secrets across namespaces.
By leveraging a policy engine, you can implement these recommendations and enforce custom policies that align with your organization's security requirements. Please refer to the documentation of the chosen policy engine (e.g., Kyverno or OPA Gatekeeper) for detailed instructions on how to define and enforce policies for ESO resources.
Provider Validation Example Policy
The following policy validates the usage of the provider
field in the SecretStore manifest.
apiVersion: kyverno.io/v1\nkind: ClusterPolicy\nmetadata:\n name: require-secretstore-aws-provider\nspec:\n validationFailureAction: Enforce\n rules:\n - name: require-secretstore-aws-provider\n match:\n any:\n - resources:\n kinds:\n - SecretStore\n - ClusterSecretStore\n validate:\n message: \"You must only use AWS SecretsManager\"\n pattern:\n spec:\n provider:\n aws:\n service: SecretsManager\n
"},{"location":"guides/security-best-practices/#regular-patches","title":"Regular Patches","text":"To maintain a secure environment, it is crucial to regularly patch and update all software components of External Secrets Operator and the underlying cluster. By doing so, known vulnerabilities can be addressed, and the overall system's security can be improved. Here are some recommended practices for ensuring timely updates:
- Automated Patching and Updating: Utilize automated patching and updating tools to streamline the process of keeping software components up-to-date
- Regular Update ESO: Stay informed about the latest updates and releases provided for ESO. The development team regularly releases updates to improve stability, performance, and security. Please refer to the Stability and Support documentation for more information on the available updates
- Cluster-wide Updates: Apart from ESO, ensure that all other software components within your cluster, such as the operating system, container runtime, and Kubernetes itself, are regularly patched and updated.
By adhering to a regular patching and updating schedule, you can proactively mitigate security risks associated with known vulnerabilities and ensure the overall stability and security of your ESO deployment.
"},{"location":"guides/security-best-practices/#verify-artefacts","title":"Verify Artefacts","text":""},{"location":"guides/security-best-practices/#verify-container-images","title":"Verify Container Images","text":"The container images of External Secrets Operator are signed using Cosign and the keyless signing feature. To ensure the authenticity and integrity of the container image, you can follow the steps outlined below:
# Retrieve Image Signature\n$ crane digest ghcr.io/external-secrets/external-secrets:v0.8.1\nsha256:36e606279dbebac51b4b9300b9fa85e8c08c1c673ba3ecc38af1402a0b035554\n\n# verify signature\n$ COSIGN_EXPERIMENTAL=1 cosign verify ghcr.io/external-secrets/external-secrets@sha256:36e606279dbebac51b4b9300b9fa85e8c08c1c673ba3ecc38af1402a0b035554 | jq\n\n# ...\n[\n {\n \"critical\": {\n \"identity\": {\n \"docker-reference\": \"ghcr.io/external-secrets/external-secrets\"\n },\n \"image\": {\n \"docker-manifest-digest\": \"sha256:36e606279dbebac51b4b9300b9fa85e8c08c1c673ba3ecc38af1402a0b035554\"\n },\n \"type\": \"cosign container image signature\"\n },\n \"optional\": {\n \"1.3.6.1.4.1.57264.1.1\": \"https://token.actions.githubusercontent.com\",\n \"1.3.6.1.4.1.57264.1.2\": \"workflow_dispatch\",\n \"1.3.6.1.4.1.57264.1.3\": \"a0d2aef2e35c259c9ee75d65f7587e6ed71ef2ad\",\n \"1.3.6.1.4.1.57264.1.4\": \"Create Release\",\n \"1.3.6.1.4.1.57264.1.5\": \"external-secrets/external-secrets\",\n \"1.3.6.1.4.1.57264.1.6\": \"refs/heads/main\",\n \"Bundle\": {\n # ...\n },\n \"GITHUB_ACTOR\": \"gusfcarvalho\",\n \"Issuer\": \"https://token.actions.githubusercontent.com\",\n \"Subject\": \"https://github.com/external-secrets/external-secrets/.github/workflows/release.yml@refs/heads/main\",\n \"githubWorkflowName\": \"Create Release\",\n \"githubWorkflowRef\": \"refs/heads/main\",\n \"githubWorkflowRepository\": \"external-secrets/external-secrets\",\n \"githubWorkflowSha\": \"a0d2aef2e35c259c9ee75d65f7587e6ed71ef2ad\",\n \"githubWorkflowTrigger\": \"workflow_dispatch\"\n }\n }\n]\n
In the output of the verification process, pay close attention to the optional.Issuer
and optional.Subject
fields. These fields contain important information about the image's authenticity. Verify that the values of Issuer and Subject match the expected values for the ESO container image. If they do not match, it indicates that the image is not legitimate and should not be used.
By following these steps and confirming that the Issuer and Subject fields align with the expected values for the ESO container image, you can ensure that the image has not been tampered with and is safe to use.
"},{"location":"guides/security-best-practices/#verifying-provenance","title":"Verifying Provenance","text":"The External Secrets Operator employs the SLSA (Supply Chain Levels for Software Artifacts) standard to create and attest to the provenance of its builds. Provenance verification is essential to ensure the integrity and trustworthiness of the software supply chain. This outlines the process of verifying the attested provenance of External Secrets Operator builds using the cosign tool.
$ COSIGN_EXPERIMENTAL=1 cosign verify-attestation --type slsaprovenance ghcr.io/external-secrets/external-secrets:v0.8.1 | jq .payload -r | base64 --decode | jq\n\nVerification for ghcr.io/external-secrets/external-secrets:v0.8.1 --\nThe following checks were performed on each of these signatures:\n - The cosign claims were validated\n - Existence of the claims in the transparency log was verified offline\n - Any certificates were verified against the Fulcio roots.\nCertificate subject: https://github.com/external-secrets/external-secrets/.github/workflows/release.yml@refs/heads/main\nCertificate issuer URL: https://token.actions.githubusercontent.com\nGitHub Workflow Trigger: workflow_dispatch\nGitHub Workflow SHA: a0d2aef2e35c259c9ee75d65f7587e6ed71ef2ad\nGitHub Workflow Name: Create Release\nGitHub Workflow Trigger external-secrets/external-secrets\nGitHub Workflow Ref: refs/heads/main\n{\n \"_type\": \"https://in-toto.io/Statement/v0.1\",\n \"predicateType\": \"https://slsa.dev/provenance/v0.2\",\n \"subject\": [\n {\n \"name\": \"ghcr.io/external-secrets/external-secrets\",\n \"digest\": {\n \"sha256\": \"36e606279dbebac51b4b9300b9fa85e8c08c1c673ba3ecc38af1402a0b035554\"\n }\n }\n ],\n \"predicate\": {\n \"builder\": {\n \"id\": \"https://github.com/external-secrets/external-secrets/Attestations/GitHubHostedActions@v1\"\n },\n \"buildType\": \"https://github.com/Attestations/GitHubActionsWorkflow@v1\",\n \"invocation\": {\n \"configSource\": {\n \"uri\": \"git+https://github.com/external-secrets/external-secrets\",\n \"digest\": {\n \"sha1\": \"a0d2aef2e35c259c9ee75d65f7587e6ed71ef2ad\"\n },\n \"entryPoint\": \"Create Release\"\n },\n \"parameters\": {\n \"version\": \"v0.8.1\"\n }\n },\n [...]\n }\n}\n
"},{"location":"guides/security-best-practices/#fetching-sbom","title":"Fetching SBOM","text":"Every External Secrets Operator image is accompanied by an SBOM (Software Bill of Materials) in SPDX JSON format. The SBOM provides detailed information about the software components and dependencies used in the image. This technical documentation explains the process of downloading and verifying the SBOM for a specific version of External Secrets Operator using the Cosign tool.
$ crane digest ghcr.io/external-secrets/external-secrets:v0.8.1\nsha256:36e606279dbebac51b4b9300b9fa85e8c08c1c673ba3ecc38af1402a0b035554\n\n$ COSIGN_EXPERIMENTAL=1 cosign verify-attestation --type spdx ghcr.io/external-secrets/external-secrets@sha256:36e606279dbebac51b4b9300b9fa85e8c08c1c673ba3ecc38af1402a0b035554 | jq '.payload |= @base64d | .payload | fromjson' | jq '.predicate.Data | fromjson'\n\n[...]\n{\n \"SPDXID\": \"SPDXRef-DOCUMENT\",\n \"name\": \"ghcr.io/external-secrets/external-secrets@sha256-36e606279dbebac51b4b9300b9fa85e8c08c1c673ba3ecc38af1402a0b035554\",\n \"spdxVersion\": \"SPDX-2.2\",\n \"creationInfo\": {\n \"created\": \"2023-03-17T23:17:01.568002344Z\",\n \"creators\": [\n \"Organization: Anchore, Inc\",\n \"Tool: syft-0.40.1\"\n ],\n \"licenseListVersion\": \"3.16\"\n },\n \"dataLicense\": \"CC0-1.0\",\n \"documentNamespace\": \"https://anchore.com/syft/image/ghcr.io/external-secrets/external-secrets@sha256-36e606279dbebac51b4b9300b9fa85e8c08c1c673ba3ecc38af1402a0b035554-83484ebb-b469-45fa-8fcc-9290c4ea4f6f\",\n \"packages\": [\n [...]\n {\n \"SPDXID\": \"SPDXRef-c809070b0beb099e\",\n \"name\": \"tzdata\",\n \"licenseConcluded\": \"NONE\",\n \"downloadLocation\": \"NOASSERTION\",\n \"externalRefs\": [\n {\n \"referenceCategory\": \"SECURITY\",\n \"referenceLocator\": \"cpe:2.3:a:tzdata:tzdata:2021a-1\\\\+deb11u8:*:*:*:*:*:*:*\",\n \"referenceType\": \"cpe23Type\"\n },\n {\n \"referenceCategory\": \"PACKAGE_MANAGER\",\n \"referenceLocator\": \"pkg:deb/debian/tzdata@2021a-1+deb11u8?arch=all&distro=debian-11\",\n \"referenceType\": \"purl\"\n }\n ],\n \"filesAnalyzed\": false,\n \"licenseDeclared\": \"NONE\",\n \"originator\": \"Person: GNU Libc Maintainers <debian-glibc@lists.debian.org>\",\n \"sourceInfo\": \"acquired package info from DPKG DB: /var/lib/dpkg/status.d/tzdata, /usr/share/doc/tzdata/copyright\",\n \"versionInfo\": \"2021a-1+deb11u8\"\n }\n ]\n}\n
"},{"location":"guides/templating-v1/","title":"Advanced Templating v1","text":"Warning
Templating Engine v1 is deprecated and will be removed in the future. Please migrate to engine v2 and take a look at our upgrade guide for changes.
With External Secrets Operator you can transform the data from the external secret provider before it is stored as Kind=Secret
. You can do this with the Spec.Target.Template
. Each data value is interpreted as a golang template.
"},{"location":"guides/templating-v1/#examples","title":"Examples","text":"You can use templates to inject your secrets into a configuration file that you mount into your pod:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: template\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: secretstore-sample\n kind: SecretStore\n target:\n name: secret-to-be-created\n\n # v2 is the default engineVersion in external-secrets.io/v1beta1\n # v1 is the default engineVersion in external-secrets.io/v1alpha1 (deprecated)\n engineVersion: v1\n\n # this is how the Kind=Secret will look like\n template:\n type: kubernetes.io/tls\n data:\n # multiline string\n config: |\n datasources:\n - name: Graphite\n type: graphite\n access: proxy\n url: http://localhost:8080\n password: \"{{ .password | toString }}\" # <-- convert []byte to string\n user: \"{{ .user | toString }}\" # <-- convert []byte to string\n\n data:\n - secretKey: user\n remoteRef:\n key: /grafana/user\n - secretKey: password\n remoteRef:\n key: /grafana/password\n
You can also use pre-defined functions to extract data from your secrets. Here: extract key/cert from a pkcs12 archive and store it as PEM.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: template\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: secretstore-sample\n kind: SecretStore\n target:\n name: secret-to-be-created\n # this is how the Kind=Secret will look like\n template:\n type: kubernetes.io/tls\n data:\n tls.crt: \"{{ .mysecret | pkcs12cert | pemCertificate }}\"\n tls.key: \"{{ .mysecret | pkcs12key | pemPrivateKey }}\"\n\n data:\n # this is a pkcs12 archive that contains\n # a cert and a private key\n - secretKey: mysecret\n remoteRef:\n key: example\n
"},{"location":"guides/templating-v1/#templatefrom","title":"TemplateFrom","text":"You do not have to define your templates inline in an ExternalSecret but you can pull ConfigMaps
or other Secrets that contain a template. Consider the following example:
# define your template in a config map\napiVersion: v1\nkind: ConfigMap\nmetadata:\n name: grafana-config-tpl\ndata:\n config.yaml: |\n datasources:\n - name: Graphite\n type: graphite\n access: proxy\n url: http://localhost:8080\n password: \"{{ .password | toString }}\" # <-- convert []byte to string\n user: \"{{ .user | toString }}\" # <-- convert []byte to string\n---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: my-template-example\nspec:\n # ...\n target:\n name: secret-to-be-created\n template:\n templateFrom:\n - configMap:\n # name of the configmap to pull in\n name: grafana-config-tpl\n # here you define the keys that should be used as template\n items:\n - key: config.yaml\n data:\n - secretKey: user\n remoteRef:\n key: /grafana/user\n - secretKey: password\n remoteRef:\n key: /grafana/password\n
"},{"location":"guides/templating-v1/#helper-functions","title":"Helper functions","text":"We provide a bunch of convenience functions that help you transform your secrets. A secret value is a []byte
.
Function Description Input Output pkcs12key extracts the private key from a pkcs12 archive []byte
[]byte
pkcs12keyPass extracts the private key from a pkcs12 archive using the provided password password string
, data []byte
[]byte
pkcs12cert extracts the certificate from a pkcs12 archive []byte
[]byte
pkcs12certPass extracts the certificate from a pkcs12 archive using the provided password password string
, data []byte
[]byte
pemPrivateKey PEM encodes the provided bytes as private key []byte
string
pemCertificate PEM encodes the provided bytes as certificate []byte
string
jwkPublicKeyPem takes an json-serialized JWK as []byte
and returns an PEM block of type PUBLIC KEY
that contains the public key (see here) for details []byte
string
jwkPrivateKeyPem takes an json-serialized JWK as []byte
and returns an PEM block of type PRIVATE KEY
that contains the private key in PKCS #8 format (see here) for details []byte
string
base64decode decodes the provided bytes as base64 []byte
[]byte
base64encode encodes the provided bytes as base64 []byte
[]byte
fromJSON parses the bytes as JSON so you can access individual properties []byte
any
toJSON encodes the provided object as json string any
string
toString converts bytes to string []byte
string
toBytes converts string to bytes string
[]byte
upper converts all characters to their upper case string
string
lower converts all character to their lower case string
string
"},{"location":"guides/templating/","title":"Advanced Templating v2","text":"With External Secrets Operator you can transform the data from the external secret provider before it is stored as Kind=Secret
. You can do this with the Spec.Target.Template
. Each data value is interpreted as a golang template.
Note
Consider using camelcase when defining .'spec.data.secretkey', example: serviceAccountToken
If your secret keys contain -
(dashes), you will need to reference them using index
Example: \\{\\{ index .data \"service-account-token\" \\}\\}
"},{"location":"guides/templating/#helm","title":"Helm","text":"When installing ExternalSecrets via helm
, the template must be escaped so that helm
will not try to render it. The most straightforward way to accomplish this would be to use backticks (raw string constants):
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: template\nspec:\n # ...\n target:\n template:\n engineVersion: v2\n data:\n name: admin\n # password: \"{{ .mysecret }}\" # If you are using plain manifests or gitops tools\n password: \"{{ `{{ .mysecret }}` }}\" # If you are using helm\n data:\n - secretKey: mysecret\n remoteRef:\n key: /credentials\n
"},{"location":"guides/templating/#examples","title":"Examples","text":"You can use templates to inject your secrets into a configuration file that you mount into your pod:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: template\nspec:\n # ...\n target:\n name: secret-to-be-created\n # this is how the Kind=Secret will look like\n template:\n engineVersion: v2\n data:\n # multiline string\n config: |\n datasources:\n - name: Graphite\n type: graphite\n access: proxy\n url: http://localhost:8080\n password: \"{{ .password }}\"\n user: \"{{ .user }}\"\n # using replace function to rewrite secret\n connection: '{{ .dburl | replace \"postgres://\" \"postgresql://\" }}'\n\n data:\n - secretKey: user\n remoteRef:\n key: /grafana/user\n - secretKey: password\n remoteRef:\n key: /grafana/password\n - secretKey: dburl\n remoteRef:\n key: /database/url\n
Another example with two keys in the same secret:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: template\nspec:\n # ...\n target:\n template:\n engineVersion: v2\n data:\n name: admin\n password: \"{{ .mysecret }}\" # If you are using plain manifests or gitops tools\n # password: \"{{ `{{ .mysecret }}` }}\" # If you are using templated tools like helm\n data:\n - secretKey: mysecret\n remoteRef:\n key: /credentials\n
"},{"location":"guides/templating/#mergepolicy","title":"MergePolicy","text":"By default, the templating mechanism will not use any information available from the original data
and dataFrom
queries to the provider, and only keep the templated information. It is possible to change this behavior through the use of the mergePolicy
field. mergePolicy
currently accepts two values: Replace
(the default) and Merge
. When using Merge
, data
and dataFrom
keys will also be embedded into the templated secret, having lower priority than the template outcome. See the example for more information:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: template\nspec:\n # ...\n target:\n template:\n mergePolicy: Merge\n engineVersion: v2\n data:\n name: admin\n password: \"{{ .password | b64dec }}\" # Overwrites the password from the data call and use this output\n data:\n - secretKey: password\n remoteRef:\n key: /credentials/password\n - secretKey: username # Preserves the username in the templated Secret\n remoteRef:\n key: /credentials/username\n
"},{"location":"guides/templating/#templatefrom","title":"TemplateFrom","text":"You do not have to define your templates inline in an ExternalSecret but you can pull ConfigMaps
or other Secrets that contain a template. Consider the following example:
# define your template in a config map\napiVersion: v1\nkind: ConfigMap\nmetadata:\n name: grafana-config-tpl\ndata:\n config.yaml: |\n datasources:\n - name: Graphite\n type: graphite\n access: proxy\n url: \"{{ .uri }}\"\n password: \"{{ .password }}\"\n user: \"{{ .user }}\"\n templated: |\n # key and value templated\n my-application-{{ .user}}: {{ .password | b64enc }}\n # conditional keys\n {{- if hasPrefix \"oci://\" .uri }}\n enableOCI: true\n {{- else }}\n enableOCI: false\n {{- end }}\n # Fixed values\n application-type: grafana\n annotations: |\n #dynamic timestamp generation\n last-synced-for-user/{{ .user }}: {{ now }}\n---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: my-template-example\nspec:\n # ...\n target:\n name: secret-to-be-created\n template:\n engineVersion: v2\n templateFrom:\n - target: Data\n configMap:\n # name of the configmap to pull in\n name: grafana-config-tpl\n # here you define the keys that should be used as template\n items:\n - key: config.yaml\n templateAs: Values\n - key: templated\n templateAs: KeysAndValues\n - target: Annotations\n configMap:\n # name of the configmap to pull in\n name: grafana-config-tpl\n # here you define the keys that should be used as template\n items:\n - key: annotations\n templateAs: KeysAndValues\n data:\n - secretKey: user\n remoteRef:\n key: /grafana/user\n - secretKey: password\n remoteRef:\n key: /grafana/password\n - secretKey: uri\n remoteRef:\n key: /grafana/uri\n
TemplateFrom
also gives you the ability to Target your template to the Secret's Annotations, Labels or the Data block. It also allows you to render the templated information as Values
or as KeysAndValues
through the templateAs
configuration:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: my-template-example\nspec:\n # ...\n target:\n name: secret-to-be-created\n template:\n engineVersion: v2\n templateFrom:\n - target: Annotations\n literal: \"last-sync-for-user/{{ .user }}: {{ .now }}\"\n data:\n - secretKey: user\n remoteRef:\n key: /grafana/user\n - secretKey: password\n remoteRef:\n key: /grafana/password\n
Lastly, TemplateFrom
also supports adding Literal
blocks for quick templating. These Literal
blocks differ from Template.Data
as they are rendered as a a key:value
pair (while the Template.Data
, you can only template the value).
See an example, how to produce a htpasswd
file that can be used by an ingress-controller (for example: https://kubernetes.github.io/ingress-nginx/examples/auth/basic/) where the contents of the htpasswd
file needs to be presented via the auth
key. We use the htpasswd
function to create a bcrytped
hash of the password.
Suppose you have multiple key-value pairs within your provider secret like
{\n \"user1\": \"password1\",\n \"user2\": \"password2\",\n ...\n}\n
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: my-template-example\nspec:\n # ...\n target:\n name: secret-to-be-created\n template:\n engineVersion: v2\n templateFrom:\n - target: Data\n literal: |-\n {{- $creds := list }}\n {{- range $user, $pw := . }}\n {{- $creds = append $creds (printf \"%s\" (htpasswd $user $pw)) }}\n {{- end }}\n auth: {{ $creds | join \"\\n\" | quote }}\n dataFrom:\n - extract:\n key: /ingress-controller/valid-users\n
"},{"location":"guides/templating/#extract-keys-and-certificates-from-pkcs12-archive","title":"Extract Keys and Certificates from PKCS#12 Archive","text":"You can use pre-defined functions to extract data from your secrets. Here: extract keys and certificates from a PKCS#12 archive and store it as PEM.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: template\nspec:\n # ...\n target:\n template:\n type: kubernetes.io/tls\n engineVersion: v2\n data:\n tls.crt: \"{{ .mysecret | pkcs12cert }}\"\n tls.key: \"{{ .mysecret | pkcs12key }}\"\n\n # if needed unlock the pkcs12 with the password\n tls.crt: \"{{ .mysecret | pkcs12certPass \"my-password\" }}\"\n
"},{"location":"guides/templating/#extract-from-jwk","title":"Extract from JWK","text":"You can extract the public or private key parts of a JWK and use them as PKCS#8 private key or PEM-encoded PKIX public key.
A JWK looks similar to this:
{\n \"kty\": \"RSA\",\n \"kid\": \"cc34c0a0-bd5a-4a3c-a50d-a2a7db7643df\",\n \"use\": \"sig\",\n \"n\": \"pjdss...\",\n \"e\": \"AQAB\"\n // ...\n}\n
And what you want may be a PEM-encoded public or private key portion of it. Take a look at this example on how to transform it into the desired format:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: template\nspec:\n # ...\n target:\n template:\n engineVersion: v2\n data:\n # .myjwk is a json-encoded JWK string.\n #\n # this template will produce for jwk_pub a PEM encoded public key:\n # -----BEGIN PUBLIC KEY-----\n # MIIBI...\n # ...\n # ...AQAB\n # -----END PUBLIC KEY-----\n jwk_pub: \"{{ .myjwk | jwkPublicKeyPem }}\"\n # private key is a pem-encoded PKCS#8 private key\n jwk_priv: \"{{ .myjwk | jwkPrivateKeyPem }}\"\n
"},{"location":"guides/templating/#filter-pem-blocks","title":"Filter PEM blocks","text":"Consider you have a secret that contains both a certificate and a private key encoded in PEM format and it is your goal to use only the certificate from that secret.
-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCvxGZOW4IXvGlh\n . . .\nm8JCpbJXDfSSVxKHgK1Siw4K6pnTsIA2e/Z+Ha2fvtocERjq7VQMAJFaIZSTKo9Q\nJwwY+vj0yxWjyzHUzZB33tg=\n-----END PRIVATE KEY-----\n-----BEGIN CERTIFICATE-----\nMIIDMDCCAhigAwIBAgIQabPaXuZCQaCg+eQAVptGGDANBgkqhkiG9w0BAQsFADAV\n . . .\nNtFUGA95RGN9s+pl6XY0YARPHf5O76ErC1OZtDTR5RdyQfcM+94gYZsexsXl0aQO\n9YD3Wg==\n-----END CERTIFICATE-----\n
You can achieve that by using the filterPEM
function to extract a specific type of PEM block from that secret. If multiple blocks of that type (here: CERTIFICATE
) exist, all of them are returned in the order specified. To extract a specific type of PEM block, pass the type as a string argument to the filterPEM function. Take a look at this example of how to transform a secret which contains a private key and a certificate into the desired format:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: template\nspec:\n # ...\n target:\n template:\n type: kubernetes.io/tls\n engineVersion: v2\n data:\n tls.crt: \"{{ .mysecret | filterPEM \"CERTIFICATE\" }}\"\n tls.key: \"{{ .mysecret | filterPEM \"PRIVATE KEY\" }}\"\n
"},{"location":"guides/templating/#templating-with-pushsecret","title":"Templating with PushSecret","text":"PushSecret
templating is much like ExternalSecrets
templating. In-fact under the hood, it's using the same data structure. Which means, anything described in the above should be possible with push secret as well resulting in a templated secret created at the provider.
apiVersion: external-secrets.io/v1beta1\nkind: PushSecret\nmetadata:\n name: template\nspec:\n # ...\n template:\n engineVersion: v2\n data:\n token: \"{{ .token | toString | upper }} was templated\"\n data:\n - match:\n secretKey: token\n remoteRef:\n remoteKey: create-secret-name\n property: token\n
"},{"location":"guides/templating/#helper-functions","title":"Helper functions","text":"Info
Note: we removed env
and expandenv
from sprig functions for security reasons.
We provide a couple of convenience functions that help you transform your secrets. This is useful when dealing with PKCS#12 archives or JSON Web Keys (JWK).
In addition to that you can use over 200+ sprig functions. If you feel a function is missing or might be valuable feel free to open an issue and submit a pull request.
Function Description pkcs12key Extracts all private keys from a PKCS#12 archive and encodes them in PKCS#8 PEM format. pkcs12keyPass Same as pkcs12key
. Uses the provided password to decrypt the PKCS#12 archive. pkcs12cert Extracts all certificates from a PKCS#12 archive and orders them if possible. If disjunct or multiple leaf certs are provided they are returned as-is. Sort order: leaf / intermediate(s) / root
. pkcs12certPass Same as pkcs12cert
. Uses the provided password to decrypt the PKCS#12 archive. pemToPkcs12 Takes a PEM encoded certificate and key and creates a base64 enoded PKCS#12 archive. pemToPkcs12Pass Same as pemToPkcs12
. Uses the provided password to encrypt the PKCS#12 archive. filterPEM Filters PEM blocks with a specific type from a list of PEM blocks. jwkPublicKeyPem Takes an json-serialized JWK and returns an PEM block of type PUBLIC KEY
that contains the public key. See here for details. jwkPrivateKeyPem Takes an json-serialized JWK as string
and returns an PEM block of type PRIVATE KEY
that contains the private key in PKCS #8 format. See here for details. toYaml Takes an interface, marshals it to yaml. It returns a string, even on marshal error (empty string). fromYaml Function converts a YAML document into a map[string]any."},{"location":"guides/templating/#migrating-from-v1","title":"Migrating from v1","text":"If you are still using v1alpha1
, You have to opt-in to use the new engine version by specifying template.engineVersion=v2
:
apiVersion: external-secrets.io/v1alpha1\nkind: ExternalSecret\nmetadata:\n name: secret\nspec:\n # ...\n target:\n template:\n engineVersion: v2\n # ...\n
The biggest change was that basically all function parameter types were changed from accepting/returning []byte
to string
. This is relevant for you because now you don't need to specify toString
all the time at the end of a template pipeline.
apiVersion: external-secrets.io/v1alpha1\nkind: ExternalSecret\n# ...\nspec:\n target:\n template:\n engineVersion: v2\n data:\n # this used to be {{ .foobar | toString }}\n egg: \"new: {{ .foobar }}\"\n
"},{"location":"guides/templating/#functions-removedreplaced","title":"Functions removed/replaced","text":" base64encode
was renamed to b64enc
. base64decode
was renamed to b64dec
. Any errors that occur during decoding are silenced. fromJSON
was renamed to fromJson
. Any errors that occur during unmarshalling are silenced. toJSON
was renamed to toJson
. Any errors that occur during marshalling are silenced. pkcs12key
and pkcs12keyPass
encode the PKCS#8 key directly into PEM format. There is no need to call pemPrivateKey
anymore. Also, these functions do extract all private keys from the PKCS#12 archive not just the first one. pkcs12cert
and pkcs12certPass
encode the certs directly into PEM format. There is no need to call pemCertificate
anymore. These functions now extract all certificates from the PKCS#12 archive not just the first one. toString
implementation was replaced by the sprig
implementation and should be api-compatible. toBytes
was removed. pemPrivateKey
was removed. It's now implemented within the pkcs12*
functions. pemCertificate
was removed. It's now implemented within the pkcs12*
functions.
"},{"location":"guides/threat-model/","title":"Threat Model","text":""},{"location":"guides/threat-model/#background","title":"Background","text":"The External Secrets Operator is a Kubernetes Operator that seamlessly incorporates external secret management systems into Kubernetes. This Operator retrieves data from the external API and generates Kubernetes Secret resources using the corresponding secret values. This process occurs continuously in the background through regular polling of the external API. Consequently, whenever a secret undergoes changes in the external API, the corresponding Kubernetes Secret will also be updated accordingly.
"},{"location":"guides/threat-model/#summary","title":"Summary","text":"Purpose Description Intended Usage Sync Secrets into Kubernetes Data Classifiation Critical Highest Risk Impact Organisation takeover"},{"location":"guides/threat-model/#components","title":"Components","text":"ESO comprises three main components: webhook
, cert controller
and a core controller
. For more detailed information, please refer to the documentation on components.
"},{"location":"guides/threat-model/#overview","title":"Overview","text":"This section provides an overview of the security aspects of the External Secrets Operator (ESO) and includes information on assets, threats, and controls involved in its operation.
The following diagram illustrates the security perspective of how ESO functions, highlighting the assets (items to protect), threats (potential risks), and controls (measures to mitigate threats).
"},{"location":"guides/threat-model/#scope","title":"Scope","text":"For the purpose of this threat model, we assume an ESO installation using helm and default settings on a public cloud provider. It is important to note that the Kubernetes SIG Security team has defined an Admission Control Threat Model, which is recommended reading for a better understanding of the security aspects that partially apply to External Secrets Operator.
ESO utilizes the ValidatingWebhookConfiguration
mechanism to validate (Cluster)SecretStore
and (Cluster)ExternalSecret
resources. However, it is essential to understand that this validation process does not serve as a security control mechanism. Instead, ESO performs validation by enforcing additional rules that go beyond the CustomResourceDefinition OpenAPI v3 Validation schema.
"},{"location":"guides/threat-model/#assets","title":"Assets","text":""},{"location":"guides/threat-model/#a01-cluster-level-access-to-secrets","title":"A01: Cluster-Level access to secrets","text":"The controller possesses privileged access to the kube-apiserver
and is authorized to read and write secret resources across all namespaces within a cluster.
"},{"location":"guides/threat-model/#a02-crd-and-webhook-write-access","title":"A02: CRD and Webhook Write access","text":"The cert-controller component has read/write access to ValidatingWebhookConfigurations
and CustomResourceDefinitions
resources. This access is necessary to inject/modify the caBundle property.
"},{"location":"guides/threat-model/#a03-secret-provider-access","title":"A03: secret provider access","text":"The core-controller
component accesses a secret provider using user-supplied credentials. These credentials can be derived from environment variables, mounted service account tokens, files within the controller container, or fetched from the Kubernetes API (e.g., Kind=Secret
). The scope of these credentials may vary, potentially providing full access to a cloud provider.
"},{"location":"guides/threat-model/#a04-capability-to-modify-resources","title":"A04: capability to modify resources","text":"The webhook component validates and converts ExternalSecret and SecretStore resources. The conversion webhook is essential for migrating resources from the old version v1alpha1
to the new version v1beta1
. The webhook component possesses the ability to modify resources during runtime.
"},{"location":"guides/threat-model/#threats","title":"Threats","text":""},{"location":"guides/threat-model/#t01-tampering-with-resources-through-mitm","title":"T01: Tampering with resources through MITM","text":"An adversary could launch a Man-in-the-Middle (MITM) attack to hijack the webhook pod, enabling them to manipulate the data of the conversion webhook. This could involve injecting malicious resources or causing a Denial-of-Service (DoS) attack. To mitigate this threat, a mutual authentication mechanism should be enforced for the connection between the Kubernetes API server and the webhook service to ensure that only authenticated endpoints can communicate.
"},{"location":"guides/threat-model/#t02-webhook-dos","title":"T02: Webhook DOS","text":"Currently, ESO generates an X.509 certificate for webhook registration without authenticating the kube-apiserver. Consequently, if an attacker gains network access to the webhook Pod, they can overload the webhook server and initiate a DoS attack. As a result, modifications to ESO resources may fail, and the ESO core controller may be impacted due to the unavailability of the conversion webhook.
"},{"location":"guides/threat-model/#t03-unauthorized-access-to-cluster-secrets","title":"T03: Unauthorized access to cluster secrets","text":"An attacker can gain unauthorized access to secrets by utilizing the service account token of the ESO core controller Pod or exploiting software vulnerabilities. This unauthorized access allows the attacker to read secrets within the cluster, potentially leading to a cluster takeover.
"},{"location":"guides/threat-model/#t04-unauthorized-access-to-secret-provider-credentials","title":"T04: unauthorized access to secret provider credentials","text":"An attacker can gain unauthorized access to credentials that provide access to external APIs storing secrets. If the credentials have overly broad permissions, this could result in an organization takeover.
"},{"location":"guides/threat-model/#t05-data-exfiltration-through-malicious-resources","title":"T05: data exfiltration through malicious resources","text":"An attacker can exfiltrate data from the cluster by utilizing maliciously crafted resources. Multiple attack vectors can be employed, e.g.:
- copying data from a namespace to an unauthorized namespace
- exfiltrating data to an unauthorized secret provider
- exfiltrating data through an authorized secret provider to a malicious provider account
Successful data exfiltration can lead to intellectual property loss, information misuse, loss of customer trust, and damage to the brand or reputation.
"},{"location":"guides/threat-model/#t06-supply-chain-attacks","title":"T06: supply chain attacks","text":"An attack can infiltrate the ESO container through various attack vectors. The following are some potential entry points, although this is not an exhaustive list. For a comprehensive analysis, refer to SLSA Threats and mitigations or GCP software supply chain threats.
- Source Threats: Unauthorized changes or inclusion of vulnerable code in ESO through code submissions.
- Build Threats: Creation and distribution of malicious builds of ESO, such as in container registries, Artifact Hub, or Operator Hub.
- Dependency Threats: Introduction of vulnerable code into ESO dependencies.
- Deployment and Runtime Threats: Injection of malicious code through compromised deployment processes.
"},{"location":"guides/threat-model/#t07-malicious-workloads-in-eso-namespace","title":"T07: malicious workloads in eso namespace","text":"An attacker can deploy malicious workloads within the external-secrets namespace, taking advantage of the ESO service account with potentially cluster-wide privileges.
"},{"location":"guides/threat-model/#controls","title":"Controls","text":""},{"location":"guides/threat-model/#c01-network-security-policy","title":"C01: Network Security Policy","text":"Implement a NetworkPolicy to restrict traffic in both inbound and outbound directions on all networks. Employ a \"deny all\" / \"permit by exception\" approach for inbound and outbound network traffic. The specific network policies for the core-controller depend on the chosen provider. The webhook and cert-controller have well-defined sets of endpoints they communicate with. Refer to the Security Best Practices documentation for inbound and outbound network requirements.
Please note that ESO does not provide pre-packaged network policies, and it is the user's responsibility to implement the necessary security controls.
"},{"location":"guides/threat-model/#c02-least-privilege-rbac","title":"C02: Least Privilege RBAC","text":"Adhere to the principle of least privilege by configuring Role-Based Access Control (RBAC) permissions not only for the ESO workload but also for all users interacting with it. Ensure that RBAC permissions on provider side are appropriate according to your setup, by for example limiting which sensitive information a given credential can have access to. Ensure that kubernetes RBAC are set up to grant access to ESO resources only where necessary. For example, allowing write access to ClusterSecretStore
/ExternalSecret
may be sufficient for a threat to become a reality.
"},{"location":"guides/threat-model/#c03-policy-enforcement","title":"C03: Policy Enforcement","text":"Implement a Policy Engine such as Kyverno or OPA to enforce restrictions on changes to ESO resources. The specific policies to be enforced depend on the environment. Here are a few suggestions:
- (Cluster)SecretStore: Restrict the allowed secret providers, disallowing unused or undesired providers (e.g. Webhook).
- (Cluster)SecretStore: Restrict the permitted authentication mechanisms (e.g. prevent usage of
secretRef
). - (Cluster)SecretStore: Enforce limitations on modifications to provider-specific fields relevant for security, such as
caBundle
, caProvider
, region
, role
, url
, environmentType
, identityId
, and others
. - ClusterSecretStore: Control the usage of
namespaceSelector
, such as forbidding or mandating the usage of the kube-system
namespace. - ClusterExternalSecret: Restrict the usage of
namespaceSelector
.
Please note that ESO does not provide pre-packaged policies, and it is the user's responsibility to implement the necessary security controls.
"},{"location":"guides/threat-model/#c04-provider-access-policy","title":"C04: Provider Access Policy","text":"Configure fine-grained access control on the HTTP endpoint of the secret provider to prevent data exfiltration across accounts or organizations. Consult the documentation of your specific provider (e.g.: AWS Secrets Manager VPC Endpoint Policies, GCP Private Service Connect, or Azure Private Link) for guidance on setting up access policies.
"},{"location":"guides/threat-model/#c05-entirely-disable-crds","title":"C05: Entirely disable CRDs","text":"You should disable unused CRDs to narrow down your attack surface. Not all users require the use of PushSecret
, ClusterSecretStore
or ClusterExternalSecret
resources.
"},{"location":"guides/using-latest-image/","title":"Using Latest Image","text":"You can test a feature that was not yet released using the following methods, use them at your own discretion:
"},{"location":"guides/using-latest-image/#helm","title":"Helm","text":" - Create a
values.yaml
file with the following content: replicaCount: 1\n\nimage:\n repository: ghcr.io/external-secrets/external-secrets\n pullPolicy: IfNotPresent\n # -- The image tag to use. The default is the chart appVersion.\n tag: \"main\"\n\n# -- If set, install and upgrade CRDs through helm chart.\ninstallCRDs: false\n
- Install the crds
make crds.install\n
- Install the external-secrets Helm chart indicating the values file created before:
helm install external-secrets external-secrets/external-secrets -f values.yaml\n
"},{"location":"guides/using-latest-image/#manual","title":"Manual","text":" - Build the Docker image
docker build -f Dockerfile.standalone -t my-org/external-secrets:latest .\n
- Apply the
bundle.yaml
kubectl apply -f deploy/crds/bundle.yaml\n
- Modify your configs to use the image
kind: Deployment\nmetadata:\n name: external-secrets|external-secrets-webhook|external-secrets-cert-controller\n...\n image: my-org/external-secrets:latest\n
"},{"location":"guides/v1beta1/","title":"Upgrading CRD versions","text":"From version v0.5.0, v1alpha1
version is deprecated, and v1beta1
is in place. This guide will cover the main differences between the two versions, and a procedure on how to safely upgrade it.
"},{"location":"guides/v1beta1/#differences-between-versions","title":"Differences between versions","text":"Versions v1alpha1 and v1beta1 are fully-compatible for SecretStores and ClusterSecretStores. For ExternalSecrets, there is a difference on the dataFrom
method.
While in v1alpha1, we could define a dataFrom
with the following format:
spec:\n dataFrom:\n - key: my-key\n - key: my-other-key\n
In v1beta1 is possible to use two methods. One of them is Extract
and has the exact same behavior as dataFrom
in v1alpha1. The other is Find
, which allows finding multiple external secrets and map them into a single Kubernetes secret. Here is an example of Find
:
spec:\n dataFrom:\n - find:\n name: #matches any secret name ending in foo-bar\n regexp: .*foo-bar$\n - find:\n tags: #matches any secrets with the following metadata.\n env: dev \n app: web\n
"},{"location":"guides/v1beta1/#upgrading","title":"Upgrading","text":"If you already have an installation of ESO using v1alpha1
, we recommend you to upgrade to v1beta1
. If you do not use dataFrom
in your ExternalSecrets, or if you deploy the CRDs using the official Helm charts, the upgrade can be done with no risk of losing data.
If you are installing CRDs manually, you will need to deploy the bundle CRD file available at deploys/crds/bundle.yaml
. This bundle file contains v1beta1
definition and a conversion webhook configuration. This configuration will ensure that new requests to handle any CRD object will only be valid after the upgrade is successfully complete - so there are no risks of losing data due to an incomplete upgrade. Once the new CRDs are applied, you can proceed to upgrade the controller version.
Once the upgrade is finished, at each reconcile, any ExternalSecret
, SecretStore
, and ClusterSecretStore
stored in v1alpha1
will be automatically converted to v1beta1
.
"},{"location":"introduction/deprecation-policy/","title":"Deprecation Policy","text":"We follow the Kubernetes Deprecation Policy and API Versioning Scheme: alpha, beta, GA.
The project is currently in beta
state. Please try the beta
features and provide feedback. After the features exits beta, it may not be practical to make more changes.
-
alpha
- The support for a feature may be dropped at any time without notice.
- The API may change in incompatible ways in a later software release without notice.
- The software is recommended for use only in short-lived testing clusters, due to increased risk of bugs and lack of long-term support.
-
beta
- The software is well tested. Enabling a feature is considered safe. Features are enabled by default.
- The support for a feature will not be dropped, though the details may change.
- The schema and/or semantics of objects may change in incompatible ways in a subsequent beta or stable release. When this happens, migration instructions are provided. Schema changes may require deleting, editing, and re-creating API objects. The editing process may not be straightforward. The migration may require downtime for applications that rely on the feature.
- The software is not recommended for production uses. Subsequent releases may introduce incompatible changes. If you have multiple clusters which can be upgraded independently, you may be able to relax this restriction.
- GA
- The stable versions of features appear in released software for many subsequent versions.
- Use it in production ;)
"},{"location":"introduction/deprecation-policy/#api-surface","title":"API Surface","text":"We define the following scope that is covered by our deprecation policy. We follow the 9 Rules of the Kubernetes Deprecation Policy.
"},{"location":"introduction/deprecation-policy/#scope","title":"Scope","text":" - API Objects and fields:
.Spec
, .Status
and .Status.Conditions[]
- Enums and constant values
- Controller Configuration: CLI flags & environment variables
- Metrics as defined in the Kubernetes docs
- a feature or specific behavior:
ExternalSecret
update mechanics
"},{"location":"introduction/deprecation-policy/#non-scope","title":"Non-Scope","text":"We do not provide stability guarantee for source code imports. The Interfaces and the behavior will change in a unexpected and backwards-incompatible way. However, The maintained helm chart is not part of this deprecation policy.
"},{"location":"introduction/faq/","title":"FAQ","text":""},{"location":"introduction/faq/#can-i-manually-trigger-a-secret-refresh","title":"Can I manually trigger a secret refresh?","text":"You can trigger a secret refresh by using kubectl or any other kubernetes api client. You just need to change an annotation, label or the spec of the resource:
kubectl annotate es my-es force-sync=$(date +%s) --overwrite\n
"},{"location":"introduction/faq/#how-do-i-know-when-my-secret-was-last-synced","title":"How do I know when my secret was last synced?","text":"The last synchronization timestamp of an ExternalSecret can be retrieved from the field refreshTime
.
kubectl get es my-external-secret -o yaml | grep refreshTime\n refreshTime: \"2022-05-21T23:02:47Z\"\n
The interval can be changed by the spec.refreshInterval
in the ExternalSecret.
"},{"location":"introduction/faq/#how-do-i-know-when-the-status-of-my-secret-changed-the-last-time","title":"How do I know when the status of my secret changed the last time?","text":"Every ExternalSecret resource contains a status condition that indicates whether a secret was successfully synchronized, along with the timestamp of the last status change of the ExternalSecret (e.g. from SecretSyncedError to SecretSynced). This can be obtained from the field lastTransitionTime
:
kubectl get es my-external-secret -o yaml | grep condition -A 5\n conditions:\n - lastTransitionTime: \"2022-05-21T21:02:47Z\"\n message: Secret was synced\n reason: SecretSynced\n status: \"True\"\n type: Ready\n
"},{"location":"introduction/faq/#differences-to-csi-secret-store","title":"Differences to csi-secret-store","text":"Please take a look at this issue comment here.
"},{"location":"introduction/faq/#how-do-i-debug-an-external-secret-that-doesnt-sync","title":"How do I debug an external-secret that doesn't sync?","text":"First, check the status of the ExternalSecret resource using kubectl describe
. That displays the status conditions as well as recent events. You should expect a status condition with Type=Ready
, Status=True
. Further you shouldn't see any events with Type=Warning
. Read carefully if they exist.
kubectl describe es my-external-secret\n[...]\nStatus:\n Conditions:\n Last Transition Time: 2022-05-21T21:02:47Z\n Message: Secret was synced\n Reason: SecretSynced\n Status: True\n Type: Ready\n Refresh Time: 2022-05-21T21:06:47Z\n Synced Resource Version: 1-5c833527afd7ba3f426cb0082ee7e083\nEvents:\n Type Reason Age From Message\n ---- ------ ---- ---- -------\n Warning UpdateFailed 4m12s external-secrets secrets \"yyyyyyy\" already exists\n Normal Updated 12s (x4 over 3m12s) external-secrets Updated Secret\n
If everything looks good you should check the corresponding secret store resource that is referenced from an ExternalSecret. Again, use kubectl describe
to show status conditions and events and look for warning signs as described above.
In an ideally, the store should be validated and Ready.
kubectl describe css kubernetes\n[...]\nStatus:\n Conditions:\n Last Transition Time: 2022-05-21T21:02:47Z\n Message: store validated\n Reason: Valid\n Status: True\n Type: Ready\nEvents:\n Type Reason Age From Message\n ---- ------ ---- ---- -------\n Normal Valid 52s (x4 over 10m) cluster-secret-store store validated\n Normal Valid 52s (x4 over 10m) cluster-secret-store store validated\n
If everything looks normal so far, please go ahead and ensure that the created secret has the expected value. Also, take a look at the logs of the controller.
"},{"location":"introduction/faq/#upgrading-from-kes-to-eso","title":"Upgrading from KES to ESO","text":"Migrating from KES to ESO is quite tricky! There is a tool we built to help users out available here, and there is a small migration procedure.
There are some incompatibilities between KES to ESO, and while the tool tries to cover most of them, some of them will require manual intervention. We recommend to first convert the manifest files, and actually see if the tool provides a warning about any file needed to be changed. Beware that the tool points the SecretStores to use KES Service Account, so you'll also need to tweak that if you plan to uninstall KES after the upgrade.
"},{"location":"introduction/getting-started/","title":"Getting started","text":"External-secrets runs within your Kubernetes cluster as a deployment resource. It utilizes CustomResourceDefinitions to configure access to secret providers through SecretStore resources and manages Kubernetes secret resources with ExternalSecret resources.
Note: The minimum supported version of Kubernetes is 1.16.0
. Users still running Kubernetes v1.15 or below should upgrade to a supported version before installing external-secrets.
"},{"location":"introduction/getting-started/#installing-with-helm","title":"Installing with Helm","text":"The default install options will automatically install and manage the CRDs as part of your helm release. If you do not want the CRDs to be automatically upgraded and managed, you must set the installCRDs
option to false
. (e.g. --set installCRDs=false
)
You can install those CRDs outside of helm
using:
kubectl apply -k \"https://github.com/external-secrets/external-secrets//config/crds/bases?ref=v0.9.11\"\n
Uncomment the relevant line in the next steps to disable the automatic install of CRDs.
"},{"location":"introduction/getting-started/#option-1-install-from-chart-repository","title":"Option 1: Install from chart repository","text":"helm repo add external-secrets https://charts.external-secrets.io\n\nhelm install external-secrets \\\n external-secrets/external-secrets \\\n -n external-secrets \\\n --create-namespace \\\n # --set installCRDs=false\n
"},{"location":"introduction/getting-started/#option-2-install-chart-from-local-build","title":"Option 2: Install chart from local build","text":"Build and install the Helm chart locally after cloning the repository.
make helm.build\n\nhelm install external-secrets \\\n ./bin/chart/external-secrets.tgz \\\n -n external-secrets \\\n --create-namespace \\\n # --set installCRDs=false\n
"},{"location":"introduction/getting-started/#create-a-secret-containing-your-aws-credentials","title":"Create a secret containing your AWS credentials","text":"echo -n 'KEYID' > ./access-key\necho -n 'SECRETKEY' > ./secret-access-key\nkubectl create secret generic awssm-secret --from-file=./access-key --from-file=./secret-access-key\n
"},{"location":"introduction/getting-started/#create-your-first-secretstore","title":"Create your first SecretStore","text":"Create a file 'basic-secret-store.yaml' with the following content.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: secretstore-sample\nspec:\n provider:\n aws:\n service: SecretsManager\n region: us-east-1\n auth:\n secretRef:\n accessKeyIDSecretRef:\n name: awssm-secret\n key: access-key\n secretAccessKeySecretRef:\n name: awssm-secret\n key: secret-access-key\n
Apply it to create a SecretStore resource.
kubectl apply -f \"basic-secret-store.yaml\"\n
"},{"location":"introduction/getting-started/#create-your-first-externalsecret","title":"Create your first ExternalSecret","text":"Create a file 'basic-external-secret.yaml' with the following content.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: secretstore-sample\n kind: SecretStore\n target:\n name: secret-to-be-created\n creationPolicy: Owner\n data:\n - secretKey: secret-key-to-be-managed\n remoteRef:\n key: provider-key\n version: provider-key-version\n property: provider-key-property\n dataFrom:\n - extract:\n key: remote-key-in-the-provider\n
Apply it to create an External Secret resource.
kubectl apply -f \"basic-external-secret.yaml\"\n
kubectl describe externalsecret example\n# [...]\nName: example\nStatus:\n Binding:\n Name: secret-to-be-created\n Conditions:\n Last Transition Time: 2021-02-24T16:45:23Z\n Message: Secret was synced\n Reason: SecretSynced\n Status: True\n Type: Ready\n Refresh Time: 2021-02-24T16:45:24Z\nEvents: <none>\n
For more advanced examples, please read the other guides.
"},{"location":"introduction/getting-started/#installing-with-olm","title":"Installing with OLM","text":"External-secrets can be managed by Operator Lifecycle Manager (OLM) via an installer operator. It is made available through OperatorHub.io, this installation method is suited best for OpenShift. See installation instructions on the external-secrets-operator package.
"},{"location":"introduction/getting-started/#uninstalling","title":"Uninstalling","text":"Before continuing, ensure that all external-secret resources that have been created by users have been deleted. You can check for any existing resources with the following command:
kubectl get SecretStores,ClusterSecretStores,ExternalSecrets --all-namespaces\n
Once all these resources have been deleted you are ready to uninstall external-secrets.
"},{"location":"introduction/getting-started/#uninstalling-with-helm","title":"Uninstalling with Helm","text":"Uninstall the helm release using the delete command.
helm delete external-secrets --namespace external-secrets\n
"},{"location":"introduction/overview/","title":"API Overview","text":""},{"location":"introduction/overview/#architecture","title":"Architecture","text":"The External Secrets Operator extends Kubernetes with Custom Resources, which define where secrets live and how to synchronize them. The controller fetches secrets from an external API and creates Kubernetes secrets. If the secret from the external API changes, the controller will reconcile the state in the cluster and update the secrets accordingly.
"},{"location":"introduction/overview/#resource-model","title":"Resource model","text":"To understand the mechanics of the operator let's start with the data model. The SecretStore references a bucket of key/value pairs. But because every external API is slightly different this bucket may be e.g. an instance of an Azure KeyVault or a AWS Secrets Manager in a certain AWS Account and region. Please take a look at the provider documentation to see what the Bucket actually maps to.
"},{"location":"introduction/overview/#secretstore","title":"SecretStore","text":"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, the SecretStore specifies how to access. This resource is namespaced.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: secretstore-sample\nspec:\n provider:\n aws:\n service: SecretsManager\n region: us-east-1\n auth:\n secretRef:\n accessKeyIDSecretRef:\n name: awssm-secret\n key: access-key\n secretAccessKeySecretRef:\n name: awssm-secret\n key: secret-access-key\n
The SecretStore
contains references to secrets which hold credentials to access the external API."},{"location":"introduction/overview/#externalsecret","title":"ExternalSecret","text":"An ExternalSecret declares what data to fetch. It has a reference to a SecretStore
which knows how to access that data. The controller uses that ExternalSecret
as a blueprint to create secrets.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: secretstore-sample\n kind: SecretStore\n target:\n name: secret-to-be-created\n creationPolicy: Owner\n data:\n - secretKey: secret-key-to-be-managed\n remoteRef:\n key: provider-key\n version: provider-key-version\n property: provider-key-property\n dataFrom:\n - extract:\n key: remote-key-in-the-provider\n
"},{"location":"introduction/overview/#clustersecretstore","title":"ClusterSecretStore","text":"The ClusterSecretStore is a global, cluster-wide SecretStore that can be referenced from all namespaces. You can use it to provide a central gateway to your secret provider.
"},{"location":"introduction/overview/#behavior","title":"Behavior","text":"The External Secret Operator (ESO for brevity) reconciles ExternalSecrets
in the following manner:
- ESO uses
spec.secretStoreRef
to find an appropriate SecretStore
. If it doesn't exist or the spec.controller
field doesn't match it won't further process this ExternalSecret. - ESO instanciates an external API client using the specified credentials from the
SecretStore
spec. - ESO fetches the secrets as requested by the
ExternalSecret
, it will decode the secrets if required - ESO creates an
Kind=Secret
based on the template provided by ExternalSecret.target.template
. The Secret.data
can be templated using the secret values from the external API. - ESO ensures that the secret values stay in sync with the external API
"},{"location":"introduction/overview/#roles-and-responsibilities","title":"Roles and responsibilities","text":"The External Secret Operator is designed to target the following persona:
- Cluster Operator: The cluster operator is responsible for setting up the External Secret Operator, managing access policies and creating ClusterSecretStores.
- Application developer: The Application developer is responsible for defining ExternalSecrets and the application configuration
Each persona will roughly map to a Kubernetes RBAC role. Depending on your environment these roles can map to a single user. Note: There is no Secret Operator that handles the lifecycle of the secret, this is out of the scope of ESO.
"},{"location":"introduction/overview/#access-control","title":"Access Control","text":"The External Secrets Operator runs as a deployment in your cluster with elevated privileges. It will create/read/update secrets in all namespaces and has access to secrets stored in some external API. Ensure that the credentials you provide give ESO the least privilege necessary.
Design your SecretStore
/ClusterSecretStore
carefully! Be sure to restrict access of application developers to read only certain keys in a shared environment.
You should also consider using Kubernetes' admission control system (e.g. OPA or Kyverno) for fine-grained access control.
"},{"location":"introduction/overview/#running-multiple-controller","title":"Running multiple Controller","text":"You can run multiple controllers within the cluster. One controller can be limited to only process SecretStores
with a predefined spec.controller
field.
Testers welcome
This is not widely tested. Please help us test the setup and/or document use-cases.
"},{"location":"introduction/stability-support/","title":"Stability and Support","text":"This page lists the status, timeline and policy for currently supported ESO releases and its providers. Please also see our deprecation policy that describes API versioning, deprecation and API surface.
"},{"location":"introduction/stability-support/#supported-versions","title":"Supported Versions","text":"We want to provide security patches and critical bug fixes in a timely manner to our users. To do so, we offer long-term support for our latest two (N, N-1) software releases. We aim for a 2-3 month minor release cycle, i.e. a given release is supported for about 4-6 months.
We want to cover the following cases:
- regular image rebuilds to update OS dependencies
- regular go dependency updates
- backport bug fixes on demand
ESO Version Kubernetes Version Release Date End of Life 0.9.x 1.19 \u2192 1.29 Jun 22, 2023 Release of 1.1 0.8.x 1.19 \u2192 1.28 Mar 16, 2023 Release of 1.0 0.7.x 1.19 \u2192 1.26 Dec 11, 2022 Jun 22, 2023 0.6.x 1.19 \u2192 1.24 Oct 9, 2022 Mar 16, 2023 0.5.x 1.19 \u2192 1.24 Apr 6, 2022 Dec 11, 2022 0.4.x 1.16 \u2192 1.24 Feb 2, 2022 Oct 9, 2022 0.3.x 1.16 \u2192 1.24 Jul 25, 2021 Apr 6, 2022"},{"location":"introduction/stability-support/#provider-stability-and-support-level","title":"Provider Stability and Support Level","text":"The following table describes the stability level of each provider and who's responsible.
Provider Stability Maintainer AWS Secrets Manager stable external-secrets AWS Parameter Store stable external-secrets Hashicorp Vault stable external-secrets GCP Secret Manager stable external-secrets Azure Keyvault stable external-secrets IBM Cloud Secrets Manager stable @knelasevero @sebagomez @ricardoptcosta @IdanAdar Kubernetes beta external-secrets Yandex Lockbox alpha @AndreyZamyslov @knelasevero GitLab Variables alpha @Jabray5 Alibaba Cloud KMS alpha @ElsaChelala Oracle Vault alpha @KianTigger @EladGabay Akeyless alpha @renanaAkeyless 1Password alpha @SimSpaceCorp @snarlysodboxer Generic Webhook alpha @willemm senhasegura DevOps Secrets Management (DSM) alpha @lfraga Doppler SecretOps Platform alpha @ryan-blunden @nmanoogian Keeper Security alpha @ppodevlab Scaleway alpha @azert9 Conjur stable @davidh-cyberark @szh Delinea alpha @michaelsauter Pulumi ESC alpha @dirien Passbolt alpha"},{"location":"introduction/stability-support/#provider-feature-support","title":"Provider Feature Support","text":"The following table show the support for features across different providers.
Provider find by name find by tags metadataPolicy Fetch referent authentication store validation push secret DeletionPolicy Merge/Delete AWS Secrets Manager x x x x x x x AWS Parameter Store x x x x x x x Hashicorp Vault x x x x x x x GCP Secret Manager x x x x x x x Azure Keyvault x x x x x x x Kubernetes x x x x x x x IBM Cloud Secrets Manager x x x Yandex Lockbox x GitLab Variables x x x Alibaba Cloud KMS x Oracle Vault x Akeyless x x x 1Password x x x x Generic Webhook x senhasegura DSM x Doppler x x Keeper Security x x x Scaleway x x x x x Conjur x x x Delinea x x Pulumi ESC x x Passbolt x x"},{"location":"introduction/stability-support/#support-policy","title":"Support Policy","text":"We provide technical support and security / bug fixes for the above listed versions.
"},{"location":"introduction/stability-support/#technical-support","title":"Technical support","text":"We provide assistance for deploying/upgrading etc. on a best-effort basis. You can request support through the following channels:
- Kubernetes Slack #external-secrets
- GitHub Issues
- GitHub Discussions
Even though we have active maintainers and people assigned to this project, we kindly ask for patience when asking for support. We will try to get to priority issues as fast as possible, but there may be some delays.
"},{"location":"provider/1password-automation/","title":"1Password Secrets Automation","text":""},{"location":"provider/1password-automation/#1password-secrets-automation","title":"1Password Secrets Automation","text":"External Secrets Operator integrates with 1Password Secrets Automation for secret management.
"},{"location":"provider/1password-automation/#important-note-about-this-documentation","title":"Important note about this documentation","text":"The 1Password API calls the entries in vaults 'Items'. These docs use the same term.
"},{"location":"provider/1password-automation/#behavior","title":"Behavior","text":" - How an Item is equated to an ExternalSecret:
remoteRef.key
is equated to an Item's Title remoteRef.property
is equated to: - An Item's field's Label (Password type)
- An Item's file's Name (Document type)
- If empty, defaults to the first file name, or the field labeled
password
remoteRef.version
is currently not supported. - One Item in a vault can equate to one Kubernetes Secret to keep things easy to comprehend.
- Support for 1Password secret types of
Password
and Document
. - The
Password
type can get data from multiple fields
in the Item. - The
Document
type can get data from files. - See creating 1Password Items compatible with ExternalSecrets.
- Ordered vaults
- Specify an ordered list of vaults in a SecretStore and the value will be sourced from the first vault with a matching Item.
- If no matching Item is found, an error is returned.
- This supports having a default or shared set of values that can also be overriden for specific environments.
dataFrom
: find.path
is equated to Item Title. find.name.regexp
is equated to field Labels. find.tags
are not supported at this time.
"},{"location":"provider/1password-automation/#prerequisites","title":"Prerequisites","text":" - 1Password requires running a 1Password Connect Server to which the API requests will be made.
- External Secrets does not run this server. See Deploy a Connect Server.
- One Connect Server is needed per 1Password Automation Environment.
- Many Vaults can be added to an Automation Environment, and Tokens can be generated in that Environment with access to any set or subset of those Vaults.
- 1Password Connect Server version 1.5.6 or higher.
"},{"location":"provider/1password-automation/#setup-authentication","title":"Setup Authentication","text":"Authentication requires a 1password-credentials.json
file provided to the Connect Server, and a related 'Access Token' for the client in this provider to authenticate to that Connect Server. Both of these are generated by 1Password.
- Setup an Automation Environment at 1Password.com, or via the op CLI.
- Note: don't be confused by the
op connect server create
syntax. This will create an Automation Environment in 1Password, and corresponding credentials for a Connect Server, nothing more. - This will result in a
1password-credentials.json
file to provide to a Connect Server Deployment, and an Access Token to provide as a Secret referenced by a SecretStore
or ClusterSecretStore
.
- Create a Kubernetes secret with the Access Token
---\napiVersion: v1\nkind: Secret\nmetadata:\n name: onepassword-connect-token-staging\ntype: Opaque\nstringData:\n token: my-token\n
- Reference the secret in a SecretStore or ClusterSecretStore
---\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: staging\nspec:\n provider:\n onepassword:\n connectHost: https://onepassword-connect-staging\n vaults:\n staging: 1 # look in this vault first\n shared: 2 # next look in here. error if not found\n auth:\n secretRef:\n connectTokenSecretRef:\n name: onepassword-connect-token-staging\n key: token\n
- Create a Kubernetes secret with the Connect Server credentials
---\napiVersion: v1\nkind: Secret\nmetadata:\n name: connect-server-credentials\ntype: Opaque\nstringData:\n # NOTE: This secret value must be base64 encoded after it becomes the OP_SESSION env var in the Connect Server Deployment, that means double base64 encoded here. (Or single w/ stringData.)\n 1password-credentials.json: |-\n eyJ2ZXJpZmllciI6eyJzYWx0IjoiZXhhbXBsZSIsImxvY2FsSGFzaCI6ImV4YW1wbGUifSwiZW5jQ3JlZGVudGlhbHMiOnsia2lkIjoiZXhhbXBsZSIsImVuYyI6ImV4YW1wbGUiLCJjdHkiOiJleGFtcGxlIiwiaXYiOiJleGFtcGxlIiwiZGF0YSI6ImV4YW1wbGUifSwidmVyc2lvbiI6IjIiLCJkZXZpY2VVdWlkIjoiZXhhbXBsZSIsInVuaXF1ZUtleSI6eyJhbGciOiJleGFtcGxlIiwiZXh0Ijp0cnVlLCJrIjoiZXhhbXBsZSIsImtleV9vcHMiOlsiZW5jcnlwdCIsImRlY3J5cHQiXSwia3R5Ijoib2N0Iiwia2lkIjoiZXhhbXBsZSJ9fQ==\n
- Reference the secret in a Connect Server Deployment
---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: onepassword-connect-staging\nspec:\n template:\n spec:\n containers:\n - name: connect-api\n image: 1password/connect-api:1.5.0\n env:\n - name: OP_SESSION\n valueFrom:\n secretKeyRef:\n name: connect-server-credentials\n key: 1password-credentials.json\n ...\n - name: connect-sync\n image: 1password/connect-sync:1.5.0\n env:\n - name: OP_SESSION\n valueFrom:\n secretKeyRef:\n name: connect-server-credentials\n key: 1password-credentials.json\n ...\n ...\n
"},{"location":"provider/1password-automation/#deploy-a-connect-server","title":"Deploy a Connect Server","text":" - Follow the remaining instructions in the Quick Start guide.
- Deploy at minimum a Deployment and Service for a Connect Server, to go along with the Secret for the Server created in the Setup Authentication section.
- The Service's name will be referenced in SecretStores/ClusterSecretStores.
- Keep in mind the likely need for additional Connect Servers for other Automation Environments when naming objects. For example dev, staging, prod, etc.
- Unencrypted secret values are passed over the connection between the Operator and the Connect Server. Encrypting the connection is recommended.
"},{"location":"provider/1password-automation/#creating-compatible-1password-items","title":"Creating Compatible 1Password Items","text":"Also see examples below for matching SecretStore and ExternalSecret specs.
"},{"location":"provider/1password-automation/#manually-password-type","title":"Manually (Password type)","text":" - Click the plus button to create a new Password type Item.
- Change the title to what you want
remoteRef.key
to be. - Set what you want
remoteRef.property
to be in the field sections where is says 'label', and values where it says 'new field'. - Click the 'Save' button.
"},{"location":"provider/1password-automation/#manually-document-type","title":"Manually (Document type)","text":" - Click the plus button to create a new Document type Item.
- Choose the file to upload and upload it.
- Change the title to match
remoteRef.key
- Click the 'Add New File' button to add more files.
- Click the 'Save' button.
"},{"location":"provider/1password-automation/#scripting-password-type-with-op-cli","title":"Scripting (Password type with op CLI)","text":" - Create
file.json
with the following contents, swapping in your keys and values. Note: section.name
's and section.title
's values are ignored by the Operator, but cannot be empty for the op
CLI {\n \"title\": \"my-title\",\n \"vault\": {\n \"id\": \"vault-id\"\n },\n \"category\": \"LOGIN\",\n \"fields\": [\n {\n \"id\": \"username\",\n \"type\": \"STRING\",\n \"purpose\": \"USERNAME\",\n \"label\": \"username\",\n \"value\": \"a-username\"\n },\n {\n \"id\": \"password\",\n \"type\": \"CONCEALED\",\n \"purpose\": \"PASSWORD\",\n \"label\": \"password\",\n \"password_details\": {\n \"strength\": \"TERRIBLE\"\n },\n \"value\": \"a-password\"\n },\n {\n \"id\": \"notesPlain\",\n \"type\": \"STRING\",\n \"purpose\": \"NOTES\",\n \"label\": \"notesPlain\",\n \"value\": \"notesPlain\"\n },\n {\n \"id\": \"customField\",\n \"type\": \"CONCEALED\",\n \"purpose\": \"custom\",\n \"label\": \"custom\",\n \"value\": \"custom-value\"\n }\n ]\n }\n
- Run
op item create --template file.json
"},{"location":"provider/1password-automation/#scripting-document-type","title":"Scripting (Document type)","text":" - Unfortunately the
op
CLI doesn't seem to support uploading multiple files to the same Item, and the current Go lib has a bug. op
can be used to create a Document type Item with one file in it, but for now it's necessary to add multiple files to the same Document via the GUI.
"},{"location":"provider/1password-automation/#in-built-field-labeled-password-on-password-type-items","title":"In-built field labeled password
on Password type Items","text":" - TL;DR if you need a field labeled
password
, use the in-built one rather than the one in a fields Section.
- 1Password automatically adds a field labeled
password
on every Password type Item, whether it's created through a GUI or the API or op
CLI. - There's no problem with using this field just like any other field, just make sure you don't end up with two fields with the same label. (For example, by automating the
op
CLI to create Items.) - The in-built
password
field is not otherwise special for the purposes of ExternalSecrets. It can be ignored when not in use.
"},{"location":"provider/1password-automation/#examples","title":"Examples","text":"Examples of using the my-env-config
and my-cert
Items seen above.
- Note: with this configuration a 1Password Item titled
my-env-config
is correlated to a ExternalSecret named my-env-config
that results in a Kubernetes secret named my-env-config
, all with matching names for the key/value pairs. This is a way to increase comprehensibility. ---\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: staging\nspec:\n provider:\n onepassword:\n connectHost: https://onepassword-connect-staging\n vaults:\n staging: 1 # look in this vault first\n shared: 2 # next look in here. error if not found\n auth:\n secretRef:\n connectTokenSecretRef:\n name: onepassword-connect-token-staging\n key: token\n
---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: my-env-config\nspec:\n secretStoreRef:\n kind: SecretStore\n name: staging\n target:\n creationPolicy: Owner\n data:\n - secretKey: MY_ENV_VAR1\n remoteRef:\n key: my-env-config\n property: MY_ENV_VAR1\n - secretKey: MY_ENV_VAR2\n remoteRef:\n key: my-env-config\n property: MY_ENV_VAR2\n # OR\n dataFrom:\n - extract:\n key: my-env-config\n property: MY_ENV_VAR1 # optional field Label to match exactly\n # OR\n - find:\n path: my-env-config # optional Item Title to match exactly\n name:\n regexp: \"^MY_ENV_VAR.*\"\n
---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: my-cert\nspec:\n secretStoreRef:\n kind: SecretStore\n name: staging\n target:\n creationPolicy: Owner\n data:\n - secretKey: cert.crt\n remoteRef:\n key: my-cert\n property: cert.crt\n - secretKey: cert.key\n remoteRef:\n key: my-cert\n property: cert.key\n # OR\n dataFrom:\n - extract:\n key: my-cert\n property: cert.key # optional field Label to match exactly\n # OR\n - find:\n path: my-cert # optional Item Title to match exactly\n name:\n regexp: \"^cert.*\"\n
"},{"location":"provider/1password-automation/#additional-notes","title":"Additional Notes","text":""},{"location":"provider/1password-automation/#general","title":"General","text":" - It's intuitive to use Document type Items for Kubernetes secrets mounted as files, and Password type Items for ones that will be mounted as environment variables, but either can be used for either. It comes down to what's more convenient.
"},{"location":"provider/1password-automation/#why-no-version-history","title":"Why no version history","text":" - 1Password only supports version history on their in-built
password
field. Therefore, implementing version history in this provider would require one Item in 1Password per remoteRef
in an ExternalSecret. Additionally remoteRef.property
would be pointless/unusable. - For example, a Kubernetes secret with 15 keys (say, used in
envFrom
,) would require 15 Items in the 1Password vault, instead of 15 Fields in 1 Item. This would quickly get untenable for more than a few secrets, because: - All Items would have to have unique names which means
secretKey
couldn't match the Item name the remoteRef
is targeting. - Maintenance, particularly clean up of no longer used secrets, would be significantly more work.
- A vault would often become a huge list of unorganized entries as opposed to a much smaller list organized by Kubernetes Secret.
- To support new and old versions of a secret value at the same time, create a new Item in 1Password with the new value, and point some ExternalSecrets at a time to the new Item.
"},{"location":"provider/1password-automation/#keeping-misconfiguration-from-working","title":"Keeping misconfiguration from working","text":" - One instance of the ExternalSecrets Operator can work with many Connect Server instances, but it may not be the best approach.
- With one Operator instance per Connect Server instance, namespaces and RBAC can be used to improve security posture, and perhaps just as importantly, it's harder to misconfigure something and have it work (supply env A's secret values to env B for example.)
- You can run as many 1Password Connect Servers as you need security boundaries to help protect against accidental misconfiguration.
"},{"location":"provider/1password-automation/#patching-externalsecrets-with-kustomize","title":"Patching ExternalSecrets with Kustomize","text":" - An overlay can provide a SecretStore specific to that overlay, and then use JSON6902 to patch all the ExternalSecrets coming from base to point to that SecretStore. Here's an example
overlays/staging/kustomization.yaml
: ---\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- ../../base/something-with-external-secrets\n- secretStore.staging.yaml\n\npatchesJson6902:\n- target:\n kind: ExternalSecret\n name: \".*\"\n patch: |-\n - op: replace\n path: /spec/secretStoreRef/name\n value: staging\n
"},{"location":"provider/akeyless/","title":"Akeyless","text":""},{"location":"provider/akeyless/#akeyless-secrets-management-platform","title":"Akeyless Secrets Management Platform","text":"External Secrets Operator integrates with the Akeyless Secrets Management Platform.
"},{"location":"provider/akeyless/#create-secret-store","title":"Create Secret Store:","text":"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:
"},{"location":"provider/akeyless/#authentication-with-kubernetes","title":"Authentication with Kubernetes:","text":"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
"},{"location":"provider/akeyless/#create-the-akeyless-secret-store-provider-with-kubernetes-auth-method","title":"Create the Akeyless Secret Store Provider with Kubernetes Auth-Method","text":"apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: akeyless-secret-store\nspec:\n provider:\n akeyless:\n # URL of your akeyless API\n akeylessGWApiURL: \"https://api.akeyless.io\"\n authSecretRef:\n kubernetesAuth:\n accessID: \"p-XXXXXX\"\n k8sConfName: \"my-conf-name\"\n\n # Optional service account field containing the name\n # of a kubernetes ServiceAccount\n serviceAccountRef:\n name: \"my-sa\"\n\n # Optional secret field containing a Kubernetes ServiceAccount JWT\n # used for authenticating with Akeyless\n secretRef:\n name: \"my-secret\"\n key: \"token\"\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
for serviceAccountRef
and secretRef
according to the namespaces where the secrets reside."},{"location":"provider/akeyless/#authentication-with-cloud-identity-or-api-access-key","title":"Authentication With Cloud-Identity or Api-Access-Key","text":"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"},{"location":"provider/akeyless/#creating-an-akeyless-credentials-secret","title":"Creating an Akeyless Credentials Secret","text":"Create a secret containing your credentials using the following example as a guide:
apiVersion: v1\nkind: Secret\nmetadata:\n name: akeyless-secret-creds\ntype: Opaque\nstringData:\n accessId: \"p-XXXX\"\n accessType: # gcp/azure_ad/api_key/k8s/aws_iam\n accessTypeParam: # optional: can be one of the following: gcp-audience/azure-obj-id/access-key/k8s-conf-name\n
"},{"location":"provider/akeyless/#create-the-akeyless-secret-store-provider-with-the-credentials-secret","title":"Create the Akeyless Secret Store Provider with the Credentials Secret","text":"apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: akeyless-secret-store\nspec:\n provider:\n akeyless:\n # URL of your akeyless API\n akeylessGWApiURL: \"https://api.akeyless.io\"\n authSecretRef:\n secretRef:\n accessID:\n name: akeyless-secret-creds\n key: accessId\n accessType:\n name: akeyless-secret-creds\n key: accessType\n accessTypeParam:\n name: akeyless-secret-creds\n key: accessTypeParam\n
NOTE: In case of a ClusterSecretStore
, be sure to provide namespace
for accessID
, accessType
and accessTypeParam
according to the namespaces where the secrets reside."},{"location":"provider/akeyless/#create-the-akeyless-secret-store-with-cas-for-tls-handshake","title":"Create the Akeyless Secret Store With CAs for TLS handshake","text":"....\nspec:\n provider:\n akeyless:\n akeylessGWApiURL: \"https://your.akeyless.gw:8080/v2\"\n\n # Optional caBundle - PEM/base64 encoded CA certificate\n caBundle: \"<base64 encoded cabundle>\"\n # Optional caProvider:\n # Instead of caBundle you can also specify a caProvider\n # this will retrieve the cert from a Secret or ConfigMap\n caProvider:\n type: \"Secret/ConfigMap\" # Can be Secret or ConfigMap\n name: \"<name of secret or configmap>\"\n key: \"<key inside secret>\"\n # namespace is mandatory for ClusterSecretStore and not relevant for SecretStore\n namespace: \"my-cert-secret-namespace\"\n ....\n
"},{"location":"provider/akeyless/#creating-an-external-secret","title":"Creating an external secret","text":"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\nkind: ExternalSecret\nmetadata:\n name: database-credentials\nspec:\n refreshInterval: 1h\n\n secretStoreRef:\n kind: SecretStore\n name: akeyless-secret-store # Must match SecretStore on the cluster\n\n target:\n name: database-credentials # Name for the secret to be created on the cluster\n creationPolicy: Owner\n\n data:\n - secretKey: username # Key given to the secret to be created on the cluster\n remoteRef:\n key: db-username # Full path of the secret on Akeyless\n - secretKey: password # Key given to the secret to be created on the cluster\n remoteRef:\n key: db-password # Full path of the secret on Akeyless\n
"},{"location":"provider/akeyless/#using-datafrom","title":"Using DataFrom","text":"DataFrom can be used to get a secret as a JSON string and attempt to parse it.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: database-credentials\nspec:\n refreshInterval: 1h\n\n secretStoreRef:\n kind: SecretStore\n name: akeyless-secret-store # Must match SecretStore on the cluster\n\n target:\n name: database-credentials-json # Name for the secret to be created on the cluster\n creationPolicy: Owner\n\n # for json formatted secrets: each key in the json will be used as the secret key in the SECRET k8s target object\n dataFrom:\n - extract:\n key: database-credentials # Full path of the secret on Akeyless\n
"},{"location":"provider/akeyless/#getting-the-kubernetes-secret","title":"Getting the Kubernetes Secret","text":"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\n
kubectl get secret database-credentials-json -o jsonpath='{.data}'\n
"},{"location":"provider/alibaba/","title":"Alibaba Cloud","text":""},{"location":"provider/alibaba/#alibaba-cloud-secrets-manager","title":"Alibaba Cloud Secrets Manager","text":"External Secrets Operator integrates with Alibaba Cloud Key Management Service for secrets and Keys management.
"},{"location":"provider/alibaba/#authentication","title":"Authentication","text":"We support Access key and RRSA authentication.
To use RRSA authentication, you should follow Use RRSA to authorize pods to access different cloud services to assign the RAM role to external-secrets operator.
"},{"location":"provider/alibaba/#access-key-authentication","title":"Access Key authentication","text":"To use accessKeyID
and accessKeySecrets
, simply create them as a regular Kind: Secret
beforehand and associate it with the SecretStore
:
apiVersion: v1\nkind: Secret\nmetadata:\n name: secret-sample\ndata:\n accessKeyID: bXlhd2Vzb21lYWNjZXNza2V5aWQ=\n accessKeySecret: bXlhd2Vzb21lYWNjZXNza2V5c2VjcmV0\n
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: secretstore-sample\nspec:\n provider:\n alibaba:\n regionID: ap-southeast-1\n auth:\n secretRef:\n accessKeyIDSecretRef:\n name: secret-sample\n key: accessKeyID\n accessKeySecretSecretRef:\n name: secret-sample\n key: accessKeySecret\n
"},{"location":"provider/alibaba/#rrsa-authentication","title":"RRSA authentication","text":"When using RRSA authentication we manually project the OIDC token file to pod as volume
extraVolumes:\n - name: oidc-token\n projected:\n sources:\n - serviceAccountToken:\n path: oidc-token\n expirationSeconds: 7200 # The validity period of the OIDC token in seconds.\n audience: \"sts.aliyuncs.com\"\n\nextraVolumeMounts:\n - name: oidc-token\n mountPath: /var/run/secrets/tokens\n
and provide the RAM role ARN and OIDC volume path to the secret store
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: secretstore-sample\nspec:\n provider:\n alibaba:\n regionID: ap-southeast-1\n auth:\n rrsa:\n oidcProviderArn: acs:ram::1234:oidc-provider/ack-rrsa-ce123456\n oidcTokenFilePath: /var/run/secrets/tokens/oidc-token\n roleArn: acs:ram::1234:role/test-role\n sessionName: secrets\n
"},{"location":"provider/alibaba/#creating-external-secret","title":"Creating external secret","text":"To create a kubernetes secret from the Alibaba Cloud Key Management Service secret a Kind=ExternalSecret
is needed.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: secretstore-sample\n kind: SecretStore\n target:\n name: example-secret\n creationPolicy: Owner\n data:\n - secretKey: secret-key\n remoteRef:\n key: ext-secret\n
"},{"location":"provider/aws-parameter-store/","title":"AWS Parameter Store","text":""},{"location":"provider/aws-parameter-store/#parameter-store","title":"Parameter Store","text":"A ParameterStore
points to AWS SSM Parameter Store in a certain account within a defined region. You should define Roles that define fine-grained access to individual secrets and pass them to ESO using spec.provider.aws.role
. This way users of the SecretStore
can only access the secrets necessary.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: parameterstore\nspec:\n provider:\n aws:\n service: ParameterStore\n # define a specific role to limit access\n # to certain secrets\n role: arn:aws:iam::123456789012:role/external-secrets\n region: eu-central-1\n auth:\n secretRef:\n accessKeyIDSecretRef:\n name: awssm-secret\n key: access-key\n secretAccessKeySecretRef:\n name: awssm-secret\n key: secret-access-key\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in accessKeyIDSecretRef
and secretAccessKeySecretRef
with the namespaces where the secrets reside.
API Pricing & Throttling
The SSM Parameter Store API is charged by throughput and is available in different tiers, see pricing. Please estimate your costs before using ESO. Cost depends on the RefreshInterval of your ExternalSecrets.
"},{"location":"provider/aws-parameter-store/#iam-policy","title":"IAM Policy","text":"The example policy below shows the minimum required permissions for fetching SSM parameters. This policy permits pinning down access to secrets with a path matching dev-*
. Other operations may require additional permission. For example, finding parameters based on tags will also require ssm:DescribeParameters
and tag:GetResources
permission with \"Resource\": \"*\"
. Generally, the specific permission required will be logged as an error if an operation fails.
For further information see AWS Documentation.
{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"ssm:GetParameter*\",\n ],\n \"Resource\": \"arn:aws:ssm:us-east-2:1234567889911:parameter/dev-*\"\n }\n ]\n}\n
"},{"location":"provider/aws-parameter-store/#json-secret-values","title":"JSON Secret Values","text":"You can store JSON objects in a parameter. You can access nested values or arrays using gjson syntax:
Consider the following JSON object that is stored in the Parameter Store key friendslist
:
{\n \"name\": {\"first\": \"Tom\", \"last\": \"Anderson\"},\n \"friends\": [\n {\"first\": \"Dale\", \"last\": \"Murphy\"},\n {\"first\": \"Roger\", \"last\": \"Craig\"},\n {\"first\": \"Jane\", \"last\": \"Murphy\"}\n ]\n}\n
This is an example on how you would look up nested keys in the above json object:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: extract-data\nspec:\n # [omitted for brevity]\n data:\n - secretKey: my_name\n remoteRef:\n key: friendslist\n property: name.first # Tom\n - secretKey: first_friend\n remoteRef:\n key: friendslist\n property: friends.1.first # Roger\n\n # metadataPolicy to fetch all the tags in JSON format\n - secretKey: tags\n remoteRef:\n metadataPolicy: Fetch\n key: database-credentials\n\n # metadataPolicy to fetch a specific tag (dev) from the source secret\n - secretKey: developer\n remoteRef:\n metadataPolicy: Fetch\n key: database-credentials\n property: dev\n
"},{"location":"provider/aws-parameter-store/#parameter-versions","title":"Parameter Versions","text":"ParameterStore creates a new version of a parameter every time it is updated with a new value. The parameter can be referenced via the version
property
"},{"location":"provider/aws-parameter-store/#setsecret","title":"SetSecret","text":"The SetSecret method for the Parameter Store allows the user to set the value stored within the Kubernetes cluster to the remote AWS Parameter Store.
"},{"location":"provider/aws-parameter-store/#creating-a-push-secret","title":"Creating a Push Secret","text":"apiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\n name: pushsecret-example # Customisable\n namespace: default # Same of the SecretStores\nspec:\n updatePolicy: Replace # Policy to overwrite existing secrets in the provider on sync\n deletionPolicy: Delete # the provider' secret will be deleted if the PushSecret is deleted\n refreshInterval: 10s # Refresh interval for which push secret will reconcile\n secretStoreRefs: # A list of secret stores to push secrets to\n - name: aws-parameterstore\n kind: SecretStore\n selector:\n secret:\n name: pokedex-credentials # Source Kubernetes secret to be pushed\n template:\n metadata:\n annotations: { }\n labels: { }\n data:\n best-pokemon: \"{{ .best-pokemon | toString | upper }} is the really best!\"\n # Uses an existing template from configmap\n # Secret is fetched, merged and templated within the referenced configMap data\n # It does not update the configmap, it creates a secret with: data[\"alertmanager.yml\"] = ...result...\n templateFrom:\n - configMap:\n name: application-config-tmpl\n items:\n - key: config.yml\n data:\n - conversionStrategy: None # Also supports the ReverseUnicode strategy\n match:\n secretKey: best-pokemon # Source Kubernetes secret key to be pushed\n remoteRef:\n remoteKey: my-first-parameter # Remote reference (where the secret is going to be pushed)\n
"},{"location":"provider/aws-parameter-store/#check-successful-secret-sync","title":"Check successful secret sync","text":"To be able to check that the secret has been succesfully synced you can run the following command:
kubectl get pushsecret pushsecret-example\n
If the secret has synced successfully it will show the status as \"Synced\".
"},{"location":"provider/aws-parameter-store/#test-new-secret-using-aws-cli","title":"Test new secret using AWS CLI","text":"To View your parameter on AWS Parameter Store using the AWS CLI, install and login to the AWS CLI using the following guide: AWS CLI.
Run the following commands to get your synchronized parameter from AWS Parameter Store:
aws ssm get-parameter --name=my-first-parameter --region=us-east-1\n
You should see something similar to the following output:
{\n \"Parameter\": {\n \"Name\": \"my-first-parameter\",\n \"Type\": \"String\",\n \"Value\": \"charmander\",\n \"Version\": 4,\n \"LastModifiedDate\": \"2022-09-15T13:04:31.098000-03:00\",\n \"ARN\": \"arn:aws:ssm:us-east-1:1234567890123:parameter/my-first-parameter\",\n \"DataType\": \"text\"\n }\n}\n
"},{"location":"provider/aws-parameter-store/#aws-authentication","title":"AWS Authentication","text":""},{"location":"provider/aws-parameter-store/#controllers-pod-identity","title":"Controller's Pod Identity","text":"Note: If you are using Parameter Store replace service: SecretsManager
with service: ParameterStore
in all examples below.
This is basicially a zero-configuration authentication method that inherits the credentials from the runtime environment using the aws sdk default credential chain.
You can attach a role to the pod using IRSA, kiam or kube2iam. When no other authentication method is configured in the Kind=Secretstore
this role is used to make all API calls against AWS Secrets Manager or SSM Parameter Store.
Based on the Pod's identity you can do a sts:assumeRole
before fetching the secrets to limit access to certain keys in your provider. This is optional.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: team-b-store\nspec:\n provider:\n aws:\n service: SecretsManager\n region: eu-central-1\n # optional: do a sts:assumeRole before fetching secrets\n role: team-b\n
"},{"location":"provider/aws-parameter-store/#access-key-id-secret-access-key","title":"Access Key ID & Secret Access Key","text":"You can store Access Key ID & Secret Access Key in a Kind=Secret
and reference it from a SecretStore.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: team-b-store\nspec:\n provider:\n aws:\n service: SecretsManager\n region: eu-central-1\n # optional: assume role before fetching secrets\n role: team-b\n auth:\n secretRef:\n accessKeyIDSecretRef:\n name: awssm-secret\n key: access-key\n secretAccessKeySecretRef:\n name: awssm-secret\n key: secret-access-key\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in accessKeyIDSecretRef
, secretAccessKeySecretRef
with the namespaces where the secrets reside.
"},{"location":"provider/aws-parameter-store/#eks-service-account-credentials","title":"EKS Service Account credentials","text":"This feature lets you use short-lived service account tokens to authenticate with AWS. You must have Service Account Volume Projection enabled - it is by default on EKS. See EKS guide on how to set up IAM roles for service accounts.
The big advantage of this approach is that ESO runs without any credentials.
apiVersion: v1\nkind: ServiceAccount\nmetadata:\n annotations:\n eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/team-a\n name: my-serviceaccount\n namespace: default\n
Reference the service account from above in the Secret Store:
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: secretstore-sample\nspec:\n provider:\n aws:\n service: SecretsManager\n region: eu-central-1\n auth:\n jwt:\n serviceAccountRef:\n name: my-serviceaccount\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
for serviceAccountRef
with the namespace where the service account resides.
"},{"location":"provider/aws-parameter-store/#custom-endpoints","title":"Custom Endpoints","text":"You can define custom AWS endpoints if you want to use regional, vpc or custom endpoints. See List of endpoints for Secrets Manager, Secure Systems Manager and Security Token Service.
Use the following environment variables to point the controller to your custom endpoints. Note: All resources managed by this controller are affected.
ENV VAR DESCRIPTION AWS_SECRETSMANAGER_ENDPOINT Endpoint for the Secrets Manager Service. The controller uses this endpoint to fetch secrets from AWS Secrets Manager. AWS_SSM_ENDPOINT Endpoint for the AWS Secure Systems Manager. The controller uses this endpoint to fetch secrets from SSM Parameter Store. AWS_STS_ENDPOINT Endpoint for the Security Token Service. The controller uses this endpoint when creating a session and when doing assumeRole
or assumeRoleWithWebIdentity
calls."},{"location":"provider/aws-secrets-manager/","title":"AWS Secrets Manager","text":""},{"location":"provider/aws-secrets-manager/#secrets-manager","title":"Secrets Manager","text":"A SecretStore
points to AWS Secrets Manager in a certain account within a defined region. You should define Roles that define fine-grained access to individual secrets and pass them to ESO using spec.provider.aws.role
. This way users of the SecretStore
can only access the secrets necessary.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: aws-secretsmanager\nspec:\n provider:\n aws:\n service: SecretsManager\n # define a specific role to limit access\n # to certain secrets.\n # role is a optional field that\n # can be omitted for test purposes\n role: arn:aws:iam::123456789012:role/external-secrets\n region: eu-central-1\n auth:\n secretRef:\n accessKeyIDSecretRef:\n name: awssm-secret\n key: access-key\n secretAccessKeySecretRef:\n name: awssm-secret\n key: secret-access-key\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in accessKeyIDSecretRef
and secretAccessKeySecretRef
with the namespaces where the secrets reside."},{"location":"provider/aws-secrets-manager/#iam-policy","title":"IAM Policy","text":"Create a IAM Policy to pin down access to secrets matching dev-*
.
{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"secretsmanager:GetResourcePolicy\",\n \"secretsmanager:GetSecretValue\",\n \"secretsmanager:DescribeSecret\",\n \"secretsmanager:ListSecretVersionIds\"\n ],\n \"Resource\": [\n \"arn:aws:secretsmanager:us-west-2:111122223333:secret:dev-*\"\n ]\n }\n ]\n}\n
"},{"location":"provider/aws-secrets-manager/#permissions-for-pushsecret","title":"Permissions for PushSecret","text":"If you're planning to use PushSecret
, ensure you also have the following permissions in your IAM policy:
{\n \"Effect\": \"Allow\",\n \"Action\": [\n \"secretsmanager:CreateSecret\",\n \"secretsmanager:PutSecretValue\",\n \"secretsmanager:TagResource\",\n \"secretsmanager:DeleteSecret\"\n ],\n \"Resource\": [\n \"arn:aws:secretsmanager:us-west-2:111122223333:secret:dev-*\"\n ]\n}\n
Here's a more restrictive version of the IAM policy:
{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"secretsmanager:CreateSecret\",\n \"secretsmanager:PutSecretValue\",\n \"secretsmanager:TagResource\"\n ],\n \"Resource\": [\n \"arn:aws:secretsmanager:us-west-2:111122223333:secret:dev-*\"\n ]\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"secretsmanager:DeleteSecret\"\n ],\n \"Resource\": [\n \"arn:aws:secretsmanager:us-west-2:111122223333:secret:dev-*\"\n ],\n \"Condition\": {\n \"StringEquals\": {\n \"secretsmanager:ResourceTag/managed-by\": \"external-secrets\"\n }\n }\n }\n ]\n}\n
In this policy, the DeleteSecret action is restricted to secrets that have the specified tag, ensuring that deletion operations are more controlled and in line with the intended management of the secrets.
"},{"location":"provider/aws-secrets-manager/#additional-settings-for-pushsecret","title":"Additional Settings for PushSecret","text":"Additional settings can be set at the SecretStore
level to control the behavior of PushSecret
when interacting with AWS Secrets Manager.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: aws-secretsmanager\nspec:\n provider:\n aws:\n service: SecretsManager\n role: arn:aws:iam::123456789012:role/external-secrets\n region: eu-central-1\n secretsManager:\n # Additional parameters can be added to the AWS Secrets Manager DeleteSecret API call.\n # These parameters are only relevant when the deletionPolicy is set to Delete.\n # See: https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_DeleteSecret.html#API_DeleteSecret_RequestSyntax\n forceDeleteWithoutRecovery: true\n # recoveryWindowInDays: 9 (conflicts with forceDeleteWithoutRecovery)\n
"},{"location":"provider/aws-secrets-manager/#additional-metadata-for-pushsecret","title":"Additional Metadata for PushSecret","text":"It's possible to configure AWS Secrets Manager to either push secrets in binary
format or as plain string
.
To control this behaviour set the following provider metadata:
apiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\n name: pushsecret-example # Customisable\n namespace: teamb # Same of the SecretStores\nspec:\n deletionPolicy: Delete\n refreshInterval: 10s # Refresh interval for which push secret will reconcile\n secretStoreRefs: # A list of secret stores to push secrets to\n - name: teamb-secret-store\n kind: SecretStore\n selector:\n secret:\n name: my-secret # Source Kubernetes secret to be pushed\n data:\n - match:\n secretKey: key1 # Source Kubernetes secret key to be pushed\n remoteRef:\n remoteKey: teamb-my-first-parameter-3 # Remote reference (where the secret is going to be pushed)\n metadata:\n secretPushFormat: string\n
secretPushFormat
takes two options. binary
and string
, where binary
is the default.
"},{"location":"provider/aws-secrets-manager/#json-secret-values","title":"JSON Secret Values","text":"SecretsManager supports simple key/value pairs that are stored as json. If you use the API you can store more complex JSON objects. You can access nested values or arrays using gjson syntax:
Consider the following JSON object that is stored in the SecretsManager key friendslist
:
{\n \"name\": {\"first\": \"Tom\", \"last\": \"Anderson\"},\n \"friends\": [\n {\"first\": \"Dale\", \"last\": \"Murphy\"},\n {\"first\": \"Roger\", \"last\": \"Craig\"},\n {\"first\": \"Jane\", \"last\": \"Murphy\"}\n ]\n}\n
This is an example on how you would look up nested keys in the above json object:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example\nspec:\n refreshInterval: 1m\n secretStoreRef:\n name: aws-secretsmanager\n kind: SecretStore\n target:\n name: friends\n creationPolicy: Owner\n data:\n - secretKey: my_name\n remoteRef:\n key: friendslist\n property: name.first # Tom\n - secretKey: first_friend\n remoteRef:\n key: friendslist\n property: friends.1.first # Roger\n\n # metadataPolicy to fetch all the labels in JSON format\n - secretKey: tags\n remoteRef:\n metadataPolicy: Fetch \n key: database-credentials\n\n # metadataPolicy to fetch a specific label (dev) from the source secret\n - secretKey: developer\n remoteRef:\n metadataPolicy: Fetch \n key: database-credentials\n property: dev\n
"},{"location":"provider/aws-secrets-manager/#secret-versions","title":"Secret Versions","text":"SecretsManager creates a new version of a secret every time it is updated. The secret version can be reference in two ways, the VersionStage
and the VersionId
. The VersionId
is a unique uuid which is generated every time the secret changes. This id is immutable and will always refer to the same secret data. The VersionStage
is an alias to a VersionId
, and can refer to different secret data as the secret is updated. By default, SecretsManager will add the version stages AWSCURRENT
and AWSPREVIOUS
to every secret, but other stages can be created via the update-secret-version-stage api.
The version
field on the remoteRef
of the ExternalSecret will normally consider the version to be a VersionStage
, but if the field is prefixed with uuid/
, then the version will be considered a VersionId
.
So in this example, the operator will request the same secret with different versions: AWSCURRENT
and AWSPREVIOUS
:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: versioned-api-key\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: aws-secretsmanager\n kind: SecretStore\n target:\n name: versioned-api-key\n creationPolicy: Owner\n data:\n - secretKey: previous-api-key\n remoteRef:\n key: \"production/api-key\"\n version: \"AWSPREVIOUS\"\n - secretKey: current-api-key\n remoteRef:\n key: \"production/api-key\"\n version: \"AWSCURRENT\"\n
While in this example, the operator will request the secret with VersionId
as abcd-1234
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: versioned-api-key\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: aws-secretsmanager\n kind: SecretStore\n target:\n name: versioned-api-key\n creationPolicy: Owner\n data:\n - secretKey: api-key\n remoteRef:\n key: \"production/api-key\"\n version: \"uuid/123e4567-e89b-12d3-a456-426614174000\"\n
"},{"location":"provider/aws-secrets-manager/#aws-authentication","title":"AWS Authentication","text":""},{"location":"provider/aws-secrets-manager/#controllers-pod-identity","title":"Controller's Pod Identity","text":"Note: If you are using Parameter Store replace service: SecretsManager
with service: ParameterStore
in all examples below.
This is basicially a zero-configuration authentication method that inherits the credentials from the runtime environment using the aws sdk default credential chain.
You can attach a role to the pod using IRSA, kiam or kube2iam. When no other authentication method is configured in the Kind=Secretstore
this role is used to make all API calls against AWS Secrets Manager or SSM Parameter Store.
Based on the Pod's identity you can do a sts:assumeRole
before fetching the secrets to limit access to certain keys in your provider. This is optional.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: team-b-store\nspec:\n provider:\n aws:\n service: SecretsManager\n region: eu-central-1\n # optional: do a sts:assumeRole before fetching secrets\n role: team-b\n
"},{"location":"provider/aws-secrets-manager/#access-key-id-secret-access-key","title":"Access Key ID & Secret Access Key","text":"You can store Access Key ID & Secret Access Key in a Kind=Secret
and reference it from a SecretStore.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: team-b-store\nspec:\n provider:\n aws:\n service: SecretsManager\n region: eu-central-1\n # optional: assume role before fetching secrets\n role: team-b\n auth:\n secretRef:\n accessKeyIDSecretRef:\n name: awssm-secret\n key: access-key\n secretAccessKeySecretRef:\n name: awssm-secret\n key: secret-access-key\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in accessKeyIDSecretRef
, secretAccessKeySecretRef
with the namespaces where the secrets reside.
"},{"location":"provider/aws-secrets-manager/#eks-service-account-credentials","title":"EKS Service Account credentials","text":"This feature lets you use short-lived service account tokens to authenticate with AWS. You must have Service Account Volume Projection enabled - it is by default on EKS. See EKS guide on how to set up IAM roles for service accounts.
The big advantage of this approach is that ESO runs without any credentials.
apiVersion: v1\nkind: ServiceAccount\nmetadata:\n annotations:\n eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/team-a\n name: my-serviceaccount\n namespace: default\n
Reference the service account from above in the Secret Store:
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: secretstore-sample\nspec:\n provider:\n aws:\n service: SecretsManager\n region: eu-central-1\n auth:\n jwt:\n serviceAccountRef:\n name: my-serviceaccount\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
for serviceAccountRef
with the namespace where the service account resides.
"},{"location":"provider/aws-secrets-manager/#custom-endpoints","title":"Custom Endpoints","text":"You can define custom AWS endpoints if you want to use regional, vpc or custom endpoints. See List of endpoints for Secrets Manager, Secure Systems Manager and Security Token Service.
Use the following environment variables to point the controller to your custom endpoints. Note: All resources managed by this controller are affected.
ENV VAR DESCRIPTION AWS_SECRETSMANAGER_ENDPOINT Endpoint for the Secrets Manager Service. The controller uses this endpoint to fetch secrets from AWS Secrets Manager. AWS_SSM_ENDPOINT Endpoint for the AWS Secure Systems Manager. The controller uses this endpoint to fetch secrets from SSM Parameter Store. AWS_STS_ENDPOINT Endpoint for the Security Token Service. The controller uses this endpoint when creating a session and when doing assumeRole
or assumeRoleWithWebIdentity
calls."},{"location":"provider/azure-key-vault/","title":"Azure Key Vault","text":""},{"location":"provider/azure-key-vault/#azure-key-vault","title":"Azure Key vault","text":"External Secrets Operator integrates with Azure Key vault for secrets, certificates and Keys management.
"},{"location":"provider/azure-key-vault/#authentication","title":"Authentication","text":"We support authentication with Microsoft Entra identities that can be used as Workload Identity or AAD Pod Identity as well as with Service Principal credentials.
Since the AAD Pod Identity is deprecated, it is recommended to use the Workload Identity authentication.
We support connecting to different cloud flavours azure supports: PublicCloud
, USGovernmentCloud
, ChinaCloud
and GermanCloud
. You have to specify the environmentType
and point to the correct cloud flavour. This defaults to PublicCloud
.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: azure-backend\nspec:\n provider:\n azurekv:\n # PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud\n environmentType: PublicCloud # default\n
Minimum required permissions are Get
over secret and certificate permissions. This can be done by adding a Key Vault access policy:
KUBELET_IDENTITY_OBJECT_ID=$(az aks show --resource-group <AKS_CLUSTER_RG_NAME> --name <AKS_CLUSTER_NAME> --query 'identityProfile.kubeletidentity.objectId' -o tsv)\naz keyvault set-policy --name kv-name-with-certs --object-id \"$KUBELET_IDENTITY_OBJECT_ID\" --certificate-permissions get --secret-permissions get\n
"},{"location":"provider/azure-key-vault/#service-principal-key-authentication","title":"Service Principal key authentication","text":"A service Principal client and Secret is created and the JSON keyfile is stored in a Kind=Secret
. The ClientID
and ClientSecret
should be configured for the secret. This service principal should have proper access rights to the keyvault to be managed by the operator
"},{"location":"provider/azure-key-vault/#managed-identity-authentication","title":"Managed Identity authentication","text":"A Managed Identity should be created in Azure, and that Identity should have proper rights to the keyvault to be managed by the operator.
Use aad-pod-identity to assign the identity to external-secrets operator. To add the selector to external-secrets operator, use podLabels
in your values.yaml in case of Helm installation of external-secrets.
If there are multiple Managed Identities for different keyvaults, the operator should have been assigned all identities via aad-pod-identity, then the SecretStore configuration should include the Id of the identity to be used via the identityId
field.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: azure-store\nspec:\n provider:\n # provider type: azure keyvault\n azurekv:\n authType: ManagedIdentity\n # Optionally set the Id of the Managed Identity, if multiple identities are assigned to external-secrets operator\n identityId: \"<MI_clientId>\"\n # URL of your vault instance, see: https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates\n vaultUrl: \"https://my-keyvault-name.vault.azure.net\"\n
"},{"location":"provider/azure-key-vault/#workload-identity","title":"Workload Identity","text":"In Microsoft Entra, Workload Identity can be Application, user-assigned Managed Identity and Service Principal.
You can use Azure AD Workload Identity Federation to access Azure managed services like Key Vault without needing to manage secrets. You need to configure a trust relationship between your Kubernetes Cluster and Azure AD. This can be done in various ways, for instance using terraform
, the Azure Portal or the az
cli. We found the azwi cli very helpful. The Azure Workload Identity Quick Start Guide is also good place to get started.
This is basically a two step process:
- Create a Kubernetes Service Account (guide)
azwi serviceaccount create phase sa \\\n --aad-application-name \"${APPLICATION_NAME}\" \\\n --service-account-namespace \"${SERVICE_ACCOUNT_NAMESPACE}\" \\\n --service-account-name \"${SERVICE_ACCOUNT_NAME}\"\n
2. Configure the trust relationship between Azure AD and Kubernetes (guide) azwi serviceaccount create phase federated-identity \\\n --aad-application-name \"${APPLICATION_NAME}\" \\\n --service-account-namespace \"${SERVICE_ACCOUNT_NAMESPACE}\" \\\n --service-account-name \"${SERVICE_ACCOUNT_NAME}\" \\\n --service-account-issuer-url \"${SERVICE_ACCOUNT_ISSUER}\"\n
With these prerequisites met you can configure ESO
to use that Service Account. You have two options:
"},{"location":"provider/azure-key-vault/#mounted-service-account","title":"Mounted Service Account","text":"You run the controller and mount that particular service account into the pod by adding the label azure.workload.identity/use: \"true\"
to the pod. That grants everyone who is able to create a secret store or reference a correctly configured one the ability to read secrets. This approach is usually not recommended. But may make sense when you want to share an identity with multiple namespaces. Also see our Multi-Tenancy Guide for design considerations.
apiVersion: v1\nkind: ServiceAccount\nmetadata:\n # this service account was created by azwi\n name: workload-identity-sa\n annotations:\n azure.workload.identity/client-id: 7d8cdf74-xxxx-xxxx-xxxx-274d963d358b\n azure.workload.identity/tenant-id: 5a02a20e-xxxx-xxxx-xxxx-0ad5b634c5d8\n---\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: azure-store\nspec:\n provider:\n azurekv:\n authType: WorkloadIdentity\n vaultUrl: \"https://xx-xxxx-xx.vault.azure.net\"\n # note: no serviceAccountRef was provided\n
"},{"location":"provider/azure-key-vault/#referenced-service-account","title":"Referenced Service Account","text":"You run the controller without service account (effectively without azure permissions). Now you have to configure the SecretStore and set the serviceAccountRef
and point to the service account you have just created. This is usually the recommended approach. It makes sense for everyone who wants to run the controller without Azure permissions and delegate authentication via service accounts in particular namespaces. Also see our Multi-Tenancy Guide for design considerations.
apiVersion: v1\nkind: ServiceAccount\nmetadata:\n # this service account was created by azwi\n name: workload-identity-sa\n annotations:\n azure.workload.identity/client-id: 7d8cdf74-xxxx-xxxx-xxxx-274d963d358b\n azure.workload.identity/tenant-id: 5a02a20e-xxxx-xxxx-xxxx-0ad5b634c5d8\n---\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: azure-store\nspec:\n provider:\n azurekv:\n authType: WorkloadIdentity\n vaultUrl: \"https://xx-xxxx-xx.vault.azure.net\"\n serviceAccountRef:\n name: workload-identity-sa\n
In case you don't have the clientId when deploying the SecretStore, such as when deploying a Helm chart that includes instructions for creating a Managed Identity using Azure Service Operator next to the SecretStore definition, you may encounter an interpolation problem. Helm lacks dependency management, which means it can create an issue when the clientId is only known after everything is deployed. Although the Service Account can inject clientId
and tenantId
into a pod, it doesn't support secretKeyRef/configMapKeyRef. Therefore, you can deliver the clientId and tenantId directly, bypassing the Service Account.
The following example demonstrates using the secretRef field to directly deliver the clientId
and tenantId
to the SecretStore while utilizing Workload Identity authentication.
apiVersion: v1\nkind: ServiceAccount\nmetadata:\n # this service account was created by azwi\n name: workload-identity-sa\n annotations: {}\n---\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: azure-store\nspec:\n provider:\n azurekv:\n # tenantId spec option #1\n tenantId: \"5a02a20e-xxxx-xxxx-xxxx-0ad5b634c5d8\"\n authType: WorkloadIdentity\n vaultUrl: \"https://xx-xxxx-xx.vault.azure.net\"\n serviceAccountRef:\n name: workload-identity-sa\n authSecretRef:\n clientId:\n name: umi-secret\n key: clientId\n # tenantId spec option #2\n tenantId:\n name: umi-secret\n key: tenantId\n
"},{"location":"provider/azure-key-vault/#update-secret-store","title":"Update secret store","text":"Be sure the azurekv
provider is listed in the Kind=SecretStore
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: azure-store\nspec:\n provider:\n # provider type: azure keyvault\n azurekv:\n # azure tenant ID, see: https://docs.microsoft.com/en-us/azure/active-directory/fundamentals/active-directory-how-to-find-tenant\n tenantId: \"2ed1d494-6c5a-4c5d-aa24-479446fb844d\"\n # URL of your vault instance, see: https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates\n vaultUrl: \"https://kvtestpushsecret.vault.azure.net\"\n authSecretRef:\n # points to the secret that contains\n # the azure service principal credentials\n clientId:\n name: azure-secret-sp\n key: ClientID\n clientSecret:\n name: azure-secret-sp\n key: ClientSecret\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in clientId
and clientSecret
with the namespaces where the secrets reside. Or in case of Managed Identity authentication:
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: azure-store\nspec:\n provider:\n # provider type: azure keyvault\n azurekv:\n authType: ManagedIdentity\n # Optionally set the Id of the Managed Identity, if multiple identities are assigned to external-secrets operator\n identityId: \"<MI_clientId>\"\n # URL of your vault instance, see: https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates\n vaultUrl: \"https://my-keyvault-name.vault.azure.net\"\n
"},{"location":"provider/azure-key-vault/#object-types","title":"Object Types","text":"Azure Key Vault manages different object types, we support keys
, secrets
and certificates
. Simply prefix the key with key
, secret
or cert
to retrieve the desired type (defaults to secret).
Object Type Return Value secret
the raw secret value. key
A JWK which contains the public key. Azure Key Vault does not export the private key. You may want to use template functions to transform this JWK into PEM encoded PKIX ASN.1 DER format. certificate
The raw CER contents of the x509 certificate. You may want to use template functions to transform this into your desired encoding"},{"location":"provider/azure-key-vault/#creating-external-secret","title":"Creating external secret","text":"To create a Kubernetes secret from the Azure Key vault secret a Kind=ExternalSecret
is needed.
You can manage keys/secrets/certificates saved inside the keyvault , by setting a \"/\" prefixed type in the secret name, the default type is a secret
. Other supported values are cert
and key
.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: database-credentials\nspec:\n refreshInterval: 1h\n secretStoreRef:\n kind: SecretStore\n name: azure-store\n\n target:\n name: database-credentials\n creationPolicy: Owner\n\n data:\n # name of the SECRET in the Azure KV (no prefix is by default a SECRET)\n - secretKey: database-username\n remoteRef:\n key: database-username\n\n # explicit type and name of secret in the Azure KV\n - secretKey: database-password\n remoteRef:\n key: secret/database-password\n\n # metadataPolicy to fetch all the tags in JSON format\n - secretKey: database-credentials-metadata\n remoteRef:\n key: database-credentials\n metadataPolicy: Fetch\n\n # metadataPolicy to fetch a specific tag which name must be in property\n - secretKey: database-credentials\n remoteRef:\n key: database-credentials\n metadataPolicy: Fetch\n property: environment\n\n # type/name of certificate in the Azure KV\n # raw value will be returned, use templating features for data processing\n - secretKey: db-client-cert\n remoteRef:\n key: cert/db-client-cert\n\n # type/name of the public key in the Azure KV\n # the key is returned PEM encoded\n - secretKey: encryption-pubkey\n remoteRef:\n key: key/encryption-pubkey\n
The operator will fetch the Azure Key vault secret and inject it as a Kind=Secret
. Then the Kubernetes secret can be fetched by issuing:
kubectl get secret secret-to-be-created -n <namespace> -o jsonpath='{.data.dev-secret-test}' | base64 -d\n
To select all secrets inside the key vault or all tags inside a secret, you can use the dataFrom
directive:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: all-secrets\nspec:\n refreshInterval: 1h # rate ESO pulls Azure Key Vault\n secretStoreRef:\n kind: SecretStore\n name: azure-store # name of the SecretStore (or kind specified)\n target:\n name: all-secrets # name of the k8s Secret to be created\n creationPolicy: Owner\n dataFrom:\n # find all secrets starting with dev-\n - find:\n name:\n regexp: \"^dev\"\n # find all secrets with tags\n - find:\n tags:\n environment: dev\n\n # extract data from a json value\n - extract:\n key: database-credentials\n\n # fetch tags from `database-credentials`\n # and store them as individual keys in a secret\n - extract:\n key: database-credentials\n metadataPolicy: Fetch\n
To get a PKCS#12 certificate from Azure Key Vault and inject it as a Kind=Secret
of type kubernetes.io/tls
:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: tls-client-credentials\nspec:\n refreshInterval: 1h\n secretStoreRef:\n kind: SecretStore\n name: azure-store\n target:\n template:\n type: kubernetes.io/tls\n engineVersion: v2\n data:\n tls.crt: \"{{ .tls | b64dec | pkcs12cert }}\"\n tls.key: \"{{ .tls | b64dec | pkcs12key }}\"\n data:\n - secretKey: tls\n remoteRef:\n # Azure Key Vault certificates must be fetched as secret/cert-name\n key: secret/tls-client-credentials\n
"},{"location":"provider/azure-key-vault/#creating-a-pushsecret","title":"Creating a PushSecret","text":"You can push secrets to Azure Key Vault into the different secret
, key
and certificate
APIs.
"},{"location":"provider/azure-key-vault/#pushing-to-a-secret","title":"Pushing to a Secret","text":"Pushing to a Secret requires no previous setup. with the secret available in Kubernetes, you can simply refer it to a PushSecret object to have it created on Azure Key Vault:
apiVersion: v1\nkind: Secret\nmetadata:\n name: source-secret\nstringData:\n source-key: \"my-secret\"\n---\napiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\n name: pushsecret-example\n namespace: default\nspec:\n refreshInterval: 10s # Refresh interval for which push secret will reconcile\n deletionPolicy: Delete\n secretStoreRefs: # A list of secret stores to push secrets to\n - name: azure-store\n kind: SecretStore\n selector:\n secret:\n name: source-secret # Source Kubernetes secret to be pushed\n data:\n - match:\n secretKey: source-key # Source Kubernetes secret key containing the secret\n remoteRef:\n remoteKey: my-azkv-secret-name \n
Note
In order to create a PushSecret targeting keys, CreateSecret
and DeleteSecret
actions must be granted to the Service Principal/Identity configured on the SecretStore.
"},{"location":"provider/azure-key-vault/#pushing-to-a-key","title":"Pushing to a Key","text":"The first step is to generate a valid Private Key. Supported Formats include PRIVATE KEY
, RSA PRIVATE KEY
AND EC PRIVATE KEY
(EC/PKCS1/PKCS8 types). After uploading your key to a Kubernetes Secret, the next step is to create a PushSecret manifest with the following configuration:
apiVersion: v1\nkind: Secret\nmetadata:\n name: source-key\ndata:\n tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlKSndJQkFBS0NBZ0VBcTRJTEFXRkZRdXNCMTFtYk1FQ2ZSRjh2WUJWeVhqYmFBczN5SE5RWXBNbUNWNkt0CmxKOVcrMlRMRUc3WnlhN1hwTGNuTlc1QWtOM3FrYW1zWGNiV0dLMUZIK3BKcXlKK2RkaktrMjlXa1RHYnV2THgKdkNWSGp6cndPN0NFdTVGWmIvV2NxcjMzb2l4YWdwNlBFYVZKR0t6U3hJaFMvZDlXR1JuN0MySnhKRnlaWlBLWgpYY01KOEg0TmZ5UDcrWjVZTjJMaWQ4eWdWUlpDWXgzQktadXdsQmdwMkpjMmpkN0x4WmQrYmx3REdGUEw4VHpPCk5LZjFRT2JndmdWY2E4M0NWVTJLZ3p0R0M0YVhkVDR3TkYrV25Hdmgza1JrVlBqMDRsbms4Z001M0ZJZ0dJV2oKalphRVd2b2RBMFJSWEtwL3IyMFI4aFRRNXlZMGJ4ejVSQVJyTEdkY1BlejRJY3FSZG5nUm10VldkQ29ZMzZNMgphdE9HRnNPd0ZCbEpuRVhUY0dxWXlnbnZYQlVzVXRNSmdYY3pDWlB1czlTODZtTGxjajlZK3BNb3FSY0NpMCtOCjBtd3VvNUt3dG1tSjBURnBXR3RLS0VSVUpOZkduNWIxekZrWGxsZSt5ODMzMkN2Nk9yWXNCemNya0pFOGJHRmUKTytZY1lqYytGblJpN3JhWXpwTzRReDJ5dzUxSGRScis3aldxNnFrejEzUlZya3hSQ1NFVW5wbVE1M0RvSTZjWgpDakN0UjZWZ3VVY0xnYndFM2w0dlluV0VXMHVNNmZjenlQem1LVis5M0RFd1U4Q3pXR09neTJrNjBYcmx2YkJwCjYrbFdlZVZnNzJJZjZEb0oyVFZZQStFZUpOWDBpaHVUTmpDNmk3VVZYdm5KRWNhSnFTRXE1QTY4OUs4Q0F3RUEKQVFLQ0FnQWN3S2x0cXN2OHd2OUZCaDJ4UWpReE55L3ZFTWxpcUJsMmZPWkpGUG1vcnF1dVczUjBSUjVFK1FuZQpFR2RzbTJaRmsvcjd4eWNGNGw1UDJ6MHRYNGRIRGMxWDQyUkVUMzBaN3FWUGdFdm4vWVFaSEYrUVprT1A3SmFYCnV5a1ZkUEdraG0ya1prS2Nxb2psK3dVTE5VV0M0SDVaT20ySGFDaTcvcElLdjQ4dVJHUG0rNURnbWpFUlkyQ0oKM3hPQUxwNmxjbXQ3SUJBRkU3MC9kcDZLaGpKZE1ZdmFac2RiazIxZ0M5ekRUYU9yTVdrd1lUeEVzWis1S0x1bQp2NmxWM1dIbUFTRG1qVXBaNWs5LzlWUUpnN2p4TWxqa2RWeklyaEFIM29BMlhub1Z5S0xlMlpDb3pRSVZhbmJ3CnRFUmJuNjNXVUJmQkdPSkl6aXZlTU9KTkY5eUxoOTBrWmszaDR0N3dqWFNodUR2SGp2ZmVaVzhjOStTVTh3VlUKTlRZQzUxaHFKYXNDdWdHa0NVZGp3V0pucXc4QU1VNGZFQkM0V1JBRWpKMTdYMDVJNmt3c2V2ZVRrNjlmOTNWSgoxS3ZVcmpKTkNpeVVXVWVzc0lrWllacGxJZnYrbExJUWNrTmVpOFdRRjV0RTh0Z09heHJLZXBWMW81NlkvT2tUCmFyYjg1Z2VYb0Z0Tm9NMUd6TkxqQnQrZ2pIY2owcExZakZ5L2Jsa2ZrZnRNMW1hN0U3L3ROK0d2bHBhQXE3RUcKNTc3a2xoNXJGWGQza09meVY1U3E3cmFQWDRZOWlPSU5EaXBVblpXcENHYjRHQS8wSFozdWpacTB6SlQ4Z0NyaQpSQndBRFBVY0J0UzYxUzE0WjJhU0Q1R1NKUmFHbFNGdVRoY1lxR0MrK08xcTllbkRpUUtDQVFFQTJjN21EN2FvClRlcExYRklWMzU0Zk5QTFhGYm9JSXZPZHhLVnYvR25NajZhMVhCd3RPdWhlQTlmNlhacUY2ZXViVmtLK1ZobWgKR1k5dm5nWHd2ZHBiZTIzdmN5d2duYWxTSDVYRGZnaE9LZU5ZMDJSYnhtWlVTMEtvWGRhSStHVDA3QWN6ZFFkaQpMRnBYTWtybmQwZC9taHZGNkVxN0t0Mkw2YkVoSXptQU5sTWMyY1lBeEIwY0UzRjJLQTNqV3dyQjRuMUZrRTlQCnMzby9tbmVXNEswMVlMVEsyMGhPOTlNeG5oNzNTV1h1SWFXdlI3T1pRcHFEMWFtYXBGUGlqY0RlRVpQczVUMFIKNEk3aVczNWF4YTl5WncxSkYrMTV5aEhkTTNHZllGaXJudy8zRlpQL282RzBJeW50YUZLNkFGU0dIaHpMcEs1awphSWRMYWVBbWlMYnpmUUtDQVFFQXlaVExET1h5V2VTZjUwV0oxUzVtTHJDMVJUNUI4K1dvZzhiVSsvSWxZTjF6Cm82eTM2QkVJcTlMWGhUUTl6cGp0MlcwNTRHa3FjU1hKcTJtajFHSEE5Q3FCTGNTaldyNHR6ZHFXTzREcnoxN0gKVCtpaEZqZ016R2praXhNSlpkZ2JoWGprQ3RkVEMzdGJhaFBiNjN4TjJGM0d6aE8xRmRUVWZ6bXM3WkVzWmRhYgpTaFZaaUFBOU40dnpmYWYyZ3I2SlB2azZwbEdpV2hvT2xkclRvVG4zSFRPNGJNYWJxc20vSFNTU2FyNUtXTUlXCnZlSVN4YjFoQTFIL1dTMXcvN1dqVHJ1UUZqWDRtU1BkT2lqL3hZblVWWjcrTjhLN3VKREJZNjcrWXVNM2RQNHgKdUJ2RjcvdDdwd3g0b002QnhBbGpQZExwZ2dxRFFLb3drVk9reFZ3b213S0NBUUJJS0pOdmdVUWhEQTRMZCtabgpQeXQzanp4U3BsOHJ0U24vakErZHdDOVZLQlhOZmtnOXk5M1p5Q1BaL3VkK3A5KytwRDRLcUZNRzlNNDF2Q0lWCnc5R3JBckRocHl6bkRzRjJWVmQrMmFHTG54WStjbkUxT1pHVG5YSEtKTmtiOGRaeW03QWdoV0d3Ny8wVFhGMXkKMXUwZlVUUXYwUkpSRVRUWkp5V2pWZGwwSmZUWThSQXY2TFQwZkJKNUVxRFArTEJqS0wxeklkTjEwbnBmNGw3Sgo4SmhPZ1piekx2RjZpUzFYQlV0SHRjMCt1SFZwZThhNm1oWXpJdzFvZzZINjlIcWR1RFF6ZmhmK0hWaEFsNHZiCkVsVUVieEpZS3dTK1BVemJUamxPNGhGNWtRQjYxWjFMeUxhMUw1N0hnU0MrRzBLVGwxYWdLR1o3ZXRjeExHR1gKeVlUQkFvSUJBRms2NWc3VmtzdTc2aFJqc2JtT0NtbE1pMUVWVi9od2hvR2VlQlQyZ1JrNXJjQ2I2ZVJ0OWRxcApRQUdVdUc5RlByUHFKNTV3cnZyYThVUlJSTlgwVjRjOWNXVWpEL1JSRHRGNm10bklIWm56cUdKMDVTbUNzaGVoCnJ0anBHbFhjcllJTm0xUTVNR2Q2dVdKaFhBNEhQaVl5akpnWUhTYUd5WEZ2eEY1OHpweGR2T3UwTzZkNkE1OGMKOGpHRE1obDU0aUxnQzlnbmRxaFB0SGtkSG1UVjFjODFYOE8ydnAyQkpIbndBR2dEeDhFMldQN0FuZkt0KzgyTwpkR3V6TTd2ZFdXYTJtL2RZK0t4Qk5lSlMxN1ZIWjVobkFyMElGRFNFenpZaTlqUXJ4QmFqbHJxYWdLblVOazRoCnRSdnBqWU9MYkVTbm9mbVFVYjFFR0srYnlPb2IrMVVDZ2dFQUJJTFZ0eVV6cFNobW1FN0crZ3I0aGpBb0UxQlgKTDd2SHVIbGdrMStNbFR6RlNLZXpZUDY4RnFsRjRocEFRT2kxTnN3Sy9zaXppdGEycUdUUDJyd1d3NkJUUW9wawplbkdDaEtWNUp0SHRBeDZ2bEZ0aUxUVzE5QTlvUXZEbEllYmNsaFRob2ZWeHV0NFI4RC8vSXZRQXRxbm5jUFFuCnZ5RzRUakl4VCtsWDZqcXdHbUlwRVI4TlpLdjVXU2EzOVVNdlF0ZUJ3Q1hUZEF6Wnlqc0RjRENodlJVRno3S2YKNVlMZ1pVdEt2cEZnbVNYNGF0b2t1TCt5Nm9LYm93Tld6bVdhNzhHbzRLUlhGK2xxUk5OL0dTM0lkM01MdDNmKwovLzRvcWNZa1lyU0dEbjJPenRabGpFcjFrK0NCQ0Rvc3pFMms2b2ZmN2pBck1YUG5McUVXQXkrWDdBPT0KLS0tLS1FTkQgUlNBIFBSSVZBVEUgS0VZLS0tLS0K\n---\napiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\n name: pushsecret-example\n namespace: default\nspec:\n refreshInterval: 10s # Refresh interval for which push secret will reconcile\n deletionPolicy: Delete\n secretStoreRefs: # A list of secret stores to push secrets to\n - name: azure-store\n kind: SecretStore\n selector:\n secret:\n name: source-key # Source Kubernetes secret to be pushed\n data:\n - match:\n secretKey: tls.key # Source Kubernetes secret key containing the JWK\n remoteRef:\n remoteKey: key/my-azkv-key-name\n
Note
In order to create a PushSecret targeting keys, ImportKey
and DeleteKey
actions must be granted to the Service Principal/Identity configured on the SecretStore.
"},{"location":"provider/azure-key-vault/#pushing-to-a-certificate","title":"Pushing to a Certificate","text":"The first step is to generate a valid P12 certificate. Currently, only PKCS1/PKCS8 types are supported. Currently only password-less P12 certificates are supported.
After uploading your P12 certificate to a Kubernetes Secret, the next step is to create a PushSecret manifest with the following configuration
apiVersion: v1\nkind: Secret\nmetadata:\n name: source-certificate\ndata:\n cert.p12: MIIQZgIBAzCCECwGCSqGSIb3DQEHAaCCEB0EghAZMIIQFTCCBi8GCSqGSIb3DQEHBqCCBiAwggYcAgEAMIIGFQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQIl69kTzb7QegCAggAgIIF6IOxs3Cr7vl4eT2/YdPNuVoadkQUMO6P5Ad6iuLvY7cDU7D9DO/cga/BVO0/OSIYXgTzbOg3KhreFUcoCTWne7/rbByYi6RHt2AjcZbs6CC6lTraRp5NzppfLGUUAX7v4BR93q55mB0H/j+FNx4QWhgC7sEjSawdvmeNyi+5IrCib0xDYqQ8AvN/g5Vhhp8nAqChx+1n26tRaDh7ULAY+/7D2ffG+gXHNxYn5tM7DGrcCW1FZtEqF53XVzbtyqAqtiWvSyXWYc9CyDN2mqfVG50BDAVGJT3SvuqCs7VO1w8Gs3LbT/eHRfczt2yjVZMLemVuMgHJ6Z3C1W5KjcFRsAhGLzi63d2rj091OnzhWP5YX0QrsAxgLYVeszhsq2GIb/vqIDubwawN0lZQk/guTFRAtcBMb+WDfzqJNPjOElz63/ugxNPTslWNyB7FpNWAtRxjT7qYB28JqnA8nepbzuQc/PZYPcuNFcZJD5YKE0aAhQEgaVOT0ygFdp+/VQ9LsfHgn2AVtsAmDUbt2UaXfyDDwLH19hVs6YPnYGNFiOSRBoTIgCzBreUeo3d/tJ8Ha4CA1TXrdisOGcqO9vszf8bXqgCQQzLl8lxAKZgCYCRoBF9TMkK/4IZ6NeEdxuO4hDhm6bbapIlVw5KsmqPk5i0wYT9TebH6aPyMT4OtYgVdZmTXI8RfkjduKjVxyEDIiX776yTZS0H8F0KtzJdfxX9euwneVg8ap9/7zEZNqfrtj8BGY/12LsXowExbeGLuyb+cgW8F83Pszyilc/EOrXzJOrmEwu3c/fIm93+NhZSoeZ5NwbkhUjOn0qox//FPZF8eSOFkB8Br5gnLuyFl41cOQ0rpVOI0Byz5TFhP4gQ1hH6AuAhRMdGhDWmg4Vot0CAOr3vthbBn/b9B7QQY23UzKlgeog9McrvJ1leM1Jeyl6Az/8tGFJTN7gIZNq91tKuV3bLqLvl6yCKGChy3Hrik+WJFvoaMwLsX38ljgYUYV/+d6gP0Oe87u+9pQ7xnZPaUJ8EJDA3KtFuagfNC2O/F/kZU2KV1Z4Q+3SDZ6O2KGbQestO9BYz/AZAiIfw0qw1Rb0ilskByXH0CLT3FxrefUDMGa57vxQOBeIpJXk91LCg5YDuZ/a8pcnII2dQrXfB+6rK/3fxQdZhliV8KSvQenyw6ZoVqwK+Z1nS1htikfOf3UW/KXHfGsX9L+cS2CA8IaA5EZAZS/boeXxt2ke16LNj2jlfxK8LX051MJ1sTM0I5K9hIp0oNaAKhTmdpWzudbGRRwtZJVhPOaUG4MHaTmrFNQLqOFtUvUDPl6w31fX4LQcPrZncrEahKPoq9vD9AqFvoI+Ku1hfuO+6/pB88fcE/eRtUU824nWB5EU9T7LOQim36fjZrYYAgBZbmwqiERGV68ILnpARbyaA/B/Sj4pIFYmPHo7mhhVWjz8o08QQC3zC4z5R3xisFb/67OCUqxk+ouI0mrM93IBzWVG1INTmmEvz3neeSlSNuUwj40hDOeKaUkUnQCsJWZy9Bx9yIeYfPVhE9GM57qkmzTKnJhM3cCSZEaZuXzvkut6rb7mkorfRI2pMFSK4TjWe743L7TWYXspMtRHe++nsNweZNQCniYvI+S6hVe8GYwbCMxRue+f57I3rBBdcKmBn2npTOcX/5fwYMCgjYEIJdWZZBSXhqEYw2ZEwU2rNvWXpGFcp5cPYwpKWjiD5GpL3eXOTj7Q5u9UHQWhMUQN7Lt/d6Fd9bsoTBhQlRnU6Xe4fdHtCyBMYTjyygqSfa/8XZUp+tZ2tX3zBxCYdw3bepOw4o7skUbqpKKGW0hjEoNgeoB8EFszeM48IY7M75CQY3adFqFzcG+XnTg5K5dJUihcCgn7LwWE1pu8mQTk8FjNkfJjD51Bv/YfEoPTa1XPDumIRZwSJO47mUOdVjg+qUzp3mRz6Gs4/1EJBfTOk3vLkpMUx/YutbzUD6sUZNa8PgICVPEapPbZHQdO/0LgD6DQi2kUsHuhiE2zCCCd4GCSqGSIb3DQEHAaCCCc8EggnLMIIJxzCCCcMGCyqGSIb3DQEMCgECoIIJbjCCCWowHAYKKoZIhvcNAQwBAzAOBAiVo1C5uK6CRwICCAAEgglIfhBryp3NDqqoOhAcaoKj2X2JXamh8KKk7vDW62QfYJVtormTKdnEXHE9f67ZfiB6ippsiTH1Sp1uFWirfiaBb0WhYjoQcUY6vry9Zb/GUd0NnyXnIz6WILFPfE9KC8v1Eo+pxOVj0qRWmf+CGrZCtZbi479k44/aCacBwrut8DaSuaTf9rDc3dgZj1ESYBINkBDXwm0lm/mpObhDbyaoL6+uwloM/EhE8VrtYmZLQ8781EuD6XVfem1GMuHCPiQBL8/23hze2yyB3NnjQzEcC9RLw2yPilWmB+PjfDUzIaCnOty6OUINZZqJ6ivoaA3qS8xh+kZTiCmAlHW/+5RyYXUL/c1bvlBMZz6z9n3lXBjnee3kRVbrQV/aa+069Nd76Mi8WBXhsjkm3+K14fuJksg1x3NohcL3/kW/iYHBXBFug2w6wX8l1T3XcxekBKDDNDfoy/ZExmDmsDAmUfIWb4zonLlaGq6z/9l3LkjrNS9/7C2YYEmh0xmMGD0mjzj1k932LWzvLdPaEIZTm2YsoI4TyraKc2yjXmmQWldGeN4yB/s0RfoaxPrMjkQsO6ZaU+gPqucd0JjL/e9gDVUWB0CL6Wy1T+H60iWBQhj0h5PoXuIbsocVj9PC08zniXmXUiVvbt62AyPm7oYci8BXJIc18WQ/BcO1EzPbQCVqI8DMWkyVCN/XUR7Oufseib//qZyf5XOSqwTHaetWU5tsIVKHcU8vzwPHqiDrFRmkBvn8pmtaQibaartr1XmiTCCkRX5yCzstbWWhjnRB/UD1zTxiMQUEmkmFD3zldLYuXWaaQNpNExog7vyJSMLUuTpff68sElBTRUA5pqqiVua5VsorzWaVMORsdagii4iJ/KQDoSs3KLZ6tXqNHBxoP69Mf6WJF8LZ+3FyYr+Ckpii2zgxx7D274fK6XfQpTS1yxeJPTxPZoEEZs9G03UKkrfi3Uv106akNB4XyAMxsyK26GTbKGkSig1C2gme/oCJfG8ZYin8hhl6QTlGk4ao2RWXT8Rh+qW6PDm+SVA4WJl9NI/eJwEtjmE2U1nt0IfkNy2miug3rHbr1yso4gnfdQUtMsHz055y7GgauJKADGa7N2dUdq7jbK4rbD59QsloYKpkN0TX2g86APMuMlHai33A942bsFnp+IC4ONHpj+LQZHgbr1ygVhI6EQs+x6OAw/0UrEq8fP0KVJBZHR96GJZHGCkVy6z+FVlRGTw4Lgb+dMpjucJeLQw852TLN3zHKsCglsygzGf6dfZhHs4o0tB+NyWr4Pgw/F8n3iXhTQCv95fHoTz9lav/LU1KTxADPhgczNUE6e2zrfZ0724d+eBOZXPY5endc+t2Kci+O2S2xS3XDxt4GDEWEogy6kjQoObjaHEoiOUcplbTfgptpXseivK1y3DU3gJPbNYTE8qJIOnFDwUxYDGYjlUH9h+SguCeRkO8sR5iQrYsjQQbDcPxss3rg6DeytcnsFwKf8bE/mwOpzHOE9CMrWuOoPrmtn7Lad7aTn1YN3hyeaHHVVAWzsbOyhhvEmsX5pifM26ZF57cabEiOU3itt5cYI9qxb90V4hc69NgfONx89RtrgsXd61rIsf8CeQDx3rQmQWZ54Pb0o5WUMnCbui/Z5Nw4RjeKdl38josYB3VZCXBz7g1y3ZWZUpl8GTn6TUZGXtXw8e4g18RJxpgt5OC3d27jY4fsDrVlUlYuZV21fbOG/MyT1YKQvNZlazpNPXXXyHK+Swj+A3H4It0K7IhM4R5+riH3ngcgbtF3M3StIM4lT5KVA84CRUWmDPIUskNbTUJWLw3nhDa5mmgCC9eRrb724leAFWG/FAvlsXmMl5BWWm5KYynu+y0pNpDbLmNNP6PlEBi9Ipms51BaUbQa2Y+LbFXj7dm4MBl07qroxQTOAu/DmUrxkBXU0ElpYhYrYoGbODuH/fD0C2KOJ5d6O8jRg3nN0228A2wrd18p47Q63mHyJlezxKI69o1Um6FNUjTtk6KU1Zp0AtW4mE5jkdKLfRNhlDPrgZAeYoT3OFU9UaPRauw/EJBNhSjmZC6aa4wqu60gmQ8xfnJ6YEd/XayZXqjoAiE9cAC3tF3bO8x3gpp0D0uKFhha5VgtYb9LTVlbE+Kb4DLi5fEkRWyTfywVMXLPgm5HnVE3Pz6SRwH8jHUjNSnqRRbwJfJ4Sb8LzQSzf1y0imoAfGRUcjbIC0tKAitYZ5LduaIzNyi4hBaAwsXLkLEkBClUqtI4LtCf6ETgPNRWmSWYKeiV6vzjyR0xhBi1VixpS8HN4OdA8Te3t41lp6w8nFaJcrD0LnLNPMeotJv5u+6gc3d1Jd/to+DtvxpFulh8J5WMEXCHJOV6nSKRb+rGUFh+2jp9qkSB98XGCcKn3blAFxEGYwtJXqpP53pPxa6Up/f0/KR87a4IWD0y5fZ90+HcvDCnQofuQWsMobpiFWN7ScYttbcO85xv7J6Qs+yUf9hzraN8rLW9o7LKnW+fCT8c0ggTIqTyaW1HwTtYDZtYDUIG9KDj3KY1YZN2yca+ErnS1phfI71m8JqjvH2k/+finxs2IexESmjzRTeqgEKGrhx1BdhwJ5/nd9moF6HuWqR3XCd2UtiLyhQbFt+Lo70vHm3m0Duzu03pKgGGXQQQqa1QM6YIAV6s3TSs/5cYm5KGZCd7UoKlMRzivHst/Nm6Zy+3jckpn626f7RkP/hIfT9Qvrd80PGYeCe2nNvTMfAfScYbczZ225knqeT6Z7vdY8+jgabAjREPLzKvZlL3wS6FquFEsGYn/BNAbkuJ9OhxWBgwqhTVLGaJdTAtl9cgcJqUKE76cclwit9ZF0ucUBdqV9twE2prGB/ujSKmhJ7Qd/FwEr7/UdJwQ8iVbs3+qJHBg91WPhTR9eab0YHzM+62FePZFWpQQ8m9RfP5Ku262YLhGEqmBHAHcOomhWUF/t3fQWewUIADG1Mr4nICeYUbLjsnS3IpASwM2uzFNBgdIe/i/xq5KZMvjtaaEqUviVPkAcHrS96L58DoEnsC+96ljH9lyBwJcJ3q2eT7rQNFY/yANRvNi5ix1mtZV8J6d/HWr2v5P67W3TnbN6yFjIVNwz2vqXOG5tsZ/5AWrctnu7kaanaHvmXgVgIkijHmzW21ZQQANPNgjGBkycGUXZMMUIwGwYJKoZIhvcNAQkUMQ4eDABNAHkAQwBlAHIAdDAjBgkqhkiG9w0BCRUxFgQU59WMkYzN/aRcemeMQJxzpRcC5nwwMTAhMAkGBSsOAwIaBQAEFN17vdeYvqbjC2HcRpRxhBWpv7ydBAgrPrMeGR5G/wICCAA=\n# Alternatively, you could also do it like this:\n#stringData:\n# certPem: |\n# -----BEGIN CERTIFICATE-----\n# ...\n# -----END CERTIFICATE-----\n# -----BEGIN PRIVATE KEY-----\n# ...\n# -----END PRIVATEKEY-----\n\n---\napiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\n name: pushsecret-example\n namespace: default\nspec:\n refreshInterval: 10s # Refresh interval for which push secret will reconcile\n deletionPolicy: Delete\n secretStoreRefs: # A list of secret stores to push secrets to\n - name: azure-store\n kind: SecretStore\n selector:\n secret:\n name: source-certificate # Source Kubernetes secret to be pushed\n data:\n - match:\n secretKey: cert.p12 # Source Kubernetes secret key containing the certificate\n remoteRef:\n remoteKey: cert/my-azkv-cert-name\n
Note
In order to create a PushSecret targeting keys, ImportCertificate
and DeleteCertificate
actions must be granted to the Service Principal/Identity configured on the SecretStore.
"},{"location":"provider/chef/","title":"Chef","text":""},{"location":"provider/chef/#chef","title":"Chef","text":"Chef External Secrets provider
will enable users to seamlessly integrate their Chef-based secret management with Kubernetes through the existing External Secrets framework.
In many enterprises, legacy applications and infrastructure are still tightly integrated with the Chef/Chef Infra Server/Chef Server Cluster for configuration and secrets management. Teams often rely on Chef data bags to securely store sensitive information such as application secrets and infrastructure configurations. These data bags serve as a centralized repository for managing and distributing sensitive data across the Chef ecosystem.
NOTE: Chef External Secrets provider
is designed only to fetch data from the Chef data bags into Kubernetes secrets, it won't update/delete any item in the data bags.
"},{"location":"provider/chef/#authentication","title":"Authentication","text":"Every request made to the Chef Infra server needs to be authenticated. Authentication is done using the Private keys of the Chef Users. The User needs to have appropriate Permissions to the data bags containing the data that they want to fetch using the External Secrets Operator.
The following command can be used to create Chef Users:
chef-server-ctl user-create USER_NAME FIRST_NAME [MIDDLE_NAME] LAST_NAME EMAIL 'PASSWORD' (options)\n
More details on the above command are available here Chef User Create Option. The above command will return the default private key (PRIVATE_KEY_VALUE), which we will use for authentication. Additionally, a Chef User with access to specific data bags, a private key pair with an expiration date can be created with the help of the knife user key command.
"},{"location":"provider/chef/#create-a-secret-containing-your-private-key","title":"Create a secret containing your private key","text":"We need to store the above User's API key into a secret resource. Example:
kubectl create secret generic chef-user-secret -n vivid --from-literal=user-private-key='PRIVATE_KEY_VALUE'\n
"},{"location":"provider/chef/#creating-clustersecretstore","title":"Creating ClusterSecretStore","text":"The Chef ClusterSecretStore
is a cluster-scoped SecretStore that can be referenced by all Chef ExternalSecrets
from all namespaces. You can follow the below example to create a ClusterSecretStore
resource.
apiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\n name: vivid-clustersecretstore # name of ClusterSecretStore\nspec:\n provider:\n chef:\n username: user # Chef User name\n serverUrl: https://manage.chef.io/organizations/testuser/ # Chef server URL\n auth:\n secretRef:\n privateKeySecretRef:\n key: user-private-key # name of the key inside Secret resource\n name: chef-user-secret # name of Kubernetes Secret resource containing the Chef User's private key\n namespace: vivid # the namespace in which the above Secret resource resides\n
"},{"location":"provider/chef/#creating-secretstore","title":"Creating SecretStore","text":"Chef SecretStores
are bound to a namespace and can not reference resources across namespaces. For cross-namespace SecretStores, you must use Chef ClusterSecretStores
.
You can follow the below example to create a SecretStore
resource.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: vivid-secretstore # name of SecretStore\n namespace: vivid # must be required for kind: SecretStore\nspec:\n provider:\n chef:\n username: user # Chef User name\n serverUrl: https://manage.chef.io/organizations/testuser/ # Chef server URL\n auth:\n secretRef:\n privateKeySecretRef:\n name: chef-user-secret # name of Kubernetes Secret resource containing the Chef User's private key\n key: user-private-key # name of the key inside Secret resource\n namespace: vivid # the ns where the k8s secret resource containing Chef User's private key resides\n
"},{"location":"provider/chef/#creating-externalsecret","title":"Creating ExternalSecret","text":"The Chef ExternalSecret
describes what data should be fetched from Chef Data bags, and how the data should be transformed and saved as a Kind=Secret.
You can follow the below example to create an ExternalSecret
resource.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: vivid-external-secrets # name of ExternalSecret\n namespace: vivid # namespace inside which the ExternalSecret will be created\n annotations:\n company/contacts: user.a@company.com, user.b@company.com\n company/team: vivid-dev\n labels:\n app.kubernetes.io/name: external-secrets\nspec:\n refreshInterval: 15m\n secretStoreRef:\n name: vivid-clustersecretstore # name of ClusterSecretStore\n kind: ClusterSecretStore\n data:\n - secretKey: USERNAME\n remoteRef:\n key: vivid_prod/global_user # databagName/dataItemName\n property: username # a json key in dataItem\n - secretKey: PASSWORD\n remoteRef:\n key: vivid_prod/global_user\n property: password\n - secretKey: APIKEY\n remoteRef:\n key: vivid_global/apikey\n property: api_key\n - secretKey: APP_PROPERTIES\n remoteRef:\n key: vivid_global/app_properties # databagName/dataItemName , it will fetch all key-vlaues present in the dataItem\n target:\n name: vivid-credentials # name of kubernetes Secret resource that will be created and will contain the obtained secrets\n creationPolicy: Owner\n template:\n mergePolicy: Replace \n engineVersion: v2\n data:\n secrets.json: |\n {\n \"username\": \"{{ .USERNAME }}\",\n \"password\": \"{{ .PASSWORD }}\",\n \"app_apikey\": \"{{ .APIKEY }}\",\n \"app_properties\": \"{{ .APP_PROPERTIES }}\"\n }\n
When the above ClusterSecretStore
and ExternalSecret
resources are created, the ExternalSecret
will connect to the Chef Server using the private key and will fetch the data bags contained in the vivid-credentials
secret resource.
To get all data items inside the data bag, you can use the dataFrom
directive:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: vivid-external-secrets # name of ExternalSecret\n namespace: vivid # namespace inside which the ExternalSecret will be created\n annotations:\n company/contacts: user.a@company.com, user.b@company.com\n company/team: vivid-dev\n labels:\n app.kubernetes.io/name: external-secrets\nspec:\n refreshInterval: 15m\n secretStoreRef:\n name: vivid-clustersecretstore # name of ClusterSecretStore\n kind: ClusterSecretStore\n dataFrom:\n - extract:\n key: vivid_global # only data bag name\n target:\n name: vivid_global_all_cred # name of Kubernetes Secret resource that will be created and will contain the obtained secrets\n creationPolicy: Owner\n
follow : this file for more info
"},{"location":"provider/cloak/","title":"Cloak End 2 End Encrypted Secrets","text":""},{"location":"provider/cloak/#cloak","title":"Cloak","text":"Sync secrets from the Cloak Encrypted Secrets Platform to Kubernetes using the External Secrets Operator.
Cloak uses the webhook provider built into the External Secrets Operator but also required a proxy service to handle decrypting secrets when they arrive into your cluster.
"},{"location":"provider/cloak/#key-setup","title":"Key Setup","text":"From the Cloak user interface create a service account and store the private key on your file system.
Now create a kubernetes secret in the same namespace as the External Secrets Operator.
HISTIGNORE='*kubectl*' kubectl --namespace=external-secrets \\\n create secret generic cloak-key \\\n --from-file=ecdh_private_key=$LOCATION_OF_YOUR_PEM_FILE\n
"},{"location":"provider/cloak/#deploy-the-decryption-proxy","title":"Deploy the decryption proxy","text":"# The cloak external secrets proxy\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: cloak-external-secrets\n namespace: external-secrets\nspec:\n selector:\n matchLabels:\n app: cloak-external-secrets\n replicas: 1\n template:\n metadata:\n labels:\n app: cloak-external-secrets\n spec:\n containers:\n - name: cloak-external-secrets\n image: purtontech/cloak-external-secrets:latest\n imagePullPolicy: IfNotPresent\n env: \n - name: ECDH_PRIVATE_KEY \n valueFrom: \n secretKeyRef: \n name: cloak-key \n key: ecdh_private_key \n ports:\n - containerPort: 7105\n
And a Kubernetes Service so External Secrets Operator can access the proxy.
apiVersion: v1\nkind: Service\nmetadata:\n name: cloak-external-secrets-service\n namespace: external-secrets\nspec:\n selector:\n app: cloak-external-secrets\n ports:\n - protocol: TCP\n port: 7105\n targetPort: 7105\n
"},{"location":"provider/cloak/#create-a-secret-store","title":"Create a secret store","text":"You can now place the configuration in any Kubernetes Namespace.
# An External secrets webhookl\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: cloak-backend\nspec:\n provider:\n webhook:\n url: \"http://cloak-external-secrets-service:7105/{{ .remoteRef.key }}\"\n result:\n jsonPath: \"$.value\"\n headers:\n Content-Type: application/json\n
"},{"location":"provider/cloak/#connect-a-secret-to-the-provider","title":"Connect a secret to the provider","text":"Each secretKey
reference in the yaml should point to the name of the secret as it is stored in Cloak.
# Access a secret\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: cloak-example\nspec:\n refreshInterval: \"15m\"\n secretStoreRef:\n name: cloak-backend\n kind: SecretStore\n target:\n name: example-sync\n data:\n - secretKey: access-token\n remoteRef:\n key: PULUMI_ACCESS_TOKEN\n - secretKey: do-access-token\n remoteRef:\n key: DIGITALOCEAN_ACCESS_TOKEN\n
"},{"location":"provider/conjur/","title":"CyberArk Conjur","text":""},{"location":"provider/conjur/#conjur-provider","title":"Conjur Provider","text":"This section describes how to set up the Conjur provider for External Secrets Operator (ESO). For a working example, see the Accelerator-K8s-External-Secrets repo.
"},{"location":"provider/conjur/#prerequisites","title":"Prerequisites","text":"Before installing the Conjur provider, you need:
- A running Conjur Server, with:
- An accessible Conjur endpoint (for example:
https://myapi.example.com
). - Your configured Conjur authentication info (such as
hostid
, apikey
, or JWT service ID). For more information on configuring Conjur, see Policy statement reference. - Support for your authentication method (
apikey
is supported by default, jwt
requires additional configuration). - Optional: Conjur server certificate (see below).
- A Kubernetes cluster with ESO installed.
"},{"location":"provider/conjur/#conjur-server-certificate","title":"Conjur server certificate","text":"If you set up your Conjur server with a self-signed certificate, we recommend that you populate the caBundle
field with the Conjur self-signed certificate in the secret-store definition. The certificate CA must be referenced in the secret-store definition using either caBundle
or caProvider
:
....\nspec:\n provider:\n conjur:\n # Service URL\n url: https://myapi.conjur.org\n\n # [OPTIONAL] base64 encoded string of certificate\n caBundle: \"<base64 encoded cabundle>\"\n\n # [OPTIONAL] caProvider:\n # Instead of caBundle you can also specify a caProvider,\n # which retrieves the cert from a Secret or ConfigMap\n caProvider:\n type: \"Secret\" # Can be Secret or ConfigMap\n name: \"<name of secret or configmap>\"\n key: \"<key inside secret or configmap>\"\n # namespace is required for ClusterSecretStore\n # but not relevant for SecretStore\n namespace: \"my-cert-secret-namespace\"\n ....\n
"},{"location":"provider/conjur/#external-secret-store","title":"External secret store","text":"The Conjur provider is configured as an external secret store in ESO. The Conjur provider supports these two methods to authenticate to Conjur:
apikey
: uses a Conjur hostid
and apikey
to authenticate with Conjur jwt
: uses a JWT to authenticate with Conjur
"},{"location":"provider/conjur/#option-1-external-secret-store-with-apikey-authentication","title":"Option 1: External secret store with apiKey authentication","text":"This method uses a Conjur hostid
and apikey
to authenticate with Conjur. It is the simplest method to set up and use because your Conjur instance requires no additional configuration.
"},{"location":"provider/conjur/#step-1-define-an-external-secret-store","title":"Step 1: Define an external secret store","text":"Tip
Save as the file as: conjur-secret-store.yaml
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: conjur\nspec:\n provider:\n conjur:\n # Service URL\n url: https://myapi.conjur.org\n # [OPTIONAL] base64 encoded string of certificate\n caBundle: OPTIONALxFIELDxxxBase64xCertxString== \n auth:\n apikey:\n # conjur account\n account: conjur\n userRef: # Get this from K8S secret\n name: conjur-creds\n key: hostid\n apiKeyRef: # Get this from K8S secret\n name: conjur-creds\n key: apikey\n
"},{"location":"provider/conjur/#step-2-create-kubernetes-secrets-for-conjur-credentials","title":"Step 2: Create Kubernetes secrets for Conjur credentials","text":"To connect to the Conjur server, the ESO Conjur provider needs to retrieve the apikey
credentials from K8s secrets.
Note
For more information about how to create K8s secrets, see Creating a secret.
Here is an example of how to create K8s secrets using the kubectl
command:
# This is all one line\nkubectl -n external-secrets create secret generic conjur-creds --from-literal=hostid=MYCONJURHOSTID --from-literal=apikey=MYAPIKEY\n\n# Example:\n# kubectl -n external-secrets create secret generic conjur-creds --from-literal=hostid=host/data/app1/host001 --from-literal=apikey=321blahblah\n
Note
conjur-creds
is the name
defined in the userRef
and apikeyRef
fields of the conjur-secret-store.yml
file.
"},{"location":"provider/conjur/#step-3-create-the-external-secrets-store","title":"Step 3: Create the external secrets store","text":"Important
Unless you are using a ClusterSecretStore, credentials must reside in the same namespace as the SecretStore.
# WARNING: creates the store in the \"external-secrets\" namespace, update the value as needed\n#\nkubectl apply -n external-secrets -f conjur-secret-store.yaml\n\n# WARNING: running the delete command will delete the secret store configuration\n#\n# If there is a need to delete the external secretstore\n# kubectl delete secretstore -n external-secrets conjur\n
"},{"location":"provider/conjur/#option-2-external-secret-store-with-jwt-authentication","title":"Option 2: External secret store with JWT authentication","text":"This method uses JWT tokens to authenticate with Conjur. You can use the following methods to retrieve a JWT token for authentication:
- JWT token from a referenced Kubernetes service account
- JWT token stored in a Kubernetes secret
"},{"location":"provider/conjur/#step-1-define-an-external-secret-store_1","title":"Step 1: Define an external secret store","text":"When you use JWT authentication, the following must be specified in the SecretStore
:
account
- The name of the Conjur account serviceId
- The ID of the JWT Authenticator WebService
configured in Conjur that is used to authenticate the JWT token
You can retrieve the JWT token from either a referenced service account or a Kubernetes secret.
For example, to retrieve a JWT token from a referenced Kubernetes service account, the following secret store definition can be used:
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: conjur\nspec:\n provider:\n conjur:\n # Service URL\n url: https://myapi.conjur.org\n # [OPTIONAL] base64 encoded string of certificate\n caBundle: OPTIONALxFIELDxxxBase64xCertxString==\n auth:\n jwt:\n # conjur account\n account: conjur\n # The authn-jwt service ID\n serviceID: my-jwt-auth-service\n # Service account to retrieve JWT token for\n serviceAccountRef:\n name: my-service-account\n # [OPTIONAL] audiences to include in JWT token\n audiences:\n - https://conjur.company.com\n
Important
This method is only supported in Kubernetes 1.22 and above as it uses the TokenRequest API to get the JWT token from the referenced service account. Audiences can be defined in the Conjur JWT authenticator.
Alternatively, here is an example where a secret containing a valid JWT token is referenced:
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: conjur\nspec:\n provider:\n conjur:\n # Service URL\n url: https://myapi.conjur.org\n # [OPTIONAL] base64 encoded string of certificate\n caBundle: OPTIONALxFIELDxxxBase64xCertxString==\n auth:\n jwt:\n # conjur account\n account: conjur\n # The authn-jwt service ID\n serviceID: my-jwt-auth-service\n # Secret containing a valid JWT token\n secretRef:\n name: my-jwt-secret\n key: token\n
The JWT token must identify your Conjur host, be compatible with your configured Conjur JWT authenticator, and meet all the Conjur JWT guidelines.
You can use an external JWT issuer or the Kubernetes API server to create the token. For example, a Kubernetes service account token can be created with this command:
kubectl create token my-service-account --audience='https://conjur.company.com' --duration=3600s\n
Save the secret store file as conjur-secret-store.yaml
.
"},{"location":"provider/conjur/#step-2-create-the-external-secrets-store","title":"Step 2: Create the external secrets store","text":"# WARNING: creates the store in the \"external-secrets\" namespace, update the value as needed\n#\nkubectl apply -n external-secrets -f conjur-secret-store.yaml\n\n# WARNING: running the delete command will delete the secret store configuration\n#\n# If there is a need to delete the external secretstore\n# kubectl delete secretstore -n external-secrets conjur\n
"},{"location":"provider/conjur/#define-an-external-secret","title":"Define an external secret","text":"After you have configured the Conjur provider secret store, you can fetch secrets from Conjur.
Here is an example of how to fetch a single secret from Conjur:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: conjur\nspec:\n refreshInterval: 10s\n secretStoreRef:\n # This name must match the metadata.name in the `SecretStore`\n name: conjur\n kind: SecretStore\n data:\n - secretKey: secret00\n remoteRef:\n key: data/app1/secret00\n
Save the external secret file as conjur-external-secret.yaml
.
"},{"location":"provider/conjur/#find-by-name-and-find-by-tag","title":"Find by Name and Find by Tag","text":"The Conjur provider also supports the Find by Name and Find by Tag ESO features. This means that you can use a regular expression or tags to dynamically fetch multiple secrets from Conjur.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: conjur-find-by-name\nspec:\n refreshInterval: 10s\n secretStoreRef:\n # This name must match the metadata.name in the `SecretStore`\n name: conjur\n kind: SecretStore\n target:\n name: k8s-secret-to-be-created\n dataFrom:\n - find:\n # You can use *either* `name` or `tags` to filter the secrets. Here are basic examples of both:\n name:\n # Match all secrets in the app1 namespace (e.g., `app1/secret00`, `app1/secret01`, etc.)\n regexp: \"^app1\\/.+$\"\n tags:\n # Only fetch Conjur secrets with the following annotations\n environment: \"prod\"\n application: \"app1\"\n
If you use these features, we strongly recommend that you limit the permissions of the Conjur host to only the secrets that it needs to access. This is more secure and it reduces the load on both the Conjur server and ESO.
"},{"location":"provider/conjur/#create-the-external-secret","title":"Create the external secret","text":"# WARNING: creates the external-secret in the \"external-secrets\" namespace, update the value as needed\n#\nkubectl apply -n external-secrets -f conjur-external-secret.yaml\n\n# WARNING: running the delete command will delete the external-secrets configuration\n#\n# If there is a need to delete the external secret\n# kubectl delete externalsecret -n external-secrets conjur\n
"},{"location":"provider/conjur/#get-the-k8s-secret","title":"Get the K8s secret","text":" - Log in to your Conjur server and verify that your secret exists
- Review the value of your Kubernetes secret to verify that it contains the same value as the Conjur server
# WARNING: this command will reveal the stored secret in plain text\n#\n# Assuming the secret name is \"secret00\", this will show the value\nkubectl get secret -n external-secrets conjur -o jsonpath=\"{.data.secret00}\" | base64 --decode && echo\n
"},{"location":"provider/conjur/#see-also","title":"See also","text":" - Accelerator-K8s-External-Secrets repo
- Configure Conjur JWT authentication
"},{"location":"provider/conjur/#license","title":"License","text":"Copyright (c) 2023-2024 CyberArk Software Ltd. All rights reserved.
Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
"},{"location":"provider/delinea/","title":"Delinea","text":""},{"location":"provider/delinea/#delinea-devops-secrets-vault","title":"Delinea DevOps Secrets Vault","text":"External Secrets Operator integrates with Delinea DevOps Secrets Vault.
Please note that the Delinea Secret Server product is NOT in scope of this integration.
"},{"location":"provider/delinea/#creating-a-secretstore","title":"Creating a SecretStore","text":"You need client ID, client secret and tenant to authenticate with DSV. Both client ID and client secret can be specified either directly in the config, or by referencing a kubernetes secret.
To acquire client ID and client secret, refer to the policy management and client management documentation.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: secret-store\nspec:\n provider:\n delinea:\n tenant: <TENANT>\n tld: <TLD>\n clientId:\n value: <CLIENT_ID>\n clientSecret:\n secretRef:\n name: <NAME_OF_KUBE_SECRET>\n key: <KEY_IN_KUBE_SECRET>\n
Both clientId
and clientSecret
can either be specified directly via the value
field or can reference a kubernetes secret.
The tenant
field must correspond to the host name / site name of your DevOps vault. If you selected a region other than the US you must also specify the TLD, e.g. tld: eu
.
If required, the URL template (urlTemplate
) can be customized as well.
"},{"location":"provider/delinea/#referencing-secrets","title":"Referencing Secrets","text":"Secrets can be referenced by path. Getting a specific version of a secret is not yet supported.
Note that because all DSV secrets are JSON objects, you must specify remoteRef.property
. You can access nested values or arrays using gjson syntax.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: secret\nspec:\n refreshInterval: 20s\n secretStoreRef:\n kind: SecretStore\n name: secret-store\n data:\n - secretKey: <KEY_IN_KUBE_SECRET>\n remoteRef:\n key: <SECRET_PATH>\n property: <JSON_PROPERTY>\n
"},{"location":"provider/doppler/","title":"Doppler","text":""},{"location":"provider/doppler/#doppler-secretops-platform","title":"Doppler SecretOps Platform","text":"Sync secrets from the Doppler SecretOps Platform to Kubernetes using the External Secrets Operator.
"},{"location":"provider/doppler/#authentication","title":"Authentication","text":"Doppler Service Tokens are recommended as they restrict access to a single config.
NOTE: Doppler Personal Tokens are also supported but require project
and config
to be set on the SecretStore
or ClusterSecretStore
.
Create the Doppler Token secret by opening the Doppler dashboard and navigating to the desired Project and Config, then create a new Service Token from the Access tab:
Create the Doppler Token Kubernetes secret with your Service Token value:
HISTIGNORE='*kubectl*' kubectl create secret generic \\\n doppler-token-auth-api \\\n --from-literal dopplerToken=\"dp.st.xxxx\"\n
Then to create a generic SecretStore
:
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: doppler-auth-api\nspec:\n provider:\n doppler:\n auth:\n secretRef:\n dopplerToken:\n name: doppler-token-auth-api\n key: dopplerToken\n
NOTE: In case of a ClusterSecretStore
, be sure to set namespace
in secretRef.dopplerToken
.
"},{"location":"provider/doppler/#use-cases","title":"Use Cases","text":"The Doppler provider allows for a wide range of use cases:
- Fetch
- Fetch all
- Filter
- JSON secret
- Name transformer
- Download
Let's explore each use case using a fictional auth-api
Doppler project.
"},{"location":"provider/doppler/#1-fetch","title":"1. Fetch","text":"To sync one or more individual secrets:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: auth-api-db-url\nspec:\n secretStoreRef:\n kind: SecretStore\n name: doppler-auth-api\n\n target:\n name: auth-api-db-url\n\n data:\n - secretKey: DB_URL\n remoteRef:\n key: DB_URL\n
"},{"location":"provider/doppler/#2-fetch-all","title":"2. Fetch all","text":"To sync every secret from a config:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: auth-api-all\nspec:\n secretStoreRef:\n kind: SecretStore\n name: doppler-auth-api\n\n target:\n name: auth-api-all\n\n dataFrom:\n - find:\n name:\n regexp: .*\n
"},{"location":"provider/doppler/#3-filter","title":"3. Filter","text":"To filter secrets by path
(path prefix), name
(regular expression) or a combination of both:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: auth-api-db\nspec:\n secretStoreRef:\n kind: SecretStore\n name: doppler-auth-api\n\n target:\n name: auth-api-db\n\n dataFrom:\n - find:\n path: DB_\n
"},{"location":"provider/doppler/#4-json-secret","title":"4. JSON secret","text":"To parse a JSON secret to its key-value pairs:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: auth-api-sa-json\nspec:\n secretStoreRef:\n kind: SecretStore\n name: doppler-auth-api\n\n target:\n name: auth-api-sa-json\n\n dataFrom:\n - extract:\n key: SA_JSON\n
"},{"location":"provider/doppler/#5-name-transformer","title":"5. Name transformer","text":"Name transformers format keys from Doppler's UPPER_SNAKE_CASE to one of the following alternatives:
- upper-camel
- camel
- lower-snake
- tf-var
- dotnet-env
- lower-kebab
Name transformers require a specifically configured SecretStore
:
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: doppler-auth-api-dotnet-env\nspec:\n provider:\n doppler:\n auth:\n secretRef:\n dopplerToken:\n name: doppler-token-auth-api\n nameTransformer: dotnet-env\n
Then an ExternalSecret
referencing the SecretStore
:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: doppler-auth-api-dotnet-env\nspec:\n secretStoreRef:\n kind: SecretStore\n name: doppler-auth-api-dotnet-env\n\n target:\n name: doppler-auth-api-dotnet-env\n creationPolicy: Owner\n\n dataFrom:\n - find:\n name:\n regexp: .*\n
"},{"location":"provider/doppler/#6-download","title":"6. Download","text":"A single DOPPLER_SECRETS_FILE
key is set where the value is the secrets downloaded in one of the following formats:
- json
- dotnet-json
- env
- env-no-quotes
- yaml
Downloading secrets requires a specifically configured SecretStore
:
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: doppler-auth-api-json-file\nspec:\n provider:\n doppler:\n auth:\n secretRef:\n dopplerToken:\n name: doppler-token-auth-api\n key: dopplerToken\n format: json\n
Then an ExternalSecret
referencing the SecretStore
:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: auth-api-json-file\nspec:\n secretStoreRef:\n kind: SecretStore\n name: doppler-auth-api-json-file\n\n target:\n name: auth-api-json-file\n\n dataFrom:\n - find:\n path: DOPPLER_SECRETS_FILE\n
"},{"location":"provider/fake/","title":"Fake","text":"We provide a fake
implementation to help with testing. This provider returns static key/value pairs and nothing else. To use the fake
provider simply create a SecretStore
or ClusterSecretStore
and configure it like in the following example:
Note
The provider returns static data configured in value
. You can define a version
, too. If set the remoteRef
from an ExternalSecret must match otherwise no value is returned.
apiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\n name: fake\nspec:\n provider:\n fake:\n data:\n - key: \"/foo/bar\"\n value: \"HELLO1\"\n version: \"v1\"\n - key: \"/foo/bar\"\n value: \"HELLO2\"\n version: \"v2\"\n - key: \"/foo/baz\"\n value: '{\"john\": \"doe\"}'\n version: \"v1\"\n
Please note that value
is intended for exclusive use with data
for dataFrom
. You can use the data
to set a JSON
compliant value to be used as dataFrom
.
Here is an example ExternalSecret
that displays this behavior:
Warning
This provider supports specifying different data[].version
configurations. However, data[].property
is ignored.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: fake\n kind: ClusterSecretStore\n target:\n name: secret-to-be-created\n data:\n - secretKey: foo_bar\n remoteRef:\n key: /foo/bar\n version: v1\n dataFrom:\n - extract:\n key: /foo/baz\n version: v1\n
This results in the following secret:
apiVersion: v1\nkind: Secret\nmetadata:\n name: secret-to-be-created\n namespace: default\ndata:\n foo_bar: SEVMTE8x # HELLO1 (via data)\n john: ZG9l #doe (via dataFrom)\n
"},{"location":"provider/fortanix/","title":"Fortanix","text":""},{"location":"provider/fortanix/#fortanix-dsm-sdkms","title":"Fortanix DSM / SDKMS","text":"Populate kubernetes secrets from OPAQUE or SECRET security objects in Fortanix.
"},{"location":"provider/fortanix/#authentication","title":"Authentication","text":"SDKMS Application API Key
"},{"location":"provider/fortanix/#creating-a-secretstore","title":"Creating a SecretStore","text":"apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: secret-store\nspec:\n provider:\n fortanix:\n apiUrl: <HOST_OF_SDKMS_API>\n apiKey:\n secretRef:\n name: <NAME_OF_KUBE_SECRET>\n key: <KEY_IN_KUBE_SECRET>\n
"},{"location":"provider/fortanix/#referencing-secrets","title":"Referencing Secrets","text":"# Raw stored value\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: secret\nspec:\n refreshInterval: 1h\n secretStoreRef:\n kind: SecretStore\n name: secret-store\n data:\n - secretKey: <KEY_IN_KUBE_SECRET>\n remoteRef:\n key: <SDKMS_SECURITY_OBJECT_NAME>\n---\n# From stored key-value JSON\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: secret-from-property\nspec:\n refreshInterval: 1h\n secretStoreRef:\n kind: SecretStore\n name: secret-store\n data:\n - secretKey: <KEY_IN_KUBE_SECRET>\n remoteRef:\n key: <SDKMS_SECURITY_OBJECT_NAME>\n property: <SECURITY_OBJECT_VALUE_INNER_PROPERTY>\n---\n# Extract all keys from stored key-value JSON\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: secret-from-extract\nspec:\n refreshInterval: 1h\n secretStoreRef:\n kind: SecretStore\n name: secret-store\n dataFrom:\n - extract:\n key: <SDKMS_SECURITY_OBJECT_NAME>\n
"},{"location":"provider/gitlab-variables/","title":"GitLab Variables","text":""},{"location":"provider/gitlab-variables/#gitlab-variables","title":"GitLab Variables","text":"External Secrets Operator integrates with GitLab to sync GitLab Project Variables API and/or GitLab Group Variables API to secrets held on the Kubernetes cluster.
"},{"location":"provider/gitlab-variables/#configuring-gitlab","title":"Configuring GitLab","text":"The GitLab API requires an access token, project ID and/or groupIDs.
To create a new access token, go to your user settings and select 'access tokens'. Give your token a name, expiration date, and select the permissions required (Note 'api' is required).
Click 'Create personal access token', and your token will be generated and displayed on screen. Copy or save this token since you can't access it again.
"},{"location":"provider/gitlab-variables/#access-token-secret","title":"Access Token secret","text":"Create a secret containing your access token:
apiVersion: v1\nkind: Secret\nmetadata:\n name: gitlab-secret\n labels: \n type: gitlab\ntype: Opaque \nstringData:\n token: \"**access token goes here**\"\n
"},{"location":"provider/gitlab-variables/#configuring-the-secret-store","title":"Configuring the secret store","text":"Be sure the gitlab
provider is listed in the Kind=SecretStore
and the ProjectID is set. If you are not using https://gitlab.com
, you must set the url
field as well.
In order to sync group variables inheritFromGroups
must be true or groupIDs
have to be defined.
In case you have defined multiple environments in Gitlab, the secret store should be constrained to a specific environment_scope
.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: gitlab-secret-store\nspec:\n provider:\n # provider type: gitlab\n gitlab:\n # url: https://gitlab.mydomain.com/\n auth:\n SecretRef:\n accessToken:\n name: gitlab-secret\n key: token\n projectID: \"**project ID goes here**\"\n groupIDs: \"**groupID(s) go here**\"\n inheritFromGroups: \"**automatically looks for variables in parent groups**\"\n environment: \"**environment scope goes here**\"\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in accessToken
with the namespace where the secret resides. Your project ID can be found on your project's page.
"},{"location":"provider/gitlab-variables/#creating-external-secret","title":"Creating external secret","text":"To sync a GitLab variable to a secret on the Kubernetes cluster, a Kind=ExternalSecret
is needed.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: gitlab-external-secret-example\nspec:\n refreshInterval: 1h\n\n secretStoreRef:\n kind: SecretStore\n name: gitlab-secret-store # Must match SecretStore on the cluster\n\n target:\n name: gitlab-secret-to-create # Name for the secret to be created on the cluster\n creationPolicy: Owner\n\n data:\n - secretKey: secretKey # Key given to the secret to be created on the cluster\n remoteRef: \n key: myGitlabVariable # Key of the variable on Gitlab\n
"},{"location":"provider/gitlab-variables/#using-datafrom","title":"Using DataFrom","text":"DataFrom can be used to get a variable as a JSON string and attempt to parse it.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: gitlab-external-secret-example\nspec:\n refreshInterval: 1h\n\n secretStoreRef:\n kind: SecretStore\n name: gitlab-secret-store # Must match SecretStore on the cluster\n\n target:\n name: gitlab-secret-to-create # Name for the secret to be created on the cluster\n creationPolicy: Owner\n\n # each secret name in the KV will be used as the secret key in the SECRET k8s target object\n dataFrom:\n - extract:\n key: \"myJsonVariable\" # Key of the variable on Gitlab\n
"},{"location":"provider/gitlab-variables/#getting-the-kubernetes-secret","title":"Getting the Kubernetes secret","text":"The operator will fetch the project variable and inject it as a Kind=Secret
.
kubectl get secret gitlab-secret-to-create -o jsonpath='{.data.secretKey}' | base64 -d\n
"},{"location":"provider/google-secrets-manager/","title":"Google Cloud Secret Manager","text":""},{"location":"provider/google-secrets-manager/#google-cloud-secret-manager","title":"Google Cloud Secret Manager","text":"External Secrets Operator integrates with GCP Secret Manager for secret management.
"},{"location":"provider/google-secrets-manager/#authentication","title":"Authentication","text":""},{"location":"provider/google-secrets-manager/#workload-identity","title":"Workload Identity","text":"Your Google Kubernetes Engine (GKE) applications can consume GCP services like Secrets Manager without using static, long-lived authentication tokens. This is our recommended approach of handling credentials in GCP. ESO offers two options for integrating with GKE workload identity: pod-based workload identity and using service accounts directly. Before using either way you need to create a service account - this is covered below.
"},{"location":"provider/google-secrets-manager/#creating-workload-identity-service-accounts","title":"Creating Workload Identity Service Accounts","text":"You can find the documentation for Workload Identity here. We will walk you through how to navigate it here.
Search the document for this editable values and change them to your values: Note: If you have installed ESO, a serviceaccount has already been created. You can either patch the existing external-secrets
SA or create a new one that fits your needs.
CLUSTER_NAME
: The name of your cluster PROJECT_ID
: Your project ID (not your Project number nor your Project name) K8S_NAMESPACE
: For us following these steps here it will be es
, but this will be the namespace where you deployed the external-secrets operator KSA_NAME
: external-secrets (if you are not creating a new one to attach to the deployment) GSA_NAME
: external-secrets for simplicity, or something else if you have to follow different naming conventions for cloud resources ROLE_NAME
: should be roles/secretmanager.secretAccessor
- so you make the pod only be able to access secrets on Secret Manager
"},{"location":"provider/google-secrets-manager/#using-service-accounts-directly","title":"Using Service Accounts directly","text":"Let's assume you have created a service account correctly and attached a appropriate workload identity. It should roughly look like this:
apiVersion: v1\nkind: ServiceAccount\nmetadata:\n name: external-secrets\n namespace: es\n annotations:\n iam.gke.io/gcp-service-account: example-team-a@my-project.iam.gserviceaccount.com\n
You can reference this particular ServiceAccount in a SecretStore
or ClusterSecretStore
. It's important that you also set the projectID
, clusterLocation
and clusterName
. The Namespace on the serviceAccountRef
is ignored when using a SecretStore
resource. This is needed to isolate the namespaces properly.
When filling clusterLocation
parameter keep in mind if it is Regional or Zonal cluster.
apiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\n name: gcp-store\nspec:\n provider:\n gcpsm:\n projectID: alphabet-123\n auth:\n workloadIdentity:\n # name of the cluster Location, region or zone\n clusterLocation: europe-central2\n # name of the GKE cluster\n clusterName: alpha-cluster-42\n # projectID of the cluster (if omitted defaults to spec.provider.gcpsm.projectID)\n clusterProjectID: my-cluster-project\n # reference the sa from above\n serviceAccountRef:\n name: team-a\n namespace: team-a\n
You need to give the Google service account the roles/iam.serviceAccountTokenCreator
role so it can generate a service account token for you (not necessary in the Pod-based Workload Identity bellow)
"},{"location":"provider/google-secrets-manager/#using-pod-based-workload-identity","title":"Using Pod-based Workload Identity","text":"You can attach a Workload Identity directly to the ESO pod. ESO then has access to all the APIs defined in the attached service account policy. You attach the workload identity by (1) creating a service account with a attached workload identity (described above) and (2) using this particular service account in the pod's serviceAccountName
field.
For this example we will assume that you installed ESO using helm and that you named the chart installation external-secrets
and the namespace where it lives es
like:
helm install external-secrets external-secrets/external-secrets --namespace es\n
Then most of the resources would have this name, the important one here being the k8s service account attached to the external-secrets operator deployment:
# ...\n containers:\n - image: ghcr.io/external-secrets/external-secrets:vVERSION\n name: external-secrets\n ports:\n - containerPort: 8080\n protocol: TCP\n restartPolicy: Always\n schedulerName: default-scheduler\n serviceAccount: external-secrets\n serviceAccountName: external-secrets # <--- here\n
The pod now has the identity. Now you need to configure the SecretStore
. You just need to set the projectID
, all other fields can be omitted.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: gcp-store\nspec:\n provider:\n gcpsm:\n projectID: alphabet-123\n
"},{"location":"provider/google-secrets-manager/#gcp-service-account-authentication","title":"GCP Service Account authentication","text":"You can use GCP Service Account to authenticate with GCP. These are static, long-lived credentials. A GCP Service Account is a JSON file that needs to be stored in a Kind=Secret
. ESO will use that Secret to authenticate with GCP. See here how you manage GCP Service Accounts. After creating a GCP Service account go to IAM & Admin
web UI, click ADD ANOTHER ROLE
button, add Secret Manager Secret Accessor
role to this service account. The Secret Manager Secret Accessor
role is required to access secrets.
apiVersion: v1\nkind: Secret\nmetadata:\n name: gcpsm-secret\n labels:\n type: gcpsm\ntype: Opaque\nstringData:\n secret-access-credentials: |-\n {\n \"type\": \"service_account\",\n \"project_id\": \"external-secrets-operator\",\n \"private_key_id\": \"\",\n \"private_key\": \"-----BEGIN PRIVATE KEY-----\\nA key\\n-----END PRIVATE KEY-----\\n\",\n \"client_email\": \"test-service-account@external-secrets-operator.iam.gserviceaccount.com\",\n \"client_id\": \"client ID\",\n \"auth_uri\": \"https://accounts.google.com/o/oauth2/auth\",\n \"token_uri\": \"https://oauth2.googleapis.com/token\",\n \"auth_provider_x509_cert_url\": \"https://www.googleapis.com/oauth2/v1/certs\",\n \"client_x509_cert_url\": \"https://www.googleapis.com/robot/v1/metadata/x509/test-service-account%40external-secrets-operator.iam.gserviceaccount.com\"\n }\n
"},{"location":"provider/google-secrets-manager/#update-secret-store","title":"Update secret store","text":"Be sure the gcpsm
provider is listed in the Kind=SecretStore
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: gcp-store\n namespace: example\nspec:\n provider:\n gcpsm: # gcpsm provider\n auth:\n secretRef:\n secretAccessKeySecretRef:\n name: gcpsm-secret # secret name containing SA key\n key: secret-access-credentials # key name containing SA key\n projectID: alphabet-123 # name of Google Cloud project\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
for SecretAccessKeyRef
with the namespace of the secret that we just created.
"},{"location":"provider/google-secrets-manager/#creating-external-secret","title":"Creating external secret","text":"To create a kubernetes secret from the GCP Secret Manager secret a Kind=ExternalSecret
is needed.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: database-credentials\nspec:\n refreshInterval: 1h # rate SecretManager pulls GCPSM\n secretStoreRef:\n kind: SecretStore\n name: gcp-store # name of the SecretStore (or kind specified)\n target:\n name: database-credentials # name of the k8s Secret to be created\n creationPolicy: Owner\n data:\n - secretKey: database_username\n remoteRef:\n key: database_username # name of the GCPSM secret key\n - secretKey: database_password\n remoteRef:\n key: database_password # name of the GCPSM secret key\n
The operator will fetch the GCP Secret Manager secret and inject it as a Kind=Secret
kubectl get secret secret-to-be-created -n <namespace> -o jsonpath='{.data.dev-secret-test}' | base64 -d\n
"},{"location":"provider/hashicorp-vault/","title":"HashiCorp Vault","text":""},{"location":"provider/hashicorp-vault/#hashicorp-vault","title":"Hashicorp Vault","text":"External Secrets Operator integrates with HashiCorp Vault for secret management.
The KV Secrets Engine is the only one supported by this provider. For other secrets engines, please refer to the Vault Generator.
"},{"location":"provider/hashicorp-vault/#example","title":"Example","text":"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\nkind: SecretStore\nmetadata:\n name: vault-backend\nspec:\n provider:\n vault:\n server: \"http://my.vault.server:8200\"\n path: \"secret\"\n # Version is the Vault KV secret engine version.\n # This can be either \"v1\" or \"v2\", defaults to \"v2\"\n version: \"v2\"\n auth:\n # points to a secret that contains a vault token\n # https://www.vaultproject.io/docs/auth/token\n tokenSecretRef:\n name: \"vault-token\"\n key: \"token\"\n---\napiVersion: v1\nkind: Secret\nmetadata:\n name: vault-token\ndata:\n token: cm9vdA== # \"root\"\n
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\n
Can check kv version using following and check for Options
column, it should indicate [version:2]:
vault secrets list -detailed\n
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\nkind: ExternalSecret\nmetadata:\n name: vault-example\nspec:\n refreshInterval: \"15s\"\n secretStoreRef:\n name: vault-backend\n kind: SecretStore\n target:\n name: example-sync\n data:\n - secretKey: foobar\n remoteRef:\n key: foo\n property: my-value\n\n # metadataPolicy to fetch all the labels in JSON format\n - secretKey: tags\n remoteRef:\n metadataPolicy: Fetch\n key: foo\n\n # metadataPolicy to fetch a specific label (dev) from the source secret\n - secretKey: developer\n remoteRef:\n metadataPolicy: Fetch\n key: foo\n property: dev\n\n---\n# will create a secret with:\nkind: Secret\nmetadata:\n name: example-sync\ndata:\n foobar: czNjcjN0\n
Keep in mind that fetching the labels with metadataPolicy: Fetch
only works with KV sercrets engine version v2.
"},{"location":"provider/hashicorp-vault/#fetching-raw-values","title":"Fetching Raw Values","text":"You can fetch all key/value pairs for a given path If you leave the remoteRef.property
empty. This returns the json-encoded secret value for that path.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: vault-example\nspec:\n # ...\n data:\n - secretKey: foobar\n remoteRef:\n key: /dev/package.json\n
"},{"location":"provider/hashicorp-vault/#nested-values","title":"Nested Values","text":"Vault supports nested key/value pairs. You can specify a gjson expression at remoteRef.property
to get a nested value.
Given the following secret - assume its path is /dev/config
:
{\n \"foo\": {\n \"nested\": {\n \"bar\": \"mysecret\"\n }\n }\n}\n
You can set the remoteRef.property
to point to the nested key using a gjson expression.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: vault-example\nspec:\n # ...\n data:\n - secretKey: foobar\n remoteRef:\n key: /dev/config\n property: foo.nested.bar\n---\n# creates a secret with:\n# foobar=mysecret\n
If you would set the remoteRef.property
to just foo
then you would get the json-encoded value of that property: {\"nested\":{\"bar\":\"mysecret\"}}
.
"},{"location":"provider/hashicorp-vault/#multiple-nested-values","title":"Multiple nested Values","text":"You can extract multiple keys from a nested secret using dataFrom
.
Given the following secret - assume its path is /dev/config
:
{\n \"foo\": {\n \"nested\": {\n \"bar\": \"mysecret\",\n \"baz\": \"bang\"\n }\n }\n}\n
You can set the remoteRef.property
to point to the nested key using a gjson expression.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: vault-example\nspec:\n # ...\n dataFrom:\n - extract:\n key: /dev/config\n property: foo.nested\n
That results in a secret with these values:
bar=mysecret\nbaz=bang\n
"},{"location":"provider/hashicorp-vault/#getting-multiple-secrets","title":"Getting multiple secrets","text":"You can extract multiple secrets from Hashicorp vault by using dataFrom.Find
Currently, dataFrom.Find
allows users to fetch secret names that match a given regexp pattern, or fetch secrets whose custom_metadata
tags match a predefined set.
Warning
The way hashicorp Vault currently allows LIST operations is through the existence of a secret metadata. If you delete the secret, you will also need to delete the secret's metadata or this will currently make Find operations fail.
Given the following secret - assume its path is /dev/config
:
{\n \"foo\": {\n \"nested\": {\n \"bar\": \"mysecret\",\n \"baz\": \"bang\"\n }\n }\n}\n
Also consider the following secret has the following custom_metadata
:
{\n \"environment\": \"dev\",\n \"component\": \"app-1\"\n}\n
It is possible to find this secret by all the following possibilities:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: vault-example\nspec:\n # ...\n dataFrom:\n - find: #will return every secret with 'dev' in it (including paths)\n name:\n regexp: dev\n - find: #will return every secret matching environment:dev tags from dev/ folder and beyond\n tags:\n environment: dev\n
will generate a secret with: {\n \"dev_config\":\"{\\\"foo\\\":{\\\"nested\\\":{\\\"bar\\\":\\\"mysecret\\\",\\\"baz\\\":\\\"bang\\\"}}}\"\n}\n
Currently, Find
operations are recursive throughout a given vault folder, starting on provider.Path
definition. It is recommended to narrow down the scope of search by setting a find.path
variable. This is also useful to automatically reduce the resulting secret key names:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: vault-example\nspec:\n # ...\n dataFrom:\n - find: #will return every secret from dev/ folder\n path: dev\n name:\n regexp: \".*\"\n - find: #will return every secret matching environment:dev tags from dev/ folder\n path: dev\n tags:\n environment: dev\n
Will generate a secret with: {\n \"config\":\"{\\\"foo\\\": {\\\"nested\\\": {\\\"bar\\\": \\\"mysecret\\\",\\\"baz\\\": \\\"bang\\\"}}}\"\n}\n
"},{"location":"provider/hashicorp-vault/#authentication","title":"Authentication","text":"We support five different modes for authentication: token-based, appRole, kubernetes-native, ldap, userPass, jwt/oidc, awsAuth and tlsCert, each one comes with it's own trade-offs. Depending on the authentication method you need to adapt your environment.
If you're using Vault namespaces, you can authenticate into one namespace and use the vault token against a different namespace, if desired.
"},{"location":"provider/hashicorp-vault/#token-based-authentication","title":"Token-based authentication","text":"A static token is stored in a Kind=Secret
and is used to authenticate with vault.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: vault-backend\n namespace: example\nspec:\n provider:\n vault:\n server: \"https://vault.acme.org\"\n path: \"secret\"\n version: \"v2\"\n auth:\n # points to a secret that contains a vault token\n # https://www.vaultproject.io/docs/auth/token\n tokenSecretRef:\n name: \"my-secret\"\n key: \"vault-token\"\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in tokenSecretRef
with the namespace where the secret resides."},{"location":"provider/hashicorp-vault/#approle-authentication-example","title":"AppRole authentication example","text":"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/v1beta1\nkind: SecretStore\nmetadata:\n name: vault-backend\n namespace: example\nspec:\n provider:\n vault:\n server: \"https://vault.acme.org\"\n path: \"secret\"\n version: \"v2\"\n auth:\n # VaultAppRole authenticates with Vault using the\n # App Role auth mechanism\n # https://www.vaultproject.io/docs/auth/approle\n appRole:\n # Path where the App Role authentication backend is mounted\n path: \"approle\"\n # RoleID configured in the App Role authentication backend\n roleId: \"db02de05-fa39-4855-059b-67221c5c2f63\"\n # Reference to a key in a K8 Secret that contains the App Role SecretId\n secretRef:\n name: \"my-secret\"\n key: \"secret-id\"\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in secretRef
with the namespace where the secret resides."},{"location":"provider/hashicorp-vault/#kubernetes-authentication","title":"Kubernetes authentication","text":"Kubernetes-native authentication has three options of obtaining credentials for vault:
- by using a service account jwt referenced in
serviceAccountRef
- by using the jwt from a
Kind=Secret
referenced by the secretRef
- by using transient credentials from the mounted service account token within the external-secrets operator
Vault validates the service account token by using the TokenReview API. \u26a0\ufe0f You have to bind the system:auth-delegator
ClusterRole to the service account that is used for authentication. Please follow the Vault documentation.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: vault-backend\n namespace: example\nspec:\n provider:\n vault:\n server: \"https://vault.acme.org\"\n path: \"secret\"\n version: \"v2\"\n auth:\n # Authenticate against Vault using a Kubernetes ServiceAccount\n # token stored in a Secret.\n # https://www.vaultproject.io/docs/auth/kubernetes\n kubernetes:\n # Path where the Kubernetes authentication backend is mounted in Vault\n mountPath: \"kubernetes\"\n # A required field containing the Vault Role to assume.\n role: \"demo\"\n # Optional service account field containing the name\n # of a kubernetes ServiceAccount\n serviceAccountRef:\n name: \"my-sa\"\n # Optional secret field containing a Kubernetes ServiceAccount JWT\n # used for authenticating with Vault\n secretRef:\n name: \"my-secret\"\n key: \"vault\"\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in serviceAccountRef
or in secretRef
, if used."},{"location":"provider/hashicorp-vault/#ldap-authentication","title":"LDAP authentication","text":"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/v1beta1\nkind: SecretStore\nmetadata:\n name: vault-backend\n namespace: example\nspec:\n provider:\n vault:\n server: \"https://vault.acme.org\"\n path: \"secret\"\n version: \"v2\"\n auth:\n # VaultLdap authenticates with Vault using the LDAP auth mechanism\n # https://www.vaultproject.io/docs/auth/ldap\n ldap:\n # Path where the LDAP authentication backend is mounted\n path: \"ldap\"\n # LDAP username\n username: \"username\"\n secretRef:\n name: \"my-secret\"\n key: \"ldap-password\"\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in secretRef
with the namespace where the secret resides."},{"location":"provider/hashicorp-vault/#userpass-authentication","title":"UserPass authentication","text":"UserPass 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/v1beta1\nkind: SecretStore\nmetadata:\n name: vault-backend\n namespace: example\nspec:\n provider:\n vault:\n server: \"https://vault.acme.org\"\n path: \"secret\"\n version: \"v2\"\n auth:\n # VaultUserPass authenticates with Vault using the UserPass auth mechanism\n # https://www.vaultproject.io/docs/auth/userpass\n userPass:\n # Path where the UserPass authentication backend is mounted\n path: \"userpass\"\n username: \"username\"\n secretRef:\n name: \"my-secret\"\n key: \"password\"\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in secretRef
with the namespace where the secret resides."},{"location":"provider/hashicorp-vault/#jwtoidc-authentication","title":"JWT/OIDC authentication","text":"JWT/OIDC uses either a JWT token stored in a Kind=Secret
and referenced by the secretRef
or a temporary Kubernetes service account token retrieved via the TokenRequest
API. Optionally a role
field can be defined in a Kind=SecretStore
or Kind=ClusterSecretStore
resource.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: vault-backend\n namespace: example\nspec:\n provider:\n vault:\n server: \"https://vault.acme.org\"\n path: \"secret\"\n version: \"v2\"\n auth:\n # VaultJwt authenticates with Vault using the JWT/OIDC auth mechanism\n # https://www.vaultproject.io/docs/auth/jwt\n jwt:\n # Path where the JWT authentication backend is mounted\n path: \"jwt\"\n # JWT role configured in a Vault server, optional.\n role: \"vault-jwt-role\"\n\n # Retrieve JWT token from a Kubernetes secret\n secretRef:\n name: \"my-secret\"\n key: \"jwt-token\"\n\n # ... or retrieve a Kubernetes service account token via the `TokenRequest` API\n kubernetesServiceAccountToken:\n serviceAccountRef:\n name: \"my-sa\"\n # `audiences` defaults to `[\"vault\"]` it not supplied\n audiences:\n - vault\n # `expirationSeconds` defaults to 10 minutes if not supplied\n expirationSeconds: 600\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in secretRef
with the namespace where the secret resides."},{"location":"provider/hashicorp-vault/#aws-iam-authentication","title":"AWS IAM authentication","text":"AWS IAM uses either a set of AWS Programmatic access credentials stored in a Kind=Secret
and referenced by the secretRef
or by getting the authentication token from an IRSA enabled service account
"},{"location":"provider/hashicorp-vault/#tls-certificates-authentication","title":"TLS certificates authentication","text":"TLS certificates auth method allows authentication using SSL/TLS client certificates which are either signed by a CA or self-signed. SSL/TLS client certificates are defined as having an ExtKeyUsage extension with the usage set to either ClientAuth or Any.
"},{"location":"provider/hashicorp-vault/#mutual-authentication-mtls","title":"Mutual authentication (mTLS)","text":"Under specific compliance requirements, the Vault server can be set up to enforce mutual authentication from clients across all APIs by configuring the server with tls_require_and_verify_client_cert = true
. This configuration differs fundamentally from the TLS certificates auth method. While the TLS certificates auth method allows the issuance of a Vault token through the /v1/auth/cert/login
API, the mTLS configuration solely focuses on TLS transport layer authentication and lacks any authorization-related capabilities. It's important to note that the Vault token must still be included in the request, following any of the supported authentication methods mentioned earlier.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: vault-backend\n namespace: example\nspec:\n provider:\n vault:\n server: \"https://vault.acme.org\"\n path: \"secret\"\n version: \"v2\"\n\n # client TLS related configuration\n caBundle: \"...\"\n tls:\n clientCert:\n name: \"my-cert-secret\"\n key: \"tls.crt\"\n secretRef:\n name: \"my-cert-secret\"\n key: \"tls.key\"\n\n # the authentication methods are not really related to the client TLS configuration\n auth:\n ...\n
"},{"location":"provider/hashicorp-vault/#access-key-id-secret-access-key","title":"Access Key ID & Secret Access Key","text":"You can store Access Key ID & Secret Access Key in a Kind=Secret
and reference it from a SecretStore.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: vault-backend-aws-iam\nspec:\n provider:\n vault:\n server: \"http://my.vault.server:8200\"\n path: secret\n version: v2\n namespace: <vault_namespace>\n auth:\n iam:\n # Path where the AWS auth method is enabled in Vault, e.g: \"aws/\". Defaults to aws\n path: aws\n # AWS Region. Defaults to us-east-1\n region: us-east-1\n # optional: assume role before fetching secrets\n role: arn:aws:iam::1234567890:role/role-a\n # Vault Role. In vault, a role describes an identity with a set of permissions, groups, or policies you want to attach a user of the secrets engine\n vaultRole: vault-role-for-aws-iam-auth\n # Optional. Placeholder to supply header X-Vault-AWS-IAM-Server-ID. It is an additional (optional) header used by Vault IAM auth method to mitigate against different types of replay attacks. More details here: https://developer.hashicorp.com/vault/docs/auth/aws\n vaultAwsIamServerID: example-vaultAwsIamServerID\n secretRef: #Use this method when you have static AWS creds.\n accessKeyIDSecretRef:\n name: vault-iam-creds-secret\n key: access-key\n secretAccessKeySecretRef:\n name: vault-iam-creds-secret\n key: secret-access-key\n sessionTokenSecretRef:\n name: vault-iam-creds-secret\n key: secret-session-token\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in accessKeyIDSecretRef
, secretAccessKeySecretRef
with the namespaces where the secrets reside.
"},{"location":"provider/hashicorp-vault/#eks-service-account-credentials","title":"EKS Service Account credentials","text":"This feature lets you use short-lived service account tokens to authenticate with AWS. You must have Service Account Volume Projection enabled - it is by default on EKS. See EKS guide on how to set up IAM roles for service accounts.
The big advantage of this approach is that ESO runs without any credentials.
apiVersion: v1\nkind: ServiceAccount\nmetadata:\n annotations:\n eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/my-irsa-enabled-role\n name: my-serviceaccount\n namespace: default\n
Reference the service account from above in the Secret Store:
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: vault-backend-aws-iam\nspec:\n provider:\n vault:\n server: \"http://my.vault.server:8200\"\n path: secret\n version: v2\n namespace: <vault_namespace>\n auth:\n iam:\n # Path where the AWS auth method is enabled in Vault, e.g: \"aws/\". Defaults to aws\n path: aws\n # AWS Region. Defaults to us-east-1\n region: us-east-1\n # Vault Role. In vault, a role describes an identity with a set of permissions, groups, or policies you want to attach a user of the secrets engine\n vaultRole: vault-role-for-aws-iam-auth\n # Optional. Placeholder to supply header X-Vault-AWS-IAM-Server-ID. It is an additional (optional) header used by Vault IAM auth method to mitigate against different types of replay attacks. More details here: https://developer.hashicorp.com/vault/docs/auth/aws\n vaultAwsIamServerID: example-vaultAwsIamServerID\n jwt:\n serviceAccountRef:\n name: my-serviceaccount #Provide service account with IRSA enabled\n
"},{"location":"provider/hashicorp-vault/#controllers-pod-identity","title":"Controller's Pod Identity","text":"This is basicially a zero-configuration authentication approach that inherits the credentials from the controller's pod identity
This approach assumes that appropriate IRSA setup is done controller's pod (i.e. IRSA enabled IAM role is created appropriately and controller's service account is annotated appropriately with the annotation \"eks.amazonaws.com/role-arn\" to enable IRSA)
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: vault-backend-aws-iam\nspec:\n provider:\n vault:\n server: \"http://my.vault.server:8200\"\n path: secret\n version: v2\n namespace: <vault_namespace>\n auth:\n iam:\n # Path where the AWS auth method is enabled in Vault, e.g: \"aws/\". Defaults to aws\n path: aws\n # AWS Region. Defaults to us-east-1\n region: us-east-1\n # Vault Role. In vault, a role describes an identity with a set of permissions, groups, or policies you want to attach a user of the secrets engine\n vaultRole: vault-role-for-aws-iam-auth\n # Optional. Placeholder to supply header X-Vault-AWS-IAM-Server-ID. It is an additional (optional) header used by Vault IAM auth method to mitigate against different types of replay attacks. More details here: https://developer.hashicorp.com/vault/docs/auth/aws\n vaultAwsIamServerID: example-vaultAwsIamServerID\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
for serviceAccountRef
with the namespace where the service account resides.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: vault-backend\n namespace: example\nspec:\n provider:\n vault:\n server: \"https://vault.acme.org\"\n path: \"secret\"\n version: \"v2\"\n auth:\n # VaultJwt authenticates with Vault using the JWT/OIDC auth mechanism\n # https://www.vaultproject.io/docs/auth/jwt\n jwt:\n # Path where the JWT authentication backend is mounted\n path: \"jwt\"\n # JWT role configured in a Vault server, optional.\n role: \"vault-jwt-role\"\n\n # Retrieve JWT token from a Kubernetes secret\n secretRef:\n name: \"my-secret\"\n key: \"jwt-token\"\n\n # ... or retrieve a Kubernetes service account token via the `TokenRequest` API\n kubernetesServiceAccountToken:\n serviceAccountRef:\n name: \"my-sa\"\n # `audiences` defaults to `[\"vault\"]` it not supplied\n audiences:\n - vault\n # `expirationSeconds` defaults to 10 minutes if not supplied\n expirationSeconds: 600\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in secretRef
with the namespace where the secret resides."},{"location":"provider/hashicorp-vault/#pushsecret","title":"PushSecret","text":"Vault supports PushSecret features which allow you to sync a given Kubernetes secret key into a Hashicorp vault secret. To do so, it is expected that the secret key is a valid JSON object or that the property
attribute has been specified under the remoteRef
. To use PushSecret, you need to give create
, read
and update
permissions to the path where you want to push secrets for both data
and metadata
of the secret. Use it with care!
Note
Since Vault KV v1 API is not supported with storing secrets metadata, PushSecret will add a custom_metadata
map to each secret in Vault that he will manage. It means pushing secret keys named custom_metadata
is not supported with Vault KV v1.
Here is an example of how to set up PushSecret
:
apiVersion: v1\nkind: Secret\nmetadata:\n name: source-secret\n namespace: default\nstringData:\n source-key1: \"{\\\"foo\\\":\\\"bar\\\"}\" # Needs to be a JSON\n source-key2: bar # Could be a plain string\n---\napiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\n name: pushsecret-example\n namespace: default\nspec:\n refreshInterval: 10s\n secretStoreRefs:\n - name: vault-secretstore\n kind: SecretStore\n selector:\n secret:\n name: source-secret\n data:\n - match:\n secretKey: source-key1\n remoteRef:\n remoteKey: vault/secret1\n - match:\n secretKey: source-key2\n remoteRef:\n remoteKey: vault/secret2\n property: foo\n
Note that in this example, we are generating two secrets in the target vault with the same structure but using different input formats.
"},{"location":"provider/hashicorp-vault/#vault-enterprise","title":"Vault Enterprise","text":""},{"location":"provider/hashicorp-vault/#eventual-consistency-and-performance-standby-nodes","title":"Eventual Consistency and Performance Standby Nodes","text":"When using Vault Enterprise with performance standby nodes, any follower can handle read requests immediately after the provider has authenticated. Since Vault becomes eventually consistent in this mode, these requests can fail if the login has not yet propagated to each server's local state.
Below are two different solutions to this scenario. You'll need to review them and pick the best fit for your environment and Vault configuration.
"},{"location":"provider/hashicorp-vault/#vault-namespaces","title":"Vault Namespaces","text":"Vault namespaces are an enterprise feature that support multi-tenancy. You can specify a vault namespace using the namespace
property when you define a SecretStore:
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: vault-backend\nspec:\n provider:\n vault:\n server: \"http://my.vault.server:8200\"\n # See https://www.vaultproject.io/docs/enterprise/namespaces\n namespace: \"ns1\"\n path: \"secret\"\n version: \"v2\"\n auth:\n # ...\n
"},{"location":"provider/hashicorp-vault/#authenticating-into-a-different-namespace","title":"Authenticating into a different namespace","text":"In some situations your authentication backend may be in one namespace, and your secrets in another. You can authenticate into one namespace, and use that token against another, by setting provider.vault.namespace
and provider.vault.auth.namespace
to different values. If provider.vault.auth.namespace
is unset but provider.vault.namespace
is, it will default to the provider.vault.namespace
value.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: vault-backend\nspec:\n provider:\n vault:\n server: \"http://my.vault.server:8200\"\n # See https://www.vaultproject.io/docs/enterprise/namespaces\n namespace: \"app-team\"\n path: \"secret\"\n version: \"v2\"\n auth:\n namespace: \"kubernetes-team\"\n # ...\n
"},{"location":"provider/hashicorp-vault/#read-your-writes","title":"Read Your Writes","text":"Vault 1.10.0 and later encodes information in the token to detect the case when a server is behind. If a Vault server does not have information about the provided token, Vault returns a 412 error so clients know to retry.
A method supported in versions Vault 1.7 and later is to utilize the X-Vault-Index
header returned on all write requests (including logins). Passing this header back on subsequent requests instructs the Vault client to retry the request until the server has an index greater than or equal to that returned with the last write. Obviously though, this has a performance hit because the read is blocked until the follower's local state has caught up.
"},{"location":"provider/hashicorp-vault/#forward-inconsistent","title":"Forward Inconsistent","text":"Vault also supports proxying inconsistent requests to the current cluster leader for immediate read-after-write consistency.
Vault 1.10.0 and later support a replication configuration that detects when forwarding should occur and does it transparently to the client.
In Vault 1.7 forwarding can be achieved by setting the X-Vault-Inconsistent
header to forward-active-node
. By default, this behavior is disabled and must be explicitly enabled in the server's replication configuration.
"},{"location":"provider/ibm-secrets-manager/","title":"IBM Secrets Manager","text":""},{"location":"provider/ibm-secrets-manager/#ibm-cloud-secret-manager","title":"IBM Cloud Secret Manager","text":"External Secrets Operator integrates with IBM Cloud Secret Manager for secret management.
"},{"location":"provider/ibm-secrets-manager/#authentication","title":"Authentication","text":"We support API key and trusted profile container authentication for this provider.
"},{"location":"provider/ibm-secrets-manager/#api-key-secret","title":"API key secret","text":"To generate your key (for test purposes we are going to generate from your user), first got to your (Access IAM) page:
On the left, click \"API Keys\", then click on \"Create\"
Pick a name and description for your key:
You have created a key. Press the eyeball to show the key. Copy or save it because keys can't be displayed or downloaded twice.
Create a secret containing your apiKey:
kubectl create secret generic ibm-secret --from-literal=apiKey='API_KEY_VALUE'\n
"},{"location":"provider/ibm-secrets-manager/#trusted-profile-container-auth","title":"Trusted Profile Container Auth","text":"To create the trusted profile, first got to your (Access IAM) page:
On the left, click \"Access groups\":
Pick a name and description for your group:
Click on \"Access\", and then on \"Assign\":
Click on \"Assign Access\", select \"IAM services\", and pick \"Secrets Manager\" from the pick-list:
Scope to \"All resources\" or \"Resources based on selected attributes\":
Select the \"SecretsReader\" service access policy:
Click \"Add\" and \"Assign\" to save the access group.
Next, on the left, click \"Trusted profiles\":
Press \"Create\" and pick a name and description for your profile:
Scope the profile's access.
The compute service type will be \"Red Hat OpenShift on IBM Cloud\". Additional restriction can be configured based on cloud or cluster metadata, or if \"Specific resources\" is selected, restriction to a specific cluster.
Click \"Add\" next to the previously created access group and then \"Create\", to associate the necessary service permissions.
To use the container-based authentication, it is necessary to map the API server serviceAccountToken
auth token to the \"external-secrets\" and \"external-secrets-webhook\" deployment descriptors. Example below:
...\nspec:\n ...\n template:\n ...\n spec:\n containers:\n ...\n volumeMounts:\n - mountPath: /var/run/secrets/tokens\n name: sa-token\n ...\n volumes:\n - name: sa-token\n projected:\n defaultMode: 420\n sources:\n - serviceAccountToken:\n audience: iam\n expirationSeconds: 3600\n path: sa-token\n...\n
"},{"location":"provider/ibm-secrets-manager/#update-secret-store","title":"Update secret store","text":"Be sure the ibm
provider is listed in the Kind=SecretStore
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: ibm-store\nspec:\n provider:\n ibm:\n serviceUrl: \"https://<SECRETS_MANAGER_ID>.<REGION>.secrets-manager.appdomain.cloud\"\n auth:\n containerAuth:\n profile: \"test container auth profile\"\n tokenLocation: \"/var/run/secrets/tokens/sa-token\"\n iamEndpoint: \"https://iam.cloud.ibm.com\"\n secretRef:\n secretApiKeySecretRef:\n name: ibm-secret\n key: apiKey\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in secretApiKeySecretRef
with the namespace where the secret resides. NOTE: Only secretApiKeySecretRef
or containerAuth
should be specified, depending on authentication method being used.
To find your serviceURL
, under your Secrets Manager resource, go to \"Endpoints\" on the left.
See here for a list of publicly available endpoints.
"},{"location":"provider/ibm-secrets-manager/#secret-types","title":"Secret Types","text":"We support the following secret types of IBM Secrets Manager:
arbitrary
username_password
iam_credentials
service_credentials
imported_cert
public_cert
private_cert
kv
To define the type of secret you would like to sync you need to prefix the secret id with the desired type. If the secret type is not specified it is defaulted to arbitrary
:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: ibm-sample\nspec:\n # [...]\n data:\n - secretKey: test\n remoteRef:\n # defaults to type=arbitrary\n key: xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n - secretKey: usr_pass\n remoteRef:\n key: username_password/yyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy\n property: username\n - secretKey: iam_cred\n remoteRef:\n key: iam_credentials/zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz\n - secretKey: srv_cred\n remoteRef:\n key: service_credentials/zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz\n - secretKey: imp_cert\n remoteRef:\n key: imported_cert/zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz\n property: certificate\n - secretKey: pub_cert\n remoteRef:\n key: public_cert/zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz\n property: certificate\n - secretKey: prvt_cert\n remoteRef:\n key: private_cert/zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz\n property: certificate\n - secretKey: kv_without_key\n remoteRef:\n key: kv/zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz\n - secretKey: kv_key\n remoteRef:\n key: kv/zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz\n property: 'keyid'\n - secretKey: kv_key_with_path\n remoteRef:\n key: kv/zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz\n property: 'key.path'\n
The behavior for the different secret types is as following:
"},{"location":"provider/ibm-secrets-manager/#arbitrary","title":"arbitrary","text":" remoteRef
retrieves a string from secrets manager and sets it for specified secretKey
dataFrom
retrieves a string from secrets manager and tries to parse it as JSON object setting the key:values pairs in resulting Kubernetes secret if successful
"},{"location":"provider/ibm-secrets-manager/#username_password","title":"username_password","text":" remoteRef
requires a property
to be set for either username
or password
to retrieve respective fields from the secrets manager secret and set in specified secretKey
dataFrom
retrieves both username
and password
fields from the secrets manager secret and sets appropriate key:value pairs in the resulting Kubernetes secret
"},{"location":"provider/ibm-secrets-manager/#iam_credentials","title":"iam_credentials","text":" remoteRef
retrieves an apikey from secrets manager and sets it for specified secretKey
dataFrom
retrieves an apikey from secrets manager and sets it for the apikey
Kubernetes secret key
"},{"location":"provider/ibm-secrets-manager/#service_credentials","title":"service_credentials","text":" remoteRef
retrieves the credentials object from secrets manager and sets it for specified secretKey
dataFrom
retrieves the credential object as a map from secrets manager and sets appropriate key:value pairs in the resulting Kubernetes secret
"},{"location":"provider/ibm-secrets-manager/#imported_cert-public_cert-and-private_cert","title":"imported_cert, public_cert, and private_cert","text":" remoteRef
requires a property
to be set for either certificate
, private_key
or intermediate
to retrieve respective fields from the secrets manager secret and set in specified secretKey
dataFrom
retrieves all certificate
, private_key
and intermediate
fields from the secrets manager secret and sets appropriate key:value pairs in the resulting Kubernetes secret
"},{"location":"provider/ibm-secrets-manager/#kv","title":"kv","text":" - An optional
property
field can be set to remoteRef
to select requested key from the KV secret. If not set, the entire secret will be returned dataFrom
retrieves a string from secrets manager and tries to parse it as JSON object setting the key:values pairs in resulting Kubernetes secret if successful. It could be either used with the methods Extract
to extract multiple key/value pairs from one secret (with optional property
field being supported as well) Find
to find secrets based on tags or regular expressions and allows finding multiple external secrets and map them into a single Kubernetes secret
{\n \"key1\": \"val1\",\n \"key2\": \"val2\",\n \"key3\": {\n \"keyA\": \"valA\",\n \"keyB\": \"valB\"\n },\n \"special.key\": \"special-content\"\n}\n
data:\n- secretKey: key3_keyB\n remoteRef:\n key: 'kv/aaaaa-bbbb-cccc-dddd-eeeeee'\n property: 'key3.keyB'\n- secretKey: special_key\n remoteRef:\n key: 'kv/aaaaa-bbbb-cccc-dddd-eeeeee'\n property: 'special.key'\n- secretKey: key_all\n remoteRef:\n key: 'kv/aaaaa-bbbb-cccc-dddd-eeeeee'\n
dataFrom:\n - extract:\n key: 'kv/fffff-gggg-iiii-dddd-eeeeee' #mandatory\n decodingStrategy: Base64 #optional\n
dataFrom:\n - find:\n name: #matches any secret name ending in foo-bar\n regexp: \"key\" #assumption that secrets are stored like /comp/key1, key2/trigger, and comp/trigger/keygen within the secret manager\n - find:\n tags: #matches any secrets with the following metadata labels\n environment: \"dev\"\n application: \"BFF\"\n
results in
data:\n # secrets from data\n key3_keyB: ... #valB\n special_key: ... #special-content\n key_all: ... #{\"key1\":\"val1\",\"key2\":\"val2\", ...\"special.key\":\"special-content\"}\n\n # secrets from dataFrom with extract method\n keyA: ... #1st key-value pair from JSON object\n keyB: ... #2nd key-value pair from JSON object\n keyC: ... #3rd key-value pair from JSON object\n\n # secrets from dataFrom with find regex method\n _comp_key1: ... #secret value for /comp/key1\n key2_trigger: ... #secret value for key2/trigger\n _comp_trigger_keygen: ... #secret value for comp/trigger/keygen\n\n # secrets from dataFrom with find tags method\n bffA: ...\n bffB: ...\n bffC: ...\n
"},{"location":"provider/ibm-secrets-manager/#creating-external-secret","title":"Creating external secret","text":"To create a kubernetes secret from the IBM Secrets Manager, a Kind=ExternalSecret
is needed. Below example creates a kubernetes secret based on ID of the secret in Secrets Manager.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: database-credentials\nspec:\n refreshInterval: 60m\n secretStoreRef:\n name: ibm-store\n kind: SecretStore\n target:\n name: database-credentials\n creationPolicy: Owner\n data:\n - secretKey: username\n remoteRef:\n key: username_password/<SECRET_ID>\n property: username\n - secretKey: password\n remoteRef:\n key: username_password/<SECRET_ID>\n property: password\n
Alternatively, the secret name along with its secret group name can be specified instead of secret ID to fetch the secret.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: database-credentials\nspec:\n refreshInterval: 60m\n secretStoreRef:\n name: ibm-store\n kind: SecretStore\n target:\n name: database-credentials\n creationPolicy: Owner\n data:\n - secretKey: username\n remoteRef:\n key: <SECRET_GROUP_NAME>/username_password/<SECRET_NAME>\n property: username\n - secretKey: password\n remoteRef:\n key: <SECRET_GROUP_NAME>/username_password/<SECRET_NAME>\n property: password\n
"},{"location":"provider/ibm-secrets-manager/#getting-the-kubernetes-secret","title":"Getting the Kubernetes secret","text":"The operator will fetch the IBM Secret Manager secret and inject it as a Kind=Secret
kubectl get secret secret-to-be-created -n <namespace> | -o jsonpath='{.data.test}' | base64 -d\n
"},{"location":"provider/ibm-secrets-manager/#populating-the-kubernetes-secret-with-metadata-from-ibm-secrets-manager-provider","title":"Populating the Kubernetes secret with metadata from IBM Secrets Manager Provider","text":"ESO can add metadata while creating or updating a Kubernetes secret to be reflected in its labels or annotations. The metadata could be any of the fields that are supported and returned in the response by IBM Secrets Manager.
In order for the user to opt in to adding metadata to secret, an existing optional field spec.dataFrom.extract.metadataPolicy
can be set to Fetch
, its default value being None
. In addition to this, templating provided be ESO can be leveraged to specify the key-value pairs of the resultant secrets' labels and annotation.
In order for the required metadata to be populated in the Kubernetes secret, combination of below should be provided in the External Secrets resource: 1. The required metadata should be specified under template.metadata.labels
or template.metadata.annotations
. 2. The required secret data should be specified under template.data
. 3. The spec.dataFrom.extract should be specified with details of the Secrets Manager secret with spec.dataFrom.extract.metadataPolicy
set to Fetch
. Below is an example, where secret_id
and updated_at
are the metadata of a secret in IBM Secrets Manager:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: database-credentials\n namespace: external-secrets\nspec:\n dataFrom:\n - extract:\n key: username_password/<SECRET_ID>\n metadataPolicy: Fetch # leveraging optional parameter, defaults to None\n secretKey: username\n secretStoreRef:\n kind: SecretStore\n name: ibm-store\n target:\n name: database-credentials\n template:\n engineVersion: v2\n data:\n secret: \"{{ .password }}\"\n metadata:\n annotations:\n secret_id: \"{{ .id }}\" # adding metadata key whose value would be added to the secret as a label\n updated_at: \"{{ .updated_at }}\"\n
While the secret is being reconciled, it will have the secret data along with the required annotations. Below is the example of the secret after reconciliation:
apiVersion: v1\ndata:\n secret: OHE0MFV5MGhQb2FmRjZTOGVva3dPQjRMeVZXeXpWSDlrSWgyR1BiVDZTMyc=\nimmutable: false\nkind: Secret\nmetadata:\n annotations:\n reconcile.external-secrets.io/data-hash: 02217008d13ed228e75cf6d26fe74324\n creationTimestamp: \"2023-05-04T08:41:24Z\"\n secret_id: \"1234\"\n updated_at: 2023-05-04T08:57:19Z\n name: database-credentials\n namespace: external-secrets\n ownerReferences:\n - apiVersion: external-secrets.io/v1beta1\n blockOwnerDeletion: true\n controller: true\n kind: ExternalSecret\n name: database-credentials\n uid: c2a018e7-1ac3-421b-bd3b-d9497204f843\n #resourceVersion: \"1803567\" #immutable for a user\n #uid: f5dff604-611b-4d41-9d65-b860c61a0b8d #immutable for a user\ntype: Opaque\n
"},{"location":"provider/keeper-security/","title":"Keeper Security","text":""},{"location":"provider/keeper-security/#keeper-security","title":"Keeper Security","text":"External Secrets Operator integrates with Keeper Security for secret management by using Keeper Secrets Manager.
"},{"location":"provider/keeper-security/#authentication","title":"Authentication","text":""},{"location":"provider/keeper-security/#secrets-manager-configuration-smc","title":"Secrets Manager Configuration (SMC)","text":"KSM can authenticate using One Time Access Token or Secret Manager Configuration. In order to work with External Secret Operator we need to configure a Secret Manager Configuration.
"},{"location":"provider/keeper-security/#creating-secrets-manager-configuration","title":"Creating Secrets Manager Configuration","text":"You can find the documentation for the Secret Manager Configuration creation here. Make sure you add the proper permissions to your device in order to be able to read and write secrets
Once you have created your SMC, you will get a config.json file or a base64 json encoded string containing the following keys:
hostname
clientId
privateKey
serverPublicKeyId
appKey
appOwnerPublicKey
This base64 encoded jsong string will be required to create your secretStores
"},{"location":"provider/keeper-security/#important-note-about-this-documentation","title":"Important note about this documentation","text":"The KepeerSecurity calls the entries in vaults 'Records'. These docs use the same term.
"},{"location":"provider/keeper-security/#update-secret-store","title":"Update secret store","text":"Be sure the keepersecurity
provider is listed in the Kind=SecretStore
---\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: keeper\nspec:\n provider:\n keepersecurity:\n authRef: # Refer to a kubernetes secret which holds the base64 encoded json string for the configuration\n name: keeper-configuration\n key: auth\n folderID: 1qdsiewFW-U # Folder ID where the secrets can be pushed. It requires write permissions\n
NOTE 1: folderID
target the folder ID where the secrets should be pushed to. It requires write permissions within the folder
NOTE 2: In case of a ClusterSecretStore
, Be sure to provide namespace
for SecretAccessKeyRef
with the namespace of the secret that we just created.
"},{"location":"provider/keeper-security/#external-secrets","title":"External Secrets","text":""},{"location":"provider/keeper-security/#behavior","title":"Behavior","text":" - How a Record is equated to an ExternalSecret:
remoteRef.key
is equated to a Record's ID remoteRef.property
is equated to one of the following options: - Fields: Record's field's Type
- CustomFields: Record's field's Label
- Files: Record's file's Name
- If empty, defaults to the complete Record in JSON format
remoteRef.version
is currently not supported.
dataFrom
: find.path
is currently not supported. find.name.regexp
is equated to one of the following options: - Fields: Record's field's Type
- CustomFields: Record's field's Label
- Files: Record's file's Name
find.tags
are not supported at this time.
NOTE: For complex types, like name, phone, bankAccount, which does not match with a single string value, external secrets will return the complete json string. Use the json template functions to decode.
"},{"location":"provider/keeper-security/#creating-external-secret","title":"Creating external secret","text":"To create a kubernetes secret from Keeper Secret Manager secret a Kind=ExternalSecret
is needed.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example\nspec:\n refreshInterval: 1h # rate SecretManager pulls KeeperSrucity\n secretStoreRef:\n kind: SecretStore\n name: example # name of the SecretStore (or kind specified)\n target:\n name: secret-to-be-created # name of the k8s Secret to be created\n creationPolicy: Owner\n dataFrom:\n - extract:\n key: OqPt3Vd37My7G8rTb-8Q # ID of the Keeper Record\n---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: regcred\n namespace: external-secrets\nspec:\n refreshInterval: 1m\n secretStoreRef:\n name: keeper\n kind: ClusterSecretStore\n target:\n name: regcred\n creationPolicy: Owner\n template:\n engineVersion: v2\n type: kubernetes.io/dockerconfigjson\n data:\n .dockerconfigjson: \"{\\\"auths\\\":{\\\"registry.example.com\\\":{\\\"username\\\":\\\"{{ .username }}\\\",\\\"password\\\":\\\"{{ .password }}\\\",\\\"auth\\\":\\\"{{(printf \\\"%s:%s\\\" .username .password) | b64enc }}\\\"}}}\"\n data:\n - secretKey: username\n remoteRef:\n key: OqPt3Vd37My7G8rTb-8Q\n property: login\n - secretKey: password\n remoteRef:\n key: OqPt3Vd37My7G8rTb-8Q\n property: password\n---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: config\n namespace: external-secrets\nspec:\n refreshInterval: 1m\n secretStoreRef:\n name: keeper\n kind: ClusterSecretStore\n target:\n name: credentials\n creationPolicy: Owner\n template:\n engineVersion: v2\n data:\n username: \"{{ .login }}\"\n password: \"{{ .password }}\"\n data:\n - secretKey: login\n remoteRef:\n key: OqPt3Vd37My7G8rTb-8Q\n property: login\n - secretKey: password\n remoteRef:\n key: OqPt3Vd37My7G8rTb-8Q\n property: password\n---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example\nspec:\n refreshInterval: 1h # rate SecretManager pulls KeeperSrucity\n secretStoreRef:\n kind: SecretStore\n name: example # name of the SecretStore (or kind specified)\n target:\n name: secret-to-be-created # name of the k8s Secret to be created\n creationPolicy: Owner\n template:\n engineVersion: v2\n data:\n username: \"{{ (fromJson .name).first }} {{ (fromJson .name).middle }} {{ (fromJson .name).last }}\" # decode json string into vars\n dataFrom:\n - extract:\n key: OqPt3Vd37My7G8rTb-8Q # ID of the Keeper Record\n
The operator will fetch the Keeper Secret Manager secret and inject it as a Kind=Secret
kubectl get secret secret-to-be-created -n <namespace> | -o jsonpath='{.data.dev-secret-test}' | base64 -d\n
"},{"location":"provider/keeper-security/#limitations","title":"Limitations","text":"There are some limitations using this provider.
- Keeper Secret Manager does not work with
General
Records types nor legacy non-typed records - Using tags
find.tags
is not supported by KSM - Using path
find.path
is not supported at the moment
"},{"location":"provider/keeper-security/#push-secrets","title":"Push Secrets","text":"Push Secret will only work with a custom KeeperSecurity Record type ExternalSecret
"},{"location":"provider/keeper-security/#behavior_1","title":"Behavior","text":" selector
: secret.name
: name of the kubernetes secret to be pushed data.match
: secretKey
: key on the selected secret to be pushed remoteRef.remoteKey
: Secret and key to be created on the remote provider - Format: SecretName/SecretKey
"},{"location":"provider/keeper-security/#creating-push-secret","title":"Creating push secret","text":"To create a Keeper Security record from kubernetes a Kind=PushSecret
is needed.
apiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\n name: example\nspec:\n secretStoreRefs:\n - name: keeper\n kind: SecretStore\n refreshInterval: \"1h\"\n deletionPolicy: Delete\n selector:\n secret:\n name: secret-name # k8s secret to be pushed\n data:\n - match:\n secretKey: secret-key # k8s key within the secret to be pushed\n remoteRef:\n remoteKey: remote-secret-name/remote-secret-key # This will create a record called \"remote-secret-name\" with a key \"remote-secret-key\"\n
"},{"location":"provider/keeper-security/#limitations_1","title":"Limitations","text":" - Only possible to push one key per secret at the moment
- If the record with the selected name exists but the key does not exists the record can not be updated. See Ability to add custom fields to existing secret #17
"},{"location":"provider/kubernetes/","title":"Kubernetes","text":"External Secrets Operator allows to retrieve secrets from a Kubernetes Cluster - this can be either a remote cluster or the local one where the operator runs in.
A SecretStore
points to a specific namespace in the target Kubernetes Cluster. You are able to retrieve all secrets from that particular namespace given you have the correct set of RBAC permissions.
The SecretStore
reconciler checks if you have read access for secrets in that namespace using SelfSubjectRulesReview
. See below on how to set that up properly.
"},{"location":"provider/kubernetes/#external-secret-spec","title":"External Secret Spec","text":"This provider supports the use of the Property
field. With it you point to the key of the remote secret. If you leave it empty it will json encode all key/value pairs.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: database-credentials\nspec:\n refreshInterval: 1h\n secretStoreRef:\n kind: SecretStore\n name: k8s-store # name of the SecretStore (or kind specified)\n target:\n name: database-credentials # name of the k8s Secret to be created\n data:\n - secretKey: username\n remoteRef:\n key: database-credentials\n property: username\n\n - secretKey: password\n remoteRef:\n key: database-credentials\n property: password\n\n # metadataPolicy to fetch all the labels and annotations in JSON format\n - secretKey: tags\n remoteRef:\n metadataPolicy: Fetch\n key: database-credentials\n\n # metadataPolicy to fetch all the labels in JSON format\n - secretKey: labels\n remoteRef:\n metadataPolicy: Fetch\n key: database-credentials\n property: labels\n\n # metadataPolicy to fetch a specific label (dev) from the source secret\n - secretKey: developer\n remoteRef:\n metadataPolicy: Fetch\n key: database-credentials\n property: labels.dev\n
"},{"location":"provider/kubernetes/#find-by-tag-name","title":"find by tag & name","text":"You can fetch secrets based on labels or names matching a regexp:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: fetch-tls-and-nginx\nspec:\n refreshInterval: 1h\n secretStoreRef:\n kind: SecretStore\n name: k8s-store\n target:\n name: fetch-tls-and-nginx\n dataFrom:\n - find:\n name:\n # match secret name with regexp\n regexp: \"tls-.*\"\n - find:\n tags:\n # fetch secrets based on label combination\n app: \"nginx\"\n
"},{"location":"provider/kubernetes/#target-api-server-configuration","title":"Target API-Server Configuration","text":"The servers url
can be omitted and defaults to kubernetes.default
. You have to provide a CA certificate in order to connect to the API Server securely. For your convenience, each namespace has a ConfigMap kube-root-ca.crt
that contains the CA certificate of the internal API Server (see RootCAConfigMap
feature gate). Use that if you want to connect to the same API server. If you want to connect to a remote API Server you need to fetch it and store it inside the cluster as ConfigMap or Secret. You may also define it inline as base64 encoded value using the caBundle
property.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: k8s-store-default-ns\nspec:\n provider:\n kubernetes:\n # with this, the store is able to pull only from `default` namespace\n remoteNamespace: default\n server:\n url: \"https://myapiserver.tld\"\n caProvider:\n type: ConfigMap\n name: kube-root-ca.crt\n key: ca.crt\n
"},{"location":"provider/kubernetes/#authentication","title":"Authentication","text":"It's possible to authenticate against the Kubernetes API using client certificates, a bearer token or service account. The operator enforces that exactly one authentication method is used. You can not use the service account that is mounted inside the operator, this is by design to avoid reading secrets across namespaces.
NOTE: SelfSubjectRulesReview
permission is required in order to validation work properly. Please use the following role as reference:
apiVersion: rbac.authorization.k8s.io/v1\nkind: Role\nmetadata:\n namespace: default\n name: eso-store-role\nrules:\n- apiGroups: [\"\"]\n resources:\n - secrets\n verbs:\n - get\n - list\n - watch\n- apiGroups:\n - authorization.k8s.io\n resources:\n - selfsubjectrulesreviews\n verbs:\n - create\n
"},{"location":"provider/kubernetes/#authenticating-with-bearertoken","title":"Authenticating with BearerToken","text":"Create a Kubernetes secret with a client token. There are many ways to acquire such a token, please refer to the Kubernetes Authentication docs.
apiVersion: v1\nkind: Secret\nmetadata:\n name: my-token\ndata:\n token: \"....\"\n
Create a SecretStore: The auth
section indicates that the type token
will be used for authentication, it includes the path to fetch the token. Set remoteNamespace
to the name of the namespace where your target secrets reside.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: k8s-store-token-auth\nspec:\n provider:\n kubernetes:\n # with this, the store is able to pull only from `default` namespace\n remoteNamespace: default\n server:\n # ...\n auth:\n token:\n bearerToken:\n name: my-token\n key: token\n
"},{"location":"provider/kubernetes/#authenticating-with-serviceaccount","title":"Authenticating with ServiceAccount","text":"Create a Kubernetes Service Account, please refer to the Service Account Tokens Documentation on how they work and how to create them.
$ kubectl create serviceaccount my-store\n
This Service Account needs permissions to read Secret
and create SelfSubjectRulesReview
resources. Please see the above role.
$ kubectl create rolebinding my-store --role=eso-store-role --serviceaccount=default:my-store\n
Create a SecretStore: the auth
section indicates that the type serviceAccount
will be used for authentication.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: k8s-store-sa-auth\nspec:\n provider:\n kubernetes:\n # with this, the store is able to pull only from `default` namespace\n remoteNamespace: default\n server:\n # ...\n auth:\n serviceAccount:\n name: \"my-store\"\n
"},{"location":"provider/kubernetes/#authenticating-with-client-certificates","title":"Authenticating with Client Certificates","text":"Create a Kubernetes secret which contains the client key and certificate. See Generate Certificates Documentations on how to create them.
$ kubectl create secret tls tls-secret --cert=path/to/tls.cert --key=path/to/tls.key\n
Reference the tls-secret
in the SecretStore
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: k8s-store-cert-auth\nspec:\n provider:\n kubernetes:\n # with this, the store is able to pull only from `default` namespace\n remoteNamespace: default\n server:\n # ...\n auth:\n cert:\n clientCert:\n name: \"tls-secret\"\n key: \"tls.crt\"\n clientKey:\n name: \"tls-secret\"\n key: \"tls.key\"\n
"},{"location":"provider/kubernetes/#pushsecret","title":"PushSecret","text":"The PushSecret functionality facilitates the replication of a Kubernetes Secret from one namespace or cluster to another. This feature proves useful in scenarios where you need to share sensitive information, such as credentials or configuration data, across different parts of your infrastructure.
To configure the PushSecret resource, you need to specify the following parameters:
-
Selector: Specify the selector that identifies the source Secret to be replicated. This selector allows you to target the specific Secret you want to share.
-
SecretKey: Set the SecretKey parameter to indicate the key within the source Secret that you want to replicate. This ensures that only the relevant information is shared.
-
RemoteRef.Property: In addition to the above parameters, the Kubernetes provider requires you to set the remoteRef.property
field. This field specifies the key of the remote Secret resource where the replicated value should be stored.
Here's an example:
apiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\n name: example\nspec:\n refreshInterval: 10s\n secretStoreRefs:\n - name: k8s-store-remote-ns\n kind: SecretStore\n selector:\n secret:\n name: pokedex-credentials\n data:\n - match:\n secretKey: best-pokemon\n remoteRef:\n remoteKey: remote-best-pokemon\n property: best-pokemon\n
To utilize the PushSecret feature effectively, the referenced SecretStore
requires specific permissions on the target cluster. In particular it requires create
, read
, update
and delete
permissions on the Secret resource:
apiVersion: rbac.authorization.k8s.io/v1\nkind: Role\nmetadata:\n namespace: remote\n name: eso-store-push-role\nrules:\n- apiGroups: [\"\"]\n resources:\n - secrets\n verbs:\n - get\n - list\n - watch\n - create\n - update\n - patch\n - delete\n- apiGroups:\n - authorization.k8s.io\n resources:\n - selfsubjectrulesreviews\n verbs:\n - create\n
"},{"location":"provider/kubernetes/#implementation-considerations","title":"Implementation Considerations","text":"When utilizing the PushSecret feature and configuring the permissions for the SecretStore, consider the following:
-
RBAC Configuration: Ensure that the Role-Based Access Control (RBAC) configuration for the SecretStore grants the appropriate permissions for creating, reading, and updating resources in the target cluster.
-
Least Privilege Principle: Adhere to the principle of least privilege when assigning permissions to the SecretStore. Only provide the minimum required permissions to accomplish the desired synchronization between Secrets.
-
Namespace or Cluster Scope: Depending on your specific requirements, configure the SecretStore to operate at the desired scope, whether it is limited to a specific namespace or encompasses the entire cluster. Consider the security and access control implications of your chosen scope.
"},{"location":"provider/onboardbase/","title":"Onboardbase","text":""},{"location":"provider/onboardbase/#onboardbase-secret-management","title":"Onboardbase Secret Management","text":"Sync secrets from Onboardbase to Kubernetes using the External Secrets Operator.
"},{"location":"provider/onboardbase/#authentication","title":"Authentication","text":""},{"location":"provider/onboardbase/#get-an-onboardbase-api-key","title":"Get an Onboardbase API Key.","text":"Create the Onboardbase API by opening the organization tab under your account settings:
And view them under the team name in your Account settings
Create an Onboardbase API secret with your API Key and Passcode value:
HISTIGNORE='*kubectl*' \\\n kubectl create secret generic onboardbase-auth-secret \\\n --from-literal=API_KEY=*****VZYKYJNMMEMK***** \\\n --from-literal=PASSCODE=api-key-passcode\n
Then to create a generic SecretStore
:
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: onboardbase-external-secret-store\nspec:\n provider:\n onboardbase:\n project: project-name # can be altered from here\n environment: development # can be altered from here\n auth:\n apiKey:\n name: onboardbase-auth-secret\n key: onboardbase-api-key \n passcode:\n name: onboardbase-auth-secret\n key: onboardbase-passcode\n
"},{"location":"provider/onboardbase/#use-cases","title":"Use Cases","text":"The below operations are possible with the Onboardbase provider:
- Fetch
- Fetch all
- Filter
Let's explore each use case using a fictional auth-api
Onboardbase project.
"},{"location":"provider/onboardbase/#1-fetch","title":"1. Fetch","text":"To sync one or more individual secrets:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: service-name-secrets\nspec:\n refreshInterval: 10m\n secretStoreRef:\n name: onboardbase-external-secret-store\n kind: SecretStore\n target:\n name: service-name-secrets\n data:\n - secretKey: DATABASE_URI\n remoteRef: \n key: DATABASE_URI\n
"},{"location":"provider/onboardbase/#2-fetch-all","title":"2. Fetch all","text":"To sync every secret from a config:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: service-name-secrets\nspec:\n refreshInterval: 10m\n secretStoreRef:\n name: onboardbase-external-secret-store\n kind: SecretStore\n target:\n name: service-name-secrets\n dataFrom:\n - find:\n name:\n regexp: .*\n
"},{"location":"provider/onboardbase/#3-filter","title":"3. Filter","text":"To filter secrets by path
(path prefix), name
(regular expression) or a combination of both:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: service-name-secrets\nspec:\n refreshInterval: 10m\n secretStoreRef:\n name: onboardbase-external-secret-store\n kind: SecretStore\n target:\n name: service-name-secrets\n dataFrom:\n - find:\n path: DATABASE_\n
"},{"location":"provider/oracle-vault/","title":"Oracle Vault","text":""},{"location":"provider/oracle-vault/#oracle-vault","title":"Oracle Vault","text":"External Secrets Operator integrates with OCI API to sync secret on the Oracle Vault to secrets held on the Kubernetes cluster.
"},{"location":"provider/oracle-vault/#authentication","title":"Authentication","text":"Specify the authenticating principal with principalType
, using UserPrincipal
, InstancePrincipal
, or Workload
as values. If principalType
or auth
are not set, the operator defaults to instance principal for authentication.
For user principal, userOCID, tenancyOCID, fingerprint and private key are required. The fingerprint and key file should be supplied in the secret with the rest being provided in the secret store.
See url for what region you you are accessing.
Select tenancy in the top right to see your user OCID as shown below.
Select your user in the top right to see your user OCID as shown below.
"},{"location":"provider/oracle-vault/#service-account-key-authentication","title":"Service account key authentication","text":"Create a secret containing your private key and fingerprint:
apiVersion: v1\nkind: Secret\nmetadata:\n name: oracle-secret\n labels: \n type: oracle\ntype: Opaque\nstringData:\n privateKey: \n fingerprint: \n
Your fingerprint will be attatched to your API key, once it has been generated. Found on the same page as the user OCID.
Once you click \"Add API Key\" you will be shown the following, where you can download the RSA key in the necessary PEM format for API requests. This will automatically generate a fingerprint.
"},{"location":"provider/oracle-vault/#update-secret-store","title":"Update secret store","text":"Be sure the oracle
provider is listed in the Kind=SecretStore
.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: example-instance-principal\nspec:\n provider:\n oracle:\n vault: # The vault OCID\n region: # The vault region\n principalType: InstancePrincipal\n\n---\n\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: example-workload-identity\nspec:\n provider:\n oracle:\n vault: # The vault OCID\n region: # The vault region\n principalType: Workload\n\n---\n\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: example-auth\nspec:\n provider:\n oracle:\n vault: # The vault OCID\n region: # The vault region\n principalType: UserPrincipal\n auth:\n user: # A user OCID\n tenancy: # A user's tenancy\n secretRef:\n privatekey:\n name: oracle-secret\n key: privateKey\n fingerprint:\n name: oracle-secret\n key: fingerprint\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in privatekey
and fingerprint
with the namespaces where the secrets reside.
"},{"location":"provider/oracle-vault/#creating-external-secret","title":"Creating external secret","text":"To create a kubernetes secret from the Oracle Cloud Interface secret aKind=ExternalSecret
is needed.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example\nspec:\n refreshInterval: 0.03m\n secretStoreRef:\n kind: SecretStore\n name: example # Must match SecretStore on the cluster\n target:\n name: secret-to-be-created # Name for the secret on the cluster\n creationPolicy: Owner\n dataFrom:\n - extract:\n key: the-secret-name\n
"},{"location":"provider/oracle-vault/#getting-the-kubernetes-secret","title":"Getting the Kubernetes secret","text":"The operator will fetch the project variable and inject it as a Kind=Secret
.
kubectl get secret oracle-secret-to-create -o jsonpath='{.data.dev-secret-test}' | base64 -d\n
"},{"location":"provider/oracle-vault/#pushsecrets-and-retrieving-multiple-secrets","title":"PushSecrets and retrieving multiple secrets.","text":"When using PushSecrets, the compartment OCID and encryption key OCID must be specified in the Oracle SecretStore. You can find your compartment and encrpytion key OCIDs in the OCI console.
If retrieving multiple secrets by tag or regex, only the compartment OCID must be specified.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: example-instance-principal\nspec:\n provider:\n oracle:\n vault: # The vault OCID\n compartment: # The compartment OCID where the vault is located. Required when using PushSecrets or retrieving multiple secrets.\n encryptionKey: # The OCID of the master encryption key that will be used for PushSecret encryption. Must exist in the vault, required when using PushSecrets.\n principalType: Workload\n
"},{"location":"provider/passbolt/","title":"Passbolt","text":"External Secrets Operator integrates with Passbolt API to sync Passbolt to secrets held on the Kubernetes cluster.
"},{"location":"provider/passbolt/#creating-a-passbolt-secret-store","title":"Creating a Passbolt secret store","text":"Be sure the passbolt
provider is listed in the Kind=SecretStore
and auth and host are set. The API requires a password and private key provided in a secret.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: passbolt\nspec:\n provider:\n passbolt:\n host: https://passbolt.passbolt.svc.cluster.local\n auth:\n passwordSecretRef:\n key: password\n name: passbolt-credentials\n privateKeySecretRef:\n key: privateKey\n name: passbolt-credentials\n
"},{"location":"provider/passbolt/#creating-an-external-secret","title":"Creating an external secret","text":"To sync a Passbolt secret to a Kubernetes secret, a Kind=ExternalSecret
is needed. By default the secret contains name, username, uri, password and description.
To only select a single property add the property
key.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: passbolt-example-simple\nspec:\n refreshInterval: \"15s\"\n secretStoreRef:\n name: passbolt\n kind: SecretStore\n target:\n name: passbolt-example\n data:\n - secretKey: full_secret\n remoteRef:\n key: e22487a8-feb8-4591-95aa-14b193930cb4 # Replace with ID of exising Passbolt secret\n - secretKey: password_only\n remoteRef:\n key: e22487a8-feb8-4591-95aa-14b193930cb4 # Replace with ID of exising Passbolt secret\n property: password # You can limit the secret to only display one property\n
The above external secret will lead to the creation of a secret in the following form:
apiVersion: v1\nkind: Secret\nmetadata:\n name: passbolt-example\ndata:\n full_secret: '{\"name\":\"passbolt-secret\",\"username\":\"some-username\",\"password\":\"supersecretpassword\",\"uri\":\"passbolt.com\",\"description\":\"some description\"}'\n password_only: supersecretpassword\ntype: Opaque\n
"},{"location":"provider/passbolt/#finding-a-secret-by-name","title":"Finding a secret by name","text":"Instead of retrieving secrets by ID you can also use dataFrom
to search for secrets by name.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: passbolt-example\nspec:\n refreshInterval: \"15s\"\n secretStoreRef:\n name: passbolt\n kind: SecretStore\n target:\n name: passbolt-example\n dataFrom:\n - find:\n name:\n regexp: \".*\"\n
"},{"location":"provider/pulumi/","title":"Pulumi ESC","text":""},{"location":"provider/pulumi/#pulumi-esc","title":"Pulumi ESC","text":"Sync environments, configs and secrets from Pulumi ESC to Kubernetes using the External Secrets Operator.
"},{"location":"provider/pulumi/#authentication","title":"Authentication","text":"Pulumi Access Tokens are recommended to access Pulumi ESC.
"},{"location":"provider/pulumi/#creating-a-secretstore","title":"Creating a SecretStore","text":"A Pulumi SecretStore can be created by specifying the organization
and environment
and referencing a Kubernetes secret containing the accessToken
.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: secret-store\nspec:\n provider:\n pulumi:\n organization: <NAME_OF_THE_ORGANIZATION>\n environment: <NAME_OF_THE_ENVIRONMENT>\n accessToken:\n secretRef:\n name: <NAME_OF_KUBE_SECRET>\n key: <KEY_IN_KUBE_SECRET>\n
If required, the API URL (apiUrl
) can be customized as well. If not specified, the default value is https://api.pulumi.com
.
"},{"location":"provider/pulumi/#referencing-secrets","title":"Referencing Secrets","text":"Secrets can be referenced by defining the key
containing the JSON path to the secret. Pulumi ESC secrets are internally organized as a JSON object.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: secret\nspec:\n refreshInterval: 5m\n secretStoreRef:\n kind: SecretStore\n name: secret-store\n data:\n - secretKey: <KEY_IN_KUBE_SECRET>\n remoteRef:\n key: <PULUMI_PATH_SYNTAX>\n
Note: key
is not following the JSON Path syntax, but rather the Pulumi path syntax.
"},{"location":"provider/pulumi/#examples","title":"Examples","text":" - root
- root.nested
- root[\"nested\"]
- root.double.nest
- root[\"double\"].nest
- root[\"double\"][\"nest\"]
- root.array[0]
- root.array[100]
- root.array[0].nested
- root.array[0][1].nested
- root.nested.array[0].double[1]
- root[\"key with \\\"escaped\\\" quotes\"]
- root[\"key with a .\"]
- [\"root key with \\\"escaped\\\" quotes\"].nested
- [\"root key with a .\"][100]
- root.array[*].field
- root.array[\"*\"].field
See Pulumi's documentation for more information.
"},{"location":"provider/scaleway/","title":"Scaleway","text":""},{"location":"provider/scaleway/#scaleway-secret-manager","title":"Scaleway Secret Manager","text":"External Secrets Operator integrates with Scaleway's Secret Manager.
"},{"location":"provider/scaleway/#creating-a-secretstore","title":"Creating a SecretStore","text":"You need an api key (access key + secret key) to authenticate with the secret manager. Both access and secret keys can be specified either directly in the config, or by referencing a kubernetes secret.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: secret-store\nspec:\n provider:\n scaleway:\n region: <REGION>\n projectId: <PROJECT_UUID>\n accessKey:\n value: <ACCESS_KEY>\n secretKey:\n secretRef:\n name: <NAME_OF_KUBE_SECRET>\n key: <KEY_IN_KUBE_SECRET>\n
"},{"location":"provider/scaleway/#referencing-secrets","title":"Referencing Secrets","text":"Secrets can be referenced by name, id or path, using the prefixes \"name:\"
, \"id:\"
and \"path:\"
respectively.
A PushSecret resource can only use a name reference.
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: secret\nspec:\n refreshInterval: 20s\n secretStoreRef:\n kind: SecretStore\n name: secret-store\n data:\n - secretKey: <KEY_IN_KUBE_SECRET>\n remoteRef:\n key: id:<SECRET_UUID>\n version: latest_enabled\n
"},{"location":"provider/senhasegura-dsm/","title":"senhasegura DevOps Secrets Management (DSM)","text":""},{"location":"provider/senhasegura-dsm/#senhasegura-devops-secrets-management-dsm","title":"senhasegura DevOps Secrets Management (DSM)","text":"External Secrets Operator integrates with senhasegura DevOps Secrets Management (DSM) module to sync application secrets to secrets held on the Kubernetes cluster.
"},{"location":"provider/senhasegura-dsm/#authentication","title":"Authentication","text":"Authentication in senhasegura uses DevOps Secrets Management (DSM) application authorization schema
You need to create an Kubernetes Secret with desired auth parameters, for example:
Instructions to setup authorizations and secrets in senhasegura DSM can be found at senhasegura docs for DSM and senhasegura YouTube channel
---\napiVersion: v1\nkind: Secret\nmetadata:\n name: senhasegura-dsm-auth\nstringData:\n CLIENT_SECRET: \"CHANGEME\"\n
"},{"location":"provider/senhasegura-dsm/#examples","title":"Examples","text":"To sync secrets between senhasegura and Kubernetes with External Secrets, we need to define an SecretStore or ClusterSecretStore resource with senhasegura provider, setting authentication in DSM module with Secret defined before
"},{"location":"provider/senhasegura-dsm/#secretstore","title":"SecretStore","text":"---\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: senhasegura\nspec:\n provider:\n senhasegura:\n url: \"https://senhasegura.changeme.com\"\n module: DSM # Select senhasegura DSM module to sync secrets\n auth:\n clientId: \"CHANGEME\"\n clientSecretSecretRef:\n name: senhasegura-dsm-auth\n key: CLIENT_SECRET\n ignoreSslCertificate: false # Optional\n
"},{"location":"provider/senhasegura-dsm/#clustersecretstore","title":"ClusterSecretStore","text":"---\napiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\n name: senhasegura\nspec:\n provider:\n senhasegura:\n url: \"https://senhasegura.changeme.com\"\n module: DSM # Select senhasegura DSM module to sync secrets\n auth:\n clientId: \"CHANGEME\"\n clientSecretSecretRef:\n name: senhasegura-dsm-auth\n key: CLIENT_SECRET\n namespace: senhasegura # Namespace of Secret \"senhasegura-dsm-auth\"\n ignoreSslCertificate: false # Optional\n
"},{"location":"provider/senhasegura-dsm/#syncing-secrets","title":"Syncing secrets","text":"In examples below, consider that three secrets (api-settings, db-settings and hsm-settings) are defined in senhasegura DSM
**Secret Identifier: ** api-settings
Secret data:
URL=https://example.com/api/example\nTOKEN=example-token-value\n
**Secret Identifier: ** db-settings
Secret data:
DB_HOST='db.example'\nDB_PORT='5432'\nDB_USERNAME='example'\nDB_PASSWORD='example'\n
**Secret Identifier: ** hsm-settings
Secret data:
HSM_ADDRESS='hsm.example'\nHSM_PORT='9223'\n
"},{"location":"provider/senhasegura-dsm/#sync-dsm-secrets-using-secret-identifiers","title":"Sync DSM secrets using Secret Identifiers","text":"You can fetch all key/value pairs for a given secret identifier If you leave the remoteRef.property empty. This returns the json-encoded secret value for that path.
If you only need a specific key, you can select it using remoteRef.property as the key name.
In this method, you can overwrites data name in Kubernetes Secret object (e.g API_SETTINGS and API_SETTINGS_TOKEN)
---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example-secret\nspec:\n refreshInterval: \"30s\"\n secretStoreRef:\n name: senhasegura\n kind: SecretStore\n target:\n name: example-secret\n data:\n # Define API_SETTINGS Kubernetes Secret key, with json-encoded values from senhasegura secret with identifier \"api-settings\"\n - secretKey: API_SETTINGS\n remoteRef:\n key: api-settings # Secret Identifier in senhasegura\n # Define API_SETTINGS_TOKEN Kubernetes Secret key, with single secret key (TOKEN) from senhasegura as string\n - secretKey: API_SETTINGS_TOKEN\n remoteRef:\n key: api-settings # Secret Identifier in senhasegura\n property: TOKEN # Optional, Key name within secret\n
Kubernetes Secret will be create with follow .data.X
API_SETTINGS='[{\"TOKEN\":\"example-token-value\",\"URL\":\"https://example.com/api/example\"}]'\nAPI_SETTINGS_TOKEN='example-token-value'\n
"},{"location":"provider/senhasegura-dsm/#sync-dsm-secrets-using-secret-identifiers-with-automatically-name-assignments","title":"Sync DSM secrets using Secret Identifiers with automatically name assignments","text":"If your app requires multiples secrets, it is not required to create multiple ExternalSecret resources, you can aggregate secrets using a single ExternalSecret resource
In this method, every secret data in senhasegura creates an Kubernetes Secret .data.X
field
---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: example-secret\nspec:\n refreshInterval: \"30s\"\n secretStoreRef:\n name: senhasegura\n kind: SecretStore\n target:\n name: example-secret\n dataFrom:\n # Define Kubernetes Secret key with any k/v pair in senhasegura Secret with identifier \"api-settings\" or \"db-settings\"\n - extract:\n key: api-settings\n - extract:\n key: db-settings\n
Kubernetes Secret will be create with follow .data.X
URL='https://example.com/api/example'\nTOKEN='example-token-value'\nDB_HOST='db.example'\nDB_PORT='5432'\nDB_USERNAME='example'\nDB_PASSWORD='example'\n
"},{"location":"provider/webhook/","title":"Webhook","text":""},{"location":"provider/webhook/#generic-webhook","title":"Generic Webhook","text":"External Secrets Operator can integrate with simple web apis by specifying the endpoint
"},{"location":"provider/webhook/#example","title":"Example","text":"First, create a SecretStore with a webhook backend. We'll use a static user/password root
:
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: webhook-backend\nspec:\n provider:\n webhook:\n url: \"http://httpbin.org/get?parameter={{ .remoteRef.key }}\"\n result:\n jsonPath: \"$.args.parameter\"\n headers:\n Content-Type: application/json\n Authorization: Basic {{ print .auth.username \":\" .auth.password | b64enc }}\n secrets:\n - name: auth\n secretRef:\n name: webhook-credentials\n---\napiVersion: v1\nkind: Secret\nmetadata:\n name: webhook-credentials\ndata:\n username: dGVzdA== # \"test\"\n password: dGVzdA== # \"test\"\n
NB: This is obviously not practical because it just returns the key as the result, but it shows how it works
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in all secrets
references with the namespaces where the secrets reside.
Now create an ExternalSecret that uses the above SecretStore:
apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: webhook-example\nspec:\n refreshInterval: \"15s\"\n secretStoreRef:\n name: webhook-backend\n kind: SecretStore\n target:\n name: example-sync\n data:\n - secretKey: foobar\n remoteRef:\n key: secret\n---\n# will create a secret with:\nkind: Secret\nmetadata:\n name: example-sync\ndata:\n foobar: c2VjcmV0\n
"},{"location":"provider/webhook/#limitations","title":"Limitations","text":"Webhook does not support authorization, other than what can be sent by generating http headers
Note
If a webhook endpoint for a given ExternalSecret
returns a 404 status code, the secret is considered to have been deleted. This will trigger the deletionPolicy
set on the ExternalSecret
.
"},{"location":"provider/webhook/#templating","title":"Templating","text":"Generic WebHook provider uses the templating engine to generate the API call. It can be used in the url, headers, body and result.jsonPath fields.
The provider inserts the secret to be retrieved in the object named remoteRef
.
In addition, secrets can be added as named objects, for example to use in authorization headers. Each secret has a name
property which determines the name of the object in the templating engine.
"},{"location":"provider/webhook/#all-parameters","title":"All Parameters","text":"apiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\n name: statervault\nspec:\n provider:\n webhook:\n # Url to call. Use templating engine to fill in the request parameters\n url: <url>\n # http method, defaults to GET\n method: <method>\n # Timeout in duration (1s, 1m, etc)\n timeout: 1s\n result:\n # [jsonPath](https://jsonpath.com) syntax, which also can be templated\n jsonPath: <jsonPath>\n # Map of headers, can be templated\n headers:\n <Header-Name>: <header contents>\n # Body to sent as request, can be templated (optional)\n body: <body>\n # List of secrets to expose to the templating engine\n secrets:\n # Use this name to refer to this secret in templating, above\n - name: <name>\n secretRef:\n namespace: <namespace> # Only used in ClusterSecretStores\n name: <name>\n # Add CAs here for the TLS handshake\n caBundle: <base64 encoded cabundle>\n caProvider:\n type: Secret or ConfigMap\n name: <name of secret or configmap>\n namespace: <namespace> # Only used in ClusterSecretStores\n key: <key inside secret>\n
"},{"location":"provider/webhook/#webhook-as-generators","title":"Webhook as generators","text":"You can also leverage webhooks as generators, following the same syntax. The only difference is that the webhook generator needs its source secrets to be labeled, as opposed to webhook secretstores. Please see the generator-webhook documentation for more information.
"},{"location":"provider/yandex-certificate-manager/","title":"Yandex Certificate Manager","text":""},{"location":"provider/yandex-certificate-manager/#yandex-certificate-manager","title":"Yandex Certificate Manager","text":"External Secrets Operator integrates with Yandex Certificate Manager for secret management.
"},{"location":"provider/yandex-certificate-manager/#prerequisites","title":"Prerequisites","text":" - External Secrets Operator installed
- Yandex.Cloud CLI installed
"},{"location":"provider/yandex-certificate-manager/#authentication","title":"Authentication","text":"At the moment, authorized key authentication is only supported:
- Create a service account in Yandex.Cloud:
yc iam service-account create --name eso-service-account\n
- Create an authorized key for the service account and save it to
authorized-key.json
file: yc iam key create \\\n --service-account-name eso-service-account \\\n --output authorized-key.json\n
- Create a k8s secret containing the authorized key saved above:
kubectl create secret generic yc-auth --from-file=authorized-key=authorized-key.json\n
- Create a SecretStore pointing to
yc-auth
k8s secret: apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: secret-store\nspec:\n provider:\n yandexcertificatemanager:\n auth:\n authorizedKeySecretRef:\n name: yc-auth\n key: authorized-key\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in all authorizedKeySecretRef
with the namespace where the secret resides.
"},{"location":"provider/yandex-certificate-manager/#creating-external-secret","title":"Creating external secret","text":"To make External Secrets Operator sync a k8s secret with a Certificate Manager certificate:
- Create a Certificate Manager certificate (follow the instructions), if not already created.
- Assign the
certificate-manager.certificates.downloader
role for accessing the certificate content to the service account used for authentication (*****
is the certificate ID): yc cm certificate add-access-binding \\\n --id ***** \\\n --service-account-name eso-service-account \\\n --role certificate-manager.certificates.downloader\n
Run the following command to ensure that the correct access binding has been added: yc cm certificate list-access-bindings --id *****\n
- Create an ExternalSecret pointing to
secret-store
and the certificate in Certificate Manager: apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: external-secret\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: secret-store\n kind: SecretStore\n target:\n name: k8s-secret # the target k8s secret name\n template:\n type: kubernetes.io/tls\n data:\n - secretKey: tls.crt # the target k8s secret key\n remoteRef:\n key: ***** # the certificate ID\n property: chain\n - secretKey: tls.key # the target k8s secret key\n remoteRef:\n key: ***** # the certificate ID\n property: privateKey\n
The following property values are possible: chain
\u2013 to fetch PEM-encoded certificate chain privateKey
\u2013 to fetch PEM-encoded private key chainAndPrivateKey
or missing property \u2013 to fetch both chain and private key
The operator will fetch the Yandex Certificate Manager certificate and inject it as a Kind=Secret
kubectl get secret k8s-secret -ojson | jq '.\"data\".\"tls.crt\"' -r | base64 --decode\nkubectl get secret k8s-secret -ojson | jq '.\"data\".\"tls.key\"' -r | base64 --decode\n
"},{"location":"provider/yandex-lockbox/","title":"Yandex Lockbox","text":""},{"location":"provider/yandex-lockbox/#yandex-lockbox","title":"Yandex Lockbox","text":"External Secrets Operator integrates with Yandex Lockbox for secret management.
"},{"location":"provider/yandex-lockbox/#prerequisites","title":"Prerequisites","text":" - External Secrets Operator installed
- Yandex.Cloud CLI installed
"},{"location":"provider/yandex-lockbox/#authentication","title":"Authentication","text":"At the moment, authorized key authentication is only supported:
- Create a service account in Yandex.Cloud:
yc iam service-account create --name eso-service-account\n
- Create an authorized key for the service account and save it to
authorized-key.json
file: yc iam key create \\\n --service-account-name eso-service-account \\\n --output authorized-key.json\n
- Create a k8s secret containing the authorized key saved above:
kubectl create secret generic yc-auth --from-file=authorized-key=authorized-key.json\n
- Create a SecretStore pointing to
yc-auth
k8s secret: apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: secret-store\nspec:\n provider:\n yandexlockbox:\n auth:\n authorizedKeySecretRef:\n name: yc-auth\n key: authorized-key\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in all authorizedKeySecretRef
with the namespace where the secret resides.
"},{"location":"provider/yandex-lockbox/#creating-external-secret","title":"Creating external secret","text":"To make External Secrets Operator sync a k8s secret with a Lockbox secret:
- Create a Lockbox secret, if not already created:
yc lockbox secret create \\\n --name lockbox-secret \\\n --payload '[{\"key\": \"password\",\"textValue\": \"p@$$w0rd\"}]'\n
- Assign the
lockbox.payloadViewer
role for accessing the lockbox-secret
payload to the service account used for authentication: yc lockbox secret add-access-binding \\\n --name lockbox-secret \\\n --service-account-name eso-service-account \\\n --role lockbox.payloadViewer\n
Run the following command to ensure that the correct access binding has been added: yc lockbox secret list-access-bindings --name lockbox-secret\n
- Create an ExternalSecret pointing to
secret-store
and lockbox-secret
: apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\n name: external-secret\nspec:\n refreshInterval: 1h\n secretStoreRef:\n name: secret-store\n kind: SecretStore\n target:\n name: k8s-secret # the target k8s secret name\n data:\n - secretKey: password # the target k8s secret key\n remoteRef:\n key: ***** # ID of lockbox-secret\n property: password # (optional) payload entry key of lockbox-secret\n
The operator will fetch the Yandex Lockbox secret and inject it as a Kind=Secret
kubectl get secret k8s-secret -n <namespace> | -o jsonpath='{.data.password}' | base64 -d\n
"},{"location":"snippets/provider-aws-access/","title":"Provider aws access","text":""},{"location":"snippets/provider-aws-access/#aws-authentication","title":"AWS Authentication","text":""},{"location":"snippets/provider-aws-access/#controllers-pod-identity","title":"Controller's Pod Identity","text":"Note: If you are using Parameter Store replace service: SecretsManager
with service: ParameterStore
in all examples below.
This is basicially a zero-configuration authentication method that inherits the credentials from the runtime environment using the aws sdk default credential chain.
You can attach a role to the pod using IRSA, kiam or kube2iam. When no other authentication method is configured in the Kind=Secretstore
this role is used to make all API calls against AWS Secrets Manager or SSM Parameter Store.
Based on the Pod's identity you can do a sts:assumeRole
before fetching the secrets to limit access to certain keys in your provider. This is optional.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: team-b-store\nspec:\n provider:\n aws:\n service: SecretsManager\n region: eu-central-1\n # optional: do a sts:assumeRole before fetching secrets\n role: team-b\n
"},{"location":"snippets/provider-aws-access/#access-key-id-secret-access-key","title":"Access Key ID & Secret Access Key","text":"You can store Access Key ID & Secret Access Key in a Kind=Secret
and reference it from a SecretStore.
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: team-b-store\nspec:\n provider:\n aws:\n service: SecretsManager\n region: eu-central-1\n # optional: assume role before fetching secrets\n role: team-b\n auth:\n secretRef:\n accessKeyIDSecretRef:\n name: awssm-secret\n key: access-key\n secretAccessKeySecretRef:\n name: awssm-secret\n key: secret-access-key\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
in accessKeyIDSecretRef
, secretAccessKeySecretRef
with the namespaces where the secrets reside.
"},{"location":"snippets/provider-aws-access/#eks-service-account-credentials","title":"EKS Service Account credentials","text":"This feature lets you use short-lived service account tokens to authenticate with AWS. You must have Service Account Volume Projection enabled - it is by default on EKS. See EKS guide on how to set up IAM roles for service accounts.
The big advantage of this approach is that ESO runs without any credentials.
apiVersion: v1\nkind: ServiceAccount\nmetadata:\n annotations:\n eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/team-a\n name: my-serviceaccount\n namespace: default\n
Reference the service account from above in the Secret Store:
apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\n name: secretstore-sample\nspec:\n provider:\n aws:\n service: SecretsManager\n region: eu-central-1\n auth:\n jwt:\n serviceAccountRef:\n name: my-serviceaccount\n
NOTE: In case of a ClusterSecretStore
, Be sure to provide namespace
for serviceAccountRef
with the namespace where the service account resides.
"},{"location":"snippets/provider-aws-access/#custom-endpoints","title":"Custom Endpoints","text":"You can define custom AWS endpoints if you want to use regional, vpc or custom endpoints. See List of endpoints for Secrets Manager, Secure Systems Manager and Security Token Service.
Use the following environment variables to point the controller to your custom endpoints. Note: All resources managed by this controller are affected.
ENV VAR DESCRIPTION AWS_SECRETSMANAGER_ENDPOINT Endpoint for the Secrets Manager Service. The controller uses this endpoint to fetch secrets from AWS Secrets Manager. AWS_SSM_ENDPOINT Endpoint for the AWS Secure Systems Manager. The controller uses this endpoint to fetch secrets from SSM Parameter Store. AWS_STS_ENDPOINT Endpoint for the Security Token Service. The controller uses this endpoint when creating a session and when doing assumeRole
or assumeRoleWithWebIdentity
calls."}]}
\ No newline at end of file
diff --git a/main/sitemap.xml b/main/sitemap.xml
old mode 100755
new mode 100644
diff --git a/main/sitemap.xml.gz b/main/sitemap.xml.gz
old mode 100755
new mode 100644
index dbfc0ddcd9d..182ad939677
Binary files a/main/sitemap.xml.gz and b/main/sitemap.xml.gz differ
diff --git a/main/snippets/1password-connect-server-deployment.yaml b/main/snippets/1password-connect-server-deployment.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/1password-connect-server-secret.yaml b/main/snippets/1password-connect-server-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/1password-external-secret-my-cert.yaml b/main/snippets/1password-external-secret-my-cert.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/1password-external-secret-my-env-config.yaml b/main/snippets/1password-external-secret-my-env-config.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/1password-secret-store.yaml b/main/snippets/1password-secret-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/1password-token-secret.yaml b/main/snippets/1password-token-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/akeyless-credentials-secret.yaml b/main/snippets/akeyless-credentials-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/akeyless-external-secret-json.yaml b/main/snippets/akeyless-external-secret-json.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/akeyless-external-secret.yaml b/main/snippets/akeyless-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/akeyless-secret-store-k8s-auth.yaml b/main/snippets/akeyless-secret-store-k8s-auth.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/akeyless-secret-store.yaml b/main/snippets/akeyless-secret-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/aws-anchore-engine-access-credentials-external-secret.yaml b/main/snippets/aws-anchore-engine-access-credentials-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/aws-jenkins-credential-github-ssh-external-secret.yaml b/main/snippets/aws-jenkins-credential-github-ssh-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/aws-jenkins-credential-sonarqube-api-token-external-secret.yaml b/main/snippets/aws-jenkins-credential-sonarqube-api-token-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/aws-jenkins-credentials-harbor-chart-robot-external-secret.yaml b/main/snippets/aws-jenkins-credentials-harbor-chart-robot-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/aws-parameter-store.yaml b/main/snippets/aws-parameter-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/aws-sm-external-secret.yaml b/main/snippets/aws-sm-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/aws-sm-push-secret-with-metadata.yaml b/main/snippets/aws-sm-push-secret-with-metadata.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/aws-sm-store-secretsmanager-config.yaml b/main/snippets/aws-sm-store-secretsmanager-config.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/aws-sm-store.yaml b/main/snippets/aws-sm-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/azkv-credentials-secret.yaml b/main/snippets/azkv-credentials-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/azkv-datafrom-external-secret.yaml b/main/snippets/azkv-datafrom-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/azkv-external-secret.yaml b/main/snippets/azkv-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/azkv-pkcs12-cert-external-secret.yaml b/main/snippets/azkv-pkcs12-cert-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/azkv-pushsecret-certificate.yaml b/main/snippets/azkv-pushsecret-certificate.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/azkv-pushsecret-key.yaml b/main/snippets/azkv-pushsecret-key.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/azkv-pushsecret-secret.yaml b/main/snippets/azkv-pushsecret-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/azkv-secret-store-mi.yaml b/main/snippets/azkv-secret-store-mi.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/azkv-secret-store.yaml b/main/snippets/azkv-secret-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/azkv-workload-identity-mounted.yaml b/main/snippets/azkv-workload-identity-mounted.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/azkv-workload-identity-secretref.yaml b/main/snippets/azkv-workload-identity-secretref.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/azkv-workload-identity.yaml b/main/snippets/azkv-workload-identity.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/basic-external-secret.yaml b/main/snippets/basic-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/basic-secret-store.yaml b/main/snippets/basic-secret-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/bitwarden-cli-deployment.yaml b/main/snippets/bitwarden-cli-deployment.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/bitwarden-cli-secrets.yaml b/main/snippets/bitwarden-cli-secrets.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/bitwarden-secret-store.yaml b/main/snippets/bitwarden-secret-store.yaml
old mode 100755
new mode 100644
index 05201c1ce96..d398e976fb7
--- a/main/snippets/bitwarden-secret-store.yaml
+++ b/main/snippets/bitwarden-secret-store.yaml
@@ -34,4 +34,14 @@ spec:
url: "http://bitwarden-cli:8087/object/item/{{ .remoteRef.key }}"
result:
jsonPath: "$.data.notes"
+---
+apiVersion: external-secrets.io/v1beta1
+kind: ClusterSecretStore
+metadata:
+ name: bitwarden-attachments
+spec:
+ provider:
+ webhook:
+ url: "http://bitwarden-cli:8087/object/attachment/{{ .remoteRef.property }}?itemid={{ .remoteRef.key }}"
+ result: {}
{% endraw %}
diff --git a/main/snippets/bitwarden-secret.yaml b/main/snippets/bitwarden-secret.yaml
old mode 100755
new mode 100644
index 81e279a2327..d91d67ccae3
--- a/main/snippets/bitwarden-secret.yaml
+++ b/main/snippets/bitwarden-secret.yaml
@@ -2,11 +2,11 @@
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
- name: my-db-secrets
+ name: my-secrets
namespace: default
spec:
target:
- name: my-db-secrets
+ name: my-secrets
deletionPolicy: Delete
template:
type: Opaque
@@ -23,6 +23,8 @@ spec:
postgresql://{{ .username }}:{{ .password }}@my-postgresql:5432/mydb
service_account_key: |-
{{ .service_account_key }}
+ ssh_pub_key: |-
+ {{ .ssh_pub_key }}
data:
- secretKey: username
sourceRef:
@@ -63,4 +65,12 @@ spec:
kind: ClusterSecretStore # or SecretStore
remoteRef:
key: service_account_key
+ - secretKey: ssh_pub_key
+ sourceRef:
+ storeRef:
+ name: bitwarden-attachments
+ kind: ClusterSecretStore # or SecretStore
+ remoteRef:
+ key: aaaabbbb-cccc-dddd-eeee-000011112222
+ property: id_rsa.pub
{% endraw %}
diff --git a/main/snippets/chef-external-secret.yaml b/main/snippets/chef-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/cloak-external-secret.yaml b/main/snippets/cloak-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/cloak-proxy-deployment.yaml b/main/snippets/cloak-proxy-deployment.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/cloak-proxy-service.yaml b/main/snippets/cloak-proxy-service.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/cloak-secret-store.yaml b/main/snippets/cloak-secret-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/conjur-ca-bundle.yaml b/main/snippets/conjur-ca-bundle.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/conjur-external-secret-find.yaml b/main/snippets/conjur-external-secret-find.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/conjur-external-secret.yaml b/main/snippets/conjur-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/conjur-secret-store-apikey.yaml b/main/snippets/conjur-secret-store-apikey.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/conjur-secret-store-jwt-secret-ref.yaml b/main/snippets/conjur-secret-store-jwt-secret-ref.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/conjur-secret-store-jwt-service-account-ref.yaml b/main/snippets/conjur-secret-store-jwt-service-account-ref.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/controller-class-store.yaml b/main/snippets/controller-class-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/dashboard.json b/main/snippets/dashboard.json
old mode 100755
new mode 100644
diff --git a/main/snippets/datafrom-rewrite-conflict.yaml b/main/snippets/datafrom-rewrite-conflict.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/datafrom-rewrite-invalid-characters.yaml b/main/snippets/datafrom-rewrite-invalid-characters.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/datafrom-rewrite-remove-path.yaml b/main/snippets/datafrom-rewrite-remove-path.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/doppler-fetch-all-secrets.yaml b/main/snippets/doppler-fetch-all-secrets.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/doppler-fetch-secret.yaml b/main/snippets/doppler-fetch-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/doppler-filtered-secrets.yaml b/main/snippets/doppler-filtered-secrets.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/doppler-generic-secret-store.yaml b/main/snippets/doppler-generic-secret-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/doppler-name-transformer-external-secret.yaml b/main/snippets/doppler-name-transformer-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/doppler-name-transformer-secret-store.yaml b/main/snippets/doppler-name-transformer-secret-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/doppler-parse-json-secret.yaml b/main/snippets/doppler-parse-json-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/doppler-secrets-download-external-secret.yaml b/main/snippets/doppler-secrets-download-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/doppler-secrets-download-secret-store.yaml b/main/snippets/doppler-secrets-download-secret-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/fake-provider-es.yaml b/main/snippets/fake-provider-es.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/fake-provider-secret.yaml b/main/snippets/fake-provider-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/fake-provider-store.yaml b/main/snippets/fake-provider-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/filterpem-template-v2-external-secret.yaml b/main/snippets/filterpem-template-v2-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/full-cluster-external-secret.yaml b/main/snippets/full-cluster-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/full-cluster-secret-store.yaml b/main/snippets/full-cluster-secret-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/full-external-secret.yaml b/main/snippets/full-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/full-pushsecret-no-key-no-property.yaml b/main/snippets/full-pushsecret-no-key-no-property.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/full-pushsecret-no-key-with-property.yaml b/main/snippets/full-pushsecret-no-key-with-property.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/full-pushsecret.yaml b/main/snippets/full-pushsecret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/full-secret-store.yaml b/main/snippets/full-secret-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/gcpsm-credentials-secret.yaml b/main/snippets/gcpsm-credentials-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/gcpsm-data-from-external-secret.yaml b/main/snippets/gcpsm-data-from-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/gcpsm-docker-config-externalsecret.yaml b/main/snippets/gcpsm-docker-config-externalsecret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/gcpsm-docker-config-helm-externalsecret.yaml b/main/snippets/gcpsm-docker-config-helm-externalsecret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/gcpsm-external-secret.yaml b/main/snippets/gcpsm-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/gcpsm-pod-wi-secret-store.yaml b/main/snippets/gcpsm-pod-wi-secret-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/gcpsm-secret-store.yaml b/main/snippets/gcpsm-secret-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/gcpsm-ssh-auth-externalsecret.yaml b/main/snippets/gcpsm-ssh-auth-externalsecret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/gcpsm-tls-externalsecret.yaml b/main/snippets/gcpsm-tls-externalsecret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/gcpsm-wi-secret-store.yaml b/main/snippets/gcpsm-wi-secret-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/generator-acr-example.yaml b/main/snippets/generator-acr-example.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/generator-acr.yaml b/main/snippets/generator-acr.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/generator-ecr-example.yaml b/main/snippets/generator-ecr-example.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/generator-ecr.yaml b/main/snippets/generator-ecr.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/generator-fake-example.yaml b/main/snippets/generator-fake-example.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/generator-fake.yaml b/main/snippets/generator-fake.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/generator-gcr-example.yaml b/main/snippets/generator-gcr-example.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/generator-gcr.yaml b/main/snippets/generator-gcr.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/generator-github-example.yaml b/main/snippets/generator-github-example.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/generator-github.yaml b/main/snippets/generator-github.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/generator-password-example.yaml b/main/snippets/generator-password-example.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/generator-password.yaml b/main/snippets/generator-password.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/generator-vault-example.yaml b/main/snippets/generator-vault-example.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/generator-vault.yaml b/main/snippets/generator-vault.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/generator-webhook-example.yaml b/main/snippets/generator-webhook-example.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/generator-webhook.yaml b/main/snippets/generator-webhook.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/getallsecrets-find-by-name.yaml b/main/snippets/getallsecrets-find-by-name.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/getallsecrets-find-by-tags.yaml b/main/snippets/getallsecrets-find-by-tags.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/gitlab-credentials-secret.yaml b/main/snippets/gitlab-credentials-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/gitlab-external-secret-json.yaml b/main/snippets/gitlab-external-secret-json.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/gitlab-external-secret.yaml b/main/snippets/gitlab-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/gitlab-secret-store.yaml b/main/snippets/gitlab-secret-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/gitops/crs/clusterSecretStore.yaml b/main/snippets/gitops/crs/clusterSecretStore.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/gitops/crs/kustomization.yaml b/main/snippets/gitops/crs/kustomization.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/gitops/deployment-crds.yaml b/main/snippets/gitops/deployment-crds.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/gitops/deployment-crs.yaml b/main/snippets/gitops/deployment-crs.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/gitops/deployment.yaml b/main/snippets/gitops/deployment.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/gitops/kustomization.yaml b/main/snippets/gitops/kustomization.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/gitops/namespace.yaml b/main/snippets/gitops/namespace.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/gitops/repositories.yaml b/main/snippets/gitops/repositories.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/gitops/secret-token.yaml b/main/snippets/gitops/secret-token.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/helm-template-v2-escape-sequence.yaml b/main/snippets/helm-template-v2-escape-sequence.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/ibm-container-auth-volume.yaml b/main/snippets/ibm-container-auth-volume.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/ibm-es-types.yaml b/main/snippets/ibm-es-types.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/ibm-external-secret-by-name.yaml b/main/snippets/ibm-external-secret-by-name.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/ibm-external-secret-with-metadata.yaml b/main/snippets/ibm-external-secret-with-metadata.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/ibm-external-secret.yaml b/main/snippets/ibm-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/ibm-secret-store.yaml b/main/snippets/ibm-secret-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/jwk-template-v2-external-secret.yaml b/main/snippets/jwk-template-v2-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/keepersecurity-external-secret.yaml b/main/snippets/keepersecurity-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/keepersecurity-push-secret.yaml b/main/snippets/keepersecurity-push-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/keepersecurity-secret-store.yaml b/main/snippets/keepersecurity-secret-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/kyverno-policy-secretstore.yaml b/main/snippets/kyverno-policy-secretstore.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/merge-template-v2-external-secret.yaml b/main/snippets/merge-template-v2-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/multikey-template-v2-external-secret.yaml b/main/snippets/multikey-template-v2-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/multiline-template-v1-external-secret.yaml b/main/snippets/multiline-template-v1-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/multiline-template-v2-external-secret.yaml b/main/snippets/multiline-template-v2-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/onboardbase-fetch-all-secrets.yaml b/main/snippets/onboardbase-fetch-all-secrets.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/onboardbase-fetch-secret.yaml b/main/snippets/onboardbase-fetch-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/onboardbase-filtered-secrets.yaml b/main/snippets/onboardbase-filtered-secrets.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/onboardbase-generic-secret-store.yaml b/main/snippets/onboardbase-generic-secret-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/oracle-credentials-secret.yaml b/main/snippets/oracle-credentials-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/oracle-external-secret.yaml b/main/snippets/oracle-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/oracle-secret-store-pushsecret.yaml b/main/snippets/oracle-secret-store-pushsecret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/oracle-secret-store.yaml b/main/snippets/oracle-secret-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/passbolt-external-secret-example.yaml b/main/snippets/passbolt-external-secret-example.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/passbolt-external-secret-findbyname.yaml b/main/snippets/passbolt-external-secret-findbyname.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/passbolt-secret-example.yaml b/main/snippets/passbolt-secret-example.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/passbolt-secret-store.yaml b/main/snippets/passbolt-secret-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/password-depot-credentials-secret.yaml b/main/snippets/password-depot-credentials-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/passworddepot-external-secret-json.yaml b/main/snippets/passworddepot-external-secret-json.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/passworddepot-external-secret.yaml b/main/snippets/passworddepot-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/passworddepot-secret-store.yaml b/main/snippets/passworddepot-secret-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/pkcs12-template-v1-external-secret.yaml b/main/snippets/pkcs12-template-v1-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/pkcs12-template-v2-external-secret.yaml b/main/snippets/pkcs12-template-v2-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/provider-aws-access/index.html b/main/snippets/provider-aws-access/index.html
old mode 100755
new mode 100644
diff --git a/main/snippets/senhasegura-dsm-clustersecretstore.yaml b/main/snippets/senhasegura-dsm-clustersecretstore.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/senhasegura-dsm-external-secret-all.yaml b/main/snippets/senhasegura-dsm-external-secret-all.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/senhasegura-dsm-external-secret-multiple.yaml b/main/snippets/senhasegura-dsm-external-secret-multiple.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/senhasegura-dsm-external-secret-single.yaml b/main/snippets/senhasegura-dsm-external-secret-single.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/senhasegura-dsm-secret.yaml b/main/snippets/senhasegura-dsm-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/senhasegura-dsm-secretstore.yaml b/main/snippets/senhasegura-dsm-secretstore.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/template-v1-from-secret.yaml b/main/snippets/template-v1-from-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/template-v2-from-secret.yaml b/main/snippets/template-v2-from-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/template-v2-literal-example.yaml b/main/snippets/template-v2-literal-example.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/template-v2-push-secret.yaml b/main/snippets/template-v2-push-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/template-v2-scope-and-target.yaml b/main/snippets/template-v2-scope-and-target.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/vault-anchore-engine-access-credentials-external-secret.yaml b/main/snippets/vault-anchore-engine-access-credentials-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/vault-approle-store.yaml b/main/snippets/vault-approle-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/vault-iam-store-controller-pod-identity.yaml b/main/snippets/vault-iam-store-controller-pod-identity.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/vault-iam-store-sa.yaml b/main/snippets/vault-iam-store-sa.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/vault-iam-store-static-creds.yaml b/main/snippets/vault-iam-store-static-creds.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/vault-iam-store.yaml b/main/snippets/vault-iam-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/vault-jenkins-credential-github-ssh-access-external-secret.yaml b/main/snippets/vault-jenkins-credential-github-ssh-access-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/vault-jenkins-credential-harbor-chart-robot-external-secret.yaml b/main/snippets/vault-jenkins-credential-harbor-chart-robot-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/vault-jenkins-credential-sonarqube-api-token-external-secret.yaml b/main/snippets/vault-jenkins-credential-sonarqube-api-token-external-secret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/vault-jwt-store.yaml b/main/snippets/vault-jwt-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/vault-kubernetes-store.yaml b/main/snippets/vault-kubernetes-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/vault-ldap-store.yaml b/main/snippets/vault-ldap-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/vault-mtls-store.yaml b/main/snippets/vault-mtls-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/vault-pushsecret.yaml b/main/snippets/vault-pushsecret.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/vault-token-store.yaml b/main/snippets/vault-token-store.yaml
old mode 100755
new mode 100644
diff --git a/main/snippets/vault-userpass-store.yaml b/main/snippets/vault-userpass-store.yaml
old mode 100755
new mode 100644
diff --git a/main/spec/index.html b/main/spec/index.html
old mode 100755
new mode 100644