| 1 |
- {"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Introduction","text":"<p>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.</p>"},{"location":"#what-is-the-goal-of-external-secrets-operator","title":"What is the goal of External Secrets Operator?","text":"<p>The goal of External Secrets Operator is to synchronize secrets from external APIs into Kubernetes. ESO is a collection of custom API resources - <code>ExternalSecret</code>, <code>SecretStore</code> and <code>ClusterSecretStore</code> that provide a user-friendly abstraction for the external API that stores and manages the lifecycle of the secrets for you.</p>"},{"location":"#where-to-get-started","title":"Where to get started","text":"<p>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.</p> <p>For a complete reference of the API types please refer to our API Reference.</p>"},{"location":"#how-to-get-involved","title":"How to get involved","text":"<p>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!</p> <p>How to get involved:</p> <ul> <li>Bi-weekly Development Meeting every odd week at 8:00 PM Berlin Time on Wednesday (agenda, jitsi call)</li> <li>Kubernetes Slack #external-secrets</li> <li>Contributing Process</li> <li>Twitter</li> </ul>"},{"location":"#kicked-off-by","title":"Kicked off by","text":""},{"location":"#sponsored-by","title":"Sponsored by","text":""},{"location":"eso-blogs/","title":"ESO Blogs","text":"<p>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!</p>"},{"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":"<p>@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</p>"},{"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":"<p>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</p>"},{"location":"eso-blogs/#tutorial-how-to-set-external-secrets-with-azure-keyvault","title":"Tutorial: How to Set External-Secrets with Azure KeyVault","text":"<p>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</p>"},{"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":"<p>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</p>"},{"location":"eso-blogs/#tutorial-how-to-set-external-secrets-with-hashicorp-vault","title":"Tutorial: How to Set External-Secrets with Hashicorp Vault","text":"<p>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</p>"},{"location":"eso-blogs/#tutorial-how-to-set-external-secrets-with-aws","title":"Tutorial: How to Set External-Secrets with AWS","text":"<p>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</p>"},{"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":"<p>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</p>"},{"location":"eso-blogs/#kubernetes-hardening-tutorial-part-2-network","title":"Kubernetes Hardening Tutorial Part 2: Network","text":"<p>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</p>"},{"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":"<p>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 <code>ClusterSecretStore</code> functionality, a cluster scoped SecretStore and is global to the Cluster that all <code>ExternalSecrets</code> can reference from all namespaces.</p>"},{"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":"<p>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</p>"},{"location":"eso-blogs/#cloud-native-secret-management-with-external-secrets-operator","title":"Cloud Native Secret Management with External Secrets Operator","text":"<p>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.</p>"},{"location":"eso-blogs/#external-secrets-operator-integration-with-hashicorp-vault","title":"External Secrets Operator Integration with HashiCorp Vault","text":"<p>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.</p>"},{"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":"<p>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.</p>"},{"location":"eso-blogs/#gcp-secret-manager-with-self-hosted-kubernetes","title":"GCP Secret Manager with self-hosted Kubernetes","text":"<p>Jacek writes about bringing GCP secrets to on-premises cluster through External Secrets Operator intergration with workload identity.</p>"},{"location":"eso-demos/","title":"ESO Demos","text":"<p>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!</p>"},{"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":"<p>Viktor Farvik shows us how to use ESO with GCP provider and explores a simple workflow with the project.</p> <p></p>"},{"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":"<p>Kim Schlesinger and Daniel Hix show us how to install and use both projects, comparing their features and limitations in different situations.</p> <p></p>"},{"location":"eso-demos/#gcp-sm-aws-sm-azure-key-vault-demo","title":"GCP SM + AWS SM + Azure Key Vault Demo","text":"<p>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.</p> <p></p>"},{"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":"<p>Balkrishna Pandey shows us here how to use ClusterSecretStore and how to integrate ESO with Hashicorp Vault on Openshift.</p> <p></p>"},{"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":"<p>Lukonde Mwila demonstrates how ESO works and how to fetch secrets from AWS Secrets Manager into your Kubernetes cluster.</p> <p></p>"},{"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":"<p>Charl Klein gives an overview of the external secrets project, and a walkthrough of getting ESO up and running with Azure Key Vault </p> <p></p>"},{"location":"eso-talks/","title":"ESO Talks","text":"<p>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!</p>"},{"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":""},{"location":"spec/","title":"Spec","text":"<p>Packages:</p> <ul> <li> external-secrets.io/v1beta1 </li> </ul>"},{"location":"spec/#external-secrets.io/v1beta1","title":"external-secrets.io/v1beta1","text":"<p> <p>Package v1beta1 contains resources for external-secrets</p> </p> <p>Resource Types:</p>"},{"location":"spec/#external-secrets.io/v1beta1.AWSAuth","title":"AWSAuth","text":"<p> (Appears on: AWSProvider) </p> <p> <p>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.</p> </p> Field Description <code>secretRef</code> AWSAuthSecretRef (Optional) <code>jwt</code> AWSJWTAuth (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.AWSAuthSecretRef","title":"AWSAuthSecretRef","text":"<p> (Appears on: AWSAuth) </p> <p> <p>AWSAuthSecretRef holds secret references for AWS credentials both AccessKeyID and SecretAccessKey must be defined in order to properly authenticate.</p> </p> Field Description <code>accessKeyIDSecretRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector <p>The AccessKeyID is used for authentication</p> <code>secretAccessKeySecretRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector <p>The SecretAccessKey is used for authentication</p> <code>sessionTokenSecretRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector <p>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</p>"},{"location":"spec/#external-secrets.io/v1beta1.AWSJWTAuth","title":"AWSJWTAuth","text":"<p> (Appears on: AWSAuth) </p> <p> <p>Authenticate against AWS using service account tokens.</p> </p> Field Description <code>serviceAccountRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.ServiceAccountSelector"},{"location":"spec/#external-secrets.io/v1beta1.AWSProvider","title":"AWSProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>AWSProvider configures a store to sync secrets with AWS.</p> </p> Field Description <code>service</code> AWSServiceType <p>Service defines which service should be used to fetch the secrets</p> <code>auth</code> AWSAuth (Optional) <p>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</p> <code>role</code> string (Optional) <p>Role is a Role ARN which the SecretManager provider will assume</p> <code>region</code> string <p>AWS Region to be used for the provider</p>"},{"location":"spec/#external-secrets.io/v1beta1.AWSServiceType","title":"AWSServiceType (<code>string</code> alias)","text":"<p> (Appears on: AWSProvider) </p> <p> <p>AWSServiceType is a enum that defines the service/API that is used to fetch the secrets.</p> </p> Value Description <p>\"ParameterStore\"</p> <p>AWSServiceParameterStore is the AWS SystemsManager ParameterStore. see: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html</p> <p>\"SecretsManager\"</p> <p>AWSServiceSecretsManager is the AWS SecretsManager. see: https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html</p>"},{"location":"spec/#external-secrets.io/v1beta1.AkeylessAuth","title":"AkeylessAuth","text":"<p> (Appears on: AkeylessProvider) </p> <p> </p> Field Description <code>secretRef</code> AkeylessAuthSecretRef (Optional) <p>Reference to a Secret that contains the details to authenticate with Akeyless.</p> <code>kubernetesAuth</code> AkeylessKubernetesAuth (Optional) <p>Kubernetes authenticates with Akeyless by passing the ServiceAccount token stored in the named Secret resource.</p>"},{"location":"spec/#external-secrets.io/v1beta1.AkeylessAuthSecretRef","title":"AkeylessAuthSecretRef","text":"<p> (Appears on: AkeylessAuth) </p> <p> <p>AkeylessAuthSecretRef AKEYLESS_ACCESS_TYPE_PARAM: AZURE_OBJ_ID OR GCP_AUDIENCE OR ACCESS_KEY OR KUB_CONFIG_NAME.</p> </p> Field Description <code>accessID</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector <p>The SecretAccessID is used for authentication</p> <code>accessType</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector <code>accessTypeParam</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector"},{"location":"spec/#external-secrets.io/v1beta1.AkeylessKubernetesAuth","title":"AkeylessKubernetesAuth","text":"<p> (Appears on: AkeylessAuth) </p> <p> <p>Authenticate with Kubernetes ServiceAccount token stored.</p> </p> Field Description <code>accessID</code> string <p>the Akeyless Kubernetes auth-method access-id</p> <code>k8sConfName</code> string <p>Kubernetes-auth configuration name in Akeyless-Gateway</p> <code>serviceAccountRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.ServiceAccountSelector (Optional) <p>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.</p> <code>secretRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) <p>Optional secret field containing a Kubernetes ServiceAccount JWT used for authenticating with Akeyless. If a name is specified without a key, <code>token</code> is the default. If one is not specified, the one bound to the controller will be used.</p>"},{"location":"spec/#external-secrets.io/v1beta1.AkeylessProvider","title":"AkeylessProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>AkeylessProvider Configures an store to sync secrets using Akeyless KV.</p> </p> Field Description <code>akeylessGWApiURL</code> string <p>Akeyless GW API Url from which the secrets to be fetched from.</p> <code>authSecretRef</code> AkeylessAuth <p>Auth configures how the operator authenticates with Akeyless.</p>"},{"location":"spec/#external-secrets.io/v1beta1.AlibabaAuth","title":"AlibabaAuth","text":"<p> (Appears on: AlibabaProvider) </p> <p> <p>AlibabaAuth contains a secretRef for credentials.</p> </p> Field Description <code>secretRef</code> AlibabaAuthSecretRef"},{"location":"spec/#external-secrets.io/v1beta1.AlibabaAuthSecretRef","title":"AlibabaAuthSecretRef","text":"<p> (Appears on: AlibabaAuth) </p> <p> <p>AlibabaAuthSecretRef holds secret references for Alibaba credentials.</p> </p> Field Description <code>accessKeyIDSecretRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector <p>The AccessKeyID is used for authentication</p> <code>accessKeySecretSecretRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector <p>The AccessKeySecret is used for authentication</p>"},{"location":"spec/#external-secrets.io/v1beta1.AlibabaProvider","title":"AlibabaProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>AlibabaProvider configures a store to sync secrets using the Alibaba Secret Manager provider.</p> </p> Field Description <code>auth</code> AlibabaAuth <code>endpoint</code> string (Optional) <code>regionID</code> string <p>Alibaba Region to be used for the provider</p>"},{"location":"spec/#external-secrets.io/v1beta1.AzureAuthType","title":"AzureAuthType (<code>string</code> alias)","text":"<p> (Appears on: AzureKVProvider) </p> <p> <p>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.</p> </p> Value Description <p>\"ManagedIdentity\"</p> <p>Using Managed Identity to authenticate. Used with aad-pod-identity installed in the cluster.</p> <p>\"ServicePrincipal\"</p> <p>Using service principal to authenticate, which needs a tenantId, a clientId and a clientSecret.</p> <p>\"WorkloadIdentity\"</p> <p>Using Workload Identity service accounts to authenticate.</p>"},{"location":"spec/#external-secrets.io/v1beta1.AzureEnvironmentType","title":"AzureEnvironmentType (<code>string</code> alias)","text":"<p> (Appears on: AzureKVProvider) </p> <p> <p>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</p> </p> Value Description <p>\"ChinaCloud\"</p> <p>\"GermanCloud\"</p> <p>\"PublicCloud\"</p> <p>\"USGovernmentCloud\"</p>"},{"location":"spec/#external-secrets.io/v1beta1.AzureKVAuth","title":"AzureKVAuth","text":"<p> (Appears on: AzureKVProvider) </p> <p> <p>Configuration used to authenticate with Azure.</p> </p> Field Description <code>clientId</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) <p>The Azure clientId of the service principle used for authentication.</p> <code>clientSecret</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) <p>The Azure ClientSecret of the service principle used for authentication.</p>"},{"location":"spec/#external-secrets.io/v1beta1.AzureKVProvider","title":"AzureKVProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>Configures an store to sync secrets using Azure KV.</p> </p> Field Description <code>authType</code> AzureAuthType (Optional) <p>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)</p> <code>vaultUrl</code> string <p>Vault Url from which the secrets to be fetched from.</p> <code>tenantId</code> string (Optional) <p>TenantID configures the Azure Tenant to send requests to. Required for ServicePrincipal auth type.</p> <code>environmentType</code> AzureEnvironmentType <p>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</p> <code>authSecretRef</code> AzureKVAuth (Optional) <p>Auth configures how the operator authenticates with Azure. Required for ServicePrincipal auth type.</p> <code>serviceAccountRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.ServiceAccountSelector (Optional) <p>ServiceAccountRef specified the service account that should be used when authenticating with WorkloadIdentity.</p> <code>identityId</code> string (Optional) <p>If multiple Managed Identity is assigned to the pod, you can select the one to be used</p>"},{"location":"spec/#external-secrets.io/v1beta1.CAProvider","title":"CAProvider","text":"<p> (Appears on: KubernetesServer, VaultProvider) </p> <p> <p>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.</p> </p> Field Description <code>type</code> CAProviderType <p>The type of provider to use such as \u201cSecret\u201d, or \u201cConfigMap\u201d.</p> <code>name</code> string <p>The name of the object located at the provider type.</p> <code>key</code> string <p>The key where the CA certificate can be found in the Secret or ConfigMap.</p> <code>namespace</code> string (Optional) <p>The namespace the Provider type is in. Can only be defined when used in a ClusterSecretStore.</p>"},{"location":"spec/#external-secrets.io/v1beta1.CAProviderType","title":"CAProviderType (<code>string</code> alias)","text":"<p> (Appears on: CAProvider) </p> <p> </p> Value Description <p>\"ConfigMap\"</p> <p>\"Secret\"</p>"},{"location":"spec/#external-secrets.io/v1beta1.CertAuth","title":"CertAuth","text":"<p> (Appears on: KubernetesAuth) </p> <p> </p> Field Description <code>clientCert</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector <code>clientKey</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector"},{"location":"spec/#external-secrets.io/v1beta1.ClusterExternalSecret","title":"ClusterExternalSecret","text":"<p> <p>ClusterExternalSecret is the Schema for the clusterexternalsecrets API.</p> </p> Field Description <code>metadata</code> Kubernetes meta/v1.ObjectMeta Refer to the Kubernetes API documentation for the fields of the <code>metadata</code> field. <code>spec</code> ClusterExternalSecretSpec <code>externalSecretSpec</code> ExternalSecretSpec <p>The spec for the ExternalSecrets to be created</p> <code>externalSecretName</code> string (Optional) <p>The name of the external secrets to be created defaults to the name of the ClusterExternalSecret</p> <code>namespaceSelector</code> Kubernetes meta/v1.LabelSelector <p>The labels to select by to find the Namespaces to create the ExternalSecrets in.</p> <code>refreshTime</code> Kubernetes meta/v1.Duration <p>The time in which the controller should reconcile it\u2019s objects and recheck namespaces for labels.</p> <code>status</code> ClusterExternalSecretStatus"},{"location":"spec/#external-secrets.io/v1beta1.ClusterExternalSecretConditionType","title":"ClusterExternalSecretConditionType (<code>string</code> alias)","text":"<p> (Appears on: ClusterExternalSecretStatusCondition) </p> <p> </p> Value Description <p>\"NotReady\"</p> <p>\"PartiallyReady\"</p> <p>\"Ready\"</p>"},{"location":"spec/#external-secrets.io/v1beta1.ClusterExternalSecretNamespaceFailure","title":"ClusterExternalSecretNamespaceFailure","text":"<p> (Appears on: ClusterExternalSecretStatus) </p> <p> <p>ClusterExternalSecretNamespaceFailure represents a failed namespace deployment and it\u2019s reason.</p> </p> Field Description <code>namespace</code> string <p>Namespace is the namespace that failed when trying to apply an ExternalSecret</p> <code>reason</code> string (Optional) <p>Reason is why the ExternalSecret failed to apply to the namespace</p>"},{"location":"spec/#external-secrets.io/v1beta1.ClusterExternalSecretSpec","title":"ClusterExternalSecretSpec","text":"<p> (Appears on: ClusterExternalSecret) </p> <p> <p>ClusterExternalSecretSpec defines the desired state of ClusterExternalSecret.</p> </p> Field Description <code>externalSecretSpec</code> ExternalSecretSpec <p>The spec for the ExternalSecrets to be created</p> <code>externalSecretName</code> string (Optional) <p>The name of the external secrets to be created defaults to the name of the ClusterExternalSecret</p> <code>namespaceSelector</code> Kubernetes meta/v1.LabelSelector <p>The labels to select by to find the Namespaces to create the ExternalSecrets in.</p> <code>refreshTime</code> Kubernetes meta/v1.Duration <p>The time in which the controller should reconcile it\u2019s objects and recheck namespaces for labels.</p>"},{"location":"spec/#external-secrets.io/v1beta1.ClusterExternalSecretStatus","title":"ClusterExternalSecretStatus","text":"<p> (Appears on: ClusterExternalSecret) </p> <p> <p>ClusterExternalSecretStatus defines the observed state of ClusterExternalSecret.</p> </p> Field Description <code>failedNamespaces</code> []ClusterExternalSecretNamespaceFailure (Optional) <p>Failed namespaces are the namespaces that failed to apply an ExternalSecret</p> <code>provisionedNamespaces</code> []string (Optional) <p>ProvisionedNamespaces are the namespaces where the ClusterExternalSecret has secrets</p> <code>conditions</code> []ClusterExternalSecretStatusCondition (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.ClusterExternalSecretStatusCondition","title":"ClusterExternalSecretStatusCondition","text":"<p> (Appears on: ClusterExternalSecretStatus) </p> <p> </p> Field Description <code>type</code> ClusterExternalSecretConditionType <code>status</code> Kubernetes core/v1.ConditionStatus <code>message</code> string (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.ClusterSecretStore","title":"ClusterSecretStore","text":"<p> <p>ClusterSecretStore represents a secure external location for storing secrets, which can be referenced as part of <code>storeRef</code> fields.</p> </p> Field Description <code>metadata</code> Kubernetes meta/v1.ObjectMeta Refer to the Kubernetes API documentation for the fields of the <code>metadata</code> field. <code>spec</code> SecretStoreSpec <code>controller</code> string (Optional) <p>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</p> <code>provider</code> SecretStoreProvider <p>Used to configure the provider. Only one provider may be set</p> <code>retrySettings</code> SecretStoreRetrySettings (Optional) <p>Used to configure http retries if failed</p> <code>refreshInterval</code> int (Optional) <p>Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.</p> <code>conditions</code> []ClusterSecretStoreCondition (Optional) <p>Used to constraint a ClusterSecretStore to specific namespaces. Relevant only to ClusterSecretStore</p> <code>status</code> SecretStoreStatus"},{"location":"spec/#external-secrets.io/v1beta1.ClusterSecretStoreCondition","title":"ClusterSecretStoreCondition","text":"<p> (Appears on: SecretStoreSpec) </p> <p> <p>ClusterSecretStoreCondition describes a condition by which to choose namespaces to process ExternalSecrets in for a ClusterSecretStore instance.</p> </p> Field Description <code>namespaceSelector</code> Kubernetes meta/v1.LabelSelector (Optional) <p>Choose namespace using a labelSelector</p> <code>namespaces</code> []string <p>Choose namespaces by name</p>"},{"location":"spec/#external-secrets.io/v1beta1.DopplerAuth","title":"DopplerAuth","text":"<p> (Appears on: DopplerProvider) </p> <p> </p> Field Description <code>secretRef</code> DopplerAuthSecretRef"},{"location":"spec/#external-secrets.io/v1beta1.DopplerAuthSecretRef","title":"DopplerAuthSecretRef","text":"<p> (Appears on: DopplerAuth) </p> <p> </p> Field Description <code>dopplerToken</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector <p>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.</p>"},{"location":"spec/#external-secrets.io/v1beta1.DopplerProvider","title":"DopplerProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>DopplerProvider configures a store to sync secrets using the Doppler provider. Project and Config are required if not using a Service Token.</p> </p> Field Description <code>auth</code> DopplerAuth <p>Auth configures how the Operator authenticates with the Doppler API</p> <code>project</code> string (Optional) <p>Doppler project (required if not using a Service Token)</p> <code>config</code> string (Optional) <p>Doppler config (required if not using a Service Token)</p> <code>nameTransformer</code> string (Optional) <p>Environment variable compatible name transforms that change secret names to a different format</p> <code>format</code> string (Optional) <p>Format enables the downloading of secrets as a file (string)</p>"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecret","title":"ExternalSecret","text":"<p> <p>ExternalSecret is the Schema for the external-secrets API.</p> </p> Field Description <code>metadata</code> Kubernetes meta/v1.ObjectMeta Refer to the Kubernetes API documentation for the fields of the <code>metadata</code> field. <code>spec</code> ExternalSecretSpec <code>secretStoreRef</code> SecretStoreRef (Optional) <code>target</code> ExternalSecretTarget (Optional) <code>refreshInterval</code> Kubernetes meta/v1.Duration <p>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.</p> <code>data</code> []ExternalSecretData (Optional) <p>Data defines the connection between the Kubernetes Secret keys and the Provider data</p> <code>dataFrom</code> []ExternalSecretDataFromRemoteRef (Optional) <p>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</p> <code>status</code> ExternalSecretStatus"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretConditionType","title":"ExternalSecretConditionType (<code>string</code> alias)","text":"<p> (Appears on: ExternalSecretStatusCondition) </p> <p> </p> Value Description <p>\"Deleted\"</p> <p>\"Ready\"</p>"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretConversionStrategy","title":"ExternalSecretConversionStrategy (<code>string</code> alias)","text":"<p> (Appears on: ExternalSecretDataRemoteRef, ExternalSecretFind) </p> <p> </p> Value Description <p>\"Default\"</p> <p>\"Unicode\"</p>"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretCreationPolicy","title":"ExternalSecretCreationPolicy (<code>string</code> alias)","text":"<p> (Appears on: ExternalSecretTarget) </p> <p> <p>ExternalSecretCreationPolicy defines rules on how to create the resulting Secret.</p> </p> Value Description <p>\"Merge\"</p> <p>Merge does not create the Secret, but merges the data fields to the Secret.</p> <p>\"None\"</p> <p>None does not create a Secret (future use with injector).</p> <p>\"Orphan\"</p> <p>Orphan creates the Secret and does not set the ownerReference. I.e. it will be orphaned after the deletion of the ExternalSecret.</p> <p>\"Owner\"</p> <p>Owner creates the Secret and sets .metadata.ownerReferences to the ExternalSecret resource.</p>"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretData","title":"ExternalSecretData","text":"<p> (Appears on: ExternalSecretSpec) </p> <p> <p>ExternalSecretData defines the connection between the Kubernetes Secret key (spec.data.) and the Provider data. Field Description <code>secretKey</code> string <p>SecretKey defines the key in which the controller stores the value. This is the key in the Kind=Secret</p> <code>remoteRef</code> ExternalSecretDataRemoteRef <p>RemoteRef points to the remote secret and defines which secret (version/property/..) to fetch.</p> <code>sourceRef</code> SourceRef <p>SourceRef allows you to override the source from which the value will pulled from.</p>"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretDataFromRemoteRef","title":"ExternalSecretDataFromRemoteRef","text":"<p> (Appears on: ExternalSecretSpec) </p> <p> </p> Field Description <code>extract</code> ExternalSecretDataRemoteRef (Optional) <p>Used to extract multiple key/value pairs from one secret Note: Extract does not support sourceRef.Generator or sourceRef.GeneratorRef.</p> <code>find</code> ExternalSecretFind (Optional) <p>Used to find secrets based on tags or regular expressions Note: Find does not support sourceRef.Generator or sourceRef.GeneratorRef.</p> <code>rewrite</code> []ExternalSecretRewrite (Optional) <p>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)</p> <code>sourceRef</code> SourceRef <p>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</p>"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretDataRemoteRef","title":"ExternalSecretDataRemoteRef","text":"<p> (Appears on: ExternalSecretData, ExternalSecretDataFromRemoteRef) </p> <p> <p>ExternalSecretDataRemoteRef defines Provider data location.</p> </p> Field Description <code>key</code> string <p>Key is the key used in the Provider, mandatory</p> <code>metadataPolicy</code> ExternalSecretMetadataPolicy (Optional) <p>Policy for fetching tags/labels from provider secrets, possible options are Fetch, None. Defaults to None</p> <code>property</code> string (Optional) <p>Used to select a specific property of the Provider value (if a map), if supported</p> <code>version</code> string (Optional) <p>Used to select a specific version of the Provider value, if supported</p> <code>conversionStrategy</code> ExternalSecretConversionStrategy (Optional) <p>Used to define a conversion Strategy</p> <code>decodingStrategy</code> ExternalSecretDecodingStrategy (Optional) <p>Used to define a decoding Strategy</p>"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretDecodingStrategy","title":"ExternalSecretDecodingStrategy (<code>string</code> alias)","text":"<p> (Appears on: ExternalSecretDataRemoteRef, ExternalSecretFind) </p> <p> </p> Value Description <p>\"Auto\"</p> <p>\"Base64\"</p> <p>\"Base64URL\"</p> <p>\"None\"</p>"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretDeletionPolicy","title":"ExternalSecretDeletionPolicy (<code>string</code> alias)","text":"<p> (Appears on: ExternalSecretTarget) </p> <p> <p>ExternalSecretDeletionPolicy defines rules on how to delete the resulting Secret.</p> </p> Value Description <p>\"Delete\"</p> <p>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.</p> <p>\"Merge\"</p> <p>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.</p> <p>\"Retain\"</p> <p>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.</p>"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretFind","title":"ExternalSecretFind","text":"<p> (Appears on: ExternalSecretDataFromRemoteRef) </p> <p> </p> Field Description <code>path</code> string (Optional) <p>A root path to start the find operations.</p> <code>name</code> FindName (Optional) <p>Finds secrets based on the name.</p> <code>tags</code> map[string]string (Optional) <p>Find secrets based on tags.</p> <code>conversionStrategy</code> ExternalSecretConversionStrategy (Optional) <p>Used to define a conversion Strategy</p> <code>decodingStrategy</code> ExternalSecretDecodingStrategy (Optional) <p>Used to define a decoding Strategy</p>"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretMetadataPolicy","title":"ExternalSecretMetadataPolicy (<code>string</code> alias)","text":"<p> (Appears on: ExternalSecretDataRemoteRef) </p> <p> </p> Value Description <p>\"Fetch\"</p> <p>\"None\"</p>"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretRewrite","title":"ExternalSecretRewrite","text":"<p> (Appears on: ExternalSecretDataFromRemoteRef) </p> <p> </p> Field Description <code>regexp</code> ExternalSecretRewriteRegexp (Optional) <p>Used to rewrite with regular expressions. The resulting key will be the output of a regexp.ReplaceAll operation.</p>"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretRewriteRegexp","title":"ExternalSecretRewriteRegexp","text":"<p> (Appears on: ExternalSecretRewrite) </p> <p> </p> Field Description <code>source</code> string <p>Used to define the regular expression of a re.Compiler.</p> <code>target</code> string <p>Used to define the target pattern of a ReplaceAll operation.</p>"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretSpec","title":"ExternalSecretSpec","text":"<p> (Appears on: ClusterExternalSecretSpec, ExternalSecret) </p> <p> <p>ExternalSecretSpec defines the desired state of ExternalSecret.</p> </p> Field Description <code>secretStoreRef</code> SecretStoreRef (Optional) <code>target</code> ExternalSecretTarget (Optional) <code>refreshInterval</code> Kubernetes meta/v1.Duration <p>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.</p> <code>data</code> []ExternalSecretData (Optional) <p>Data defines the connection between the Kubernetes Secret keys and the Provider data</p> <code>dataFrom</code> []ExternalSecretDataFromRemoteRef (Optional) <p>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</p>"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretStatus","title":"ExternalSecretStatus","text":"<p> (Appears on: ExternalSecret) </p> <p> </p> Field Description <code>refreshTime</code> Kubernetes meta/v1.Time <p>refreshTime is the time and date the external secret was fetched and the target secret updated</p> <code>syncedResourceVersion</code> string <p>SyncedResourceVersion keeps track of the last synced version</p> <code>conditions</code> []ExternalSecretStatusCondition (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretStatusCondition","title":"ExternalSecretStatusCondition","text":"<p> (Appears on: ExternalSecretStatus) </p> <p> </p> Field Description <code>type</code> ExternalSecretConditionType <code>status</code> Kubernetes core/v1.ConditionStatus <code>reason</code> string (Optional) <code>message</code> string (Optional) <code>lastTransitionTime</code> Kubernetes meta/v1.Time (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretTarget","title":"ExternalSecretTarget","text":"<p> (Appears on: ExternalSecretSpec) </p> <p> <p>ExternalSecretTarget defines the Kubernetes Secret to be created There can be only one target per ExternalSecret.</p> </p> Field Description <code>name</code> string (Optional) <p>Name defines the name of the Secret resource to be managed This field is immutable Defaults to the .metadata.name of the ExternalSecret resource</p> <code>creationPolicy</code> ExternalSecretCreationPolicy (Optional) <p>CreationPolicy defines rules on how to create the resulting Secret Defaults to \u2018Owner\u2019</p> <code>deletionPolicy</code> ExternalSecretDeletionPolicy (Optional) <p>DeletionPolicy defines rules on how to delete the resulting Secret Defaults to \u2018Retain\u2019</p> <code>template</code> ExternalSecretTemplate (Optional) <p>Template defines a blueprint for the created Secret resource.</p> <code>immutable</code> bool (Optional) <p>Immutable defines if the final secret will be immutable</p>"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretTemplate","title":"ExternalSecretTemplate","text":"<p> (Appears on: ExternalSecretTarget) </p> <p> <p>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</p> </p> Field Description <code>type</code> Kubernetes core/v1.SecretType (Optional) <code>engineVersion</code> TemplateEngineVersion <code>metadata</code> ExternalSecretTemplateMetadata (Optional) <code>data</code> map[string]string (Optional) <code>templateFrom</code> []TemplateFrom (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretTemplateMetadata","title":"ExternalSecretTemplateMetadata","text":"<p> (Appears on: ExternalSecretTemplate) </p> <p> <p>ExternalSecretTemplateMetadata defines metadata fields for the Secret blueprint.</p> </p> Field Description <code>annotations</code> map[string]string (Optional) <code>labels</code> map[string]string (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.ExternalSecretValidator","title":"ExternalSecretValidator","text":""},{"location":"spec/#external-secrets.io/v1beta1.FakeProvider","title":"FakeProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>FakeProvider configures a fake provider that returns static values.</p> </p> Field Description <code>data</code> []FakeProviderData"},{"location":"spec/#external-secrets.io/v1beta1.FakeProviderData","title":"FakeProviderData","text":"<p> (Appears on: FakeProvider) </p> <p> </p> Field Description <code>key</code> string <code>value</code> string <code>valueMap</code> map[string]string <code>version</code> string"},{"location":"spec/#external-secrets.io/v1beta1.FindName","title":"FindName","text":"<p> (Appears on: ExternalSecretFind) </p> <p> </p> Field Description <code>regexp</code> string (Optional) <p>Finds secrets base</p>"},{"location":"spec/#external-secrets.io/v1beta1.GCPSMAuth","title":"GCPSMAuth","text":"<p> (Appears on: GCPSMProvider) </p> <p> </p> Field Description <code>secretRef</code> GCPSMAuthSecretRef (Optional) <code>workloadIdentity</code> GCPWorkloadIdentity (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.GCPSMAuthSecretRef","title":"GCPSMAuthSecretRef","text":"<p> (Appears on: GCPSMAuth) </p> <p> </p> Field Description <code>secretAccessKeySecretRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) <p>The SecretAccessKey is used for authentication</p>"},{"location":"spec/#external-secrets.io/v1beta1.GCPSMProvider","title":"GCPSMProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>GCPSMProvider Configures a store to sync secrets using the GCP Secret Manager provider.</p> </p> Field Description <code>auth</code> GCPSMAuth (Optional) <p>Auth defines the information necessary to authenticate against GCP</p> <code>projectID</code> string <p>ProjectID project where secret is located</p>"},{"location":"spec/#external-secrets.io/v1beta1.GCPWorkloadIdentity","title":"GCPWorkloadIdentity","text":"<p> (Appears on: GCPSMAuth) </p> <p> </p> Field Description <code>serviceAccountRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.ServiceAccountSelector <code>clusterLocation</code> string <code>clusterName</code> string <code>clusterProjectID</code> string"},{"location":"spec/#external-secrets.io/v1beta1.GeneratorRef","title":"GeneratorRef","text":"<p> (Appears on: SourceRef) </p> <p> <p>GeneratorRef points to a generator custom resource.</p> </p> Field Description <code>apiVersion</code> string <p>Specify the apiVersion of the generator resource</p> <code>kind</code> string <p>Specify the Kind of the resource, e.g. Password, ACRAccessToken etc.</p> <code>name</code> string <p>Specify the name of the generator resource</p>"},{"location":"spec/#external-secrets.io/v1beta1.GenericStore","title":"GenericStore","text":"<p> <p>GenericStore is a common interface for interacting with ClusterSecretStore or a namespaced SecretStore.</p> </p>"},{"location":"spec/#external-secrets.io/v1beta1.GenericStoreValidator","title":"GenericStoreValidator","text":""},{"location":"spec/#external-secrets.io/v1beta1.GitlabAuth","title":"GitlabAuth","text":"<p> (Appears on: GitlabProvider) </p> <p> </p> Field Description <code>SecretRef</code> GitlabSecretRef"},{"location":"spec/#external-secrets.io/v1beta1.GitlabProvider","title":"GitlabProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>Configures a store to sync secrets with a GitLab instance.</p> </p> Field Description <code>url</code> string <p>URL configures the GitLab instance URL. Defaults to https://gitlab.com/.</p> <code>auth</code> GitlabAuth <p>Auth configures how secret-manager authenticates with a GitLab instance.</p> <code>projectID</code> string <p>ProjectID specifies a project where secrets are located.</p> <code>inheritFromGroups</code> bool <p>InheritFromGroups specifies whether parent groups should be discovered and checked for secrets.</p> <code>groupIDs</code> []string <p>GroupIDs specify, which gitlab groups to pull secrets from. Group secrets are read from left to right followed by the project variables.</p> <code>environment</code> string <p>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)</p>"},{"location":"spec/#external-secrets.io/v1beta1.GitlabSecretRef","title":"GitlabSecretRef","text":"<p> (Appears on: GitlabAuth) </p> <p> </p> Field Description <code>accessToken</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector <p>AccessToken is used for authentication.</p>"},{"location":"spec/#external-secrets.io/v1beta1.IBMAuth","title":"IBMAuth","text":"<p> (Appears on: IBMProvider) </p> <p> </p> Field Description <code>secretRef</code> IBMAuthSecretRef <code>containerAuth</code> IBMAuthContainerAuth"},{"location":"spec/#external-secrets.io/v1beta1.IBMAuthContainerAuth","title":"IBMAuthContainerAuth","text":"<p> (Appears on: IBMAuth) </p> <p> <p>IBM Container-based auth with IAM Trusted Profile.</p> </p> Field Description <code>profile</code> string <p>the IBM Trusted Profile</p> <code>tokenLocation</code> string <p>Location the token is mounted on the pod</p> <code>iamEndpoint</code> string"},{"location":"spec/#external-secrets.io/v1beta1.IBMAuthSecretRef","title":"IBMAuthSecretRef","text":"<p> (Appears on: IBMAuth) </p> <p> </p> Field Description <code>secretApiKeySecretRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector <p>The SecretAccessKey is used for authentication</p>"},{"location":"spec/#external-secrets.io/v1beta1.IBMProvider","title":"IBMProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>Configures an store to sync secrets using a IBM Cloud Secrets Manager backend.</p> </p> Field Description <code>auth</code> IBMAuth <p>Auth configures how secret-manager authenticates with the IBM secrets manager.</p> <code>serviceUrl</code> string <p>ServiceURL is the Endpoint URL that is specific to the Secrets Manager service instance</p>"},{"location":"spec/#external-secrets.io/v1beta1.KubernetesAuth","title":"KubernetesAuth","text":"<p> (Appears on: KubernetesProvider) </p> <p> </p> Field Description <code>cert</code> CertAuth (Optional) <p>has both clientCert and clientKey as secretKeySelector</p> <code>token</code> TokenAuth (Optional) <p>use static token to authenticate with</p> <code>serviceAccount</code> github.com/external-secrets/external-secrets/apis/meta/v1.ServiceAccountSelector (Optional) <p>points to a service account that should be used for authentication</p>"},{"location":"spec/#external-secrets.io/v1beta1.KubernetesProvider","title":"KubernetesProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>Configures a store to sync secrets with a Kubernetes instance.</p> </p> Field Description <code>server</code> KubernetesServer <p>configures the Kubernetes server Address.</p> <code>auth</code> KubernetesAuth <p>Auth configures how secret-manager authenticates with a Kubernetes instance.</p> <code>remoteNamespace</code> string (Optional) <p>Remote namespace to fetch the secrets from</p>"},{"location":"spec/#external-secrets.io/v1beta1.KubernetesServer","title":"KubernetesServer","text":"<p> (Appears on: KubernetesProvider) </p> <p> </p> Field Description <code>url</code> string (Optional) <p>configures the Kubernetes server Address.</p> <code>caBundle</code> []byte (Optional) <p>CABundle is a base64-encoded CA certificate</p> <code>caProvider</code> CAProvider (Optional) <p>see: https://external-secrets.io/v0.4.1/spec/#external-secrets.io/v1alpha1.CAProvider</p>"},{"location":"spec/#external-secrets.io/v1beta1.NoSecretError","title":"NoSecretError","text":"<p> <p>NoSecretError shall be returned when a GetSecret can not find the desired secret. This is used for deletionPolicy.</p> </p>"},{"location":"spec/#external-secrets.io/v1beta1.OnePasswordAuth","title":"OnePasswordAuth","text":"<p> (Appears on: OnePasswordProvider) </p> <p> <p>OnePasswordAuth contains a secretRef for credentials.</p> </p> Field Description <code>secretRef</code> OnePasswordAuthSecretRef"},{"location":"spec/#external-secrets.io/v1beta1.OnePasswordAuthSecretRef","title":"OnePasswordAuthSecretRef","text":"<p> (Appears on: OnePasswordAuth) </p> <p> <p>OnePasswordAuthSecretRef holds secret references for 1Password credentials.</p> </p> Field Description <code>connectTokenSecretRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector <p>The ConnectToken is used for authentication to a 1Password Connect Server.</p>"},{"location":"spec/#external-secrets.io/v1beta1.OnePasswordProvider","title":"OnePasswordProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>OnePasswordProvider configures a store to sync secrets using the 1Password Secret Manager provider.</p> </p> Field Description <code>auth</code> OnePasswordAuth <p>Auth defines the information necessary to authenticate against OnePassword Connect Server</p> <code>connectHost</code> string <p>ConnectHost defines the OnePassword Connect Server to connect to</p> <code>vaults</code> map[string]int <p>Vaults defines which OnePassword vaults to search in which order</p>"},{"location":"spec/#external-secrets.io/v1beta1.OracleAuth","title":"OracleAuth","text":"<p> (Appears on: OracleProvider) </p> <p> </p> Field Description <code>tenancy</code> string <p>Tenancy is the tenancy OCID where user is located.</p> <code>user</code> string <p>User is an access OCID specific to the account.</p> <code>secretRef</code> OracleSecretRef <p>SecretRef to pass through sensitive information.</p>"},{"location":"spec/#external-secrets.io/v1beta1.OracleProvider","title":"OracleProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>Configures an store to sync secrets using a Oracle Vault backend.</p> </p> Field Description <code>region</code> string <p>Region is the region where vault is located.</p> <code>vault</code> string <p>Vault is the vault\u2019s OCID of the specific vault where secret is located.</p> <code>auth</code> OracleAuth (Optional) <p>Auth configures how secret-manager authenticates with the Oracle Vault. If empty, use the instance principal, otherwise the user credentials specified in Auth.</p>"},{"location":"spec/#external-secrets.io/v1beta1.OracleSecretRef","title":"OracleSecretRef","text":"<p> (Appears on: OracleAuth) </p> <p> </p> Field Description <code>privatekey</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector <p>PrivateKey is the user\u2019s API Signing Key in PEM format, used for authentication.</p> <code>fingerprint</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector <p>Fingerprint is the fingerprint of the API private key.</p>"},{"location":"spec/#external-secrets.io/v1beta1.Provider","title":"Provider","text":"<p> <p>Provider is a common interface for interacting with secret backends.</p> </p>"},{"location":"spec/#external-secrets.io/v1beta1.SecretStore","title":"SecretStore","text":"<p> <p>SecretStore represents a secure external location for storing secrets, which can be referenced as part of <code>storeRef</code> fields.</p> </p> Field Description <code>metadata</code> Kubernetes meta/v1.ObjectMeta Refer to the Kubernetes API documentation for the fields of the <code>metadata</code> field. <code>spec</code> SecretStoreSpec <code>controller</code> string (Optional) <p>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</p> <code>provider</code> SecretStoreProvider <p>Used to configure the provider. Only one provider may be set</p> <code>retrySettings</code> SecretStoreRetrySettings (Optional) <p>Used to configure http retries if failed</p> <code>refreshInterval</code> int (Optional) <p>Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.</p> <code>conditions</code> []ClusterSecretStoreCondition (Optional) <p>Used to constraint a ClusterSecretStore to specific namespaces. Relevant only to ClusterSecretStore</p> <code>status</code> SecretStoreStatus"},{"location":"spec/#external-secrets.io/v1beta1.SecretStoreConditionType","title":"SecretStoreConditionType (<code>string</code> alias)","text":"<p> (Appears on: SecretStoreStatusCondition) </p> <p> </p> Value Description <p>\"Ready\"</p>"},{"location":"spec/#external-secrets.io/v1beta1.SecretStoreProvider","title":"SecretStoreProvider","text":"<p> (Appears on: SecretStoreSpec) </p> <p> <p>SecretStoreProvider contains the provider-specific configuration.</p> </p> Field Description <code>aws</code> AWSProvider (Optional) <p>AWS configures this store to sync secrets using AWS Secret Manager provider</p> <code>azurekv</code> AzureKVProvider (Optional) <p>AzureKV configures this store to sync secrets using Azure Key Vault provider</p> <code>akeyless</code> AkeylessProvider (Optional) <p>Akeyless configures this store to sync secrets using Akeyless Vault provider</p> <code>vault</code> VaultProvider (Optional) <p>Vault configures this store to sync secrets using Hashi provider</p> <code>gcpsm</code> GCPSMProvider (Optional) <p>GCPSM configures this store to sync secrets using Google Cloud Platform Secret Manager provider</p> <code>oracle</code> OracleProvider (Optional) <p>Oracle configures this store to sync secrets using Oracle Vault provider</p> <code>ibm</code> IBMProvider (Optional) <p>IBM configures this store to sync secrets using IBM Cloud provider</p> <code>yandexcertificatemanager</code> YandexCertificateManagerProvider (Optional) <p>YandexCertificateManager configures this store to sync secrets using Yandex Certificate Manager provider</p> <code>yandexlockbox</code> YandexLockboxProvider (Optional) <p>YandexLockbox configures this store to sync secrets using Yandex Lockbox provider</p> <code>gitlab</code> GitlabProvider (Optional) <p>GitLab configures this store to sync secrets using GitLab Variables provider</p> <code>alibaba</code> AlibabaProvider (Optional) <p>Alibaba configures this store to sync secrets using Alibaba Cloud provider</p> <code>onepassword</code> OnePasswordProvider (Optional) <p>OnePassword configures this store to sync secrets using the 1Password Cloud provider</p> <code>webhook</code> WebhookProvider (Optional) <p>Webhook configures this store to sync secrets using a generic templated webhook</p> <code>kubernetes</code> KubernetesProvider (Optional) <p>Kubernetes configures this store to sync secrets using a Kubernetes cluster provider</p> <code>fake</code> FakeProvider (Optional) <p>Fake configures a store with static key/value pairs</p> <code>senhasegura</code> SenhaseguraProvider (Optional) <p>Senhasegura configures this store to sync secrets using senhasegura provider</p> <code>doppler</code> DopplerProvider (Optional) <p>Doppler configures this store to sync secrets using the Doppler provider</p>"},{"location":"spec/#external-secrets.io/v1beta1.SecretStoreRef","title":"SecretStoreRef","text":"<p> (Appears on: ExternalSecretSpec, SourceRef) </p> <p> <p>SecretStoreRef defines which SecretStore to fetch the ExternalSecret data.</p> </p> Field Description <code>name</code> string <p>Name of the SecretStore resource</p> <code>kind</code> string (Optional) <p>Kind of the SecretStore resource (SecretStore or ClusterSecretStore) Defaults to <code>SecretStore</code></p>"},{"location":"spec/#external-secrets.io/v1beta1.SecretStoreRetrySettings","title":"SecretStoreRetrySettings","text":"<p> (Appears on: SecretStoreSpec) </p> <p> </p> Field Description <code>maxRetries</code> int32 <code>retryInterval</code> string"},{"location":"spec/#external-secrets.io/v1beta1.SecretStoreSpec","title":"SecretStoreSpec","text":"<p> (Appears on: ClusterSecretStore, SecretStore) </p> <p> <p>SecretStoreSpec defines the desired state of SecretStore.</p> </p> Field Description <code>controller</code> string (Optional) <p>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</p> <code>provider</code> SecretStoreProvider <p>Used to configure the provider. Only one provider may be set</p> <code>retrySettings</code> SecretStoreRetrySettings (Optional) <p>Used to configure http retries if failed</p> <code>refreshInterval</code> int (Optional) <p>Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.</p> <code>conditions</code> []ClusterSecretStoreCondition (Optional) <p>Used to constraint a ClusterSecretStore to specific namespaces. Relevant only to ClusterSecretStore</p>"},{"location":"spec/#external-secrets.io/v1beta1.SecretStoreStatus","title":"SecretStoreStatus","text":"<p> (Appears on: ClusterSecretStore, SecretStore) </p> <p> <p>SecretStoreStatus defines the observed state of the SecretStore.</p> </p> Field Description <code>conditions</code> []SecretStoreStatusCondition (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.SecretStoreStatusCondition","title":"SecretStoreStatusCondition","text":"<p> (Appears on: SecretStoreStatus) </p> <p> </p> Field Description <code>type</code> SecretStoreConditionType <code>status</code> Kubernetes core/v1.ConditionStatus <code>reason</code> string (Optional) <code>message</code> string (Optional) <code>lastTransitionTime</code> Kubernetes meta/v1.Time (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.SecretsClient","title":"SecretsClient","text":"<p> <p>SecretsClient provides access to secrets.</p> </p>"},{"location":"spec/#external-secrets.io/v1beta1.SenhaseguraAuth","title":"SenhaseguraAuth","text":"<p> (Appears on: SenhaseguraProvider) </p> <p> <p>SenhaseguraAuth tells the controller how to do auth in senhasegura.</p> </p> Field Description <code>clientId</code> string <code>clientSecretSecretRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector"},{"location":"spec/#external-secrets.io/v1beta1.SenhaseguraModuleType","title":"SenhaseguraModuleType (<code>string</code> alias)","text":"<p> (Appears on: SenhaseguraProvider) </p> <p> <p>SenhaseguraModuleType enum defines senhasegura target module to fetch secrets</p> </p> Value Description <p>\"DSM\"</p> <pre><code> SenhaseguraModuleDSM is the senhasegura DevOps Secrets Management module\nsee: https://senhasegura.com/devops\n</code></pre>"},{"location":"spec/#external-secrets.io/v1beta1.SenhaseguraProvider","title":"SenhaseguraProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>SenhaseguraProvider setup a store to sync secrets with senhasegura.</p> </p> Field Description <code>url</code> string <p>URL of senhasegura</p> <code>module</code> SenhaseguraModuleType <p>Module defines which senhasegura module should be used to get secrets</p> <code>auth</code> SenhaseguraAuth <p>Auth defines parameters to authenticate in senhasegura</p> <code>ignoreSslCertificate</code> bool <p>IgnoreSslCertificate defines if SSL certificate must be ignored</p>"},{"location":"spec/#external-secrets.io/v1beta1.SourceRef","title":"SourceRef","text":"<p> (Appears on: ExternalSecretData, ExternalSecretDataFromRemoteRef) </p> <p> <p>SourceRef allows you to override the source from which the secret will be pulled from. You can define at maximum one property.</p> </p> Field Description <code>storeRef</code> SecretStoreRef (Optional) <code>generatorRef</code> GeneratorRef (Optional) <p>GeneratorRef points to a generator custom resource in</p>"},{"location":"spec/#external-secrets.io/v1beta1.TemplateEngineVersion","title":"TemplateEngineVersion (<code>string</code> alias)","text":"<p> (Appears on: ExternalSecretTemplate) </p> <p> </p> Value Description <p>\"v1\"</p> <p>\"v2\"</p>"},{"location":"spec/#external-secrets.io/v1beta1.TemplateFrom","title":"TemplateFrom","text":"<p> (Appears on: ExternalSecretTemplate) </p> <p> </p> Field Description <code>configMap</code> TemplateRef <code>secret</code> TemplateRef <code>scope</code> TemplateScope (Optional) <code>target</code> TemplateTarget (Optional) <code>literal</code> string (Optional)"},{"location":"spec/#external-secrets.io/v1beta1.TemplateRef","title":"TemplateRef","text":"<p> (Appears on: TemplateFrom) </p> <p> </p> Field Description <code>name</code> string <code>items</code> []TemplateRefItem"},{"location":"spec/#external-secrets.io/v1beta1.TemplateRefItem","title":"TemplateRefItem","text":"<p> (Appears on: TemplateRef) </p> <p> </p> Field Description <code>key</code> string"},{"location":"spec/#external-secrets.io/v1beta1.TemplateScope","title":"TemplateScope (<code>string</code> alias)","text":"<p> (Appears on: TemplateFrom) </p> <p> </p> Value Description <p>\"KeysAndValues\"</p> <p>\"Values\"</p>"},{"location":"spec/#external-secrets.io/v1beta1.TemplateTarget","title":"TemplateTarget (<code>string</code> alias)","text":"<p> (Appears on: TemplateFrom) </p> <p> </p> Value Description <p>\"Annotations\"</p> <p>\"Data\"</p> <p>\"Labels\"</p> <p>\"StringData\"</p>"},{"location":"spec/#external-secrets.io/v1beta1.TokenAuth","title":"TokenAuth","text":"<p> (Appears on: KubernetesAuth) </p> <p> </p> Field Description <code>bearerToken</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector"},{"location":"spec/#external-secrets.io/v1beta1.ValidationResult","title":"ValidationResult (<code>byte</code> alias)","text":"Value Description <p>2</p> <p>Error indicates that there is a misconfiguration.</p> <p>0</p> <p>Ready indicates that the client is configured correctly and can be used.</p> <p>1</p> <p>Unknown indicates that the client can be used but information is missing and it can not be validated.</p>"},{"location":"spec/#external-secrets.io/v1beta1.VaultAppRole","title":"VaultAppRole","text":"<p> (Appears on: VaultAuth) </p> <p> <p>VaultAppRole authenticates with Vault using the App Role auth mechanism, with the role and secret stored in a Kubernetes Secret resource.</p> </p> Field Description <code>path</code> string <p>Path where the App Role authentication backend is mounted in Vault, e.g: \u201capprole\u201d</p> <code>roleId</code> string <p>RoleID configured in the App Role authentication backend when setting up the authentication backend in Vault.</p> <code>secretRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector <p>Reference to a key in a Secret that contains the App Role secret used to authenticate with Vault. The <code>key</code> field must be specified and denotes which entry within the Secret resource is used as the app role secret.</p>"},{"location":"spec/#external-secrets.io/v1beta1.VaultAuth","title":"VaultAuth","text":"<p> (Appears on: VaultProvider) </p> <p> <p>VaultAuth is the configuration used to authenticate with a Vault server. Only one of <code>tokenSecretRef</code>, <code>appRole</code>, <code>kubernetes</code>, <code>ldap</code>, <code>userPass</code>, <code>jwt</code> or <code>cert</code> can be specified.</p> </p> Field Description <code>tokenSecretRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) <p>TokenSecretRef authenticates with Vault by presenting a token.</p> <code>appRole</code> VaultAppRole (Optional) <p>AppRole authenticates with Vault using the App Role auth mechanism, with the role and secret stored in a Kubernetes Secret resource.</p> <code>kubernetes</code> VaultKubernetesAuth (Optional) <p>Kubernetes authenticates with Vault by passing the ServiceAccount token stored in the named Secret resource to the Vault server.</p> <code>ldap</code> VaultLdapAuth (Optional) <p>Ldap authenticates with Vault by passing username/password pair using the LDAP authentication method</p> <code>userPass</code> VaultUserPassAuth (Optional) <p>UserPass authenticates with Vault by passing username/password pair using the userPass authentication method</p> <code>jwt</code> VaultJwtAuth (Optional) <p>Jwt authenticates with Vault by passing role and JWT token using the JWT/OIDC authentication method</p> <code>cert</code> VaultCertAuth (Optional) <p>Cert authenticates with TLS Certificates by passing client certificate, private key and ca certificate Cert authentication method</p>"},{"location":"spec/#external-secrets.io/v1beta1.VaultCertAuth","title":"VaultCertAuth","text":"<p> (Appears on: VaultAuth) </p> <p> <p>VaultJwtAuth authenticates with Vault using the JWT/OIDC authentication method, with the role name and token stored in a Kubernetes Secret resource.</p> </p> Field Description <code>clientCert</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) <p>ClientCert is a certificate to authenticate using the Cert Vault authentication method</p> <code>secretRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector <p>SecretRef to a key in a Secret resource containing client private key to authenticate with Vault using the Cert authentication method</p>"},{"location":"spec/#external-secrets.io/v1beta1.VaultJwtAuth","title":"VaultJwtAuth","text":"<p> (Appears on: VaultAuth) </p> <p> <p>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 <code>TokenRequest</code>.</p> </p> Field Description <code>path</code> string <p>Path where the JWT authentication backend is mounted in Vault, e.g: \u201cjwt\u201d</p> <code>role</code> string (Optional) <p>Role is a JWT role to authenticate using the JWT/OIDC Vault authentication method</p> <code>secretRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) <p>Optional SecretRef that refers to a key in a Secret resource containing JWT token to authenticate with Vault using the JWT/OIDC authentication method.</p> <code>kubernetesServiceAccountToken</code> VaultKubernetesServiceAccountTokenAuth (Optional) <p>Optional ServiceAccountToken specifies the Kubernetes service account for which to request a token for with the <code>TokenRequest</code> API.</p>"},{"location":"spec/#external-secrets.io/v1beta1.VaultKVStoreVersion","title":"VaultKVStoreVersion (<code>string</code> alias)","text":"<p> (Appears on: VaultProvider) </p> <p> </p> Value Description <p>\"v1\"</p> <p>\"v2\"</p>"},{"location":"spec/#external-secrets.io/v1beta1.VaultKubernetesAuth","title":"VaultKubernetesAuth","text":"<p> (Appears on: VaultAuth) </p> <p> <p>Authenticate against Vault using a Kubernetes ServiceAccount token stored in a Secret.</p> </p> Field Description <code>mountPath</code> string <p>Path where the Kubernetes authentication backend is mounted in Vault, e.g: \u201ckubernetes\u201d</p> <code>serviceAccountRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.ServiceAccountSelector (Optional) <p>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.</p> <code>secretRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) <p>Optional secret field containing a Kubernetes ServiceAccount JWT used for authenticating with Vault. If a name is specified without a key, <code>token</code> is the default. If one is not specified, the one bound to the controller will be used.</p> <code>role</code> string <p>A required field containing the Vault Role to assume. A Role binds a Kubernetes ServiceAccount with a set of Vault policies.</p>"},{"location":"spec/#external-secrets.io/v1beta1.VaultKubernetesServiceAccountTokenAuth","title":"VaultKubernetesServiceAccountTokenAuth","text":"<p> (Appears on: VaultJwtAuth) </p> <p> <p>VaultKubernetesServiceAccountTokenAuth authenticates with Vault using a temporary Kubernetes service account token retrieved by the <code>TokenRequest</code> API.</p> </p> Field Description <code>serviceAccountRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.ServiceAccountSelector <p>Service account field containing the name of a kubernetes ServiceAccount.</p> <code>audiences</code> []string (Optional) <p>Optional audiences field that will be used to request a temporary Kubernetes service account token for the service account referenced by <code>serviceAccountRef</code>. Defaults to a single audience <code>vault</code> it not specified. Deprecated: use serviceAccountRef.Audiences instead</p> <code>expirationSeconds</code> int64 (Optional) <p>Optional expiration time in seconds that will be used to request a temporary Kubernetes service account token for the service account referenced by <code>serviceAccountRef</code>. Deprecated: this will be removed in the future. Defaults to 10 minutes.</p>"},{"location":"spec/#external-secrets.io/v1beta1.VaultLdapAuth","title":"VaultLdapAuth","text":"<p> (Appears on: VaultAuth) </p> <p> <p>VaultLdapAuth authenticates with Vault using the LDAP authentication method, with the username and password stored in a Kubernetes Secret resource.</p> </p> Field Description <code>path</code> string <p>Path where the LDAP authentication backend is mounted in Vault, e.g: \u201cldap\u201d</p> <code>username</code> string <p>Username is a LDAP user name used to authenticate using the LDAP Vault authentication method</p> <code>secretRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector <p>SecretRef to a key in a Secret resource containing password for the LDAP user used to authenticate with Vault using the LDAP authentication method</p>"},{"location":"spec/#external-secrets.io/v1beta1.VaultUserPassAuth","title":"VaultUserPassAuth","text":"<p> (Appears on: VaultAuth) </p> <p> <p>VaultUserPassAuth authenticates with Vault using the UserPass authentication method, with the username and password stored in a Kubernetes Secret resource.</p> </p> Field Description <code>path</code> string <p>Path where the UserPass authentication backend is mounted in Vault, e.g: \u201cuserpass\u201d</p> <code>username</code> string <p>Username is a user name used to authenticate using the UserPass Vault authentication method</p> <code>secretRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector <p>SecretRef to a key in a Secret resource containing password for the user used to authenticate with Vault using the UserPass authentication method</p>"},{"location":"spec/#external-secrets.io/v1beta1.VaultProvider","title":"VaultProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>Configures an store to sync secrets using a HashiCorp Vault KV backend.</p> </p> Field Description <code>auth</code> VaultAuth <p>Auth configures how secret-manager authenticates with the Vault server.</p> <code>server</code> string <p>Server is the connection address for the Vault server, e.g: \u201chttps://vault.example.com:8200\u201d.</p> <code>path</code> string (Optional) <p>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.</p> <code>version</code> VaultKVStoreVersion <p>Version is the Vault KV secret engine version. This can be either \u201cv1\u201d or \u201cv2\u201d. Version defaults to \u201cv2\u201d.</p> <code>namespace</code> string (Optional) <p>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</p> <code>caBundle</code> []byte (Optional) <p>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.</p> <code>caProvider</code> CAProvider (Optional) <p>The provider for the CA bundle to use to validate Vault server certificate.</p> <code>readYourWrites</code> bool (Optional) <p>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</p> <code>forwardInconsistent</code> bool (Optional) <p>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</p>"},{"location":"spec/#external-secrets.io/v1beta1.WebhookCAProvider","title":"WebhookCAProvider","text":"<p> (Appears on: WebhookProvider) </p> <p> <p>Defines a location to fetch the cert for the webhook provider from.</p> </p> Field Description <code>type</code> WebhookCAProviderType <p>The type of provider to use such as \u201cSecret\u201d, or \u201cConfigMap\u201d.</p> <code>name</code> string <p>The name of the object located at the provider type.</p> <code>key</code> string <p>The key the value inside of the provider type to use, only used with \u201cSecret\u201d type</p> <code>namespace</code> string (Optional) <p>The namespace the Provider type is in.</p>"},{"location":"spec/#external-secrets.io/v1beta1.WebhookCAProviderType","title":"WebhookCAProviderType (<code>string</code> alias)","text":"<p> (Appears on: WebhookCAProvider) </p> <p> </p> Value Description <p>\"ConfigMap\"</p> <p>\"Secret\"</p>"},{"location":"spec/#external-secrets.io/v1beta1.WebhookProvider","title":"WebhookProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>AkeylessProvider Configures an store to sync secrets using Akeyless KV.</p> </p> Field Description <code>method</code> string <p>Webhook Method</p> <code>url</code> string <p>Webhook url to call</p> <code>headers</code> map[string]string (Optional) <p>Headers</p> <code>body</code> string (Optional) <p>Body</p> <code>timeout</code> Kubernetes meta/v1.Duration (Optional) <p>Timeout</p> <code>result</code> WebhookResult <p>Result formatting</p> <code>secrets</code> []WebhookSecret (Optional) <p>Secrets to fill in templates These secrets will be passed to the templating function as key value pairs under the given name</p> <code>caBundle</code> []byte (Optional) <p>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.</p> <code>caProvider</code> WebhookCAProvider (Optional) <p>The provider for the CA bundle to use to validate webhook server certificate.</p>"},{"location":"spec/#external-secrets.io/v1beta1.WebhookResult","title":"WebhookResult","text":"<p> (Appears on: WebhookProvider) </p> <p> </p> Field Description <code>jsonPath</code> string (Optional) <p>Json path of return value</p>"},{"location":"spec/#external-secrets.io/v1beta1.WebhookSecret","title":"WebhookSecret","text":"<p> (Appears on: WebhookProvider) </p> <p> </p> Field Description <code>name</code> string <p>Name of this secret in templates</p> <code>secretRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector <p>Secret ref to fill in credentials</p>"},{"location":"spec/#external-secrets.io/v1beta1.YandexCertificateManagerAuth","title":"YandexCertificateManagerAuth","text":"<p> (Appears on: YandexCertificateManagerProvider) </p> <p> </p> Field Description <code>authorizedKeySecretRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) <p>The authorized key used for authentication</p>"},{"location":"spec/#external-secrets.io/v1beta1.YandexCertificateManagerCAProvider","title":"YandexCertificateManagerCAProvider","text":"<p> (Appears on: YandexCertificateManagerProvider) </p> <p> </p> Field Description <code>certSecretRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector"},{"location":"spec/#external-secrets.io/v1beta1.YandexCertificateManagerProvider","title":"YandexCertificateManagerProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>YandexCertificateManagerProvider Configures a store to sync secrets using the Yandex Certificate Manager provider.</p> </p> Field Description <code>apiEndpoint</code> string (Optional) <p>Yandex.Cloud API endpoint (e.g. \u2018api.cloud.yandex.net:443\u2019)</p> <code>auth</code> YandexCertificateManagerAuth <p>Auth defines the information necessary to authenticate against Yandex Certificate Manager</p> <code>caProvider</code> YandexCertificateManagerCAProvider (Optional) <p>The provider for the CA bundle to use to validate Yandex.Cloud server certificate.</p>"},{"location":"spec/#external-secrets.io/v1beta1.YandexLockboxAuth","title":"YandexLockboxAuth","text":"<p> (Appears on: YandexLockboxProvider) </p> <p> </p> Field Description <code>authorizedKeySecretRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector (Optional) <p>The authorized key used for authentication</p>"},{"location":"spec/#external-secrets.io/v1beta1.YandexLockboxCAProvider","title":"YandexLockboxCAProvider","text":"<p> (Appears on: YandexLockboxProvider) </p> <p> </p> Field Description <code>certSecretRef</code> github.com/external-secrets/external-secrets/apis/meta/v1.SecretKeySelector"},{"location":"spec/#external-secrets.io/v1beta1.YandexLockboxProvider","title":"YandexLockboxProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>YandexLockboxProvider Configures a store to sync secrets using the Yandex Lockbox provider.</p> </p> Field Description <code>apiEndpoint</code> string (Optional) <p>Yandex.Cloud API endpoint (e.g. \u2018api.cloud.yandex.net:443\u2019)</p> <code>auth</code> YandexLockboxAuth <p>Auth defines the information necessary to authenticate against Yandex Lockbox</p> <code>caProvider</code> YandexLockboxCAProvider (Optional) <p>The provider for the CA bundle to use to validate Yandex.Cloud server certificate.</p> <p> Generated with <code>gen-crd-api-reference-docs</code>. </p>"},{"location":"api/clusterexternalsecret/","title":"ClusterExternalSecret","text":"<p>The <code>ClusterExternalSecret</code> is a cluster scoped resource that can be used to manage <code>ExternalSecret</code> resources in specific namespaces.</p> <p>With <code>namespaceSelector</code> 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.</p>"},{"location":"api/clusterexternalsecret/#example","title":"Example","text":"<p>Below is an example of the <code>ClusterExternalSecret</code> in use.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ClusterExternalSecret\nmetadata:\nname: \"hello-world\"\nspec:\n# The name to be used on the ExternalSecrets\nexternalSecretName: \"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\nnamespaceSelector:\nmatchLabels: 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\nrefreshTime: \"1m\"\n\n# This is the spec of the ExternalSecrets to be created\n# The content of this was taken from our ExternalSecret example\nexternalSecretSpec:\nsecretStoreRef:\nname: secret-store-name\nkind: SecretStore\n\nrefreshInterval: \"1h\"\ntarget:\nname: my-secret\ncreationPolicy: 'Merge'\ntemplate:\ntype: kubernetes.io/dockerconfigjson\n\nmetadata:\nannotations: {}\nlabels: {}\ndata:\nconfig.yml: |\nendpoints:\n- https://{{ .data.user }}:{{ .data.password }}@api.exmaple.com\ntemplateFrom:\n- configMap:\nname: alertmanager\nitems:\n- key: alertmanager.yaml\ndata:\n- secretKey: secret-key-to-be-managed\nremoteRef:\nkey: provider-key\nversion: provider-key-version\nproperty: provider-key-property\ndataFrom:\n- key: provider-key\nversion: provider-key-version\nproperty: 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.\nfailedNamespaces:\n- namespace: \"matching-ns-1\"\n# This is one of the possible messages, and likely the most common\nreason: \"external secret already exists in namespace\"\n\n# You can find all matching and successfully deployed namespaces here\nprovisionedNamespaces:\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\nconditions:\n- type: PartiallyReady\nstatus: \"True\"\nlastTransitionTime: \"2022-01-12T12:33:02Z\"\n</code></pre>"},{"location":"api/clustersecretstore/","title":"ClusterSecretStore","text":"<p>The <code>ClusterSecretStore</code> is a cluster scoped SecretStore that can be referenced by all <code>ExternalSecrets</code> from all namespaces. Use it to offer a central gateway to your secret backend.</p>"},{"location":"api/clustersecretstore/#example","title":"Example","text":"<p>For a full list of supported fields see spec or dig into our guides.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\nname: 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\ncontroller: dev\n\n# provider field contains the configuration to access the provider\n# which contains the secret exactly one provider must be configured.\nprovider:\n# (1): AWS Secrets Manager\n# aws configures this store to sync secrets using AWS Secret Manager provider\naws:\nservice: SecretsManager\n# Role is a Role ARN which the SecretManager provider will assume\nrole: iam-role\n# AWS Region to be used for the provider\nregion: eu-central-1\n# Auth defines the information necessary to authenticate against AWS\nauth:\n# Getting the accessKeyID and secretAccessKey from an already created Kubernetes Secret\nsecretRef:\naccessKeyIDSecretRef:\nname: awssm-secret\nkey: access-key\nsecretAccessKeySecretRef:\nname: awssm-secret\nkey: 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\njwt:\nserviceAccountRef:\nname: my-serviceaccount\nnamespace: sa-namespace\n\nvault:\nserver: \"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\npath: \"secret\"\n# Version is the Vault KV secret engine version.\n# This can be either \"v1\" or \"v2\", defaults to \"v2\"\nversion: \"v2\"\n# vault enterprise namespace: https://www.vaultproject.io/docs/enterprise/namespaces\nnamespace: \"a-team\"\n# base64 encoded string of certificate\ncaBundle: \"...\"\n# Instead of caBundle you can also specify a caProvider\n# this will retrieve the cert from a Secret or ConfigMap\ncaProvider:\n# Can be Secret or ConfigMap\ntype: \"Secret\"\n# namespace is mandatory for ClusterSecretStore and not relevant for SecretStore\nnamespace: \"my-cert-secret-namespace\"\nname: \"my-cert-secret\"\nkey: \"cert-key\"\nauth:\n# static token: https://www.vaultproject.io/docs/auth/token\ntokenSecretRef:\nname: \"my-secret\"\nnamespace: \"secret-admin\"\nkey: \"vault-token\"\n\n# AppRole auth: https://www.vaultproject.io/docs/auth/approle\nappRole:\npath: \"approle\"\nroleId: \"db02de05-fa39-4855-059b-67221c5c2f63\"\nsecretRef:\nname: \"my-secret\"\nnamespace: \"secret-admin\"\nkey: \"vault-token\"\n\n# Kubernetes auth: https://www.vaultproject.io/docs/auth/kubernetes\nkubernetes:\nmountPath: \"kubernetes\"\nrole: \"demo\"\n# Optional service account reference\nserviceAccountRef:\nname: \"my-sa\"\nnamespace: \"secret-admin\"\n# Optional secret field containing a Kubernetes ServiceAccount JWT\n# used for authenticating with Vault\nsecretRef:\nname: \"my-secret\"\nnamespace: \"secret-admin\"\nkey: \"vault\"\n\n# (2): GCP Secret Manager\ngcpsm:\n# Auth defines the information necessary to authenticate against GCP by getting\n# the credentials from an already created Kubernetes Secret.\nauth:\nsecretRef:\nsecretAccessKeySecretRef:\nname: gcpsm-secret\nkey: secret-access-credentials\nnamespace: example\nprojectID: myproject\n\n# (3): Kubernetes provider\nkubernetes:\nserver:\nurl: \"https://myapiserver.tld\"\ncaProvider:\ntype: Secret\nname: my-cluster-secrets\nnamespace: example\nkey: ca.crt\nauth:\nserviceAccount:\nname: \"example-sa\"\nnamespace: \"example\"\n\n# (4): Oracle provider\noracle:\n# The vault OCID\nvault: ocid1.vault.oc1.eu-frankfurt-1.aaa1aaaaaaaaa.aaaaaaaaaaaaaa1aaaaaaa111aaaaaaaaaaaaaaaa\n# The vault region\nregion: eu-frankfurt-1\nauth:\n# The user OCID\nuser: ocid1.user.oc1..aaa1aaaaaaaaa.aaaaaaaaaaaaaa1aaaaaaa111aaaaaaaaaaaaaaaa\n# The tenancy OCID\ntenancy: ocid1.tenancy.oc1..aaa1aaaaaaaaa.aaaaaaaaaaaaaa1aaaaaaa111aaaaaaaaaaaaaaaa\nsecretRef:\nprivatekey:\n# The secret that contains your privatekey\nname: oci-secret-name\nkey: privateKey\nfingerprint:\n# The secret that contains your fingerprint\nname: oci-secret-name\nkey: fingerprint\n\n# (TODO): add more provider examples here\n\n# Conditions about namespaces in which the ClusterSecretStore is usable for ExternalSecrets\nconditions:\n# Options are namespaceSelector, or namespaces\n- namespaceSelector:\nmatchLabels:\nmy.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\nconditions:\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\nstatus: \"False\"\nreason: \"ConfigError\"\nmessage: \"SecretStore validation failed\"\nlastTransitionTime: \"2019-08-12T12:33:02Z\"\n</code></pre>"},{"location":"api/components/","title":"Components","text":""},{"location":"api/components/#overview","title":"Overview","text":"<p>Exernal Secrets comes with three components: <code>Core Controller</code>, <code>Webhook</code> and <code>Cert Controller</code>.</p> <p>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 <code>ExternalSecret</code> and <code>SecretStore</code> resources.</p> <p>These features are optional but highly recommended. You can disable them with helm chart values <code>certController.create=false</code> and <code>webhook.create=false</code>.</p> <p> </p>"},{"location":"api/components/#tls-bootstrap","title":"TLS Bootstrap","text":"<p>Cert-controller is responsible for (1) generating TLS credentials which will be used by the webhook component and (2) injecting the certificate as <code>caBundle</code> into <code>Kind=CustomResourceDefinition</code> for conversion webhooks and <code>Kind=ValidatingWebhookConfiguration</code> for validating admission webhook. The TLS credentials are stored in a <code>Kind=Secret</code> which is consumed by the webhook.</p> <p></p>"},{"location":"api/controller-options/","title":"Controller Options","text":"<p>The external-secrets binary includes three components: <code>core controller</code>, <code>certcontroller</code> and <code>webook</code>.</p>"},{"location":"api/controller-options/#core-controller-flags","title":"Core Controller Flags","text":"<p>The core controller is invoked without a subcommand and can be configured with the following flags:</p> Name Type Default Description <code>--client-burst</code> int uses rest client default (10) Maximum Burst allowed to be passed to rest.Client <code>--client-qps</code> float32 uses rest client default (5) QPS configuration to be passed to rest.Client <code>--concurrent</code> int 1 The number of concurrent reconciles. <code>--controller-class</code> string default The controller is instantiated with a specific controller name and filters ES based on this property <code>--enable-cluster-external-secret-reconciler</code> boolean true Enables the cluster external secret reconciler. <code>--enable-cluster-store-reconciler</code> boolean true Enables the cluster store reconciler. <code>--enable-push-secret-reconciler</code> boolean true Enables the push secret reconciler. <code>--enable-secrets-caching</code> boolean false Enables the secrets caching for external-secrets pod. <code>--enable-configmaps-caching</code> boolean false Enables the ConfigMap caching for external-secrets pod. <code>--enable-flood-gate</code> boolean true Enable flood gate. External secret will be reconciled only if the ClusterStore or Store have an healthy or unknown state. <code>--enable-extended-metric-labels</code> boolean true Enable recommended kubernetes annotations as labels in metrics. <code>--enable-leader-election</code> boolean false Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager. <code>--experimental-enable-aws-session-cache</code> boolean false Enable experimental AWS session cache. External secret will reuse the AWS session without creating a new one on each request. <code>--help</code> help for external-secrets <code>--loglevel</code> string info loglevel to use, one of: debug, info, warn, error, dpanic, panic, fatal <code>--metrics-addr</code> string :8080 The address the metric endpoint binds to. <code>--namespace</code> 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 <code>--store-requeue-interval</code> 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 <code>--crd-requeue-interval</code> duration 5m0s Time duration between reconciling CRDs for new certs <code>--enable-leader-election</code> boolean false Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager. <code>--healthz-addr</code> string :8081 The address the health endpoint binds to. <code>--help</code> help for certcontroller <code>--loglevel</code> string info loglevel to use, one of: debug, info, warn, error, dpanic, panic, fatal <code>--metrics-addr</code> string :8080 The address the metric endpoint binds to. <code>--secret-name</code> string external-secrets-webhook Secret to store certs for webhook <code>--secret-namespace</code> string default namespace of the secret to store certs <code>--service-name</code> string external-secrets-webhook Webhook service name <code>--service-namespace</code> string default Webhook service namespace"},{"location":"api/controller-options/#webhook-flags","title":"Webhook Flags","text":"Name Type Default Description <code>--cert-dir</code> string /tmp/k8s-webhook-server/serving-certs path to check for certs <code>--check-interval</code> duration 5m0s certificate check interval <code>--dns-name</code> string localhost DNS name to validate certificates with <code>--healthz-addr</code> string :8081 The address the health endpoint binds to. <code>--help</code> help for webhook <code>--loglevel</code> string info loglevel to use, one of: debug, info, warn, error, dpanic, panic, fatal <code>--lookahead-interval</code> duration 2160h0m0s (90d) certificate check interval <code>--metrics-addr</code> string :8080 The address the metric endpoint binds to. <code>--port</code> number 10250 Port number that the webhook server will serve. <code>--tls-ciphers</code> 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' <code>--tls-min-version</code> string 1.2 minimum version of TLS supported."},{"location":"api/externalsecret/","title":"ExternalSecret","text":"<p>The <code>ExternalSecret</code> describes what data should be fetched, how the data should be transformed and saved as a <code>Kind=Secret</code>:</p> <ul> <li>tells the operator what secrets should be synced by using <code>spec.data</code> to explicitly sync individual keys or use <code>spec.dataFrom</code> to get all values from the external API.</li> <li>you can specify how the secret should look like by specifying a <code>spec.target.template</code></li> </ul>"},{"location":"api/externalsecret/#template","title":"Template","text":"<p>When the controller reconciles the <code>ExternalSecret</code> it will use the <code>spec.template</code> as a blueprint to construct a new <code>Kind=Secret</code>. You can use golang templates to define the blueprint and use template functions to transform secret values. You can also pull in <code>ConfigMaps</code> that contain golang-template data using <code>templateFrom</code>. See advanced templating for details.</p>"},{"location":"api/externalsecret/#update-behavior","title":"Update Behavior","text":"<p>The <code>Kind=Secret</code> is updated when:</p> <ul> <li>the <code>spec.refreshInterval</code> has passed and is not <code>0</code></li> <li>the <code>ExternalSecret</code>'s <code>labels</code> or <code>annotations</code> are changed</li> <li>the <code>ExternalSecret</code>'s <code>spec</code> has been changed</li> </ul> <p>You can trigger a secret refresh by using kubectl or any other kubernetes api client:</p> <pre><code>kubectl annotate es my-es force-sync=$(date +%s) --overwrite\n</code></pre>"},{"location":"api/externalsecret/#features","title":"Features","text":"<p>Individual features are described in the Guides section:</p> <ul> <li>Find many secrets / Extract from structured data</li> <li>Templating</li> <li>Using Generators</li> <li>Secret Ownership and Deletion</li> <li>Key Rewriting</li> <li>Decoding Strategy</li> </ul>"},{"location":"api/externalsecret/#example","title":"Example","text":"<p>Take a look at an annotated example to understand the design behind the <code>ExternalSecret</code>.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: \"hello-world\"\n\n# labels and annotations are copied over to the\n# secret that will be created\nlabels:\nacme.org/owned-by: \"q-team\"\nannotations:\nacme.org/sha: 1234\n\nspec:\n\n# Optional, SecretStoreRef defines the default SecretStore to use when fetching the secret data.\nsecretStoreRef:\nname: aws-store\nkind: 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\nrefreshInterval: \"1h\"\n\n# the target describes the secret that shall be created\n# there can only be one target per ExternalSecret\ntarget:\n\n# The secret name of the resource\n# Defaults to .metadata.name of the ExternalSecret\n# It is immutable\nname: 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)\ncreationPolicy: '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\ndeletionPolicy: \"Retain\"\n\n# Specify a blueprint for the resulting Kind=Secret\ntemplate:\ntype: kubernetes.io/dockerconfigjson # or TLS...\n\nmetadata:\nannotations: {}\nlabels: {}\n\n# Use inline templates to construct your desired config file that contains your secret\ndata:\nconfig.yml: |\ndatabase:\nconnection: 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...\ntemplateFrom:\n- configMap:\nname: application-config-tmpl\nitems:\n- key: config.yml\n\n# Data defines the connection between the Kubernetes Secret keys and the Provider data\ndata:\n- secretKey: username\nremoteRef:\nkey: database-credentials\nversion: v1\nproperty: username\ndecodingStrategy: None # can be None, Base64, Base64URL or Auto\n\n# define the source of the secret. Can be a SecretStore or a Generator kind\nsourceRef:\n# point to a SecretStore that should be used to fetch a secret.\n# must be defined if no spec.secretStoreRef is defined.\nstoreRef:\nname: aws-secretstore\nkind: ClusterSecretStore\n\n# point to a generator resource that provides the secret value\ngeneratorRef:\napiVersion: generators.external-secrets.io/v1alpha1\nkind: Password\nname: db-password\n\n# Used to fetch all properties from the Provider key\n# If multiple dataFrom are specified, secrets are merged in the specified order\ndataFrom:\n- extract:\nkey: database-credentials\nversion: v1\nproperty: data\nconversionStrategy: Default\ndecodingStrategy: Auto\nrewrite:\n- regexp:\nsource: \"exp-(.*?)-ression\"\ntarget: \"rewriting-${1}-with-groups\"\n- find:\npath: path-to-filter\nsource: \"exp-(.*?)-ression\"\ntarget: \"rewriting-${1}-with-groups\"\nname:\nregexp: \".*foobar.*\"\ntags:\nfoo: bar\nconversionStrategy: Unicode\ndecodingStrategy: Base64\nrewrite:\n- regexp:\nsource: \"foo\"\ntarget: \"bar\"\n\nstatus:\n# refreshTime is the time and date the external secret was fetched and\n# the target secret updated\nrefreshTime: \"2019-08-12T12:33:02Z\"\n# Standard condition schema\nconditions:\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\nstatus: \"True\" # False if last refresh was not successful\nreason: \"SecretSynced\"\nmessage: \"Secret was synced\"\nlastTransitionTime: \"2019-08-12T12:33:02Z\"\n</code></pre>"},{"location":"api/metrics/","title":"Metrics","text":"<p>The External Secrets Operator exposes its Prometheus metrics in the <code>/metrics</code> path. To enable it, set the <code>serviceMonitor.enabled</code> Helm flag to <code>true</code>.</p> <p>If you are using a different monitoring tool that also needs a <code>/metrics</code> endpoint, you can set the <code>metrics.service.enabled</code> Helm flag to <code>true</code>. In addition you can also set <code>webhook.metrics.service.enabled</code> and <code>certController.metrics.service.enabled</code> to scrape the other components.</p> <p>The Operator has the controller-runtime metrics inherited from kubebuilder plus some custom metrics with a resource name prefix, such as <code>externalsecret_</code>.</p>"},{"location":"api/metrics/#cluster-external-secret-metrics","title":"Cluster External Secret Metrics","text":"Name Type Description <code>clusterexternalsecret_status_condition</code> Gauge The status condition of a specific Cluster External Secret <code>clusterexternalsecret_reconcile_duration</code> Gauge The duration time to reconcile the Cluster External Secret"},{"location":"api/metrics/#external-secret-metrics","title":"External Secret Metrics","text":"Name Type Description <code>externalsecret_provider_api_calls_count</code> Counter Number of API calls made to an upstream secret provider API. The metric provides a <code>provider</code>, <code>call</code> and <code>status</code> labels. <code>externalsecret_sync_calls_total</code> Counter Total number of the External Secret sync calls <code>externalsecret_sync_calls_error</code> Counter Total number of the External Secret sync errors <code>externalsecret_status_condition</code> Gauge The status condition of a specific External Secret <code>externalsecret_reconcile_duration</code> 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 <code>clustersecretstore_status_condition</code> Gauge The status condition of a specific Cluster Secret Store <code>clustersecretstore_reconcile_duration</code> Gauge The duration time to reconcile the Cluster Secret Store"},{"location":"api/metrics/#secret-store-metrics","title":"Secret Store Metrics","text":"Name Type Description <code>secretstore_status_condition</code> Gauge The status condition of a specific Secret Store <code>secretstore_reconcile_duration</code> Gauge The duration time to reconcile the Secret Store"},{"location":"api/metrics/#controller-runtime-metrics","title":"Controller Runtime Metrics","text":"<p>See the kubebuilder documentation on the default exported metrics by controller-runtime.</p>"},{"location":"api/metrics/#dashboard","title":"Dashboard","text":"<p>We provide a Grafana Dashboard that gives you an overview of External Secrets Operator:</p> <p> </p>"},{"location":"api/metrics/#service-level-indicators-and-alerts","title":"Service Level Indicators and Alerts","text":"<p>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).</p>"},{"location":"api/metrics/#webhook-http-status-codes","title":"Webhook HTTP Status Codes","text":"<p>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 <code>kube-apiserver</code>.</p> <p>SLI Example: request error percentage. <pre><code>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</code></pre></p>"},{"location":"api/metrics/#webhook-http-request-latency","title":"Webhook HTTP Request Latency","text":"<p>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 <code>kube-apiserver</code>.</p> <p>SLI Example: p99 across all webhook requests. <pre><code>histogram_quantile(0.99,\n sum(rate(controller_runtime_webhook_latency_seconds_bucket{service=~\"external-secrets.*\"}[5m])) by (le)\n)\n</code></pre></p>"},{"location":"api/metrics/#controller-workqueue-depth","title":"Controller Workqueue Depth","text":"<p>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.</p> <p>Note: when a controller is restarted, then <code>queue length = total number of resources</code>. 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.</p> <pre><code>sum(\n workqueue_depth{service=~\"external-secrets.*\"}\n) by (name)\n</code></pre>"},{"location":"api/metrics/#controller-reconcile-latency","title":"Controller Reconcile Latency","text":"<p>The controller should be able to reconcile resources within a reasonable timeframe. When latency is high secret delivery may impacted.</p> <p>SLI Example: p99 across all controllers. <pre><code>histogram_quantile(0.99,\n sum(rate(controller_runtime_reconcile_time_seconds_bucket{service=~\"external-secrets.*\"}[5m])) by (le)\n)\n</code></pre></p>"},{"location":"api/metrics/#controller-reconcile-error","title":"Controller Reconcile Error","text":"<p>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.</p> <pre><code>sum(increase(\n controller_runtime_reconcile_total{service=~\"external-secrets.*\",controller=~\"$controller\"}[1m])\n) by (result)\n</code></pre>"},{"location":"api/pushsecret/","title":"PushSecret","text":"<p>The <code>PushSecret</code> is namespaced and specifies how to push secrets to secret stores.</p> <pre><code>apiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\nname: pushsecret-example # Customisable\nnamespace: default # Same of the SecretStores\nspec:\nrefreshInterval: 10s # Refresh interval for which push secret will reconcile\nsecretStoreRefs: # A list of secret stores to push secrets to\n- name: aws-parameterstore\nkind: SecretStore\nselector:\nsecret:\nname: pokedex-credentials # Source Kubernetes secret to be pushed\ndata:\n- match:\nsecretKey: best-pokemon # Source Kubernetes secret key to be pushed\nremoteRef:\nremoteKey: my-first-parameter # Remote reference (where the secret is going to be pushed)\n</code></pre>"},{"location":"api/secretstore/","title":"SecretStore","text":"<p>The <code>SecretStore</code> is namespaced and specifies how to access the external API. The SecretStore maps to exactly one instance of an external API.</p> <p>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.</p>"},{"location":"api/secretstore/#example","title":"Example","text":"<p>For a full list of supported fields see spec or dig into our guides.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: example\nnamespace: 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\ncontroller: 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, IBM\nretrySettings:\nmaxRetries: 5\nretryInterval: \"10s\"\n\n# provider field contains the configuration to access the provider\n# which contains the secret exactly one provider must be configured.\nprovider:\n\n# (1): AWS Secrets Manager\n# aws configures this store to sync secrets using AWS Secret Manager provider\naws:\nservice: SecretsManager\n# Role is a Role ARN which the SecretManager provider will assume\nrole: iam-role\n# AWS Region to be used for the provider\nregion: 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\nauth:\nsecretRef:\naccessKeyIDSecretRef:\nname: awssm-secret\nkey: access-key\nsecretAccessKeySecretRef:\nname: awssm-secret\nkey: secret-access-key\n\nvault:\nserver: \"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\npath: \"secret\"\n# Version is the Vault KV secret engine version.\n# This can be either \"v1\" or \"v2\", defaults to \"v2\"\nversion: \"v2\"\n# vault enterprise namespace: https://www.vaultproject.io/docs/enterprise/namespaces\nnamespace: \"a-team\"\n# base64 encoded string of certificate\ncaBundle: \"...\"\n# Instead of caBundle you can also specify a caProvider\n# this will retrieve the cert from a Secret or ConfigMap\ncaProvider:\n# Can be Secret or ConfigMap\ntype: \"Secret\"\nname: \"my-cert-secret\"\nkey: \"cert-key\"\n\nauth:\n# static token: https://www.vaultproject.io/docs/auth/token\ntokenSecretRef:\nname: \"my-secret\"\nkey: \"vault-token\"\n\n# AppRole auth: https://www.vaultproject.io/docs/auth/approle\nappRole:\npath: \"approle\"\nroleId: \"db02de05-fa39-4855-059b-67221c5c2f63\"\nsecretRef:\nname: \"my-secret\"\nkey: \"vault-token\"\n\n# Kubernetes auth: https://www.vaultproject.io/docs/auth/kubernetes\nkubernetes:\nmountPath: \"kubernetes\"\nrole: \"demo\"\n# Optional service account reference\nserviceAccountRef:\nname: \"my-sa\"\n# Optional secret field containing a Kubernetes ServiceAccount JWT\n# used for authenticating with Vault\nsecretRef:\nname: \"my-secret\"\nkey: \"vault\"\n\n# (2): GCP Secret Manager\ngcpsm:\n# Auth defines the information necessary to authenticate against GCP by getting\n# the credentials from an already created Kubernetes Secret.\nauth:\nsecretRef:\nsecretAccessKeySecretRef:\nname: gcpsm-secret\nkey: secret-access-credentials\nprojectID: myproject\n# (TODO): add more provider examples here\n\nstatus:\n# Standard condition schema\nconditions:\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\nstatus: \"False\"\nreason: \"ConfigError\"\nmessage: \"SecretStore validation failed\"\nlastTransitionTime: \"2019-08-12T12:33:02Z\"\n</code></pre>"},{"location":"api/spec/","title":"API specification","text":"<p>Packages:</p> <ul> <li> external-secrets.io/v1beta1 </li> </ul>"},{"location":"api/spec/#external-secrets.io/v1beta1","title":"external-secrets.io/v1beta1","text":"<p> <p>Package v1beta1 contains resources for external-secrets</p> </p> <p>Resource Types:</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.AWSAuth","title":"AWSAuth","text":"<p> (Appears on: AWSProvider) </p> <p> <p>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.</p> </p> Field Description <code>secretRef</code> AWSAuthSecretRef (Optional) <code>jwt</code> AWSJWTAuth (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.AWSAuthSecretRef","title":"AWSAuthSecretRef","text":"<p> (Appears on: AWSAuth) </p> <p> <p>AWSAuthSecretRef holds secret references for AWS credentials both AccessKeyID and SecretAccessKey must be defined in order to properly authenticate.</p> </p> Field Description <code>accessKeyIDSecretRef</code> External Secrets meta/v1.SecretKeySelector <p>The AccessKeyID is used for authentication</p> <code>secretAccessKeySecretRef</code> External Secrets meta/v1.SecretKeySelector <p>The SecretAccessKey is used for authentication</p> <code>sessionTokenSecretRef</code> External Secrets meta/v1.SecretKeySelector <p>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</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.AWSJWTAuth","title":"AWSJWTAuth","text":"<p> (Appears on: AWSAuth) </p> <p> <p>Authenticate against AWS using service account tokens.</p> </p> Field Description <code>serviceAccountRef</code> External Secrets meta/v1.ServiceAccountSelector"},{"location":"api/spec/#external-secrets.io/v1beta1.AWSProvider","title":"AWSProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>AWSProvider configures a store to sync secrets with AWS.</p> </p> Field Description <code>service</code> AWSServiceType <p>Service defines which service should be used to fetch the secrets</p> <code>auth</code> AWSAuth (Optional) <p>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</p> <code>role</code> string (Optional) <p>Role is a Role ARN which the SecretManager provider will assume</p> <code>region</code> string <p>AWS Region to be used for the provider</p> <code>additionalRoles</code> []string (Optional) <p>AdditionalRoles is a chained list of Role ARNs which the SecretManager provider will sequentially assume before assuming Role</p> <code>externalID</code> string <p>AWS External ID set on assumed IAM roles</p> <code>sessionTags</code> []*github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1.Tag (Optional) <p>AWS STS assume role session tags</p> <code>transitiveTagKeys</code> []*string (Optional) <p>AWS STS assume role transitive session tags. Required when multiple rules are used with SecretStore</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.AWSServiceType","title":"AWSServiceType (<code>string</code> alias)","text":"<p> (Appears on: AWSProvider) </p> <p> <p>AWSServiceType is a enum that defines the service/API that is used to fetch the secrets.</p> </p> Value Description <p>\"ParameterStore\"</p> <p>AWSServiceParameterStore is the AWS SystemsManager ParameterStore. see: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html</p> <p>\"SecretsManager\"</p> <p>AWSServiceSecretsManager is the AWS SecretsManager. see: https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.AkeylessAuth","title":"AkeylessAuth","text":"<p> (Appears on: AkeylessProvider) </p> <p> </p> Field Description <code>secretRef</code> AkeylessAuthSecretRef (Optional) <p>Reference to a Secret that contains the details to authenticate with Akeyless.</p> <code>kubernetesAuth</code> AkeylessKubernetesAuth (Optional) <p>Kubernetes authenticates with Akeyless by passing the ServiceAccount token stored in the named Secret resource.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.AkeylessAuthSecretRef","title":"AkeylessAuthSecretRef","text":"<p> (Appears on: AkeylessAuth) </p> <p> <p>AkeylessAuthSecretRef AKEYLESS_ACCESS_TYPE_PARAM: AZURE_OBJ_ID OR GCP_AUDIENCE OR ACCESS_KEY OR KUB_CONFIG_NAME.</p> </p> Field Description <code>accessID</code> External Secrets meta/v1.SecretKeySelector <p>The SecretAccessID is used for authentication</p> <code>accessType</code> External Secrets meta/v1.SecretKeySelector <code>accessTypeParam</code> External Secrets meta/v1.SecretKeySelector"},{"location":"api/spec/#external-secrets.io/v1beta1.AkeylessKubernetesAuth","title":"AkeylessKubernetesAuth","text":"<p> (Appears on: AkeylessAuth) </p> <p> <p>Authenticate with Kubernetes ServiceAccount token stored.</p> </p> Field Description <code>accessID</code> string <p>the Akeyless Kubernetes auth-method access-id</p> <code>k8sConfName</code> string <p>Kubernetes-auth configuration name in Akeyless-Gateway</p> <code>serviceAccountRef</code> External Secrets meta/v1.ServiceAccountSelector (Optional) <p>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.</p> <code>secretRef</code> External Secrets meta/v1.SecretKeySelector (Optional) <p>Optional secret field containing a Kubernetes ServiceAccount JWT used for authenticating with Akeyless. If a name is specified without a key, <code>token</code> is the default. If one is not specified, the one bound to the controller will be used.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.AkeylessProvider","title":"AkeylessProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>AkeylessProvider Configures an store to sync secrets using Akeyless KV.</p> </p> Field Description <code>akeylessGWApiURL</code> string <p>Akeyless GW API Url from which the secrets to be fetched from.</p> <code>authSecretRef</code> AkeylessAuth <p>Auth configures how the operator authenticates with Akeyless.</p> <code>caBundle</code> []byte (Optional) <p>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.</p> <code>caProvider</code> CAProvider (Optional) <p>The provider for the CA bundle to use to validate Akeyless Gateway certificate.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.AlibabaAuth","title":"AlibabaAuth","text":"<p> (Appears on: AlibabaProvider) </p> <p> <p>AlibabaAuth contains a secretRef for credentials.</p> </p> Field Description <code>secretRef</code> AlibabaAuthSecretRef (Optional) <code>rrsa</code> AlibabaRRSAAuth (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.AlibabaAuthSecretRef","title":"AlibabaAuthSecretRef","text":"<p> (Appears on: AlibabaAuth) </p> <p> <p>AlibabaAuthSecretRef holds secret references for Alibaba credentials.</p> </p> Field Description <code>accessKeyIDSecretRef</code> External Secrets meta/v1.SecretKeySelector <p>The AccessKeyID is used for authentication</p> <code>accessKeySecretSecretRef</code> External Secrets meta/v1.SecretKeySelector <p>The AccessKeySecret is used for authentication</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.AlibabaProvider","title":"AlibabaProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>AlibabaProvider configures a store to sync secrets using the Alibaba Secret Manager provider.</p> </p> Field Description <code>auth</code> AlibabaAuth <code>regionID</code> string <p>Alibaba Region to be used for the provider</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.AlibabaRRSAAuth","title":"AlibabaRRSAAuth","text":"<p> (Appears on: AlibabaAuth) </p> <p> <p>Authenticate against Alibaba using RRSA.</p> </p> Field Description <code>oidcProviderArn</code> string <code>oidcTokenFilePath</code> string <code>roleArn</code> string <code>sessionName</code> string"},{"location":"api/spec/#external-secrets.io/v1beta1.AzureAuthType","title":"AzureAuthType (<code>string</code> alias)","text":"<p> (Appears on: AzureKVProvider) </p> <p> <p>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.</p> </p> Value Description <p>\"ManagedIdentity\"</p> <p>Using Managed Identity to authenticate. Used with aad-pod-identity installed in the cluster.</p> <p>\"ServicePrincipal\"</p> <p>Using service principal to authenticate, which needs a tenantId, a clientId and a clientSecret.</p> <p>\"WorkloadIdentity\"</p> <p>Using Workload Identity service accounts to authenticate.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.AzureEnvironmentType","title":"AzureEnvironmentType (<code>string</code> alias)","text":"<p> (Appears on: AzureKVProvider) </p> <p> <p>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</p> </p> Value Description <p>\"ChinaCloud\"</p> <p>\"GermanCloud\"</p> <p>\"PublicCloud\"</p> <p>\"USGovernmentCloud\"</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.AzureKVAuth","title":"AzureKVAuth","text":"<p> (Appears on: AzureKVProvider) </p> <p> <p>Configuration used to authenticate with Azure.</p> </p> Field Description <code>clientId</code> External Secrets meta/v1.SecretKeySelector (Optional) <p>The Azure clientId of the service principle used for authentication.</p> <code>clientSecret</code> External Secrets meta/v1.SecretKeySelector (Optional) <p>The Azure ClientSecret of the service principle used for authentication.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.AzureKVProvider","title":"AzureKVProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>Configures an store to sync secrets using Azure KV.</p> </p> Field Description <code>authType</code> AzureAuthType (Optional) <p>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)</p> <code>vaultUrl</code> string <p>Vault Url from which the secrets to be fetched from.</p> <code>tenantId</code> string (Optional) <p>TenantID configures the Azure Tenant to send requests to. Required for ServicePrincipal auth type.</p> <code>environmentType</code> AzureEnvironmentType <p>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</p> <code>authSecretRef</code> AzureKVAuth (Optional) <p>Auth configures how the operator authenticates with Azure. Required for ServicePrincipal auth type.</p> <code>serviceAccountRef</code> External Secrets meta/v1.ServiceAccountSelector (Optional) <p>ServiceAccountRef specified the service account that should be used when authenticating with WorkloadIdentity.</p> <code>identityId</code> string (Optional) <p>If multiple Managed Identity is assigned to the pod, you can select the one to be used</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.CAProvider","title":"CAProvider","text":"<p> (Appears on: AkeylessProvider, KubernetesServer, VaultProvider) </p> <p> <p>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.</p> </p> Field Description <code>type</code> CAProviderType <p>The type of provider to use such as \u201cSecret\u201d, or \u201cConfigMap\u201d.</p> <code>name</code> string <p>The name of the object located at the provider type.</p> <code>key</code> string <p>The key where the CA certificate can be found in the Secret or ConfigMap.</p> <code>namespace</code> string (Optional) <p>The namespace the Provider type is in. Can only be defined when used in a ClusterSecretStore.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.CAProviderType","title":"CAProviderType (<code>string</code> alias)","text":"<p> (Appears on: CAProvider) </p> <p> </p> Value Description <p>\"ConfigMap\"</p> <p>\"Secret\"</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.CertAuth","title":"CertAuth","text":"<p> (Appears on: KubernetesAuth) </p> <p> </p> Field Description <code>clientCert</code> External Secrets meta/v1.SecretKeySelector <code>clientKey</code> External Secrets meta/v1.SecretKeySelector"},{"location":"api/spec/#external-secrets.io/v1beta1.ClusterExternalSecret","title":"ClusterExternalSecret","text":"<p> <p>ClusterExternalSecret is the Schema for the clusterexternalsecrets API.</p> </p> Field Description <code>metadata</code> Kubernetes meta/v1.ObjectMeta Refer to the Kubernetes API documentation for the fields of the <code>metadata</code> field. <code>spec</code> ClusterExternalSecretSpec <code>externalSecretSpec</code> ExternalSecretSpec <p>The spec for the ExternalSecrets to be created</p> <code>externalSecretName</code> string (Optional) <p>The name of the external secrets to be created defaults to the name of the ClusterExternalSecret</p> <code>externalSecretMetadata</code> ExternalSecretMetadata (Optional) <p>The metadata of the external secrets to be created</p> <code>namespaceSelector</code> Kubernetes meta/v1.LabelSelector <p>The labels to select by to find the Namespaces to create the ExternalSecrets in.</p> <code>refreshTime</code> Kubernetes meta/v1.Duration <p>The time in which the controller should reconcile it\u2019s objects and recheck namespaces for labels.</p> <code>status</code> ClusterExternalSecretStatus"},{"location":"api/spec/#external-secrets.io/v1beta1.ClusterExternalSecretConditionType","title":"ClusterExternalSecretConditionType (<code>string</code> alias)","text":"<p> (Appears on: ClusterExternalSecretStatusCondition) </p> <p> </p> Value Description <p>\"NotReady\"</p> <p>\"PartiallyReady\"</p> <p>\"Ready\"</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.ClusterExternalSecretNamespaceFailure","title":"ClusterExternalSecretNamespaceFailure","text":"<p> (Appears on: ClusterExternalSecretStatus) </p> <p> <p>ClusterExternalSecretNamespaceFailure represents a failed namespace deployment and it\u2019s reason.</p> </p> Field Description <code>namespace</code> string <p>Namespace is the namespace that failed when trying to apply an ExternalSecret</p> <code>reason</code> string (Optional) <p>Reason is why the ExternalSecret failed to apply to the namespace</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.ClusterExternalSecretSpec","title":"ClusterExternalSecretSpec","text":"<p> (Appears on: ClusterExternalSecret) </p> <p> <p>ClusterExternalSecretSpec defines the desired state of ClusterExternalSecret.</p> </p> Field Description <code>externalSecretSpec</code> ExternalSecretSpec <p>The spec for the ExternalSecrets to be created</p> <code>externalSecretName</code> string (Optional) <p>The name of the external secrets to be created defaults to the name of the ClusterExternalSecret</p> <code>externalSecretMetadata</code> ExternalSecretMetadata (Optional) <p>The metadata of the external secrets to be created</p> <code>namespaceSelector</code> Kubernetes meta/v1.LabelSelector <p>The labels to select by to find the Namespaces to create the ExternalSecrets in.</p> <code>refreshTime</code> Kubernetes meta/v1.Duration <p>The time in which the controller should reconcile it\u2019s objects and recheck namespaces for labels.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.ClusterExternalSecretStatus","title":"ClusterExternalSecretStatus","text":"<p> (Appears on: ClusterExternalSecret) </p> <p> <p>ClusterExternalSecretStatus defines the observed state of ClusterExternalSecret.</p> </p> Field Description <code>failedNamespaces</code> []ClusterExternalSecretNamespaceFailure (Optional) <p>Failed namespaces are the namespaces that failed to apply an ExternalSecret</p> <code>provisionedNamespaces</code> []string (Optional) <p>ProvisionedNamespaces are the namespaces where the ClusterExternalSecret has secrets</p> <code>conditions</code> []ClusterExternalSecretStatusCondition (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.ClusterExternalSecretStatusCondition","title":"ClusterExternalSecretStatusCondition","text":"<p> (Appears on: ClusterExternalSecretStatus) </p> <p> </p> Field Description <code>type</code> ClusterExternalSecretConditionType <code>status</code> Kubernetes core/v1.ConditionStatus <code>message</code> string (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.ClusterSecretStore","title":"ClusterSecretStore","text":"<p> <p>ClusterSecretStore represents a secure external location for storing secrets, which can be referenced as part of <code>storeRef</code> fields.</p> </p> Field Description <code>metadata</code> Kubernetes meta/v1.ObjectMeta Refer to the Kubernetes API documentation for the fields of the <code>metadata</code> field. <code>spec</code> SecretStoreSpec <code>controller</code> string (Optional) <p>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</p> <code>provider</code> SecretStoreProvider <p>Used to configure the provider. Only one provider may be set</p> <code>retrySettings</code> SecretStoreRetrySettings (Optional) <p>Used to configure http retries if failed</p> <code>refreshInterval</code> int (Optional) <p>Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.</p> <code>conditions</code> []ClusterSecretStoreCondition (Optional) <p>Used to constraint a ClusterSecretStore to specific namespaces. Relevant only to ClusterSecretStore</p> <code>status</code> SecretStoreStatus"},{"location":"api/spec/#external-secrets.io/v1beta1.ClusterSecretStoreCondition","title":"ClusterSecretStoreCondition","text":"<p> (Appears on: SecretStoreSpec) </p> <p> <p>ClusterSecretStoreCondition describes a condition by which to choose namespaces to process ExternalSecrets in for a ClusterSecretStore instance.</p> </p> Field Description <code>namespaceSelector</code> Kubernetes meta/v1.LabelSelector (Optional) <p>Choose namespace using a labelSelector</p> <code>namespaces</code> []string <p>Choose namespaces by name</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.ConjurApikey","title":"ConjurApikey","text":"<p> (Appears on: ConjurAuth) </p> <p> </p> Field Description <code>account</code> string <code>userRef</code> External Secrets meta/v1.SecretKeySelector <code>apiKeyRef</code> External Secrets meta/v1.SecretKeySelector"},{"location":"api/spec/#external-secrets.io/v1beta1.ConjurAuth","title":"ConjurAuth","text":"<p> (Appears on: ConjurProvider) </p> <p> </p> Field Description <code>apikey</code> ConjurApikey"},{"location":"api/spec/#external-secrets.io/v1beta1.ConjurProvider","title":"ConjurProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> </p> Field Description <code>url</code> string <code>caBundle</code> string <code>auth</code> ConjurAuth"},{"location":"api/spec/#external-secrets.io/v1beta1.DelineaProvider","title":"DelineaProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>See https://github.com/DelineaXPM/dsv-sdk-go/blob/main/vault/vault.go.</p> </p> Field Description <code>clientId</code> DelineaProviderSecretRef <p>ClientID is the non-secret part of the credential.</p> <code>clientSecret</code> DelineaProviderSecretRef <p>ClientSecret is the secret part of the credential.</p> <code>tenant</code> string <p>Tenant is the chosen hostname / site name.</p> <code>urlTemplate</code> string (Optional) <p>URLTemplate If unset, defaults to \u201chttps://%s.secretsvaultcloud.%s/v1/%s%s\u201d.</p> <code>tld</code> string (Optional) <p>TLD is based on the server location that was chosen during provisioning. If unset, defaults to \u201ccom\u201d.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.DelineaProviderSecretRef","title":"DelineaProviderSecretRef","text":"<p> (Appears on: DelineaProvider) </p> <p> </p> Field Description <code>value</code> string (Optional) <p>Value can be specified directly to set a value without using a secret.</p> <code>secretRef</code> External Secrets meta/v1.SecretKeySelector (Optional) <p>SecretRef references a key in a secret that will be used as value.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.DopplerAuth","title":"DopplerAuth","text":"<p> (Appears on: DopplerProvider) </p> <p> </p> Field Description <code>secretRef</code> DopplerAuthSecretRef"},{"location":"api/spec/#external-secrets.io/v1beta1.DopplerAuthSecretRef","title":"DopplerAuthSecretRef","text":"<p> (Appears on: DopplerAuth) </p> <p> </p> Field Description <code>dopplerToken</code> External Secrets meta/v1.SecretKeySelector <p>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.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.DopplerProvider","title":"DopplerProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>DopplerProvider configures a store to sync secrets using the Doppler provider. Project and Config are required if not using a Service Token.</p> </p> Field Description <code>auth</code> DopplerAuth <p>Auth configures how the Operator authenticates with the Doppler API</p> <code>project</code> string (Optional) <p>Doppler project (required if not using a Service Token)</p> <code>config</code> string (Optional) <p>Doppler config (required if not using a Service Token)</p> <code>nameTransformer</code> string (Optional) <p>Environment variable compatible name transforms that change secret names to a different format</p> <code>format</code> string (Optional) <p>Format enables the downloading of secrets as a file (string)</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecret","title":"ExternalSecret","text":"<p> <p>ExternalSecret is the Schema for the external-secrets API.</p> </p> Field Description <code>metadata</code> Kubernetes meta/v1.ObjectMeta Refer to the Kubernetes API documentation for the fields of the <code>metadata</code> field. <code>spec</code> ExternalSecretSpec <code>secretStoreRef</code> SecretStoreRef (Optional) <code>target</code> ExternalSecretTarget (Optional) <code>refreshInterval</code> Kubernetes meta/v1.Duration <p>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.</p> <code>data</code> []ExternalSecretData (Optional) <p>Data defines the connection between the Kubernetes Secret keys and the Provider data</p> <code>dataFrom</code> []ExternalSecretDataFromRemoteRef (Optional) <p>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</p> <code>status</code> ExternalSecretStatus"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretConditionType","title":"ExternalSecretConditionType (<code>string</code> alias)","text":"<p> (Appears on: ExternalSecretStatusCondition) </p> <p> </p> Value Description <p>\"Deleted\"</p> <p>\"Ready\"</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretConversionStrategy","title":"ExternalSecretConversionStrategy (<code>string</code> alias)","text":"<p> (Appears on: ExternalSecretDataRemoteRef, ExternalSecretFind) </p> <p> </p> Value Description <p>\"Default\"</p> <p>\"Unicode\"</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretCreationPolicy","title":"ExternalSecretCreationPolicy (<code>string</code> alias)","text":"<p> (Appears on: ExternalSecretTarget) </p> <p> <p>ExternalSecretCreationPolicy defines rules on how to create the resulting Secret.</p> </p> Value Description <p>\"Merge\"</p> <p>Merge does not create the Secret, but merges the data fields to the Secret.</p> <p>\"None\"</p> <p>None does not create a Secret (future use with injector).</p> <p>\"Orphan\"</p> <p>Orphan creates the Secret and does not set the ownerReference. I.e. it will be orphaned after the deletion of the ExternalSecret.</p> <p>\"Owner\"</p> <p>Owner creates the Secret and sets .metadata.ownerReferences to the ExternalSecret resource.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretData","title":"ExternalSecretData","text":"<p> (Appears on: ExternalSecretSpec) </p> <p> <p>ExternalSecretData defines the connection between the Kubernetes Secret key (spec.data.) and the Provider data. Field Description <code>secretKey</code> string <p>SecretKey defines the key in which the controller stores the value. This is the key in the Kind=Secret</p> <code>remoteRef</code> ExternalSecretDataRemoteRef <p>RemoteRef points to the remote secret and defines which secret (version/property/..) to fetch.</p> <code>sourceRef</code> SourceRef <p>SourceRef allows you to override the source from which the value will pulled from.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretDataFromRemoteRef","title":"ExternalSecretDataFromRemoteRef","text":"<p> (Appears on: ExternalSecretSpec) </p> <p> </p> Field Description <code>extract</code> ExternalSecretDataRemoteRef (Optional) <p>Used to extract multiple key/value pairs from one secret Note: Extract does not support sourceRef.Generator or sourceRef.GeneratorRef.</p> <code>find</code> ExternalSecretFind (Optional) <p>Used to find secrets based on tags or regular expressions Note: Find does not support sourceRef.Generator or sourceRef.GeneratorRef.</p> <code>rewrite</code> []ExternalSecretRewrite (Optional) <p>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)</p> <code>sourceRef</code> SourceRef <p>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</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretDataRemoteRef","title":"ExternalSecretDataRemoteRef","text":"<p> (Appears on: ExternalSecretData, ExternalSecretDataFromRemoteRef) </p> <p> <p>ExternalSecretDataRemoteRef defines Provider data location.</p> </p> Field Description <code>key</code> string <p>Key is the key used in the Provider, mandatory</p> <code>metadataPolicy</code> ExternalSecretMetadataPolicy (Optional) <p>Policy for fetching tags/labels from provider secrets, possible options are Fetch, None. Defaults to None</p> <code>property</code> string (Optional) <p>Used to select a specific property of the Provider value (if a map), if supported</p> <code>version</code> string (Optional) <p>Used to select a specific version of the Provider value, if supported</p> <code>conversionStrategy</code> ExternalSecretConversionStrategy (Optional) <p>Used to define a conversion Strategy</p> <code>decodingStrategy</code> ExternalSecretDecodingStrategy (Optional) <p>Used to define a decoding Strategy</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretDecodingStrategy","title":"ExternalSecretDecodingStrategy (<code>string</code> alias)","text":"<p> (Appears on: ExternalSecretDataRemoteRef, ExternalSecretFind) </p> <p> </p> Value Description <p>\"Auto\"</p> <p>\"Base64\"</p> <p>\"Base64URL\"</p> <p>\"None\"</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretDeletionPolicy","title":"ExternalSecretDeletionPolicy (<code>string</code> alias)","text":"<p> (Appears on: ExternalSecretTarget) </p> <p> <p>ExternalSecretDeletionPolicy defines rules on how to delete the resulting Secret.</p> </p> Value Description <p>\"Delete\"</p> <p>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.</p> <p>\"Merge\"</p> <p>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.</p> <p>\"Retain\"</p> <p>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.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretFind","title":"ExternalSecretFind","text":"<p> (Appears on: ExternalSecretDataFromRemoteRef) </p> <p> </p> Field Description <code>path</code> string (Optional) <p>A root path to start the find operations.</p> <code>name</code> FindName (Optional) <p>Finds secrets based on the name.</p> <code>tags</code> map[string]string (Optional) <p>Find secrets based on tags.</p> <code>conversionStrategy</code> ExternalSecretConversionStrategy (Optional) <p>Used to define a conversion Strategy</p> <code>decodingStrategy</code> ExternalSecretDecodingStrategy (Optional) <p>Used to define a decoding Strategy</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretMetadata","title":"ExternalSecretMetadata","text":"<p> (Appears on: ClusterExternalSecretSpec) </p> <p> <p>ExternalSecretMetadata defines metadata fields for the ExternalSecret generated by the ClusterExternalSecret.</p> </p> Field Description <code>annotations</code> map[string]string (Optional) <code>labels</code> map[string]string (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretMetadataPolicy","title":"ExternalSecretMetadataPolicy (<code>string</code> alias)","text":"<p> (Appears on: ExternalSecretDataRemoteRef) </p> <p> </p> Value Description <p>\"Fetch\"</p> <p>\"None\"</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretRewrite","title":"ExternalSecretRewrite","text":"<p> (Appears on: ExternalSecretDataFromRemoteRef) </p> <p> </p> Field Description <code>regexp</code> ExternalSecretRewriteRegexp (Optional) <p>Used to rewrite with regular expressions. The resulting key will be the output of a regexp.ReplaceAll operation.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretRewriteRegexp","title":"ExternalSecretRewriteRegexp","text":"<p> (Appears on: ExternalSecretRewrite) </p> <p> </p> Field Description <code>source</code> string <p>Used to define the regular expression of a re.Compiler.</p> <code>target</code> string <p>Used to define the target pattern of a ReplaceAll operation.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretSpec","title":"ExternalSecretSpec","text":"<p> (Appears on: ClusterExternalSecretSpec, ExternalSecret) </p> <p> <p>ExternalSecretSpec defines the desired state of ExternalSecret.</p> </p> Field Description <code>secretStoreRef</code> SecretStoreRef (Optional) <code>target</code> ExternalSecretTarget (Optional) <code>refreshInterval</code> Kubernetes meta/v1.Duration <p>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.</p> <code>data</code> []ExternalSecretData (Optional) <p>Data defines the connection between the Kubernetes Secret keys and the Provider data</p> <code>dataFrom</code> []ExternalSecretDataFromRemoteRef (Optional) <p>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</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretStatus","title":"ExternalSecretStatus","text":"<p> (Appears on: ExternalSecret) </p> <p> </p> Field Description <code>refreshTime</code> Kubernetes meta/v1.Time <p>refreshTime is the time and date the external secret was fetched and the target secret updated</p> <code>syncedResourceVersion</code> string <p>SyncedResourceVersion keeps track of the last synced version</p> <code>conditions</code> []ExternalSecretStatusCondition (Optional) <code>binding</code> Kubernetes core/v1.LocalObjectReference <p>Binding represents a servicebinding.io Provisioned Service reference to the secret</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretStatusCondition","title":"ExternalSecretStatusCondition","text":"<p> (Appears on: ExternalSecretStatus) </p> <p> </p> Field Description <code>type</code> ExternalSecretConditionType <code>status</code> Kubernetes core/v1.ConditionStatus <code>reason</code> string (Optional) <code>message</code> string (Optional) <code>lastTransitionTime</code> Kubernetes meta/v1.Time (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretTarget","title":"ExternalSecretTarget","text":"<p> (Appears on: ExternalSecretSpec) </p> <p> <p>ExternalSecretTarget defines the Kubernetes Secret to be created There can be only one target per ExternalSecret.</p> </p> Field Description <code>name</code> string (Optional) <p>Name defines the name of the Secret resource to be managed This field is immutable Defaults to the .metadata.name of the ExternalSecret resource</p> <code>creationPolicy</code> ExternalSecretCreationPolicy (Optional) <p>CreationPolicy defines rules on how to create the resulting Secret Defaults to \u2018Owner\u2019</p> <code>deletionPolicy</code> ExternalSecretDeletionPolicy (Optional) <p>DeletionPolicy defines rules on how to delete the resulting Secret Defaults to \u2018Retain\u2019</p> <code>template</code> ExternalSecretTemplate (Optional) <p>Template defines a blueprint for the created Secret resource.</p> <code>immutable</code> bool (Optional) <p>Immutable defines if the final secret will be immutable</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretTemplate","title":"ExternalSecretTemplate","text":"<p> (Appears on: ExternalSecretTarget) </p> <p> <p>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</p> </p> Field Description <code>type</code> Kubernetes core/v1.SecretType (Optional) <code>engineVersion</code> TemplateEngineVersion <code>metadata</code> ExternalSecretTemplateMetadata (Optional) <code>mergePolicy</code> TemplateMergePolicy <code>data</code> map[string]string (Optional) <code>templateFrom</code> []TemplateFrom (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.ExternalSecretTemplateMetadata","title":"ExternalSecretTemplateMetadata","text":"<p> (Appears on: ExternalSecretTemplate) </p> <p> <p>ExternalSecretTemplateMetadata defines metadata fields for the Secret blueprint.</p> </p> Field Description <code>annotations</code> map[string]string (Optional) <code>labels</code> 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":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>FakeProvider configures a fake provider that returns static values.</p> </p> Field Description <code>data</code> []FakeProviderData"},{"location":"api/spec/#external-secrets.io/v1beta1.FakeProviderData","title":"FakeProviderData","text":"<p> (Appears on: FakeProvider) </p> <p> </p> Field Description <code>key</code> string <code>value</code> string <code>valueMap</code> map[string]string <code>version</code> string"},{"location":"api/spec/#external-secrets.io/v1beta1.FindName","title":"FindName","text":"<p> (Appears on: ExternalSecretFind) </p> <p> </p> Field Description <code>regexp</code> string (Optional) <p>Finds secrets base</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.GCPSMAuth","title":"GCPSMAuth","text":"<p> (Appears on: GCPSMProvider) </p> <p> </p> Field Description <code>secretRef</code> GCPSMAuthSecretRef (Optional) <code>workloadIdentity</code> GCPWorkloadIdentity (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.GCPSMAuthSecretRef","title":"GCPSMAuthSecretRef","text":"<p> (Appears on: GCPSMAuth) </p> <p> </p> Field Description <code>secretAccessKeySecretRef</code> External Secrets meta/v1.SecretKeySelector (Optional) <p>The SecretAccessKey is used for authentication</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.GCPSMProvider","title":"GCPSMProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>GCPSMProvider Configures a store to sync secrets using the GCP Secret Manager provider.</p> </p> Field Description <code>auth</code> GCPSMAuth (Optional) <p>Auth defines the information necessary to authenticate against GCP</p> <code>projectID</code> string <p>ProjectID project where secret is located</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.GCPWorkloadIdentity","title":"GCPWorkloadIdentity","text":"<p> (Appears on: GCPSMAuth) </p> <p> </p> Field Description <code>serviceAccountRef</code> External Secrets meta/v1.ServiceAccountSelector <code>clusterLocation</code> string <code>clusterName</code> string <code>clusterProjectID</code> string"},{"location":"api/spec/#external-secrets.io/v1beta1.GeneratorRef","title":"GeneratorRef","text":"<p> (Appears on: SourceRef) </p> <p> <p>GeneratorRef points to a generator custom resource.</p> </p> Field Description <code>apiVersion</code> string <p>Specify the apiVersion of the generator resource</p> <code>kind</code> string <p>Specify the Kind of the resource, e.g. Password, ACRAccessToken etc.</p> <code>name</code> string <p>Specify the name of the generator resource</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.GenericStore","title":"GenericStore","text":"<p> <p>GenericStore is a common interface for interacting with ClusterSecretStore or a namespaced SecretStore.</p> </p>"},{"location":"api/spec/#external-secrets.io/v1beta1.GenericStoreValidator","title":"GenericStoreValidator","text":""},{"location":"api/spec/#external-secrets.io/v1beta1.GitlabAuth","title":"GitlabAuth","text":"<p> (Appears on: GitlabProvider) </p> <p> </p> Field Description <code>SecretRef</code> GitlabSecretRef"},{"location":"api/spec/#external-secrets.io/v1beta1.GitlabProvider","title":"GitlabProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>Configures a store to sync secrets with a GitLab instance.</p> </p> Field Description <code>url</code> string <p>URL configures the GitLab instance URL. Defaults to https://gitlab.com/.</p> <code>auth</code> GitlabAuth <p>Auth configures how secret-manager authenticates with a GitLab instance.</p> <code>projectID</code> string <p>ProjectID specifies a project where secrets are located.</p> <code>inheritFromGroups</code> bool <p>InheritFromGroups specifies whether parent groups should be discovered and checked for secrets.</p> <code>groupIDs</code> []string <p>GroupIDs specify, which gitlab groups to pull secrets from. Group secrets are read from left to right followed by the project variables.</p> <code>environment</code> string <p>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)</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.GitlabSecretRef","title":"GitlabSecretRef","text":"<p> (Appears on: GitlabAuth) </p> <p> </p> Field Description <code>accessToken</code> External Secrets meta/v1.SecretKeySelector <p>AccessToken is used for authentication.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.IBMAuth","title":"IBMAuth","text":"<p> (Appears on: IBMProvider) </p> <p> </p> Field Description <code>secretRef</code> IBMAuthSecretRef <code>containerAuth</code> IBMAuthContainerAuth"},{"location":"api/spec/#external-secrets.io/v1beta1.IBMAuthContainerAuth","title":"IBMAuthContainerAuth","text":"<p> (Appears on: IBMAuth) </p> <p> <p>IBM Container-based auth with IAM Trusted Profile.</p> </p> Field Description <code>profile</code> string <p>the IBM Trusted Profile</p> <code>tokenLocation</code> string <p>Location the token is mounted on the pod</p> <code>iamEndpoint</code> string"},{"location":"api/spec/#external-secrets.io/v1beta1.IBMAuthSecretRef","title":"IBMAuthSecretRef","text":"<p> (Appears on: IBMAuth) </p> <p> </p> Field Description <code>secretApiKeySecretRef</code> External Secrets meta/v1.SecretKeySelector <p>The SecretAccessKey is used for authentication</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.IBMProvider","title":"IBMProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>Configures an store to sync secrets using a IBM Cloud Secrets Manager backend.</p> </p> Field Description <code>auth</code> IBMAuth <p>Auth configures how secret-manager authenticates with the IBM secrets manager.</p> <code>serviceUrl</code> string <p>ServiceURL is the Endpoint URL that is specific to the Secrets Manager service instance</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.KeeperSecurityProvider","title":"KeeperSecurityProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>KeeperSecurityProvider Configures a store to sync secrets using Keeper Security.</p> </p> Field Description <code>authRef</code> External Secrets meta/v1.SecretKeySelector <code>folderID</code> string"},{"location":"api/spec/#external-secrets.io/v1beta1.KubernetesAuth","title":"KubernetesAuth","text":"<p> (Appears on: KubernetesProvider) </p> <p> </p> Field Description <code>cert</code> CertAuth (Optional) <p>has both clientCert and clientKey as secretKeySelector</p> <code>token</code> TokenAuth (Optional) <p>use static token to authenticate with</p> <code>serviceAccount</code> External Secrets meta/v1.ServiceAccountSelector (Optional) <p>points to a service account that should be used for authentication</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.KubernetesProvider","title":"KubernetesProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>Configures a store to sync secrets with a Kubernetes instance.</p> </p> Field Description <code>server</code> KubernetesServer <p>configures the Kubernetes server Address.</p> <code>auth</code> KubernetesAuth <p>Auth configures how secret-manager authenticates with a Kubernetes instance.</p> <code>remoteNamespace</code> string (Optional) <p>Remote namespace to fetch the secrets from</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.KubernetesServer","title":"KubernetesServer","text":"<p> (Appears on: KubernetesProvider) </p> <p> </p> Field Description <code>url</code> string (Optional) <p>configures the Kubernetes server Address.</p> <code>caBundle</code> []byte (Optional) <p>CABundle is a base64-encoded CA certificate</p> <code>caProvider</code> CAProvider (Optional) <p>see: https://external-secrets.io/v0.4.1/spec/#external-secrets.io/v1alpha1.CAProvider</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.NoSecretError","title":"NoSecretError","text":"<p> <p>NoSecretError shall be returned when a GetSecret can not find the desired secret. This is used for deletionPolicy.</p> </p>"},{"location":"api/spec/#external-secrets.io/v1beta1.OnePasswordAuth","title":"OnePasswordAuth","text":"<p> (Appears on: OnePasswordProvider) </p> <p> <p>OnePasswordAuth contains a secretRef for credentials.</p> </p> Field Description <code>secretRef</code> OnePasswordAuthSecretRef"},{"location":"api/spec/#external-secrets.io/v1beta1.OnePasswordAuthSecretRef","title":"OnePasswordAuthSecretRef","text":"<p> (Appears on: OnePasswordAuth) </p> <p> <p>OnePasswordAuthSecretRef holds secret references for 1Password credentials.</p> </p> Field Description <code>connectTokenSecretRef</code> External Secrets meta/v1.SecretKeySelector <p>The ConnectToken is used for authentication to a 1Password Connect Server.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.OnePasswordProvider","title":"OnePasswordProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>OnePasswordProvider configures a store to sync secrets using the 1Password Secret Manager provider.</p> </p> Field Description <code>auth</code> OnePasswordAuth <p>Auth defines the information necessary to authenticate against OnePassword Connect Server</p> <code>connectHost</code> string <p>ConnectHost defines the OnePassword Connect Server to connect to</p> <code>vaults</code> map[string]int <p>Vaults defines which OnePassword vaults to search in which order</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.OracleAuth","title":"OracleAuth","text":"<p> (Appears on: OracleProvider) </p> <p> </p> Field Description <code>tenancy</code> string <p>Tenancy is the tenancy OCID where user is located.</p> <code>user</code> string <p>User is an access OCID specific to the account.</p> <code>secretRef</code> OracleSecretRef <p>SecretRef to pass through sensitive information.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.OracleProvider","title":"OracleProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>Configures an store to sync secrets using a Oracle Vault backend.</p> </p> Field Description <code>region</code> string <p>Region is the region where vault is located.</p> <code>vault</code> string <p>Vault is the vault\u2019s OCID of the specific vault where secret is located.</p> <code>auth</code> OracleAuth (Optional) <p>Auth configures how secret-manager authenticates with the Oracle Vault. If empty, use the instance principal, otherwise the user credentials specified in Auth.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.OracleSecretRef","title":"OracleSecretRef","text":"<p> (Appears on: OracleAuth) </p> <p> </p> Field Description <code>privatekey</code> External Secrets meta/v1.SecretKeySelector <p>PrivateKey is the user\u2019s API Signing Key in PEM format, used for authentication.</p> <code>fingerprint</code> External Secrets meta/v1.SecretKeySelector <p>Fingerprint is the fingerprint of the API private key.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.Provider","title":"Provider","text":"<p> <p>Provider is a common interface for interacting with secret backends.</p> </p>"},{"location":"api/spec/#external-secrets.io/v1beta1.PushRemoteRef","title":"PushRemoteRef","text":"<p> <p>This interface is to allow using v1alpha1 content in Provider registered in v1beta1.</p> </p>"},{"location":"api/spec/#external-secrets.io/v1beta1.ScalewayProvider","title":"ScalewayProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> </p> Field Description <code>apiUrl</code> string (Optional) <p>APIURL is the url of the api to use. Defaults to https://api.scaleway.com</p> <code>region</code> string <p>Region where your secrets are located: https://developers.scaleway.com/en/quickstart/#region-and-zone</p> <code>projectId</code> string <p>ProjectID is the id of your project, which you can find in the console: https://console.scaleway.com/project/settings</p> <code>accessKey</code> ScalewayProviderSecretRef <p>AccessKey is the non-secret part of the api key.</p> <code>secretKey</code> ScalewayProviderSecretRef <p>SecretKey is the non-secret part of the api key.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.ScalewayProviderSecretRef","title":"ScalewayProviderSecretRef","text":"<p> (Appears on: ScalewayProvider) </p> <p> </p> Field Description <code>value</code> string (Optional) <p>Value can be specified directly to set a value without using a secret.</p> <code>secretRef</code> External Secrets meta/v1.SecretKeySelector (Optional) <p>SecretRef references a key in a secret that will be used as value.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStore","title":"SecretStore","text":"<p> <p>SecretStore represents a secure external location for storing secrets, which can be referenced as part of <code>storeRef</code> fields.</p> </p> Field Description <code>metadata</code> Kubernetes meta/v1.ObjectMeta Refer to the Kubernetes API documentation for the fields of the <code>metadata</code> field. <code>spec</code> SecretStoreSpec <code>controller</code> string (Optional) <p>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</p> <code>provider</code> SecretStoreProvider <p>Used to configure the provider. Only one provider may be set</p> <code>retrySettings</code> SecretStoreRetrySettings (Optional) <p>Used to configure http retries if failed</p> <code>refreshInterval</code> int (Optional) <p>Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.</p> <code>conditions</code> []ClusterSecretStoreCondition (Optional) <p>Used to constraint a ClusterSecretStore to specific namespaces. Relevant only to ClusterSecretStore</p> <code>status</code> SecretStoreStatus"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStoreCapabilities","title":"SecretStoreCapabilities (<code>string</code> alias)","text":"<p> (Appears on: SecretStoreStatus) </p> <p> <p>SecretStoreCapabilities defines the possible operations a SecretStore can do.</p> </p> Value Description <p>\"ReadOnly\"</p> <p>\"ReadWrite\"</p> <p>\"WriteOnly\"</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStoreConditionType","title":"SecretStoreConditionType (<code>string</code> alias)","text":"<p> (Appears on: SecretStoreStatusCondition) </p> <p> </p> Value Description <p>\"Ready\"</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStoreProvider","title":"SecretStoreProvider","text":"<p> (Appears on: SecretStoreSpec) </p> <p> <p>SecretStoreProvider contains the provider-specific configuration.</p> </p> Field Description <code>aws</code> AWSProvider (Optional) <p>AWS configures this store to sync secrets using AWS Secret Manager provider</p> <code>azurekv</code> AzureKVProvider (Optional) <p>AzureKV configures this store to sync secrets using Azure Key Vault provider</p> <code>akeyless</code> AkeylessProvider (Optional) <p>Akeyless configures this store to sync secrets using Akeyless Vault provider</p> <code>vault</code> VaultProvider (Optional) <p>Vault configures this store to sync secrets using Hashi provider</p> <code>gcpsm</code> GCPSMProvider (Optional) <p>GCPSM configures this store to sync secrets using Google Cloud Platform Secret Manager provider</p> <code>oracle</code> OracleProvider (Optional) <p>Oracle configures this store to sync secrets using Oracle Vault provider</p> <code>ibm</code> IBMProvider (Optional) <p>IBM configures this store to sync secrets using IBM Cloud provider</p> <code>yandexcertificatemanager</code> YandexCertificateManagerProvider (Optional) <p>YandexCertificateManager configures this store to sync secrets using Yandex Certificate Manager provider</p> <code>yandexlockbox</code> YandexLockboxProvider (Optional) <p>YandexLockbox configures this store to sync secrets using Yandex Lockbox provider</p> <code>gitlab</code> GitlabProvider (Optional) <p>GitLab configures this store to sync secrets using GitLab Variables provider</p> <code>alibaba</code> AlibabaProvider (Optional) <p>Alibaba configures this store to sync secrets using Alibaba Cloud provider</p> <code>onepassword</code> OnePasswordProvider (Optional) <p>OnePassword configures this store to sync secrets using the 1Password Cloud provider</p> <code>webhook</code> WebhookProvider (Optional) <p>Webhook configures this store to sync secrets using a generic templated webhook</p> <code>kubernetes</code> KubernetesProvider (Optional) <p>Kubernetes configures this store to sync secrets using a Kubernetes cluster provider</p> <code>fake</code> FakeProvider (Optional) <p>Fake configures a store with static key/value pairs</p> <code>senhasegura</code> SenhaseguraProvider (Optional) <p>Senhasegura configures this store to sync secrets using senhasegura provider</p> <code>scaleway</code> ScalewayProvider (Optional) <p>Scaleway</p> <code>doppler</code> DopplerProvider (Optional) <p>Doppler configures this store to sync secrets using the Doppler provider</p> <code>keepersecurity</code> KeeperSecurityProvider (Optional) <p>KeeperSecurity configures this store to sync secrets using the KeeperSecurity provider</p> <code>conjur</code> ConjurProvider (Optional) <p>Conjur configures this store to sync secrets using conjur provider</p> <code>delinea</code> DelineaProvider (Optional) <p>Delinea DevOps Secrets Vault https://docs.delinea.com/online-help/products/devops-secrets-vault/current</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStoreRef","title":"SecretStoreRef","text":"<p> (Appears on: ExternalSecretSpec, SourceRef) </p> <p> <p>SecretStoreRef defines which SecretStore to fetch the ExternalSecret data.</p> </p> Field Description <code>name</code> string <p>Name of the SecretStore resource</p> <code>kind</code> string (Optional) <p>Kind of the SecretStore resource (SecretStore or ClusterSecretStore) Defaults to <code>SecretStore</code></p>"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStoreRetrySettings","title":"SecretStoreRetrySettings","text":"<p> (Appears on: SecretStoreSpec) </p> <p> </p> Field Description <code>maxRetries</code> int32 <code>retryInterval</code> string"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStoreSpec","title":"SecretStoreSpec","text":"<p> (Appears on: ClusterSecretStore, SecretStore) </p> <p> <p>SecretStoreSpec defines the desired state of SecretStore.</p> </p> Field Description <code>controller</code> string (Optional) <p>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</p> <code>provider</code> SecretStoreProvider <p>Used to configure the provider. Only one provider may be set</p> <code>retrySettings</code> SecretStoreRetrySettings (Optional) <p>Used to configure http retries if failed</p> <code>refreshInterval</code> int (Optional) <p>Used to configure store refresh interval in seconds. Empty or 0 will default to the controller config.</p> <code>conditions</code> []ClusterSecretStoreCondition (Optional) <p>Used to constraint a ClusterSecretStore to specific namespaces. Relevant only to ClusterSecretStore</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStoreStatus","title":"SecretStoreStatus","text":"<p> (Appears on: ClusterSecretStore, SecretStore) </p> <p> <p>SecretStoreStatus defines the observed state of the SecretStore.</p> </p> Field Description <code>conditions</code> []SecretStoreStatusCondition (Optional) <code>capabilities</code> SecretStoreCapabilities (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretStoreStatusCondition","title":"SecretStoreStatusCondition","text":"<p> (Appears on: SecretStoreStatus) </p> <p> </p> Field Description <code>type</code> SecretStoreConditionType <code>status</code> Kubernetes core/v1.ConditionStatus <code>reason</code> string (Optional) <code>message</code> string (Optional) <code>lastTransitionTime</code> Kubernetes meta/v1.Time (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.SecretsClient","title":"SecretsClient","text":"<p> <p>SecretsClient provides access to secrets.</p> </p>"},{"location":"api/spec/#external-secrets.io/v1beta1.SenhaseguraAuth","title":"SenhaseguraAuth","text":"<p> (Appears on: SenhaseguraProvider) </p> <p> <p>SenhaseguraAuth tells the controller how to do auth in senhasegura.</p> </p> Field Description <code>clientId</code> string <code>clientSecretSecretRef</code> External Secrets meta/v1.SecretKeySelector"},{"location":"api/spec/#external-secrets.io/v1beta1.SenhaseguraModuleType","title":"SenhaseguraModuleType (<code>string</code> alias)","text":"<p> (Appears on: SenhaseguraProvider) </p> <p> <p>SenhaseguraModuleType enum defines senhasegura target module to fetch secrets</p> </p> Value Description <p>\"DSM\"</p> <pre><code> SenhaseguraModuleDSM is the senhasegura DevOps Secrets Management module\nsee: https://senhasegura.com/devops\n</code></pre>"},{"location":"api/spec/#external-secrets.io/v1beta1.SenhaseguraProvider","title":"SenhaseguraProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>SenhaseguraProvider setup a store to sync secrets with senhasegura.</p> </p> Field Description <code>url</code> string <p>URL of senhasegura</p> <code>module</code> SenhaseguraModuleType <p>Module defines which senhasegura module should be used to get secrets</p> <code>auth</code> SenhaseguraAuth <p>Auth defines parameters to authenticate in senhasegura</p> <code>ignoreSslCertificate</code> bool <p>IgnoreSslCertificate defines if SSL certificate must be ignored</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.SourceRef","title":"SourceRef","text":"<p> (Appears on: ExternalSecretData, ExternalSecretDataFromRemoteRef) </p> <p> <p>SourceRef allows you to override the source from which the secret will be pulled from. You can define at maximum one property.</p> </p> Field Description <code>storeRef</code> SecretStoreRef (Optional) <code>generatorRef</code> GeneratorRef (Optional) <p>GeneratorRef points to a generator custom resource in</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.Tag","title":"Tag","text":"Field Description <code>key</code> string <code>value</code> string"},{"location":"api/spec/#external-secrets.io/v1beta1.TemplateEngineVersion","title":"TemplateEngineVersion (<code>string</code> alias)","text":"<p> (Appears on: ExternalSecretTemplate) </p> <p> </p> Value Description <p>\"v1\"</p> <p>\"v2\"</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.TemplateFrom","title":"TemplateFrom","text":"<p> (Appears on: ExternalSecretTemplate) </p> <p> </p> Field Description <code>configMap</code> TemplateRef <code>secret</code> TemplateRef <code>target</code> TemplateTarget (Optional) <code>literal</code> string (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.TemplateMergePolicy","title":"TemplateMergePolicy (<code>string</code> alias)","text":"<p> (Appears on: ExternalSecretTemplate) </p> <p> </p> Value Description <p>\"Merge\"</p> <p>\"Replace\"</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.TemplateRef","title":"TemplateRef","text":"<p> (Appears on: TemplateFrom) </p> <p> </p> Field Description <code>name</code> string <code>items</code> []TemplateRefItem"},{"location":"api/spec/#external-secrets.io/v1beta1.TemplateRefItem","title":"TemplateRefItem","text":"<p> (Appears on: TemplateRef) </p> <p> </p> Field Description <code>key</code> string <code>templateAs</code> TemplateScope"},{"location":"api/spec/#external-secrets.io/v1beta1.TemplateScope","title":"TemplateScope (<code>string</code> alias)","text":"<p> (Appears on: TemplateRefItem) </p> <p> </p> Value Description <p>\"KeysAndValues\"</p> <p>\"Values\"</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.TemplateTarget","title":"TemplateTarget (<code>string</code> alias)","text":"<p> (Appears on: TemplateFrom) </p> <p> </p> Value Description <p>\"Annotations\"</p> <p>\"Data\"</p> <p>\"Labels\"</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.TokenAuth","title":"TokenAuth","text":"<p> (Appears on: KubernetesAuth) </p> <p> </p> Field Description <code>bearerToken</code> External Secrets meta/v1.SecretKeySelector"},{"location":"api/spec/#external-secrets.io/v1beta1.ValidationResult","title":"ValidationResult (<code>byte</code> alias)","text":"Value Description <p>2</p> <p>Error indicates that there is a misconfiguration.</p> <p>0</p> <p>Ready indicates that the client is configured correctly and can be used.</p> <p>1</p> <p>Unknown indicates that the client can be used but information is missing and it can not be validated.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultAppRole","title":"VaultAppRole","text":"<p> (Appears on: VaultAuth) </p> <p> <p>VaultAppRole authenticates with Vault using the App Role auth mechanism, with the role and secret stored in a Kubernetes Secret resource.</p> </p> Field Description <code>path</code> string <p>Path where the App Role authentication backend is mounted in Vault, e.g: \u201capprole\u201d</p> <code>roleId</code> string (Optional) <p>RoleID configured in the App Role authentication backend when setting up the authentication backend in Vault.</p> <code>roleRef</code> External Secrets meta/v1.SecretKeySelector (Optional) <p>Reference to a key in a Secret that contains the App Role ID used to authenticate with Vault. The <code>key</code> field must be specified and denotes which entry within the Secret resource is used as the app role id.</p> <code>secretRef</code> External Secrets meta/v1.SecretKeySelector <p>Reference to a key in a Secret that contains the App Role secret used to authenticate with Vault. The <code>key</code> field must be specified and denotes which entry within the Secret resource is used as the app role secret.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultAuth","title":"VaultAuth","text":"<p> (Appears on: VaultProvider) </p> <p> <p>VaultAuth is the configuration used to authenticate with a Vault server. Only one of <code>tokenSecretRef</code>, <code>appRole</code>, <code>kubernetes</code>, <code>ldap</code>, <code>userPass</code>, <code>jwt</code> or <code>cert</code> can be specified.</p> </p> Field Description <code>tokenSecretRef</code> External Secrets meta/v1.SecretKeySelector (Optional) <p>TokenSecretRef authenticates with Vault by presenting a token.</p> <code>appRole</code> VaultAppRole (Optional) <p>AppRole authenticates with Vault using the App Role auth mechanism, with the role and secret stored in a Kubernetes Secret resource.</p> <code>kubernetes</code> VaultKubernetesAuth (Optional) <p>Kubernetes authenticates with Vault by passing the ServiceAccount token stored in the named Secret resource to the Vault server.</p> <code>ldap</code> VaultLdapAuth (Optional) <p>Ldap authenticates with Vault by passing username/password pair using the LDAP authentication method</p> <code>jwt</code> VaultJwtAuth (Optional) <p>Jwt authenticates with Vault by passing role and JWT token using the JWT/OIDC authentication method</p> <code>cert</code> VaultCertAuth (Optional) <p>Cert authenticates with TLS Certificates by passing client certificate, private key and ca certificate Cert authentication method</p> <code>iam</code> VaultIamAuth (Optional) <p>Iam authenticates with vault by passing a special AWS request signed with AWS IAM credentials AWS IAM authentication method</p> <code>userPass</code> VaultUserPassAuth (Optional) <p>UserPass authenticates with Vault by passing username/password pair</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultAwsAuth","title":"VaultAwsAuth","text":"<p> <p>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.</p> </p> Field Description <code>secretRef</code> VaultAwsAuthSecretRef (Optional) <code>jwt</code> VaultAwsJWTAuth (Optional)"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultAwsAuthSecretRef","title":"VaultAwsAuthSecretRef","text":"<p> (Appears on: VaultAwsAuth, VaultIamAuth) </p> <p> <p>VaultAWSAuthSecretRef holds secret references for AWS credentials both AccessKeyID and SecretAccessKey must be defined in order to properly authenticate.</p> </p> Field Description <code>accessKeyIDSecretRef</code> External Secrets meta/v1.SecretKeySelector <p>The AccessKeyID is used for authentication</p> <code>secretAccessKeySecretRef</code> External Secrets meta/v1.SecretKeySelector <p>The SecretAccessKey is used for authentication</p> <code>sessionTokenSecretRef</code> External Secrets meta/v1.SecretKeySelector <p>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</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultAwsJWTAuth","title":"VaultAwsJWTAuth","text":"<p> (Appears on: VaultAwsAuth, VaultIamAuth) </p> <p> <p>Authenticate against AWS using service account tokens.</p> </p> Field Description <code>serviceAccountRef</code> External Secrets meta/v1.ServiceAccountSelector"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultCertAuth","title":"VaultCertAuth","text":"<p> (Appears on: VaultAuth) </p> <p> <p>VaultJwtAuth authenticates with Vault using the JWT/OIDC authentication method, with the role name and token stored in a Kubernetes Secret resource.</p> </p> Field Description <code>clientCert</code> External Secrets meta/v1.SecretKeySelector (Optional) <p>ClientCert is a certificate to authenticate using the Cert Vault authentication method</p> <code>secretRef</code> External Secrets meta/v1.SecretKeySelector <p>SecretRef to a key in a Secret resource containing client private key to authenticate with Vault using the Cert authentication method</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultIamAuth","title":"VaultIamAuth","text":"<p> (Appears on: VaultAuth) </p> <p> <p>VaultIamAuth authenticates with Vault using the Vault\u2019s AWS IAM authentication method. Refer: https://developer.hashicorp.com/vault/docs/auth/aws</p> </p> Field Description <code>path</code> string <p>Path where the AWS auth method is enabled in Vault, e.g: \u201caws\u201d</p> <code>region</code> string <p>AWS region</p> <code>role</code> string <p>This is the AWS role to be assumed before talking to vault</p> <code>vaultRole</code> string <p>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</p> <code>externalID</code> string <p>AWS External ID set on assumed IAM roles</p> <code>vaultAwsIamServerID</code> string <p>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</p> <code>secretRef</code> VaultAwsAuthSecretRef (Optional) <p>Specify credentials in a Secret object</p> <code>jwt</code> VaultAwsJWTAuth (Optional) <p>Specify a service account with IRSA enabled</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultJwtAuth","title":"VaultJwtAuth","text":"<p> (Appears on: VaultAuth) </p> <p> <p>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 <code>TokenRequest</code>.</p> </p> Field Description <code>path</code> string <p>Path where the JWT authentication backend is mounted in Vault, e.g: \u201cjwt\u201d</p> <code>role</code> string (Optional) <p>Role is a JWT role to authenticate using the JWT/OIDC Vault authentication method</p> <code>secretRef</code> External Secrets meta/v1.SecretKeySelector (Optional) <p>Optional SecretRef that refers to a key in a Secret resource containing JWT token to authenticate with Vault using the JWT/OIDC authentication method.</p> <code>kubernetesServiceAccountToken</code> VaultKubernetesServiceAccountTokenAuth (Optional) <p>Optional ServiceAccountToken specifies the Kubernetes service account for which to request a token for with the <code>TokenRequest</code> API.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultKVStoreVersion","title":"VaultKVStoreVersion (<code>string</code> alias)","text":"<p> (Appears on: VaultProvider) </p> <p> </p> Value Description <p>\"v1\"</p> <p>\"v2\"</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultKubernetesAuth","title":"VaultKubernetesAuth","text":"<p> (Appears on: VaultAuth) </p> <p> <p>Authenticate against Vault using a Kubernetes ServiceAccount token stored in a Secret.</p> </p> Field Description <code>mountPath</code> string <p>Path where the Kubernetes authentication backend is mounted in Vault, e.g: \u201ckubernetes\u201d</p> <code>serviceAccountRef</code> External Secrets meta/v1.ServiceAccountSelector (Optional) <p>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.</p> <code>secretRef</code> External Secrets meta/v1.SecretKeySelector (Optional) <p>Optional secret field containing a Kubernetes ServiceAccount JWT used for authenticating with Vault. If a name is specified without a key, <code>token</code> is the default. If one is not specified, the one bound to the controller will be used.</p> <code>role</code> string <p>A required field containing the Vault Role to assume. A Role binds a Kubernetes ServiceAccount with a set of Vault policies.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultKubernetesServiceAccountTokenAuth","title":"VaultKubernetesServiceAccountTokenAuth","text":"<p> (Appears on: VaultJwtAuth) </p> <p> <p>VaultKubernetesServiceAccountTokenAuth authenticates with Vault using a temporary Kubernetes service account token retrieved by the <code>TokenRequest</code> API.</p> </p> Field Description <code>serviceAccountRef</code> External Secrets meta/v1.ServiceAccountSelector <p>Service account field containing the name of a kubernetes ServiceAccount.</p> <code>audiences</code> []string (Optional) <p>Optional audiences field that will be used to request a temporary Kubernetes service account token for the service account referenced by <code>serviceAccountRef</code>. Defaults to a single audience <code>vault</code> it not specified. Deprecated: use serviceAccountRef.Audiences instead</p> <code>expirationSeconds</code> int64 (Optional) <p>Optional expiration time in seconds that will be used to request a temporary Kubernetes service account token for the service account referenced by <code>serviceAccountRef</code>. Deprecated: this will be removed in the future. Defaults to 10 minutes.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultLdapAuth","title":"VaultLdapAuth","text":"<p> (Appears on: VaultAuth) </p> <p> <p>VaultLdapAuth authenticates with Vault using the LDAP authentication method, with the username and password stored in a Kubernetes Secret resource.</p> </p> Field Description <code>path</code> string <p>Path where the LDAP authentication backend is mounted in Vault, e.g: \u201cldap\u201d</p> <code>username</code> string <p>Username is a LDAP user name used to authenticate using the LDAP Vault authentication method</p> <code>secretRef</code> External Secrets meta/v1.SecretKeySelector <p>SecretRef to a key in a Secret resource containing password for the LDAP user used to authenticate with Vault using the LDAP authentication method</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultProvider","title":"VaultProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>Configures an store to sync secrets using a HashiCorp Vault KV backend.</p> </p> Field Description <code>auth</code> VaultAuth <p>Auth configures how secret-manager authenticates with the Vault server.</p> <code>server</code> string <p>Server is the connection address for the Vault server, e.g: \u201chttps://vault.example.com:8200\u201d.</p> <code>path</code> string (Optional) <p>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.</p> <code>version</code> VaultKVStoreVersion <p>Version is the Vault KV secret engine version. This can be either \u201cv1\u201d or \u201cv2\u201d. Version defaults to \u201cv2\u201d.</p> <code>namespace</code> string (Optional) <p>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</p> <code>caBundle</code> []byte (Optional) <p>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.</p> <code>caProvider</code> CAProvider (Optional) <p>The provider for the CA bundle to use to validate Vault server certificate.</p> <code>readYourWrites</code> bool (Optional) <p>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</p> <code>forwardInconsistent</code> bool (Optional) <p>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</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.VaultUserPassAuth","title":"VaultUserPassAuth","text":"<p> (Appears on: VaultAuth) </p> <p> <p>VaultUserPassAuth authenticates with Vault using UserPass authentication method, with the username and password stored in a Kubernetes Secret resource.</p> </p> Field Description <code>path</code> string <p>Path where the UserPassword authentication backend is mounted in Vault, e.g: \u201cuser\u201d</p> <code>username</code> string <p>Username is a user name used to authenticate using the UserPass Vault authentication method</p> <code>secretRef</code> External Secrets meta/v1.SecretKeySelector <p>SecretRef to a key in a Secret resource containing password for the user used to authenticate with Vault using the UserPass authentication method</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.WebhookCAProvider","title":"WebhookCAProvider","text":"<p> (Appears on: WebhookProvider) </p> <p> <p>Defines a location to fetch the cert for the webhook provider from.</p> </p> Field Description <code>type</code> WebhookCAProviderType <p>The type of provider to use such as \u201cSecret\u201d, or \u201cConfigMap\u201d.</p> <code>name</code> string <p>The name of the object located at the provider type.</p> <code>key</code> string <p>The key the value inside of the provider type to use, only used with \u201cSecret\u201d type</p> <code>namespace</code> string (Optional) <p>The namespace the Provider type is in.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.WebhookCAProviderType","title":"WebhookCAProviderType (<code>string</code> alias)","text":"<p> (Appears on: WebhookCAProvider) </p> <p> </p> Value Description <p>\"ConfigMap\"</p> <p>\"Secret\"</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.WebhookProvider","title":"WebhookProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>AkeylessProvider Configures an store to sync secrets using Akeyless KV.</p> </p> Field Description <code>method</code> string <p>Webhook Method</p> <code>url</code> string <p>Webhook url to call</p> <code>headers</code> map[string]string (Optional) <p>Headers</p> <code>body</code> string (Optional) <p>Body</p> <code>timeout</code> Kubernetes meta/v1.Duration (Optional) <p>Timeout</p> <code>result</code> WebhookResult <p>Result formatting</p> <code>secrets</code> []WebhookSecret (Optional) <p>Secrets to fill in templates These secrets will be passed to the templating function as key value pairs under the given name</p> <code>caBundle</code> []byte (Optional) <p>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.</p> <code>caProvider</code> WebhookCAProvider (Optional) <p>The provider for the CA bundle to use to validate webhook server certificate.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.WebhookResult","title":"WebhookResult","text":"<p> (Appears on: WebhookProvider) </p> <p> </p> Field Description <code>jsonPath</code> string (Optional) <p>Json path of return value</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.WebhookSecret","title":"WebhookSecret","text":"<p> (Appears on: WebhookProvider) </p> <p> </p> Field Description <code>name</code> string <p>Name of this secret in templates</p> <code>secretRef</code> External Secrets meta/v1.SecretKeySelector <p>Secret ref to fill in credentials</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.YandexCertificateManagerAuth","title":"YandexCertificateManagerAuth","text":"<p> (Appears on: YandexCertificateManagerProvider) </p> <p> </p> Field Description <code>authorizedKeySecretRef</code> External Secrets meta/v1.SecretKeySelector (Optional) <p>The authorized key used for authentication</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.YandexCertificateManagerCAProvider","title":"YandexCertificateManagerCAProvider","text":"<p> (Appears on: YandexCertificateManagerProvider) </p> <p> </p> Field Description <code>certSecretRef</code> External Secrets meta/v1.SecretKeySelector"},{"location":"api/spec/#external-secrets.io/v1beta1.YandexCertificateManagerProvider","title":"YandexCertificateManagerProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>YandexCertificateManagerProvider Configures a store to sync secrets using the Yandex Certificate Manager provider.</p> </p> Field Description <code>apiEndpoint</code> string (Optional) <p>Yandex.Cloud API endpoint (e.g. \u2018api.cloud.yandex.net:443\u2019)</p> <code>auth</code> YandexCertificateManagerAuth <p>Auth defines the information necessary to authenticate against Yandex Certificate Manager</p> <code>caProvider</code> YandexCertificateManagerCAProvider (Optional) <p>The provider for the CA bundle to use to validate Yandex.Cloud server certificate.</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.YandexLockboxAuth","title":"YandexLockboxAuth","text":"<p> (Appears on: YandexLockboxProvider) </p> <p> </p> Field Description <code>authorizedKeySecretRef</code> External Secrets meta/v1.SecretKeySelector (Optional) <p>The authorized key used for authentication</p>"},{"location":"api/spec/#external-secrets.io/v1beta1.YandexLockboxCAProvider","title":"YandexLockboxCAProvider","text":"<p> (Appears on: YandexLockboxProvider) </p> <p> </p> Field Description <code>certSecretRef</code> External Secrets meta/v1.SecretKeySelector"},{"location":"api/spec/#external-secrets.io/v1beta1.YandexLockboxProvider","title":"YandexLockboxProvider","text":"<p> (Appears on: SecretStoreProvider) </p> <p> <p>YandexLockboxProvider Configures a store to sync secrets using the Yandex Lockbox provider.</p> </p> Field Description <code>apiEndpoint</code> string (Optional) <p>Yandex.Cloud API endpoint (e.g. \u2018api.cloud.yandex.net:443\u2019)</p> <code>auth</code> YandexLockboxAuth <p>Auth defines the information necessary to authenticate against Yandex Lockbox</p> <code>caProvider</code> YandexLockboxCAProvider (Optional) <p>The provider for the CA bundle to use to validate Yandex.Cloud server certificate.</p> <p> Generated with <code>gen-crd-api-reference-docs</code>. </p>"},{"location":"api/generator/","title":"Index","text":"<p>Generators allow you to generate values. See Generators Guide</p>"},{"location":"api/generator/acr/","title":"Azure Container Registry","text":"<p>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 <code>spec.registry</code>.</p>"},{"location":"api/generator/acr/#output-keys-and-values","title":"Output Keys and Values","text":"Key Description username username for the <code>docker login</code> command password password for the <code>docker login</code> command"},{"location":"api/generator/acr/#authentication","title":"Authentication","text":"<p>You must choose one out of three authentication mechanisms:</p> <ul> <li>service principal</li> <li>managed identity</li> <li>workload identity</li> </ul> <p>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.</p> <p>You can scope tokens to a particular repository using <code>spec.scope</code>.</p>"},{"location":"api/generator/acr/#scope","title":"Scope","text":"<p>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 <code>spec.scope</code> if it is defined it obtains an ACR access token. If <code>spec.scope</code> is missing it obtains an ACR refresh token:</p> <ul> <li>access tokens are scoped to a specific repository or action (pull,push)</li> <li>refresh tokens can are scoped to whatever policy is attached to the identity that creates the acr refresh token</li> </ul> <p>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 <code>pull</code> or <code>push</code>.</p> <p>Example scopes:</p> <pre><code>repository:my-repository:pull,push\nrepository:my-repository:pull\n</code></pre>"},{"location":"api/generator/acr/#example-manifest","title":"Example Manifest","text":"<pre><code>apiVersion: generators.external-secrets.io/v1alpha1\nkind: ACRAccessToken\nmetadata:\nname: my-azurecr\nspec:\ntenantId: 11111111-2222-3333-4444-111111111111\nregistry: 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.\nscope: \"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\nenvironmentType: \"PublicCloud\"\n\n# choose one authentication method\nauth:\n\n# option 1: point to a secret that contains a client-id and client-secret\nservicePrincipal:\nsecretRef:\nclientSecret:\nname: az-secret\nkey: clientsecret\nclientId:\nname: az-secret\nkey: clientid\n\n# option 2:\nmanagedIdentity:\nidentityId: \"xxxxx\"\n\n# option 3:\nworkloadIdentity:\n# note: you can reference service accounts across namespaces.\nserviceAccountRef:\nname: \"my-service-account\"\naudiences: []\n</code></pre> <p>Example <code>ExternalSecret</code> that references the ACR generator: <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: azurecr-credentials\nspec:\ndataFrom:\n- sourceRef:\ngeneratorRef:\napiVersion: generators.external-secrets.io/v1alpha1\nkind: ACRAccessToken\nname: my-azurecr\nrefreshInterval: 12h\ntarget:\nname: azurecr-credentials\ntemplate:\ntype: kubernetes.io/dockerconfigjson\ndata:\n.dockerconfigjson: |\n{\n\"auths\": {\n\"myregistry.azurecr.io\": {\n\"username\": \"{{ .username }}\",\n\"identitytoken\": \"{{ .password }}\",\n}\n}\n}\n</code></pre></p>"},{"location":"api/generator/ecr/","title":"AWS Elastic Container Registry","text":"<p>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.</p>"},{"location":"api/generator/ecr/#output-keys-and-values","title":"Output Keys and Values","text":"Key Description username username for the <code>docker login</code> command. password password for the <code>docker login</code> command. proxy_endpoint The registry URL to use for this authorization token in a <code>docker login</code> command. expires_at time when token expires in UNIX time (seconds since January 1, 1970 UTC)."},{"location":"api/generator/ecr/#authentication","title":"Authentication","text":"<p>You can choose from three authentication mechanisms:</p> <ul> <li>static credentials using <code>spec.auth.secretRef</code></li> <li>point to a IRSA Service Account with <code>spec.auth.jwt</code></li> <li>use credentials from the SDK default credentials chain from the controller environment</li> </ul>"},{"location":"api/generator/ecr/#example-manifest","title":"Example Manifest","text":"<pre><code>apiVersion: generators.external-secrets.io/v1alpha1\nkind: ECRAuthorizationToken\nmetadata:\nname: ecr-gen\nspec:\n\n# specify aws region (mandatory)\nregion: eu-west-1\n\n# assume role with the given authentication credentials\nrole: \"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.\nauth:\n\n# 1: static credentials\n# point to a secret that contains static credentials\n# like AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY\nsecretRef:\naccessKeyIDSecretRef:\nname: \"my-aws-creds\"\nkey: \"key-id\"\nsecretAccessKeySecretRef:\nname: \"my-aws-creds\"\nkey: \"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)\njwt:\nserviceAccountRef:\nname: \"oci-token-sync\"\n</code></pre> <p>Example <code>ExternalSecret</code> that references the ECR generator: <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: \"ecr-secret\"\nspec:\nrefreshInterval: \"1h\"\ntarget:\nname: ecr-secret\ndataFrom:\n- sourceRef:\ngeneratorRef:\napiVersion: generators.external-secrets.io/v1alpha1\nkind: ECRAuthorizationToken\nname: \"ecr-gen\"\n</code></pre></p>"},{"location":"api/generator/fake/","title":"Fake","text":"<p>The Fake generator provides hard-coded key/value pairs. The intended use is just for debugging and testing. The key/value pairs defined in <code>spec.data</code> is returned as-is.</p>"},{"location":"api/generator/fake/#example-manifest","title":"Example Manifest","text":"<pre><code>apiVersion: generators.external-secrets.io/v1alpha1\nkind: Fake\nmetadata:\nname: fake-key\nspec:\ndata:\nfoo: bar\nbaz: bang\n</code></pre> <p>Example <code>ExternalSecret</code> that references the Fake generator: <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: \"fake\"\nspec:\nrefreshInterval: \"30m\"\ntarget:\nname: fake\ndataFrom:\n- sourceRef:\ngeneratorRef:\napiVersion: generators.external-secrets.io/v1alpha1\nkind: Fake\nname: \"fake-key\"\n</code></pre></p>"},{"location":"api/generator/gcr/","title":"Google Container Registry","text":"<p>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</p> <p>You must specify the <code>spec.projectID</code> in which GCR is located.</p>"},{"location":"api/generator/gcr/#output-keys-and-values","title":"Output Keys and Values","text":"Key Description username username for the <code>docker login</code> command. password password for the <code>docker login</code> 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":"<p>Use <code>spec.auth.workloadIdentity</code> to point to a Service Account that has Workload Identity enabled. For details see GCP Secret Manager.</p>"},{"location":"api/generator/gcr/#gcp-service-account","title":"GCP Service Account","text":"<p>Use <code>spec.auth.secretRef</code> to point to a Secret that contains a GCP Service Account. For details see GCP Secret Manager.</p>"},{"location":"api/generator/gcr/#example-manifest","title":"Example Manifest","text":"<pre><code>apiVersion: generators.external-secrets.io/v1alpha1\nkind: GCRAccessToken\nmetadata:\nname: gcr-gen\nspec:\n# project where gcr lives in\nprojectID: \"\"\n\n# choose authentication strategy\nauth:\n# option 1: workload identity\nworkloadIdentity:\n# point to the workload identity\n# service account\nserviceAccountRef:\nname: \"\"\naudiences: []\n# the cluster can live in a different project or location\n# use the following fields to configure where the cluster lives\nclusterLocation: \"\"\nclusterName: \"\"\nclusterProjectID: \"\"\n\n\n# option 2: GCP service account\nsecretRef:\nsecretAccessKeySecretRef:\nname: \"\"\nkey: \"\"\n</code></pre> <p>Example <code>ExternalSecret</code> that references the GCR generator: <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: \"gcr-token\"\nspec:\nrefreshInterval: \"30m\"\ntarget:\nname: gcr-token\ndataFrom:\n- sourceRef:\ngeneratorRef:\napiVersion: generators.external-secrets.io/v1alpha1\nkind: GCRAccessToken\nname: \"gcr-gen\"\n</code></pre></p>"},{"location":"api/generator/password/","title":"Password","text":"<p>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.</p> <p>Passwords are completely randomized</p> <p>It is possible that we may generate passwords that don't match the expected character set from your application.</p>"},{"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":"<p>You can influence the behavior of the generator by providing the following args</p> 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":"<pre><code>apiVersion: generators.external-secrets.io/v1alpha1\nkind: Password\nmetadata:\nname: my-password\nspec:\nlength: 42\ndigits: 5\nsymbols: 5\nsymbolCharacters: \"-_$@\"\nnoUpper: false\nallowRepeat: true\n</code></pre> <p>Example <code>ExternalSecret</code> that references the Password generator: <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: \"password\"\nspec:\nrefreshInterval: \"30m\"\ntarget:\nname: password-secret\ndataFrom:\n- sourceRef:\ngeneratorRef:\napiVersion: generators.external-secrets.io/v1alpha1\nkind: Password\nname: \"my-password\"\n</code></pre></p> <p>Which will generate a <code>Kind=Secret</code> with a key called 'password' that may look like:</p> <pre><code>RMngCHKtZ@@h@3aja$WZDuDVhkCkN48JBa9OF8jH$R\nVB$pX8SSUMIlk9K8g@XxJAhGz$0$ktbJ1ArMukg-bD\nHi$-aK_3Rrrw1Pj9-sIpPZuk5abvEDJlabUYUcS$9L\n</code></pre> <p>With default values you would get something like:</p> <pre><code>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</code></pre>"},{"location":"api/generator/vault/","title":"Vault Dynamic Secret","text":"<p>The <code>VaultDynamicSecret</code> Generator provides an interface to HashiCorp Vault's Secrets engines. Specifically, it enables obtaining dynamic secrets not covered by the HashiCorp Vault provider.</p> <p>Any Vault authentication method supported by the provider can be used here (<code>provider</code> block of the spec).</p> <p>All secrets engines should be supported by providing matching <code>path</code>, <code>method</code> and <code>parameters</code> values to the Generator spec (see example below).</p> <p>Exact output keys and values depend on the Vault secret engine used; nested values are stored into the resulting Secret in JSON format.</p>"},{"location":"api/generator/vault/#example-manifest","title":"Example manifest","text":"<pre><code>apiVersion: generators.external-secrets.io/v1alpha1\nkind: VaultDynamicSecret\nmetadata:\nname: \"pki-example\"\nspec:\npath: \"/pki/issue/example-dot-com\"\nmethod: \"POST\"\nparameters:\ncommon_name: \"localhost\"\nip_sans: \"127.0.0.1,127.0.0.11\"\nprovider:\nserver: \"http://vault.default.svc.cluster.local:8200\"\nauth:\nkubernetes:\nmountPath: \"kubernetes\"\nrole: \"external-secrets-operator\"\nserviceAccountRef:\nname: \"default\"\n</code></pre> <p>Example <code>ExternalSecret</code> that references the Vault generator: <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: \"pki-example-com\"\nspec:\nrefreshInterval: \"768h\"\ntarget:\nname: pki-example-com\ndataFrom:\n- sourceRef:\ngeneratorRef:\napiVersion: generators.external-secrets.io/v1alpha1\nkind: VaultDynamicSecret\nname: \"pki-example\"\n</code></pre></p>"},{"location":"contributing/coc/","title":"Code of Conduct","text":""},{"location":"contributing/coc/#our-pledge","title":"Our Pledge","text":"<p>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.</p> <p>We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.</p>"},{"location":"contributing/coc/#our-standards","title":"Our Standards","text":"<p>Examples of behavior that contributes to a positive environment for our community include:</p> <ul> <li>Demonstrating empathy and kindness toward other people</li> <li>Being respectful of differing opinions, viewpoints, and experiences</li> <li>Giving and gracefully accepting constructive feedback</li> <li>Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience</li> <li>Focusing on what is best not just for us as individuals, but for the overall community</li> </ul> <p>Examples of unacceptable behavior include:</p> <ul> <li>The use of sexualized language or imagery, and sexual attention or advances of any kind</li> <li>Trolling, insulting or derogatory comments, and personal or political attacks</li> <li>Public or private harassment</li> <li>Publishing others' private information, such as a physical or email address, without their explicit permission</li> <li>Other conduct which could reasonably be considered inappropriate in a professional setting</li> </ul>"},{"location":"contributing/coc/#enforcement-responsibilities","title":"Enforcement Responsibilities","text":"<p>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.</p> <p>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.</p>"},{"location":"contributing/coc/#scope","title":"Scope","text":"<p>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.</p>"},{"location":"contributing/coc/#enforcement","title":"Enforcement","text":"<p>Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at contact@external-secrets.io. All complaints will be reviewed and investigated promptly and fairly.</p> <p>All community leaders are obligated to respect the privacy and security of the reporter of any incident.</p>"},{"location":"contributing/coc/#enforcement-guidelines","title":"Enforcement Guidelines","text":"<p>Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:</p>"},{"location":"contributing/coc/#1-correction","title":"1. Correction","text":"<p>Community Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.</p> <p>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.</p>"},{"location":"contributing/coc/#2-warning","title":"2. Warning","text":"<p>Community Impact: A violation through a single incident or series of actions.</p> <p>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.</p>"},{"location":"contributing/coc/#3-temporary-ban","title":"3. Temporary Ban","text":"<p>Community Impact: A serious violation of community standards, including sustained inappropriate behavior.</p> <p>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.</p>"},{"location":"contributing/coc/#4-permanent-ban","title":"4. Permanent Ban","text":"<p>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.</p> <p>Consequence: A permanent ban from any sort of public interaction within the community.</p>"},{"location":"contributing/coc/#attribution","title":"Attribution","text":"<p>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.</p> <p>Community Impact Guidelines were inspired by Mozilla's code of conduct enforcement ladder.</p> <p>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.</p>"},{"location":"contributing/devguide/","title":"Developer guide","text":""},{"location":"contributing/devguide/#getting-started","title":"Getting Started","text":"<p>You must have a working Go environment and then clone the repo:</p> <pre><code>git clone https://github.com/external-secrets/external-secrets.git\ncd external-secrets\n</code></pre> <p>Note: many of the <code>make</code> commands use yq, version 4.2X.X or higher.</p> <p>If you want to run controller tests you also need to install kubebuilder's <code>envtest</code>.</p> <p>The recommended way to do so is to install setup-envtest</p> <p>Here is an example on how to set it up:</p> <pre><code>go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest\n\n# list available versions\nsetup-envtest list --os $(go env GOOS) --arch $(go env GOARCH)\n\n# To use a specific version\nsetup-envtest use -p path 1.20.2\n\n#To set environment variables\nsource <(setup-envtest use 1.20.2 -p env --os $(go env GOOS) --arch $(go env GOARCH))\n</code></pre> <p>for more information, please see setup-envtest docs</p> <p>Our helm chart is tested using <code>helm-unittest</code>. You will need it to run tests locally if you modify the helm chart. Install it with the following command:</p> <pre><code>$ helm plugin install https://github.com/helm-unittest/helm-unittest\n</code></pre>"},{"location":"contributing/devguide/#building-testing","title":"Building & Testing","text":"<p>The project uses the <code>make</code> build system. It'll run code generators, tests and static code analysis.</p> <p>Building the operator binary and docker image:</p> <pre><code>make build\nmake docker.build IMG=external-secrets:latest\n</code></pre> <p>Run tests and lint the code: (golangci-lint@1.49.0 is needed.) <pre><code>make test\nmake lint # OR\ndocker run --rm -v $(pwd):/app -w /app golangci/golangci-lint:v1.49.0 golangci-lint run\n</code></pre></p> <p>Build the documentation: <pre><code>make docs\n</code></pre></p>"},{"location":"contributing/devguide/#installing","title":"Installing","text":"<p>To install the External Secret Operator into a Kubernetes Cluster run:</p> <pre><code>helm repo add external-secrets https://charts.external-secrets.io\nhelm repo update\nhelm install external-secrets external-secrets/external-secrets\n</code></pre> <p>You can alternatively run the controller on your host system for development purposes:</p> <pre><code>make crds.install\nmake run\n</code></pre> <p>To remove the CRDs run:</p> <pre><code>make crds.uninstall\n</code></pre> <p>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:</p> <pre><code># 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 -n 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\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</code></pre> <p>Contributing Flow</p> <p>The HOW TO guide for contributing is at the Contributing Process page.</p>"},{"location":"contributing/devguide/#documentation","title":"Documentation","text":"<p>We use mkdocs material and mike to generate this documentation. See <code>/docs</code> for the source code and <code>/hack/api-docs</code> for the build process.</p> <p>When writing documentation it is advised to run the mkdocs server with livereload:</p> <pre><code>make docs.serve\n</code></pre> <p>Run the following command to run a complete build. The rendered assets are available under <code>/site</code>.</p> <pre><code>make docs\nmake docs.serve\n</code></pre> <p>Open <code>http://localhost:8000</code> in your browser.</p> <p>Since mike uses a branch to create/update documentation, any docs operation will create a diff on your local <code>gh-pages</code> branch.</p> <p>When finished writing/reviewing the docs, clean up your local docs branch changes with <code>git branch -D gh-pages</code></p>"},{"location":"contributing/process/","title":"Contributing Process","text":""},{"location":"contributing/process/#project-management","title":"Project Management","text":"<p>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.</p>"},{"location":"contributing/process/#issues","title":"Issues","text":"<p>Features, bugs and any issues regarding the documentation should be filed as GitHub Issue in our repository. We use labels like <code>kind/feature</code>, <code>kind/bug</code>, <code>area/aws</code> to organize the issues. Issues labeled <code>good first issue</code> and <code>help wanted</code> are especially good for a first contribution. If you want to pick up an issue just leave a comment.</p>"},{"location":"contributing/process/#submitting-a-pull-request","title":"Submitting a Pull Request","text":"<p>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:</p> <ul> <li>ideally, there is an issue that documents the problem or feature in depth.</li> <li>code must have a reasonable amount of test coverage</li> <li>tests must pass</li> <li>PR needs be reviewed and approved</li> </ul> <p>Once these steps are completed the PR will be merged by a code owner. We're using the pull request <code>assignee</code> 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.</p>"},{"location":"contributing/process/#triggering-e2e-tests","title":"Triggering e2e tests","text":"<p>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 <code>kind</code> cluster in the GitHub Actions runner:</p> <pre><code>/ok-to-test sha=xxxxxx\n</code></pre>"},{"location":"contributing/process/#executing-e2e-tests-locally","title":"Executing e2e tests locally","text":"<p>You have to prepare your shell environment with the necessary variables so the e2e test runner knows what credentials to use. See <code>e2e/run.sh</code> for the variables that are passed in. If you e.g. want to test AWS integration make sure set all <code>AWS_*</code> variables mentioned in that file.</p> <p>Use ginkgo labels to select the tests you want to execute. You have to specify <code>!managed</code> to ensure that you do not run managed tests.</p> <pre><code>make test.e2e GINKGO_LABELS='gcp&&!managed'\n</code></pre>"},{"location":"contributing/process/#managed-kubernetes-e2e-tests","title":"Managed Kubernetes e2e tests","text":"<p>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...).</p> <p>These tests are time intensive (~20-45min) and must be triggered manually by a maintainer when a particular provider or authentication mechanism was changed:</p> <pre><code>/ok-to-test-managed sha=xxxxxx provider=aws\n# or\n/ok-to-test-managed sha=xxxxxx provider=gcp\n</code></pre> <p>Both tests can run in parallel. Once started they add a dynamic GitHub check <code>integration-managed-(gcp|aws)</code> to the PR that triggered the test.</p>"},{"location":"contributing/process/#executing-managed-kubernetes-e2e-tests-locally","title":"Executing Managed Kubernetes e2e tests locally","text":"<p>You have to prepare your shell environment with the necessary variables so the e2e test runner knows what credentials to use. See <code>.github/workflows/e2e-managed.yml</code> for the variables that are passed in. If you e.g. want to test AWS integration make sure set all variables containing <code>AWS_*</code> and <code>TF_VAR_AWS_*</code> mentioned in that file.</p> <p>Then execute <code>tf.apply.aws</code> or <code>tf.apply.gcp</code> to create the infrastructure.</p> <pre><code>make tf.apply.aws\n</code></pre> <p>Then run the <code>managed</code> testsuite. You will need push permissions to the external-secrets ghcr repository. You can set <code>IMAGE_NAME</code> to control which image registry is used to store the controller and e2e test images in.</p> <p>You also have to setup a proper Kubeconfig so the e2e test pod gets deployed into the managed cluster.</p> <pre><code>aws eks update-kubeconfig --name ${AWS_CLUSTER_NAME}\nor\ngcloud container clusters get-credentials ${GCP_GKE_CLUSTER} --region europe-west1-b\n</code></pre> <p>Use ginkgo labels to select the tests you want to execute.</p> <pre><code># you may have to set IMAGE_NAME=docker.io/your-user/external-secrets\nmake test.e2e.managed GINKGO_LABELS='gcp'\n</code></pre>"},{"location":"contributing/process/#proposal-process","title":"Proposal Process","text":"<p>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:</p> <ul> <li>creating new custom resources</li> <li>proposing breaking changes</li> <li>changing the behavior of the controller significantly</li> </ul> <p>Please create a document in the <code>design/</code> directory based on the template <code>000-template.md</code> 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.</p>"},{"location":"contributing/process/#release-planning","title":"Release Planning","text":"<p>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.</p> <p>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:</p> <ol> <li>assign new issues to the GH Project</li> <li>add a milestone if needed</li> <li>add appropriate labels</li> </ol> <p>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.</p>"},{"location":"contributing/process/#support-questions","title":"Support & Questions","text":"<p>Providing support to end users is an important and difficult task. We have three different channels through which support questions arise:</p> <ol> <li>Kubernetes Slack #external-secrets</li> <li>GitHub Discussions</li> <li>GitHub Issues</li> </ol> <p>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:</p> <ul> <li><code>triage/needs-information</code>: Indicates an issue needs more information in order to work on it.</li> <li><code>triage/not-reproducible</code>: Indicates an issue can not be reproduced as described.</li> <li><code>triage/support</code>: Indicates an issue that is a support question.</li> </ul>"},{"location":"contributing/process/#cutting-releases","title":"Cutting Releases","text":"<p>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.</p>"},{"location":"contributing/release/","title":"Release Process","text":"<p>ESO and the ESO Helm Chart have two distinct lifecycles and can be released independently. Helm Chart releases are named <code>external-secrets-x.y.z</code>.</p> <p>The external-secrets project is released on a as-needed basis. Feel free to open a issue to request a release.</p>"},{"location":"contributing/release/#release-eso","title":"Release ESO","text":"<p>When doing a release it's best to start with with the \"Create Release\" issue template, it has a checklist to go over.</p> <p>\u26a0\ufe0f Note: when releasing multiple versions, make sure to first release the \"old\" version, then the newer version. Otherwise the <code>latest</code> 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).</p> <ol> <li>Run <code>Create Release</code> Action to create a new release, pass in the desired version number to release.<ol> <li>choose the right <code>branch</code> to execute the action: use <code>main</code> when creating a new release. Use <code>release-x.y</code> when you want to bump a LTS release.</li> <li>\u26a0\ufe0f make sure that CI on the relevant branch has completed the docker build/push jobs. Otherwise an old image will be promoted.</li> </ol> </li> <li>GitHub Release, Changelog will be created by the <code>release.yml</code> workflow which also promotes the container image.</li> <li>update Helm Chart, see below</li> <li>update OLM bundle, see helm-operator docs</li> </ol>"},{"location":"contributing/release/#release-helm-chart","title":"Release Helm Chart","text":"<ol> <li>Update <code>version</code> and/or <code>appVersion</code> in <code>Chart.yaml</code> and run <code>make helm.docs helm.update.appversion helm.test.update helm.test</code></li> <li>push to branch and open pr</li> <li>run <code>/ok-to-test-managed</code> commands for all cloud providers</li> <li>merge PR if everyhing is green</li> <li>CI picks up the new chart version and creates a new GitHub Release for it</li> <li>create/merge into release branch<ol> <li>on a <code>minor</code> release: create a new branch <code>release-x.y</code></li> <li>on a <code>patch</code> release: merge main into <code>release-x.y</code></li> </ol> </li> </ol>"},{"location":"contributing/release/#release-olm-bundle","title":"Release OLM Bundle","text":"<p>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.</p> <p>To create a bundle first increment the <code>VERSION</code> in the Makefile as described above. Then run the following commands in the root of the repository:</p> <pre><code># 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</code></pre> <p>Check the generated files in the <code>bundle/</code> 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.</p> <pre><code>git status\ngit add .\ngit commit -s -m \"chore: bump version xyz\"\ngit push\n</code></pre> <p>Once the PR is merged and the image build job on <code>main</code> 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: <pre><code>make attach-image-digests\nmake bundle-operatorhub\n</code></pre></p> <p>This command will add/commit/push and open pull requests in the respective repositories.</p>"},{"location":"contributing/roadmap/","title":"The road to external-secrets GA","text":"<p>The following external-secret custom resource APIs are considered stable:</p> <ul> <li><code>ExternalSecret</code></li> <li><code>ClusterExternalSecret</code></li> <li><code>SecretStore</code></li> <li><code>ClusterSecretStore</code></li> </ul> <p>These CRDs are currently at <code>v1beta1</code> and are considered production ready. Going forward, breaking changes to these APIs will be accompanied by a conversion mechanism.</p> <p>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.</p> <ul> <li>Conformance testing<ul> <li>\u2713 end to end testing with ArgoCD and Flux</li> <li>\u2713 end to end testing for all project maintained providers</li> </ul> </li> <li>API enhancements<ul> <li>consolidate provider fields</li> <li>\u2713 dataFrom key rewrites</li> <li>provider versioning strategy</li> <li>\u2713 pushing secrets to a provider</li> </ul> </li> <li>Documentation Improvements<ul> <li>Troubleshooting Guides</li> <li>\u2713 FAQ</li> <li>\u2713 review multi tenancy docs</li> <li>\u2713 security model for infosec teams</li> <li>\u2713 security best practices guide</li> <li>\u2713 provider specific guides</li> </ul> </li> <li>Observability<ul> <li>\u2713 Provide Grafana Dashboard and Prometheus alerts</li> <li>\u2713 add provider-level metrics</li> </ul> </li> <li>Pentest</li> <li>\u2713 SBOM</li> </ul>"},{"location":"examples/anchore-engine-credentials/","title":"Getting started","text":"<p>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</p>"},{"location":"examples/anchore-engine-credentials/#installing-with-helm","title":"Installing with Helm","text":"<p>There are several parts of the installation that require credentials these being :-</p> <p>ANCHORE_ADMIN_USERNAME ANCHORE_ADMIN_PASSWORD ANCHORE_DB_PASSWORD db-url db-user postgres-password</p> <p>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.</p>"},{"location":"examples/anchore-engine-credentials/#hashicorp-vault","title":"Hashicorp Vault","text":"<pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: anchore-access-credentials\nnamespace: security\nspec:\nrefreshInterval: 1m\nsecretStoreRef:\nname: vault-backend\nkind: ClusterSecretStore\ntarget:\nname: anchore-access-credentials\ntemplate:\n\ndata:\nANCHORE_ADMIN_USERNAME: >-\n{{ printf \"{{ .username | toString }}\" }}\nANCHORE_ADMIN_PASSWORD: >-\n{{ printf \"{{ .password | toString }}\" }}\nANCHORE_DB_PASSWORD: >-\n{{ printf \"{{ .dbPassword | toString }}\" }}\ndb-url: >-\n{{ printf \"{{ .dbUrl | toString }}\" }}\ndb-user: >-\n{{ printf \"{{ .dbUser | toString }}\" }}\npostgres-password: >-\n{{ printf \"{{ .postgresPassword | toString }}\" }}\n\ndata:\n- secretKey: password\nremoteRef:\nkey: anchore-engine\nproperty: ANCHORE_ADMIN_PASSWORD\n- secretKey: username\nremoteRef:\nkey: anchore-engine\nproperty: ANCHORE_ADMIN_USERNAME\n- secretKey: dbPassword\nremoteRef:\nkey: anchore-engine\nproperty: ANCHORE_DB_PASSWORD\n- secretKey: dbUrl\nremoteRef:\nkey: anchore-engine\nproperty: db-url\n- secretKey: dbUser\nremoteRef:\nkey: anchore-engine\nproperty: db-user\n- secretKey: postgresPassword\nremoteRef:\nkey: anchore-engine\nproperty: postgres-password\n</code></pre>"},{"location":"examples/anchore-engine-credentials/#aws-secrets-manager","title":"AWS Secrets Manager","text":"<pre><code>---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: anchore-access-credentials\nnamespace: ci\nspec:\nrefreshInterval: 1m\nsecretStoreRef:\nname: cluster-secrets-store\nkind: ClusterSecretStore\ntarget:\nname: anchore-access-credentials\ndataFrom:\n- extract:\nkey: service/anchore-engine/engineAccess\n</code></pre>"},{"location":"examples/bitwarden/","title":"Bitwarden support using webhook provider","text":"<p>Bitwarden is an integrated open source password management solution for individuals, teams, and business organizations.</p>"},{"location":"examples/bitwarden/#how-is-it-working","title":"How is it working ?","text":"<p>To make external-secret compatible with BitWarden, we need:</p> <ul> <li>External-Secret >= 0.8.0</li> <li>To use the Webhook Provider</li> <li>2 (Cluster)SecretStores</li> <li>BitWarden CLI image running <code>bw serve</code></li> </ul> <p>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.</p>"},{"location":"examples/bitwarden/#requirements","title":"Requirements","text":"<ul> <li>Bitwarden account (it works also with VaultWarden)</li> <li>A Kubernetes secret which contains your BitWarden Credentials</li> <li>You need a Docker image with BitWarden CLI installed. You could use <code>registry.gitlab.com/ttblt-oss/docker-bw:2023.1.0</code> or build your own.</li> </ul> <p>Here an example of Dockerfile use to build this image: <pre><code>FROM debian:sid\n\nENV BW_CLI_VERSION=2023.1.0\n\nRUN apt update && \\\napt install -y wget unzip && \\\nwget https://github.com/bitwarden/clients/releases/download/cli-v${BW_CLI_VERSION}/bw-linux-${BW_CLI_VERSION}.zip && \\\nunzip bw-linux-${BW_CLI_VERSION}.zip && \\\nchmod +x bw && \\\nmv bw /usr/local/bin/bw && \\\nrm -rfv *.zip\n\nCOPY entrypoint.sh /\n\nCMD [\"/entrypoint.sh\"]\n</code></pre></p> <p>And the content of <code>entrypoint.sh</code> <pre><code>#!/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</code></pre></p>"},{"location":"examples/bitwarden/#deploy-bitwarden-credentials","title":"Deploy Bitwarden Credentials","text":"<pre><code>apiVersion: v1\ndata:\nBW_HOST: ...\nBW_USERNAME: ...\nBW_PASSWORD: ....\nkind: Secret\nmetadata:\nname: bitwarden-cli\nnamespace: bitwarden\ntype: Opaque\n</code></pre>"},{"location":"examples/bitwarden/#deploy-bitwarden-cli-container","title":"Deploy Bitwarden CLI container","text":"<pre><code>apiVersion: apps/v1\nkind: Deployment\nmetadata:\nname: bitwarden-cli\nnamespace: bitwarden\nlabels:\napp.kubernetes.io/instance: bitwarden-cli\napp.kubernetes.io/name: bitwarden-cli\nspec:\nreplicas: 1\nstrategy:\ntype: Recreate\nselector:\nmatchLabels:\napp.kubernetes.io/name: bitwarden-cli\napp.kubernetes.io/instance: bitwarden-cli\ntemplate:\nmetadata:\nlabels:\napp.kubernetes.io/name: bitwarden-cli\napp.kubernetes.io/instance: bitwarden-cli\nspec:\ncontainers:\n- name: bitwarden-cli\nimage: YOUR_BITWARDEN_CLI_IMAGE\nimagePullPolicy: IfNotPresent\nenv:\n- name: BW_HOST\nvalueFrom:\nsecretKeyRef:\nname: bitwarden-cli\nkey: BW_HOST\n- name: BW_USER\nvalueFrom:\nsecretKeyRef:\nname: bitwarden-cli\nkey: BW_USERNAME\n- name: BW_PASSWORD\nvalueFrom:\nsecretKeyRef:\nname: bitwarden-cli\nkey: BW_PASSWORD\nports:\n- name: http\ncontainerPort: 8087\nprotocol: TCP\nlivenessProbe:\nexec:\ncommand:\n- wget\n- -q\n- http://127.0.0.1:8087/sync\n- --post-data=''\ninitialDelaySeconds: 20\nfailureThreshold: 3\ntimeoutSeconds: 1\nperiodSeconds: 120\nreadinessProbe:\ntcpSocket:\nport: 8087\ninitialDelaySeconds: 20\nfailureThreshold: 3\ntimeoutSeconds: 1\nperiodSeconds: 10\nstartupProbe:\ntcpSocket:\nport: 8087\ninitialDelaySeconds: 10\nfailureThreshold: 30\ntimeoutSeconds: 1\nperiodSeconds: 5\n---\napiVersion: v1\nkind: Service\nmetadata:\nname: bitwarden-cli\nnamespace: bitwarden\nlabels:\napp.kubernetes.io/instance: bitwarden-cli\napp.kubernetes.io/name: bitwarden-cli\nannotations:\nspec:\ntype: ClusterIP\nports:\n- port: 8087\ntargetPort: http\nprotocol: TCP\nname: http\nselector:\napp.kubernetes.io/name: bitwarden-cli\napp.kubernetes.io/instance: bitwarden-cli\n---\nkind: NetworkPolicy\napiVersion: networking.k8s.io/v1\nmetadata:\nnamespace: bitwarden\nname: external-secret-2-bw-cli\nspec:\npodSelector:\nmatchLabels:\napp.kubernetes.io/instance: bitwarden-cli\napp.kubernetes.io/name: bitwarden-cli\ningress:\n- from:\n- podSelector:\nmatchLabels:\napp.kubernetes.io/instance: external-secrets\napp.kubernetes.io/name: external-secrets\n</code></pre> <p>NOTE: Deploying a network policy is recommended since, there is no authentication to query the BitWarden CLI, which means that your secrets are exposed.</p> <p>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)</p>"},{"location":"examples/bitwarden/#deploy-clustersecretstore-or-secretstore","title":"Deploy ClusterSecretStore (Or SecretStore)","text":"<p>Here the two ClusterSecretStore to deploy</p> <pre><code>---\napiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\nname: bitwarden-login\nspec:\nprovider:\nwebhook:\nurl: \"http://bitwarden-cli:8087/object/item/{{ .remoteRef.key }}\"\nheaders:\nContent-Type: application/json\nresult:\njsonPath: \"$.data.login.{{ .remoteRef.property }}\"\n---\napiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\nname: bitwarden-fields\nspec:\nprovider:\nwebhook:\nurl: \"http://bitwarden-cli:8087/object/item/{{ .remoteRef.key }}\"\nresult:\njsonPath: \"$.data.fields[?@.name==\\\"{{ .remoteRef.property }}\\\"].value\"\n</code></pre>"},{"location":"examples/bitwarden/#how-to-use-it","title":"How to use it ?","text":"<ul> <li>If you need the <code>username</code> or the <code>password</code> of a secret, you have to use <code>bitwarden-login</code></li> <li>If you need a custom field of a secret, you have to use <code>bitwarden-fields</code></li> <li>The <code>key</code> is the ID of a secret, which can be find in the URL with the <code>itemId</code> value: <code>https://myvault.com/#/vault?itemId=........-....-....-....-............</code></li> <li>The <code>property</code> is the name of the field:</li> <li><code>username</code> for the username of a secret (<code>bitwarden-login</code> SecretStore)</li> <li><code>password</code> for the password of a secret (<code>bitwarden-login</code> SecretStore)</li> <li><code>name_of_the_custom_field</code> for any custom field (<code>bitwarden-fields</code> SecretStore)</li> </ul> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: my-db-secrets\nnamespace: default\nspec:\ntarget:\nname: my-db-secrets\ndeletionPolicy: Delete\ntemplate:\ntype: Opaque\ndata:\nusername: |-\n{{ .username }}\npassword: |-\n{{ .password }}\npostgres-password: |-\n{{ .postgres_password }}\npostgres-replication-password: |-\n{{ .postgres_replication_password }}\ndb_url: |-\npostgresql://{{ .username }}:{{ .password }}@my-postgresql:5432/mydb\ndata:\n- secretKey: username\nsourceRef:\nstoreRef:\nname: bitwarden-login\nkind: ClusterSecretStore # or SecretStore\nremoteRef:\nkey: aaaabbbb-cccc-dddd-eeee-000011112222\nproperty: username\n- secretKey: password\nsourceRef:\nstoreRef:\nname: bitwarden-login\nkind: ClusterSecretStore # or SecretStore\nremoteRef:\nkey: aaaabbbb-cccc-dddd-eeee-000011112222\nproperty: password\n- secretKey: postgres_password\nsourceRef:\nstoreRef:\nname: bitwarden-fields\nkind: ClusterSecretStore # or SecretStore\nremoteRef:\nkey: aaaabbbb-cccc-dddd-eeee-000011112222\nproperty: admin-password\n- secretKey: postgres_replication_password\nsourceRef:\nstoreRef:\nname: bitwarden-fields\nkind: ClusterSecretStore # or SecretStore\nremoteRef:\nkey: aaaabbbb-cccc-dddd-eeee-000011112222\nproperty: postgres-replication-password\n</code></pre>"},{"location":"examples/gitops-using-fluxcd/","title":"GitOps using FluxCD (v2)","text":"<p>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.</p>"},{"location":"examples/gitops-using-fluxcd/#advantages","title":"Advantages","text":"<p>This approach has several advantages as follows:</p> <ul> <li>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</li> <li>Reduce security risks, because credentials can be easily obtained, so temptation to store them locally is reduced.</li> <li>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.</li> <li>Automation by default oh, come on!</li> </ul>"},{"location":"examples/gitops-using-fluxcd/#the-approach","title":"The approach","text":"<p>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.</p> <p>External Secrets can be deployed using Helm as explained here. The deployment includes the CRDs if enabled on the <code>values.yaml</code>, but after this, you need to deploy some <code>SecretStore</code> to start getting credentials from your secrets manager with External Secrets.</p> <p>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.</p>"},{"location":"examples/gitops-using-fluxcd/#the-problem","title":"The problem","text":"<p>This can sound easy, but External Secrets is deployed using Helm, which is managed by the HelmController, and your custom resources, for example a <code>ClusterSecretStore</code> and the related <code>Secret</code>, are often deployed using a <code>kustomization.yaml</code>, which is deployed by the KustomizeController.</p> <p>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 (<code>SecretStore</code>,<code>ClusterSecretStore</code>...) tries to be deployed before than the CRDs needed to recognize them.</p>"},{"location":"examples/gitops-using-fluxcd/#the-solution","title":"The solution","text":"<p>Let's see the conditions to start working on a solution:</p> <ul> <li>The External Secrets operator is deployed with Helm, and admits disabling the CRDs deployment</li> <li>The race condition only affects the deployment of <code>CustomResourceDefinition</code> and the CRs needed later</li> <li>CRDs can be deployed directly from the Git repository of the project using a Flux <code>Kustomization</code></li> <li>Required CRs can be deployed using a Flux <code>Kustomization</code> too, allowing dependency between CRDs and CRs</li> <li>All previous manifests can be applied with a Kubernetes <code>kustomization</code></li> </ul>"},{"location":"examples/gitops-using-fluxcd/#create-the-main-kustomization","title":"Create the main kustomization","text":"<p>To have a better view of things needed later, the first manifest to be created is the <code>kustomization.yaml</code></p> <pre><code>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</code></pre>"},{"location":"examples/gitops-using-fluxcd/#create-the-secret","title":"Create the secret","text":"<p>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 <code>secret-token.yaml</code> is show as an example:</p> <pre><code># The namespace.yaml first\napiVersion: v1\nkind: Namespace\nmetadata:\nname: external-secrets\n</code></pre> <pre><code>apiVersion: v1\nkind: Secret\nmetadata:\nname: vault-token-global\nnamespace: external-secrets\nstringData:\n# This token must be patched by overlays. Not here for security reasons\ntoken: change-me-placeholder\n</code></pre>"},{"location":"examples/gitops-using-fluxcd/#creating-the-references-to-repositories","title":"Creating the references to repositories","text":"<p>Create a manifest called <code>repositories.yaml</code> to store the references to external repositories for Flux</p> <pre><code># Reference to Helm repository\napiVersion: source.toolkit.fluxcd.io/v1beta1\nkind: HelmRepository\nmetadata:\nname: external-secrets\nnamespace: flux-system\nspec:\ninterval: 10m\nurl: https://charts.external-secrets.io\n---\napiVersion: source.toolkit.fluxcd.io/v1beta1\nkind: GitRepository\nmetadata:\nname: external-secrets\nnamespace: flux-system\nspec:\ninterval: 10m\nref:\nbranch: main\nurl: http://github.com/external-secrets/external-secrets\n</code></pre>"},{"location":"examples/gitops-using-fluxcd/#deploy-the-crds","title":"Deploy the CRDs","text":"<p>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 <code>deployment-crds.yaml</code> as follows:</p> <pre><code>---\napiVersion: kustomize.toolkit.fluxcd.io/v1beta2\nkind: Kustomization\nmetadata:\nname: external-secrets-crds\nnamespace: flux-system\nspec:\ninterval: 10m\npath: ./deploy/crds\nprune: true\nsourceRef:\nkind: GitRepository\nname: external-secrets\n</code></pre>"},{"location":"examples/gitops-using-fluxcd/#deploy-the-operator","title":"Deploy the operator","text":"<p>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 <code>values</code> of the manifest called <code>deployment.yaml</code>, as follows:</p> <pre><code># 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:\nname: external-secrets\nnamespace: 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\nreleaseName: external-secrets\ntargetNamespace: external-secrets\ninterval: 10m\nchart:\nspec:\nchart: external-secrets\nversion: 0.3.9\nsourceRef:\nkind: HelmRepository\nname: external-secrets\nnamespace: flux-system\nvalues:\ninstallCRDs: false\n\n# Ref: https://fluxcd.io/docs/components/helm/api/#helm.toolkit.fluxcd.io/v2beta1.Install\ninstall:\ncreateNamespace: true\n</code></pre>"},{"location":"examples/gitops-using-fluxcd/#deploy-the-crs","title":"Deploy the CRs","text":"<p>Now, be ready for the arcane magic. Create a Kustomization manifest called <code>deployment-crs.yaml</code> with the following content:</p> <pre><code>---\napiVersion: kustomize.toolkit.fluxcd.io/v1beta2\nkind: Kustomization\nmetadata:\nname: external-secrets-crs\nnamespace: flux-system\nspec:\ndependsOn:\n- name: external-secrets-crds\ninterval: 10m\npath: ./infrastructure/external-secrets/crs\nprune: true\nsourceRef:\nkind: GitRepository\nname: flux-system\n</code></pre> <p>There are several interesting details to see here, that finally solves the race condition:</p> <ol> <li>First one is the field <code>dependsOn</code>, which points to a previous Kustomization called <code>external-secrets-crds</code>. This dependency forces this deployment to wait for the other to be ready, before start being deployed.</li> <li>The reference to the place where to find the CRs <pre><code>path: ./infrastructure/external-secrets/crs\nsourceRef:\nkind: GitRepository\nname: flux-system\n</code></pre> Custom Resources will be searched in the relative path <code>./infrastructure/external-secrets/crs</code> of the GitRepository called <code>flux-system</code>, 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 <code>crs</code></li> </ol> <p>Of course, allocate inside the mentioned path <code>./infrastructure/external-secrets/crs</code>, all the desired CRs to be deployed, for example, a manifest <code>clusterSecretStore.yaml</code> to reach your Hashicorp Vault as follows:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\nname: vault-backend-global\nspec:\nprovider:\nvault:\nserver: \"https://vault.your-domain.com\"\npath: secret\nversion: v2\nauth:\n# points to a secret that contains a vault token\n# https://www.vaultproject.io/docs/auth/token\ntokenSecretRef:\nname: \"vault-token-global\"\nkey: \"token\"\nnamespace: external-secrets\n</code></pre>"},{"location":"examples/gitops-using-fluxcd/#results","title":"Results","text":"<p>At the end, the required files tree is shown in the following picture:</p> <p></p>"},{"location":"examples/jenkins-kubernetes-credentials/","title":"Getting started","text":"<p>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.</p>"},{"location":"examples/jenkins-kubernetes-credentials/#examples","title":"Examples","text":"<p>The Jenkins credentials plugin uses labels and annotations on a kubernetes secret to create a Jenkins credential.</p> <p>The different types of Jenkins credentials that can be created are SecretText, privateSSHKey, UsernamePassword.</p>"},{"location":"examples/jenkins-kubernetes-credentials/#secrettext","title":"SecretText","text":"<p>Here are some examples of SecretText with the Hashicorp Vault and AWS External Secrets providers:</p>"},{"location":"examples/jenkins-kubernetes-credentials/#hashicorp-vault","title":"Hashicorp Vault","text":"<pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: sonarqube-api-token\nnamespace: ci\nspec:\nrefreshInterval: 1m\nsecretStoreRef:\nname: vault-backend\nkind: ClusterSecretStore\ntarget:\nname: sonarqube-api-token\ntemplate:\nmetadata:\nlabels:\n\"jenkins.io/credentials-type\": \"secretText\"\nannotations:\n\"jenkins.io/credentials-description\": \"sonarqube api token\"\ndata:\ntext: >-\n{{ printf \"{{ .password | toString }}\" }}\ndata:\n- secretKey: password\nremoteRef:\nkey: jenkins-credentials\nproperty: sonarqube-api-token\n</code></pre>"},{"location":"examples/jenkins-kubernetes-credentials/#aws-secrets-manager","title":"AWS Secrets Manager","text":"<pre><code>---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: sonarqube-api-token\nnamespace: ci\nspec:\nrefreshInterval: 1m\nsecretStoreRef:\nname: cluster-secrets-store\nkind: ClusterSecretStore\ntarget:\nname: sonarqube-api-token\ntemplate:\nmetadata:\nlabels:\n\"jenkins.io/credentials-type\": \"secretText\"\nannotations:\n\"jenkins.io/credentials-description\": \"Sonar API token\"\ndata:\n- secretKey: text\nremoteRef:\nkey: service/sonarqube/apiToken\n</code></pre>"},{"location":"examples/jenkins-kubernetes-credentials/#usernamepassword","title":"UsernamePassword","text":"<p>Here are some examples of UsernamePassword credentials with the Hashicorp Vault and AWS External Secrets providers:</p>"},{"location":"examples/jenkins-kubernetes-credentials/#hashicorp-vault_1","title":"Hashicorp Vault","text":"<pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: harbor-chart-robot\nnamespace: ci\nspec:\nrefreshInterval: 1m\nsecretStoreRef:\nname: vault-backend\nkind: ClusterSecretStore\ntarget:\nname: harbor-chart-robot\ntemplate:\nmetadata:\nlabels:\n\"jenkins.io/credentials-type\": \"usernamePassword\"\nannotations:\n\"jenkins.io/credentials-description\": \"harbor chart robot\"\ndata:\nusername: >-\n{{ printf \"{{ .username | toString }}\" }}\npassword: >-\n{{ printf \"{{ .password | toString }}\" }}\ndata:\n- secretKey: username\nremoteRef:\nkey: my-kv\nproperty: harbor-chart-robot-username\n- secretKey: password\nremoteRef:\nkey: my-kv\nproperty: harbor-chart-robot-token\n</code></pre>"},{"location":"examples/jenkins-kubernetes-credentials/#aws-secrets-manager_1","title":"AWS Secrets Manager","text":"<pre><code>---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: harbor-chart-robot\nnamespace: ci\nspec:\nrefreshInterval: 1m\nsecretStoreRef:\nname: cluster-secrets-store\nkind: ClusterSecretStore\ntarget:\nname: harbor-chart-robot\ntemplate:\nmetadata:\nlabels:\n\"jenkins.io/credentials-type\": \"usernamePassword\"\nannotations:\n\"jenkins.io/credentials-description\": \"harbor chart robot access\"\ndata:\n- secretKey: password\nremoteRef:\nkey: service/harbor/chartRobot\nproperty: password\n- secretKey: username\nremoteRef:\nkey: service/harbor/chartRobot\nproperty: username\n</code></pre>"},{"location":"examples/jenkins-kubernetes-credentials/#basicsshuserprivatekey","title":"basicSSHUserPrivateKey","text":"<p>Here are some examples of basicSSHUserPrivateKey credentials with the Hashicorp Vault and AWS External Secrets providers:</p>"},{"location":"examples/jenkins-kubernetes-credentials/#hashicorp-vault_2","title":"Hashicorp Vault","text":"<pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: github-ssh-access\nnamespace: ci\nspec:\nrefreshInterval: 1m\nsecretStoreRef:\nname: vault-backend\nkind: ClusterSecretStore\ntarget:\nname: github-ssh-access\ntemplate:\nmetadata:\nlabels:\n\"jenkins.io/credentials-type\": \"basicSSHUserPrivateKey\"\nannotations:\n\"jenkins.io/credentials-description\": \"github-ssh-access key\"\ndata:\nusername: >-\n{{ printf \"{{ .username | toString }}\" }}\nprivateKey: >-\n{{ printf \"{{ .privateKey | toString }}\" }}\ndata:\n- secretKey: username\nremoteRef:\nkey: my-kv\nproperty: github-ssh-access-username\n- secretKey: privateKey\nremoteRef:\nkey: my-kv\nproperty: github-ssh-access-private-key\n</code></pre>"},{"location":"examples/jenkins-kubernetes-credentials/#aws-secrets-manager_2","title":"AWS Secrets Manager","text":"<pre><code>---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: github-ssh-access\nnamespace: ci\nspec:\nrefreshInterval: 1m\nsecretStoreRef:\nname: cluster-parameter-store\nkind: ClusterSecretStore\ntarget:\nname: github-ssh-access\ntemplate:\nmetadata:\nlabels:\n\"jenkins.io/credentials-type\": \"basicSSHUserPrivateKey\"\nannotations:\n\"jenkins.io/credentials-description\": \"github-ssh-access key\"\ndata:\n- secretKey: username\nremoteRef:\nkey: /service/github/sshUserPrivateKeyUserName\n- secretKey: privateKey\nremoteRef:\nkey: /service/github/sshUserPrivateKey\n</code></pre>"},{"location":"guides/all-keys-one-secret/","title":"All Keys, One Secret","text":"<p>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).</p> <p>Please follow the authentication and SecretStore steps of the Google Cloud Secrets Manager guide to setup access to your google cloud account first.</p> <p>Then create a secret in Google Cloud Secret Manager that contains a JSON string with multiple key values like this:</p> <p></p> <p>Let's call this secret all-keys-example-secret on Google Cloud.</p>"},{"location":"guides/all-keys-one-secret/#creating-datafrom-external-secret","title":"Creating dataFrom external secret","text":"<p>Now, when creating our ExternalSecret resource, instead of using the data field, we use the dataFrom field:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: example\nspec:\nrefreshInterval: 1h # rate SecretManager pulls GCPSM\nsecretStoreRef:\nkind: SecretStore\nname: example # name of the SecretStore (or kind specified)\ntarget:\nname: secret-to-be-created # name of the k8s Secret to be created\ncreationPolicy: Owner\ndataFrom:\n- extract:\nkey: all-keys-example-secret # name of the GCPSM secret\n</code></pre> <p>To check both values we can run:</p> <pre><code>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</code></pre>"},{"location":"guides/common-k8s-secret-types/","title":"A few common k8s secret types examples","text":"<p>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.</p> <p>Please follow the authentication and SecretStore steps of the Google Cloud Secrets Manager guide to setup access to your google cloud account first.</p>"},{"location":"guides/common-k8s-secret-types/#dockerconfigjson-example","title":"Dockerconfigjson example","text":"<p>First create a secret in Google Cloud Secrets Manager containing your docker config:</p> <p></p> <p>Let's call this secret docker-config-example on Google Cloud.</p> <p>Then create a ExternalSecret resource taking advantage of templating to populate the generated secret:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: dk-cfg-example\nspec:\nrefreshInterval: 1h\nsecretStoreRef:\nname: example\nkind: SecretStore\ntarget:\ntemplate:\ntype: kubernetes.io/dockerconfigjson\ndata:\n.dockerconfigjson: \"{{ .mysecret | toString }}\"\nname: secret-to-be-created\ncreationPolicy: Owner\ndata:\n- secretKey: mysecret\nremoteRef:\nkey: docker-config-example\n</code></pre> <p>For Helm users: since Helm interprets the template above, the ExternalSecret resource can be written this way:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: dk-cfg-example\nspec:\nrefreshInterval: 1h\nsecretStoreRef:\nname: example\nkind: SecretStore\ntarget:\ntemplate:\ntype: kubernetes.io/dockerconfigjson\nengineVersion: v2\ndata:\n.dockerconfigjson: \"{{ `{{ .mysecret }}` }}\"\nname: secret-to-be-created\ncreationPolicy: Owner\ndata:\n- secretKey: mysecret\nremoteRef:\nkey: docker-config-example\n</code></pre> <p>For more information, please see this issue</p> <p>This will generate a valid dockerconfigjson secret for you to use!</p> <p>You can get the final value with:</p> <pre><code>kubectl get secret secret-to-be-created -n <namespace> -o jsonpath=\"{.data\\.dockerconfigjson}\" | base64 -d\n</code></pre>"},{"location":"guides/common-k8s-secret-types/#tls-cert-example","title":"TLS Cert example","text":"<p>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.</p> <pre><code>openssl pkcs12 -export -out certificate.p12 -inkey privkey.pem -in cert.pem\n</code></pre> <p>With a certificate.p12 you can upload it to Google Cloud Secrets Manager:</p> <p></p> <p>And now you can create an ExternalSecret that gets it. You will end up with a k8s secret of type tls with pem values.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: template-tls-example\nspec:\nrefreshInterval: 1h\nsecretStoreRef:\nname: example\nkind: SecretStore\ntarget:\nname: secret-to-be-created\n# this is how the Kind=Secret will look like\ntemplate:\ntype: kubernetes.io/tls\ndata:\ntls.crt: \"{{ .mysecret | pkcs12cert | pemCertificate }}\"\ntls.key: \"{{ .mysecret | pkcs12key | pemPrivateKey }}\"\n\ndata:\n# this is a pkcs12 archive that contains\n# a cert and a private key\n- secretKey: mysecret\nremoteRef:\nkey: ssl-certificate-p12-example\n</code></pre> <p>You can get their values with:</p> <pre><code>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</code></pre>"},{"location":"guides/common-k8s-secret-types/#ssh-auth-example","title":"SSH Auth example","text":"<p>Add the ssh privkey to a new Google Cloud Secrets Manager secret:</p> <p></p> <p>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.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: ssh-auth-example\nspec:\nrefreshInterval: 1h\nsecretStoreRef:\nname: example\nkind: SecretStore\ntarget:\nname: secret-to-be-created\ntemplate:\ntype: kubernetes.io/ssh-auth\ndata:\nssh-privatekey: \"{{ .mysecret | toString }}\"\nname: secret-to-be-created\ncreationPolicy: Owner\ndata:\n- secretKey: mysecret\nremoteRef:\nkey: ssh-priv-key-example\n</code></pre> <p>You can get the privkey value with:</p> <pre><code>kubectl get secret secret-to-be-created -n <namespace> -o jsonpath=\"{.data.ssh-privatekey}\" | base64 -d\n</code></pre>"},{"location":"guides/common-k8s-secret-types/#more-examples","title":"More examples","text":"<p>We need more examples here</p> <p>Feel free to contribute with our docs and add more examples here!</p>"},{"location":"guides/controller-class/","title":"Controller Classes","text":"<p>NOTE: this feature is experimental and not highly tested</p> <p>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.</p>"},{"location":"guides/controller-class/#setting-up-controller-class","title":"Setting up Controller Class","text":"<p>In order to deploy the controller with a specific class, install the helm charts specifying the controller class, and create a <code>SecretStore</code> with the appropriate <code>spec.controller</code> values: <pre><code>helm install custom-external-secrets external-secrets/external-secrets --set controllerClass=custom\n</code></pre> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: controller-custom-example\nspec:\n#define the controller label to the matching value of the deployment\ncontroller: custom\n#configure provider the same way\nprovider:\nvault:\nserver: \"http://vault.default:8200\"\npath: \"secret\"\nversion: \"v2\"\nauth:\nkubernetes:\nmountPath: \"kubernetes\"\nrole: \"demo-role\"\n</code></pre></p> <p>Now, any <code>ExternalSecret</code> bound to this secret store will be evaluated by the operator with the controllerClass custom.</p> <p>Note: Any SecretStore without <code>spec.controller</code> set will be considered as valid by any operator, regardless of their respective controllerClasses.</p>"},{"location":"guides/datafrom-rewrite/","title":"Rewriting Keys in DataFrom","text":"<p>When calling out an ExternalSecret with <code>dataFrom.extract</code> or <code>dataFrom.find</code>, 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.</p> <p>In order to do so, it is possible to define a set of rewrite operations using <code>dataFrom.rewrite</code>. These operations can be stacked, hence allowing complex manipulations of the secret keys.</p> <p>Rewrite operations are all applied before <code>ConversionStrategy</code> is applied.</p>"},{"location":"guides/datafrom-rewrite/#methods","title":"Methods","text":""},{"location":"guides/datafrom-rewrite/#regexp","title":"Regexp","text":"<p>This method implements rewriting through the use of regular expressions. It needs a <code>source</code> and a <code>target</code> field. The source field is where the definition of the matching regular expression goes, where the <code>target</code> field is where the replacing expression goes.</p> <p>Some considerations about the implementation of Regexp Rewrite:</p> <ol> <li>The input of a subsequent rewrite operation are the outputs of the previous rewrite.</li> <li>If a given set of keys do not match any Rewrite operation, there will be no error. Rather, the original keys will be used.</li> <li>If a <code>source</code> is not a compilable <code>regexp</code> expression, an error will be produced and the external secret goes into a error state.</li> </ol>"},{"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":"<p>The following ExternalSecret: <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: example\nspec:\nrefreshInterval: 1h\nsecretStoreRef:\nkind: SecretStore\nname: backend\ntarget:\nname: secret-to-be-created\ndataFrom:\n- find:\npath: path/to/my\nname: regexp: secrets\nrewrite:\n- regexp:\nsource: \"path/to/my/secrets/(.*)\"\ntarget: \"$1\"\n</code></pre> Will get all the secrets matching <code>path/to/my/secrets/*</code> and then rewrite them by removing the common path away.</p> <p>In this example, if we had the following secrets available in the provider: <pre><code>path/to/my/secrets/username\npath/to/my/secrets/password\n</code></pre> the output kubernetes secret would be: <pre><code>apiVersion: v1\nkind: Secret\ntype: Opaque\ndata:\nusername: ...\npassword: ...\n</code></pre></p>"},{"location":"guides/datafrom-rewrite/#avoiding-key-collisions","title":"Avoiding key collisions","text":"<p>The following ExternalSecret: <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: example\nspec:\nrefreshInterval: 1h\nsecretStoreRef:\nkind: SecretStore\nname: backend\ntarget:\nname: secret-to-be-created\ndataFrom:\n- extract:\nkey: my-secrets-dev\nrewrite:\n- regexp:\nsource: \"(.*)\"\ntarget: \"dev-$1\" - extract:\nkey: my-secrets-prod\nrewrite:\n- regexp:\nsource: \"(.*)\"\ntarget: \"prod-$1\"\n</code></pre> 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: <pre><code>{\n\"my-secrets-dev\": {\n\"password\": \"bar\",\n},\n\"my-secrets-prod\": {\n\"password\": \"safebar\",\n}\n}\n</code></pre> the output kubernetes secret would be: <pre><code>apiVersion: v1\nkind: Secret\ntype: Opaque\ndata:\ndev_password: YmFy #bar\nprod_password: c2FmZWJhcg== #safebar\n</code></pre></p>"},{"location":"guides/datafrom-rewrite/#remove-invalid-characters","title":"Remove invalid characters","text":"<p>The following ExternalSecret: <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: example\nspec:\nrefreshInterval: 1h\nsecretStoreRef:\nkind: SecretStore\nname: backend\ntarget:\nname: secret-to-be-created\ndataFrom:\n- extract:\nkey: development\nrewrite:\n- regexp:\nsource: \"[^a-zA-Z0-9 -]\"\ntarget: \"_\"\n</code></pre> Will remove invalid characters from the secret key. In this example, if we had the following secrets available in the provider: <pre><code>{\n\"development\": {\n\"foo/bar\": \"1111\",\n\"foo$baz\": \"2222\"\n}\n}\n</code></pre> the output kubernetes secret would be: <pre><code>apiVersion: v1\nkind: Secret\ntype: Opaque\ndata:\nfoo_bar: MTExMQ== #1111\nfoo_baz: MjIyMg== #2222\n</code></pre></p>"},{"location":"guides/datafrom-rewrite/#limitations","title":"Limitations","text":"<p>Regexp Rewrite is based on golang <code>regexp</code>, which in turns implements <code>RE2</code> regexp language. There a a series of known limitations to this implementation, such as:</p> <ul> <li>Lack of ability to do lookaheads or lookbehinds;</li> <li>Lack of negation expressions;</li> <li>Lack of support for conditional branches;</li> <li>Lack of support for possessive repetitions.</li> </ul> <p>A list of compatibility and known limitations considering other commonly used regexp frameworks (such as PCRE and PERL) are listed here.</p>"},{"location":"guides/decoding-strategy/","title":"Decoding Strategies","text":"<p>The External Secrets Operator has the feature to allow multiple decoding strategies during an object generation.</p> <p>The <code>decodingStrategy</code> field allows the user to set the following Decoding Strategies based on their needs. <code>decodingStrategy</code> can be placed under <code>spec.data.remoteRef</code>, <code>spec.dataFrom.extract</code> or <code>spec.dataFrom.find</code>. It will configure the decoding strategy for that specific operation, leaving others with the default behavior if not set.</p>"},{"location":"guides/decoding-strategy/#none-default","title":"None (default)","text":"<p>ESO will not try to decode the secret value.</p>"},{"location":"guides/decoding-strategy/#base64","title":"Base64","text":"<p>ESO will try to decode the secret value using base64 method. If the decoding fails, an error is produced.</p>"},{"location":"guides/decoding-strategy/#base64url","title":"Base64URL","text":"<p>ESO will try to decode the secret value using base64url method. If the decoding fails, an error is produced.</p>"},{"location":"guides/decoding-strategy/#auto","title":"Auto","text":"<p>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.</p>"},{"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":"<p>Given that we have the given secret information: <pre><code>{\n \"name\": \"Gustavo\",\n \"surname\": \"Fring\",\n \"address\":\"aGFwcHkgc3RyZWV0\",\n}\n</code></pre> if we apply the following dataFrom: <pre><code>spec:\n dataFrom:\n - extract:\n key: my-secret\n decodingStrategy: Auto\n</code></pre> It will render the following Kubernetes Secret: <pre><code>data:\n name: R3VzdGF2bw== #Gustavo\n surname: RnJpbmc= #Fring\n address: aGFwcHkgc3RyZWV0 #happy street\n</code></pre></p>"},{"location":"guides/decoding-strategy/#limitations","title":"Limitations","text":"<p>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 <code>123456</code> or some specially crafted string values such as <code>happy/street</code>. </p> <p>Note</p> <p>If you are using <code>decodeStrategy: Auto</code> and start to see ESO pulling completely wrong secret values into your kubernetes secret, consider changing it to <code>None</code> to investigate it.</p>"},{"location":"guides/disable-cluster-features/","title":"Deploying without ClusterSecretStore and ClusterExternalSecret","text":"<p>When deploying External Secrets Operator via Helm chart, the default configuration will install <code>ClusterSecretStore</code> and <code>ClusterExternalSecret</code> CRDs and these objects will be processed by the operator.</p> <p>In order to disable both or one of these features, it is necessary to configure the <code>crds.*</code> Helm value, as well as the <code>process*</code> Helm value, as these 2 values are connected.</p> <p>If you would like to install the operator without <code>ClusterSecretStore</code> and <code>ClusterExternalSecret</code> management, you will have to :</p> <ul> <li>set <code>crds.createClusterExternalSecret</code> to false</li> <li>set <code>crds.createClusterSecretStore</code> to false</li> <li>set <code>processClusterExternalSecret</code> to false</li> <li>set <code>processClusterStore</code> to false</li> </ul> <p>Example:</p> <pre><code>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</code></pre>"},{"location":"guides/generator/","title":"Generators","text":"<p>Generators allow you to generate values. They are used through a ExternalSecret <code>spec.DataFrom</code>. They are referenced from a custom resource using <code>sourceRef.generatorRef</code>.</p> <p>If the External Secret should be refreshed via <code>spec.refreshInterval</code> the generator produces a map of values with the <code>generator.spec</code> as input. The generator does not keep track of the produced values. Every invocation produces a new set of values.</p> <p>These values can be used with the other features like <code>rewrite</code> or <code>template</code>. I.e. you can modify, encode, decode, pack the values as needed.</p>"},{"location":"guides/generator/#reference-custom-resource","title":"Reference Custom Resource","text":"<p>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 <code>ExternalSecrets</code> or <code>spec.dataFrom[]</code> entries.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: \"ecr-token\"\nspec:\nrefreshInterval: \"30m\"\ntarget:\nname: ecr-token\ndataFrom:\n- sourceRef:\ngeneratorRef:\napiVersion: generators.external-secrets.io/v1alpha1\nkind: ECRAuthorizationToken\nname: \"my-ecr\"\n</code></pre>"},{"location":"guides/getallsecrets/","title":"Fetching information from multiple secrets","text":"<p>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 <code>dataFrom.find</code> option.</p> <p>Note</p> <p>The secret's contents as defined in the provider are going to be stored in the kubernetes secret as a single key. Currently, it 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, <code>decodingStrategy: Auto</code> would not decode it)</p>"},{"location":"guides/getallsecrets/#fetching-secrets-matching-a-given-name-pattern","title":"Fetching secrets matching a given name pattern","text":"<p>To fetch multiple secrets matching a name pattern from a common SecretStore you can apply the following manifest: <pre><code>apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret\nmetadata:\nname: find-by-tags\nspec:\nrefreshInterval: 1h\nsecretStoreRef:\nname: secretstore-sample\nkind: SecretStore\ntarget:\nname: secret-to-be-created\ndataFrom:\n- find:\nname:\nregexp: \"key\"\n</code></pre></p> <p>Suppose we contain secrets <code>/path/key1</code>, <code>key2/path</code>, and <code>path/to/keyring</code> with their respective values. The above YAML will produce the following kubernetes Secret:</p> <pre><code>_path_key1: Cg==\nkey2_path: Cg==\npath_to_keyring: Cg==\n</code></pre>"},{"location":"guides/getallsecrets/#fetching-secrets-matching-a-set-of-metadata-tags","title":"Fetching secrets matching a set of metadata tags","text":"<p>To fetch multiple secrets matching a name pattern from a common SecretStore you can apply the following manifest: <pre><code>apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret\nmetadata:\nname: find-by-tags\nspec:\nrefreshInterval: 1h\nsecretStoreRef:\nname: secretstore-sample\nkind: SecretStore\ntarget:\nname: secret-to-be-created\ndataFrom:\n- find:\ntags:\nenvironment: \"prod\"\napplication: \"app-name\"\n</code></pre> This will match any secrets containing all of the metadata labels in the <code>tags</code> parameter. At least one tag must be provided in order to allow finding secrets by metadata tags.</p>"},{"location":"guides/getallsecrets/#searching-only-in-a-given-path","title":"Searching only in a given path","text":"<p>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 <code>find.path</code> to filter out these secrets into only this path, instead of the root path.</p>"},{"location":"guides/getallsecrets/#avoiding-name-conflicts","title":"Avoiding name conflicts","text":"<p>By default, kubernetes Secrets accepts only a given range of characters. <code>Find</code> operations will automatically replace any not allowed character with a <code>_</code>. So if we have a given secret <code>a_c</code> and <code>a/c</code> would lead to a naming conflict.</p> <p>If you happen to have a case where a conflict is happening, you can use the <code>rewrite</code> block to apply a regexp on one of the find operations (for more information please refer to Rewriting Keys from DataFrom).</p> <p>You can also set <code>dataFrom.find.conversionStrategy: Unicode</code> to reduce the collistion probability. When using <code>Unicode</code>, any invalid character will be replaced by its unicode, in the form of <code>_UXXXX_</code>. In this case, the available kubernetes keys would be <code>a_c</code> and <code>a_U2215_c</code>, hence avoiding most of possible conflicts.</p> <p>PRs welcome</p> <p>Some providers might not have the implementation needed for fetching multiple secrets. If that's your case, please feel free to contribute!</p>"},{"location":"guides/introduction/","title":"Guides","text":"<p>The following guides demonstrate use-cases and provide examples of how to use the API. Please pick one of the following guides:</p> <ul> <li>Multi-Tenancy Design Considerations</li> <li>Find multiple secrets & Extract Secret values</li> <li>Advanced Templating</li> <li>Generating Passwords using generators</li> <li>Ownership and Deletion Policy</li> <li>Key Rewriting</li> <li>Controller Class</li> <li>Decoding Strategy</li> <li>v1beta1 Migration</li> <li>Deploying image from main</li> <li>Deploying without cluster features</li> </ul>"},{"location":"guides/multi-tenancy/","title":"Multi Tenancy","text":"<p>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.</p> <p>For a multi-tenant deployment you should first examine your organizational structure:</p> <ol> <li>what roles (i.e. Application Developers, Cluster Admins, ...) do you have in your organization,</li> <li>what responsibilities do they have and</li> <li>how does that map to Kubernetes RBAC roles.</li> </ol> <p>Further, you should examine how your external API provider manages access control for your secrets. Can you limit access by secret names (e.g. <code>db/dev/*</code>)? Or only on a bucket level? Please keep in mind that not all external APIs provide fine-grained access management for secrets.</p> <p>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.</p>"},{"location":"guides/multi-tenancy/#shared-clustersecretstore","title":"Shared ClusterSecretStore","text":"<p>A Cluster Administrator deploys a <code>ClusterSecretStore</code> (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 <code>ExternalSecret</code> 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).</p> <p>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.</p>"},{"location":"guides/multi-tenancy/#managed-secretstore-per-namespace","title":"Managed SecretStore per Namespace","text":"<p>Cluster Administrators manage one or multiple <code>SecretStores</code> 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.</p>"},{"location":"guides/multi-tenancy/#eso-as-a-service","title":"ESO as a Service","text":"<p>Every namespace is self-contained. Application developers manage <code>SecretStore</code>, <code>ExternalSecret</code> and secret infrastructure on their own. Cluster Administrators just provide the External Secrets Operator as a service.</p> <p>This makes sense if application developers should be completely autonomous while a central team provides common services.</p>"},{"location":"guides/ownership-deletion-policy/","title":"Lifecycle","text":"<p>The External Secrets Operator manages the lifecycle of secrets in Kubernetes. With <code>creationPolicy</code> and <code>deletionPolicy</code> you get fine-grained control of its lifecycle.</p> <p>Creation/Deletion Policy Combinations</p> <p>Some combinations of creationPolicy/deletionPolicy are not allowed as they would delete existing secrets: - <code>deletionPolicy=Delete</code> & <code>creationPolicy=Merge</code> - <code>deletionPolicy=Delete</code> & <code>creationPolicy=None</code> - <code>deletionPolicy=Merge</code> & <code>creationPolicy=None</code></p>"},{"location":"guides/ownership-deletion-policy/#creation-policy","title":"Creation Policy","text":"<p>The field <code>spec.target.creationPolicy</code> defines how the operator creates the a secret.</p>"},{"location":"guides/ownership-deletion-policy/#owner-default","title":"Owner (default)","text":"<p>The External Secret Operator creates secret and sets the <code>ownerReference</code> field on the Secret. This secret is subject to garbage collection if the initial <code>ExternalSecret</code> 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.</p>"},{"location":"guides/ownership-deletion-policy/#orphan","title":"Orphan","text":"<p>The operator creates the secret but does not set the <code>ownerReference</code> 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.</p>"},{"location":"guides/ownership-deletion-policy/#merge","title":"Merge","text":"<p>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 <code>creationPolicy=Merge</code> with a single secret as long as the fields don't collide - otherwise you end up in an oscillating state.</p>"},{"location":"guides/ownership-deletion-policy/#none","title":"None","text":"<p>The operator does not create or update the secret, this is basically a no-op.</p>"},{"location":"guides/ownership-deletion-policy/#deletion-policy","title":"Deletion Policy","text":"<p>DeletionPolicy defines what should happen if a given secret gets deleted from the provider.</p> <p>DeletionPolicy is only supported on the specific providers, please refer to our stability/support table.</p>"},{"location":"guides/ownership-deletion-policy/#retain-default","title":"Retain (default)","text":"<p>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.</p>"},{"location":"guides/ownership-deletion-policy/#delete","title":"Delete","text":"<p>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.</p>"},{"location":"guides/ownership-deletion-policy/#merge_1","title":"Merge","text":"<p>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.</p>"},{"location":"guides/security-best-practices/","title":"Security Best Practices","text":"<p>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.</p>"},{"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":"<p>To maintain security boundaries, ESO ensures that namespaced resources like <code>SecretStore</code> and <code>ExternalSecret</code> are limited to their respective namespaces. The following rules apply:</p> <ol> <li><code>ExternalSecret</code> resources must not have cross-namespace references of <code>Kind=SecretStore</code> or <code>Kind=Secret</code> resources</li> <li><code>SecretStore</code> resources must not have cross-namespace references of <code>Kind=Secret</code> or others</li> </ol> <p>For cluster-wide resources like <code>ClusterSecretStore</code> and <code>ClusterExternalSecret</code>, 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.</p>"},{"location":"guides/security-best-practices/#2-configure-clustersecretstore-match-conditions","title":"2. Configure ClusterSecretStore match conditions","text":"<p>Utilize the ClusterSecretStore resource to define specific match conditions using <code>namespaceSelector</code> or an explicit namespaces list. This restricts the usage of the <code>ClusterSecretStore</code> to a predetermined list of namespaces or a namespace that matches a predefined label. Here's an example:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\nname: fake\nspec:\nconditions:\nnamespaceSelector:\napp: frontend\n</code></pre>"},{"location":"guides/security-best-practices/#3-selectively-disable-reconciliation-of-cluster-wide-resources","title":"3. Selectively Disable Reconciliation of Cluster-Wide Resources","text":"<p>ESO allows you to selectively disable the reconciliation of cluster-wide resources such as <code>ClusterSecretStore</code>, <code>ClusterExternalSecret</code>, and <code>PushSecret</code>. You can disable the installation of CRDs in the Helm chart or disable reconciliation in the core-controller using the following options:</p> <p>To disable CRD installation:</p> <pre><code># disable cluster-wide resources & push secret\ncrds:\ncreateClusterExternalSecret: false\ncreateClusterSecretStore: false\ncreatePushSecret: false\n</code></pre> <p>To disable reconciliation in the core-controller:</p> <pre><code>--enable-cluster-external-secret-reconciler\n--enable-cluster-store-reconciler\n</code></pre>"},{"location":"guides/security-best-practices/#4-implement-namespace-scoped-installation","title":"4. Implement Namespace-Scoped Installation","text":"<p>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:</p> <pre><code># 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</code></pre>"},{"location":"guides/security-best-practices/#pod-security","title":"Pod Security","text":"<p>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.</p> <p>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 <code>v0.8.2</code>, and it is recommended to maintain this setting to align with the principle of least privilege.</p>"},{"location":"guides/security-best-practices/#role-based-access-control-rbac","title":"Role-Based Access Control (RBAC)","text":"<p>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 <code>ExternalSecret</code> and <code>SecretStore</code> where necessary. This is particularly important for cluster-scoped resources like <code>ClusterExternalSecret</code> and <code>ClusterSecretStore</code>. Unauthorized tampering with these resources by an attacker could lead to unauthorized access to secrets or potential data exfiltration from your system.</p> <p>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 <code>scopedRBAC</code> and <code>scopedNamespace</code> options in the helm chart.</p> <p>To ensure a secure RBAC configuration, consider the following checklist:</p> <ul> <li>Restrict access to execute shell commands (pods/exec) within the External Secrets Operator Pod.</li> <li>Restrict access to (Cluster)ExternalSecret and (Cluster)SecretStore resources.</li> <li>Limit access to aggregated ClusterRoles (view/edit/admin) as needed.</li> <li>If necessary, deploy ESO with scoped RBAC or within a specific namespace.</li> </ul> <p>By carefully managing RBAC permissions and scoping the External Secrets Operator appropriately, you can enhance the security of your Kubernetes cluster.</p>"},{"location":"guides/security-best-practices/#network-traffic-and-security","title":"Network Traffic and Security","text":"<p>To ensure a secure network environment, it is recommended to restrict network traffic to and from the External Secrets Operator using <code>NetworkPolicies</code> or similar mechanisms. By default, the External Secrets Operator does not include pre-defined Network Policies.</p> <p>To implement network restrictions effectively, consider the following steps:</p> <ul> <li>Define and apply appropriate NetworkPolicies to limit inbound and outbound traffic for the External Secrets Operator.</li> <li>Specify a \"deny all\" policy by default and selectively permit necessary communication based on your specific requirements.</li> <li>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.</li> <li>Regularly review and update the Network Policies to align with changes in your network infrastructure and security requirements.</li> </ul> <p>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.</p> <p>Data Exfiltration Risk</p> <p>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.</p>"},{"location":"guides/security-best-practices/#outbound-traffic-restrictions","title":"Outbound Traffic Restrictions","text":""},{"location":"guides/security-best-practices/#core-controller","title":"Core Controller","text":"<p>Restrict outbound traffic from the core controller component to the following destinations:</p> <ul> <li><code>kube-apiserver</code>: The Kubernetes API server.</li> <li>Secret provider (e.g., AWS, GCP): Whenever possible, use private endpoints to establish secure and private communication.</li> </ul>"},{"location":"guides/security-best-practices/#webhook","title":"Webhook","text":"<ul> <li>Restrict outbound traffic from the webhook component to the <code>kube-apiserver</code>.</li> </ul>"},{"location":"guides/security-best-practices/#cert-controller","title":"Cert Controller","text":"<ul> <li>Restrict outbound traffic from the cert controller component to the <code>kube-apiserver</code>.</li> </ul>"},{"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":"<ul> <li>Restrict inbound traffic to the core controller component by allowing communication on port <code>8080</code> from your monitoring agent.</li> </ul>"},{"location":"guides/security-best-practices/#cert-controller_1","title":"Cert Controller","text":"<ul> <li>Restrict inbound traffic to the cert controller component by allowing communication on port <code>8080</code> from your monitoring agent.</li> <li>Additionally, permit inbound traffic on port <code>8081</code> from the kubelet for health check endpoints (healthz/readyz).</li> </ul>"},{"location":"guides/security-best-practices/#webhook_1","title":"Webhook","text":"<p>Restrict inbound traffic to the webhook component as follows:</p> <ul> <li>Allow communication on port <code>10250</code> from the kube-apiserver.</li> <li>Allow communication on port <code>8080</code> from your monitoring agent.</li> <li>Permit inbound traffic on port <code>8081</code> from the kubelet for health check endpoints (healthz/readyz).</li> </ul>"},{"location":"guides/security-best-practices/#policy-engine-best-practices","title":"Policy Engine Best Practices","text":"<p>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.</p> <p>Data Exfiltration Risk</p> <p>ESO could be used to exfiltrate data out of your cluster. You should disable all providers you don't need. Further, you should implement <code>NetworkPolicies</code> to restrict network access to known entities (see above), to prevent data exfiltration.</p> <p>Here are some recommendations to consider when configuring your policies:</p> <ol> <li>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.</li> <li>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 <code>.spec.data[].remoteRef.key</code> field. This helps ensure that only authorized entities can access sensitive information.</li> <li>Restrict <code>ClusterSecretStore</code> 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.</li> </ol> <p>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.</p> <p>Provider Validation Example Policy</p> <p>The following policy validates the usage of the <code>provider</code> field in the SecretStore manifest.</p> <pre><code>apiVersion: kyverno.io/v1\nkind: ClusterPolicy\nmetadata:\nname: require-secretstore-aws-provider\nspec:\nvalidationFailureAction: Enforce\nrules:\n- name: require-secretstore-aws-provider\nmatch:\nany:\n- resources:\nkinds:\n- SecretStore\n- ClusterSecretStore\nvalidate:\nmessage: \"You must only use AWS SecretsManager\"\npattern:\nspec:\nprovider:\naws:\nservice: SecretsManager\n</code></pre>"},{"location":"guides/security-best-practices/#regular-patches","title":"Regular Patches","text":"<p>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:</p> <ol> <li>Automated Patching and Updating: Utilize automated patching and updating tools to streamline the process of keeping software components up-to-date</li> <li>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</li> <li>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.</li> </ol> <p>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.</p>"},{"location":"guides/security-best-practices/#verify-artefacts","title":"Verify Artefacts","text":""},{"location":"guides/security-best-practices/#verify-container-images","title":"Verify Container Images","text":"<p>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:</p> <pre><code># 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</code></pre> <p>In the output of the verification process, pay close attention to the <code>optional.Issuer</code> and <code>optional.Subject</code> 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.</p> <p>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.</p>"},{"location":"guides/security-best-practices/#verifying-provenance","title":"Verifying Provenance","text":"<p>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.</p> <pre><code>$ 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</code></pre>"},{"location":"guides/security-best-practices/#fetching-sbom","title":"Fetching SBOM","text":"<p>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.</p> <pre><code>$ 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</code></pre>"},{"location":"guides/templating-v1/","title":"Advanced Templating v1","text":"<p>Warning</p> <p>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.</p> <p>With External Secrets Operator you can transform the data from the external secret provider before it is stored as <code>Kind=Secret</code>. You can do this with the <code>Spec.Target.Template</code>. Each data value is interpreted as a golang template.</p>"},{"location":"guides/templating-v1/#examples","title":"Examples","text":"<p>You can use templates to inject your secrets into a configuration file that you mount into your pod: <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: template\nspec:\nrefreshInterval: 1h\nsecretStoreRef:\nname: secretstore-sample\nkind: SecretStore\ntarget:\nname: 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)\nengineVersion: v1\n\n# this is how the Kind=Secret will look like\ntemplate:\ntype: kubernetes.io/tls\ndata:\n# multiline string\nconfig: |\ndatasources:\n- name: Graphite\ntype: graphite\naccess: proxy\nurl: http://localhost:8080\npassword: \"{{ .password | toString }}\" # <-- convert []byte to string\nuser: \"{{ .user | toString }}\" # <-- convert []byte to string\n\ndata:\n- secretKey: user\nremoteRef:\nkey: /grafana/user\n- secretKey: password\nremoteRef:\nkey: /grafana/password\n</code></pre></p> <p>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. <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: template\nspec:\nrefreshInterval: 1h\nsecretStoreRef:\nname: secretstore-sample\nkind: SecretStore\ntarget:\nname: secret-to-be-created\n# this is how the Kind=Secret will look like\ntemplate:\ntype: kubernetes.io/tls\ndata:\ntls.crt: \"{{ .mysecret | pkcs12cert | pemCertificate }}\"\ntls.key: \"{{ .mysecret | pkcs12key | pemPrivateKey }}\"\n\ndata:\n# this is a pkcs12 archive that contains\n# a cert and a private key\n- secretKey: mysecret\nremoteRef:\nkey: example\n</code></pre></p>"},{"location":"guides/templating-v1/#templatefrom","title":"TemplateFrom","text":"<p>You do not have to define your templates inline in an ExternalSecret but you can pull <code>ConfigMaps</code> or other Secrets that contain a template. Consider the following example:</p> <pre><code># define your template in a config map\napiVersion: v1\nkind: ConfigMap\nmetadata:\nname: grafana-config-tpl\ndata:\nconfig.yaml: |\ndatasources:\n- name: Graphite\ntype: graphite\naccess: proxy\nurl: http://localhost:8080\npassword: \"{{ .password | toString }}\" # <-- convert []byte to string\nuser: \"{{ .user | toString }}\" # <-- convert []byte to string\n---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: my-template-example\nspec:\n# ...\ntarget:\nname: secret-to-be-created\ntemplate:\ntemplateFrom:\n- configMap:\n# name of the configmap to pull in\nname: grafana-config-tpl\n# here you define the keys that should be used as template\nitems:\n- key: config.yaml\ndata:\n- secretKey: user\nremoteRef:\nkey: /grafana/user\n- secretKey: password\nremoteRef:\nkey: /grafana/password\n</code></pre>"},{"location":"guides/templating-v1/#helper-functions","title":"Helper functions","text":"<p>We provide a bunch of convenience functions that help you transform your secrets. A secret value is a <code>[]byte</code>.</p> Function Description Input Output pkcs12key extracts the private key from a pkcs12 archive <code>[]byte</code> <code>[]byte</code> pkcs12keyPass extracts the private key from a pkcs12 archive using the provided password password <code>string</code>, data <code>[]byte</code> <code>[]byte</code> pkcs12cert extracts the certificate from a pkcs12 archive <code>[]byte</code> <code>[]byte</code> pkcs12certPass extracts the certificate from a pkcs12 archive using the provided password password <code>string</code>, data <code>[]byte</code> <code>[]byte</code> pemPrivateKey PEM encodes the provided bytes as private key <code>[]byte</code> <code>string</code> pemCertificate PEM encodes the provided bytes as certificate <code>[]byte</code> <code>string</code> jwkPublicKeyPem takes an json-serialized JWK as <code>[]byte</code> and returns an PEM block of type <code>PUBLIC KEY</code> that contains the public key (see here) for details <code>[]byte</code> <code>string</code> jwkPrivateKeyPem takes an json-serialized JWK as <code>[]byte</code> and returns an PEM block of type <code>PRIVATE KEY</code> that contains the private key in PKCS #8 format (see here) for details <code>[]byte</code> <code>string</code> base64decode decodes the provided bytes as base64 <code>[]byte</code> <code>[]byte</code> base64encode encodes the provided bytes as base64 <code>[]byte</code> <code>[]byte</code> fromJSON parses the bytes as JSON so you can access individual properties <code>[]byte</code> <code>interface{}</code> toJSON encodes the provided object as json string <code>interface{}</code> <code>string</code> toString converts bytes to string <code>[]byte</code> <code>string</code> toBytes converts string to bytes <code>string</code> <code>[]byte</code> upper converts all characters to their upper case <code>string</code> <code>string</code> lower converts all character to their lower case <code>string</code> <code>string</code>"},{"location":"guides/templating/","title":"Advanced Templating v2","text":"<p>With External Secrets Operator you can transform the data from the external secret provider before it is stored as <code>Kind=Secret</code>. You can do this with the <code>Spec.Target.Template</code>. Each data value is interpreted as a golang template.</p>"},{"location":"guides/templating/#examples","title":"Examples","text":"<p>You can use templates to inject your secrets into a configuration file that you mount into your pod:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: template\nspec:\n# ...\ntarget:\nname: secret-to-be-created\n# this is how the Kind=Secret will look like\ntemplate:\nengineVersion: v2\ndata:\n# multiline string\nconfig: |\ndatasources:\n- name: Graphite\ntype: graphite\naccess: proxy\nurl: http://localhost:8080\npassword: \"{{ .password }}\"\nuser: \"{{ .user }}\"\n# using replace function to rewrite secret\nconnection: '{{ .dburl | replace \"postgres://\" \"postgresql://\" }}'\n\ndata:\n- secretKey: user\nremoteRef:\nkey: /grafana/user\n- secretKey: password\nremoteRef:\nkey: /grafana/password\n- secretKey: dburl\nremoteRef:\nkey: /database/url\n</code></pre> <p>Another example with two keys in the same secret:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: template\nspec:\n# ...\ntarget:\ntemplate:\nengineVersion: v2\ndata:\nname: admin\npassword: \"{{ .mysecret }}\" # If you are using plain manifests or gitops tools\n# password: '{{ printf \"{{ .mysecret }}\" }}' # If you are using templated tools like helm\ndata:\n- secretKey: mysecret\nremoteRef:\nkey: /credentials\n</code></pre>"},{"location":"guides/templating/#mergepolicy","title":"MergePolicy","text":"<p>By default, the templating mechanism will not use any information available from the original <code>data</code> and <code>dataFrom</code> queries to the provider, and only keep the templated information. It is possible to change this behavior through the use of the <code>mergePolicy</code> field. <code>mergePolicy</code> currently accepts two values: <code>Replace</code> (the default) and <code>Merge</code>. When using <code>Merge</code>, <code>data</code> and <code>dataFrom</code> keys will also be embedded into the templated secret, having lower priority than the template outcome. See the example for more information:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: template\nspec:\n# ...\ntarget:\ntemplate:\nmergePolicy: Merge\nengineVersion: v2\ndata:\nname: admin\npassword: \"{{ .password | b64dec }}\" # Overwrites the password from the data call and use this output\ndata:\n- secretKey: password\nremoteRef:\nkey: /credentials/password\n- secretKey: username # Preserves the username in the templated Secret\nremoteRef:\nkey: /credentials/username\n</code></pre>"},{"location":"guides/templating/#templatefrom","title":"TemplateFrom","text":"<p>You do not have to define your templates inline in an ExternalSecret but you can pull <code>ConfigMaps</code> or other Secrets that contain a template. Consider the following example:</p> <pre><code># define your template in a config map\napiVersion: v1\nkind: ConfigMap\nmetadata:\nname: grafana-config-tpl\ndata:\nconfig.yaml: |\ndatasources:\n- name: Graphite\ntype: graphite\naccess: proxy\nurl: \"{{ .uri }}\"\npassword: \"{{ .password }}\"\nuser: \"{{ .user }}\"\ntemplated: |\n# key and value templated\nmy-application-{{ .user}}: {{ .password | b64enc }}\n# conditional keys\n{{- if hasPrefix \"oci://\" .uri }}\nenableOCI: true\n{{- else }}\nenableOCI: false\n{{- end }}\n# Fixed values\napplication-type: grafana\nannotations: |\n#dynamic timestamp generation\nlast-synced-for-user/{{ .user }}: {{ now }}\n---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: my-template-example\nspec:\n# ...\ntarget:\nname: secret-to-be-created\ntemplate:\nengineVersion: v2\ntemplateFrom:\n- target: Data\nconfigMap:\n# name of the configmap to pull in\nname: grafana-config-tpl\n# here you define the keys that should be used as template\nitems:\n- key: config.yaml\ntemplateAs: Values\n- key: generated\ntemplateAs: KeysAndValues\n- target: Annotations\nconfigMap:\n# name of the configmap to pull in\nname: grafana-config-tpl\n# here you define the keys that should be used as template\nitems:\n- key: annotations\ntemplateAs: KeysAndValues\ndata:\n- secretKey: user\nremoteRef:\nkey: /grafana/user\n- secretKey: password\nremoteRef:\nkey: /grafana/password\n- secretKey: uri\nremoteRef:\nkey: /grafana/uri\n</code></pre> <p><code>TemplateFrom</code> 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 <code>Values</code> or as <code>KeysAndValues</code> through the <code>templateAs</code> configuration:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: my-template-example\nspec:\n# ...\ntarget:\nname: secret-to-be-created\ntemplate:\nengineVersion: v2\ntemplateFrom:\n- target: Annotations\nliteral: \"last-sync-for-user/{{ .user }}: {{ .now }}\"\ndata:\n- secretKey: user\nremoteRef:\nkey: /grafana/user\n- secretKey: password\nremoteRef:\nkey: /grafana/password\n</code></pre> <p>Lastly, <code>TemplateFrom</code> also supports adding <code>Literal</code> blocks for quick templating. These <code>Literal</code> blocks differ from <code>Template.Data</code> as they are rendered as a a <code>key:value</code> pair (while the <code>Template.Data</code>, you can only template the value).</p>"},{"location":"guides/templating/#extract-keys-and-certificates-from-pkcs12-archive","title":"Extract Keys and Certificates from PKCS#12 Archive","text":"<p>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.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: template\nspec:\n# ...\ntarget:\ntemplate:\ntype: kubernetes.io/tls\nengineVersion: v2\ndata:\ntls.crt: \"{{ .mysecret | pkcs12cert }}\"\ntls.key: \"{{ .mysecret | pkcs12key }}\"\n\n# if needed unlock the pkcs12 with the password\ntls.crt: \"{{ .mysecret | pkcs12certPass \"my-password\" }}\"\n</code></pre>"},{"location":"guides/templating/#extract-from-jwk","title":"Extract from JWK","text":"<p>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.</p> <p>A JWK looks similar to this:</p> <pre><code>{\n\"kty\": \"RSA\",\n\"kid\": \"cc34c0a0-bd5a-4a3c-a50d-a2a7db7643df\",\n\"use\": \"sig\",\n\"n\": \"pjdss...\",\n\"e\": \"AQAB\"\n// ...\n}\n</code></pre> <p>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:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: template\nspec:\n# ...\ntarget:\ntemplate:\nengineVersion: v2\ndata:\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-----\njwk_pub: \"{{ .myjwk | jwkPublicKeyPem }}\"\n# private key is a pem-encoded PKCS#8 private key\njwk_priv: \"{{ .myjwk | jwkPrivateKeyPem }}\"\n</code></pre>"},{"location":"guides/templating/#filter-pem-blocks","title":"Filter PEM blocks","text":"<p>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.</p> <pre><code>-----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</code></pre> <p>You can achieve that by using the <code>filterPEM</code> function to extract a specific type of PEM block from that secret. If multiple blocks of that type (here: <code>CERTIFICATE</code>) exist then all of them are returned in the order they are specified.</p>"},{"location":"guides/templating/#helper-functions","title":"Helper functions","text":"<p>Info</p> <p>Note: we removed <code>env</code> and <code>expandenv</code> from sprig functions for security reasons.</p> <p>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).</p> <p>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.</p> <p></p> Function Description pkcs12key Extracts all private keys from a PKCS#12 archive and encodes them in PKCS#8 PEM format. pkcs12keyPass Same as <code>pkcs12key</code>. 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: <code>leaf / intermediate(s) / root</code>. pkcs12certPass Same as <code>pkcs12cert</code>. Uses the provided password to decrypt 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 <code>PUBLIC KEY</code> that contains the public key. See here for details. jwkPrivateKeyPem Takes an json-serialized JWK as <code>string</code> and returns an PEM block of type <code>PRIVATE KEY</code> 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]interface{}."},{"location":"guides/templating/#migrating-from-v1","title":"Migrating from v1","text":"<p>If you are still using <code>v1alpha1</code>, You have to opt-in to use the new engine version by specifying <code>template.engineVersion=v2</code>:</p> <pre><code>apiVersion: external-secrets.io/v1alpha1\nkind: ExternalSecret\nmetadata:\nname: secret\nspec:\n# ...\ntarget:\ntemplate:\nengineVersion: v2\n# ...\n</code></pre> <p>The biggest change was that basically all function parameter types were changed from accepting/returning <code>[]byte</code> to <code>string</code>. This is relevant for you because now you don't need to specify <code>toString</code> all the time at the end of a template pipeline.</p> <pre><code>apiVersion: external-secrets.io/v1alpha1\nkind: ExternalSecret\n# ...\nspec:\ntarget:\ntemplate:\nengineVersion: v2\ndata:\n# this used to be {{ .foobar | toString }}\negg: \"new: {{ .foobar }}\"\n</code></pre>"},{"location":"guides/templating/#functions-removedreplaced","title":"Functions removed/replaced","text":"<ul> <li><code>base64encode</code> was renamed to <code>b64enc</code>.</li> <li><code>base64decode</code> was renamed to <code>b64dec</code>. Any errors that occur during decoding are silenced.</li> <li><code>fromJSON</code> was renamed to <code>fromJson</code>. Any errors that occur during unmarshalling are silenced.</li> <li><code>toJSON</code> was renamed to <code>toJson</code>. Any errors that occur during marshalling are silenced.</li> <li><code>pkcs12key</code> and <code>pkcs12keyPass</code> encode the PKCS#8 key directly into PEM format. There is no need to call <code>pemPrivateKey</code> anymore. Also, these functions do extract all private keys from the PKCS#12 archive not just the first one.</li> <li><code>pkcs12cert</code> and <code>pkcs12certPass</code> encode the certs directly into PEM format. There is no need to call <code>pemCertificate</code> anymore. These functions now extract all certificates from the PKCS#12 archive not just the first one.</li> <li><code>toString</code> implementation was replaced by the <code>sprig</code> implementation and should be api-compatible.</li> <li><code>toBytes</code> was removed.</li> <li><code>pemPrivateKey</code> was removed. It's now implemented within the <code>pkcs12*</code> functions.</li> <li><code>pemCertificate</code> was removed. It's now implemented within the <code>pkcs12*</code> functions.</li> </ul>"},{"location":"guides/threat-model/","title":"Threat Model","text":""},{"location":"guides/threat-model/#background","title":"Background","text":"<p>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.</p>"},{"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":"<p>ESO comprises three main components: <code>webhook</code>, <code>cert controller</code> and a <code>core controller</code>. For more detailed information, please refer to the documentation on components.</p>"},{"location":"guides/threat-model/#overview","title":"Overview","text":"<p>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.</p> <p>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).</p> <p></p>"},{"location":"guides/threat-model/#scope","title":"Scope","text":"<p>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.</p> <p>ESO utilizes the <code>ValidatingWebhookConfiguration</code> mechanism to validate <code>(Cluster)SecretStore</code> and <code>(Cluster)ExternalSecret</code> 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.</p>"},{"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":"<p>The controller possesses privileged access to the <code>kube-apiserver</code> and is authorized to read and write secret resources across all namespaces within a cluster.</p>"},{"location":"guides/threat-model/#a02-crd-and-webhook-write-access","title":"A02: CRD and Webhook Write access","text":"<p>The cert-controller component has read/write access to <code>ValidatingWebhookConfigurations</code> and <code>CustomResourceDefinitions</code> resources. This access is necessary to inject/modify the caBundle property.</p>"},{"location":"guides/threat-model/#a03-secret-provider-access","title":"A03: secret provider access","text":"<p>The <code>core-controller</code> 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., <code>Kind=Secret</code>). The scope of these credentials may vary, potentially providing full access to a cloud provider.</p>"},{"location":"guides/threat-model/#a04-capability-to-modify-resources","title":"A04: capability to modify resources","text":"<p>The webhook component validates and converts ExternalSecret and SecretStore resources. The conversion webhook is essential for migrating resources from the old version <code>v1alpha1</code> to the new version <code>v1beta1</code>. The webhook component possesses the ability to modify resources during runtime.</p>"},{"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":"<p>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.</p>"},{"location":"guides/threat-model/#t02-webhook-dos","title":"T02: Webhook DOS","text":"<p>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.</p>"},{"location":"guides/threat-model/#t03-unauthorized-access-to-cluster-secrets","title":"T03: Unauthorized access to cluster secrets","text":"<p>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.</p>"},{"location":"guides/threat-model/#t04-unauthorized-access-to-secret-provider-credentials","title":"T04: unauthorized access to secret provider credentials","text":"<p>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.</p>"},{"location":"guides/threat-model/#t05-data-exfiltration-through-malicious-resources","title":"T05: data exfiltration through malicious resources","text":"<p>An attacker can exfiltrate data from the cluster by utilizing maliciously crafted resources. Multiple attack vectors can be employed, e.g.:</p> <ol> <li>copying data from a namespace to an unauthorized namespace</li> <li>exfiltrating data to an unauthorized secret provider</li> <li>exfiltrating data through an authorized secret provider to a malicious provider account</li> </ol> <p>Successful data exfiltration can lead to intellectual property loss, information misuse, loss of customer trust, and damage to the brand or reputation.</p>"},{"location":"guides/threat-model/#t06-supply-chain-attacks","title":"T06: supply chain attacks","text":"<p>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.</p> <ol> <li>Source Threats: Unauthorized changes or inclusion of vulnerable code in ESO through code submissions.</li> <li>Build Threats: Creation and distribution of malicious builds of ESO, such as in container registries, Artifact Hub, or Operator Hub.</li> <li>Dependency Threats: Introduction of vulnerable code into ESO dependencies.</li> <li>Deployment and Runtime Threats: Injection of malicious code through compromised deployment processes.</li> </ol>"},{"location":"guides/threat-model/#t07-malicious-workloads-in-eso-namespace","title":"T07: malicious workloads in eso namespace","text":"<p>An attacker can deploy malicious workloads within the external-secrets namespace, taking advantage of the ESO service account with potentially cluster-wide privileges.</p>"},{"location":"guides/threat-model/#controls","title":"Controls","text":""},{"location":"guides/threat-model/#c01-network-security-policy","title":"C01: Network Security Policy","text":"<p>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.</p> <p>Please note that ESO does not provide pre-packaged network policies, and it is the user's responsibility to implement the necessary security controls.</p>"},{"location":"guides/threat-model/#c02-least-privilege-rbac","title":"C02: Least Privilege RBAC","text":"<p>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 <code>ClusterSecretStore</code>/<code>ExternalSecret</code> may be sufficient for a threat to become a reality.</p>"},{"location":"guides/threat-model/#c03-policy-enforcement","title":"C03: Policy Enforcement","text":"<p>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:</p> <ol> <li>(Cluster)SecretStore: Restrict the allowed secret providers, disallowing unused or undesired providers (e.g. Webhook).</li> <li>(Cluster)SecretStore: Restrict the permitted authentication mechanisms (e.g. prevent usage of <code>secretRef</code>).</li> <li>(Cluster)SecretStore: Enforce limitations on modifications to provider-specific fields relevant for security, such as <code>caBundle</code>, <code>caProvider</code>, <code>region</code>, <code>role</code>, <code>url</code>, <code>environmentType</code>, <code>identityId</code>, and <code>others</code>.</li> <li>ClusterSecretStore: Control the usage of <code>namespaceSelector</code>, such as forbidding or mandating the usage of the <code>kube-system</code> namespace.</li> <li>ClusterExternalSecret: Restrict the usage of <code>namespaceSelector</code>.</li> </ol> <p>Please note that ESO does not provide pre-packaged policies, and it is the user's responsibility to implement the necessary security controls.</p>"},{"location":"guides/threat-model/#c04-provider-access-policy","title":"C04: Provider Access Policy","text":"<p>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.</p>"},{"location":"guides/threat-model/#c05-entirely-disable-crds","title":"C05: Entirely disable CRDs","text":"<p>You should disable unused CRDs to narrow down your attack surface. Not all users require the use of <code>PushSecret</code>, <code>ClusterSecretStore</code> or <code>ClusterExternalSecret</code> resources.</p>"},{"location":"guides/using-latest-image/","title":"Using Latest Image","text":"<p>You can test a feature that was not yet released using the following methods, use them at your own discretion:</p>"},{"location":"guides/using-latest-image/#helm","title":"Helm","text":"<ol> <li>Create a <code>values.yaml</code> file with the following content: <pre><code>replicaCount: 1\n\nimage:\nrepository: ghcr.io/external-secrets/external-secrets\npullPolicy: IfNotPresent\n# -- The image tag to use. The default is the chart appVersion.\ntag: \"main\"\n\n# -- If set, install and upgrade CRDs through helm chart.\ninstallCRDs: false\n</code></pre></li> <li>Install the crds <pre><code>make crds.install\n</code></pre></li> <li>Install the external-secrets Helm chart indicating the values file created before: <pre><code>helm install external-secrets external-secrets/external-secrets -f values.yaml\n</code></pre></li> </ol>"},{"location":"guides/using-latest-image/#manual","title":"Manual","text":"<ol> <li>Build the Docker image <pre><code>docker build -f Dockerfile.standalone -t my-org/external-secrets:latest .\n</code></pre></li> <li>Apply the <code>bundle.yaml</code> <pre><code>kubectl apply -f deploy/crds/bundle.yaml\n</code></pre></li> <li>Modify your configs to use the image <pre><code>kind: Deployment\nmetadata:\nname: external-secrets|external-secrets-webhook|external-secrets-cert-controller\n...\nimage: my-org/external-secrets:latest\n</code></pre></li> </ol>"},{"location":"guides/v1beta1/","title":"Upgrading CRD versions","text":"<p>From version v0.5.0, <code>v1alpha1</code> version is deprecated, and <code>v1beta1</code> is in place. This guide will cover the main differences between the two versions, and a procedure on how to safely upgrade it.</p>"},{"location":"guides/v1beta1/#differences-between-versions","title":"Differences between versions","text":"<p>Versions v1alpha1 and v1beta1 are fully-compatible for SecretStores and ClusterSecretStores. For ExternalSecrets, there is a difference on the <code>dataFrom</code> method.</p> <p>While in v1alpha1, we could define a <code>dataFrom</code> with the following format:</p> <pre><code>spec:\n dataFrom:\n - key: my-key\n - key: my-other-key\n</code></pre> <p>In v1beta1 is possible to use two methods. One of them is <code>Extract</code> and has the exact same behavior as <code>dataFrom</code> in v1alpha1. The other is <code>Find</code>, which allows finding multiple external secrets and map them into a single Kubernetes secret. Here is an example of <code>Find</code>:</p> <pre><code>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</code></pre>"},{"location":"guides/v1beta1/#upgrading","title":"Upgrading","text":"<p>If you already have an installation of ESO using <code>v1alpha1</code>, we recommend you to upgrade to <code>v1beta1</code>. If you do not use <code>dataFrom</code> 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. </p> <p>If you are installing CRDs manually, you will need to deploy the bundle CRD file available at <code>deploys/crds/bundle.yaml</code>. This bundle file contains <code>v1beta1</code> 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.</p> <p>Once the upgrade is finished, at each reconcile, any <code>ExternalSecret</code>, <code>SecretStore</code>, and <code>ClusterSecretStore</code> stored in <code>v1alpha1</code> will be automatically converted to <code>v1beta1</code>. </p>"},{"location":"introduction/deprecation-policy/","title":"Deprecation Policy","text":"<p>We follow the Kubernetes Deprecation Policy and API Versioning Scheme: alpha, beta, GA.</p> <p>The project is currently in <code>beta</code> state. Please try the <code>beta</code> features and provide feedback. After the features exits beta, it may not be practical to make more changes.</p> <ul> <li> <p>alpha</p> <ul> <li>The support for a feature may be dropped at any time without notice.</li> <li>The API may change in incompatible ways in a later software release without notice.</li> <li>The software is recommended for use only in short-lived testing clusters, due to increased risk of bugs and lack of long-term support.</li> </ul> </li> <li> <p>beta</p> <ul> <li>The software is well tested. Enabling a feature is considered safe. Features are enabled by default.</li> <li>The support for a feature will not be dropped, though the details may change.</li> <li>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.</li> <li>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.</li> </ul> </li> <li>GA<ul> <li>The stable versions of features appear in released software for many subsequent versions.</li> <li>Use it in production ;)</li> </ul> </li> </ul>"},{"location":"introduction/deprecation-policy/#api-surface","title":"API Surface","text":"<p>We define the following scope that is covered by our deprecation policy. We follow the 9 Rules of the Kuberenetes Deprecation Policy.</p>"},{"location":"introduction/deprecation-policy/#scope","title":"Scope","text":"<ul> <li>API Objects and fields: <code>.Spec</code>, <code>.Status</code> and <code>.Status.Conditions[]</code></li> <li>Enums and constant values</li> <li>Controller Configuration: CLI flags & environment variables</li> <li>Metrics as defined in the Kubernetes docs</li> <li>a feature or specific behavior:<ul> <li><code>ExternalSecret</code> update mechanics</li> </ul> </li> </ul>"},{"location":"introduction/deprecation-policy/#non-scope","title":"Non-Scope","text":"<p>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.</p>"},{"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":"<p>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:</p> <pre><code>kubectl annotate es my-es force-sync=$(date +%s) --overwrite\n</code></pre>"},{"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":"<p>Every ExternalSecret resource contains a status condition that indicates the time when the secret was last synced:</p> <pre><code>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</code></pre>"},{"location":"introduction/faq/#differences-to-csi-secret-store","title":"Differences to csi-secret-store","text":"<p>Please take a look at this issue comment here.</p>"},{"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":"<p>First, check the status of the ExternalSecret resource using <code>kubectl describe</code>. That displays the status conditions as well as recent events. You should expect a status condition with <code>Type=Ready</code>, <code>Status=True</code>. Further you shouldn't see any events with <code>Type=Warning</code>. Read carefully if they exist.</p> <pre><code>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</code></pre> <p>If everything looks good you should check the corresponding secret store resource that is referenced from an ExternalSecret. Again, use <code>kubectl describe</code> to show status conditions and events and look for warning signs as described above.</p> <p>In an ideally, the store should be validated and Ready.</p> <pre><code>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</code></pre> <p>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.</p>"},{"location":"introduction/faq/#upgrading-from-kes-to-eso","title":"Upgrading from KES to ESO","text":"<p>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.</p> <p>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.</p>"},{"location":"introduction/getting-started/","title":"Getting started","text":"<p>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.</p> <p>Note: The minimum supported version of Kubernetes is <code>1.16.0</code>. Users still running Kubernetes v1.15 or below should upgrade to a supported version before installing external-secrets.</p>"},{"location":"introduction/getting-started/#installing-with-helm","title":"Installing with Helm","text":"<p>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 <code>installCRDs</code> option to <code>false</code>. (e.g. <code>--set installCRDS=false</code>)</p> <p>Uncomment the relevant line in the next steps to disable the automatic install of CRDs.</p>"},{"location":"introduction/getting-started/#option-1-install-from-chart-repository","title":"Option 1: Install from chart repository","text":"<pre><code>helm repo add external-secrets https://charts.external-secrets.io\n\nhelm install external-secrets \\\nexternal-secrets/external-secrets \\\n-n external-secrets \\\n--create-namespace \\\n# --set installCRDs=false\n</code></pre>"},{"location":"introduction/getting-started/#option-2-install-chart-from-local-build","title":"Option 2: Install chart from local build","text":"<p>Build and install the Helm chart locally after cloning the repository.</p> <pre><code>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</code></pre>"},{"location":"introduction/getting-started/#create-a-secret-containing-your-aws-credentials","title":"Create a secret containing your AWS credentials","text":"<pre><code>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</code></pre>"},{"location":"introduction/getting-started/#create-your-first-secretstore","title":"Create your first SecretStore","text":"<pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: secretstore-sample\nspec:\nprovider:\naws:\nservice: SecretsManager\nregion: us-east-1\nauth:\nsecretRef:\naccessKeyIDSecretRef:\nname: awssm-secret\nkey: access-key\nsecretAccessKeySecretRef:\nname: awssm-secret\nkey: secret-access-key\n</code></pre>"},{"location":"introduction/getting-started/#create-your-first-externalsecret","title":"Create your first ExternalSecret","text":"<pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: example\nspec:\nrefreshInterval: 1h\nsecretStoreRef:\nname: secretstore-sample\nkind: SecretStore\ntarget:\nname: secret-to-be-created\ncreationPolicy: Owner\ndata:\n- secretKey: secret-key-to-be-managed\nremoteRef:\nkey: provider-key\nversion: provider-key-version\nproperty: provider-key-property\ndataFrom:\n- extract:\nkey: remote-key-in-the-provider\n</code></pre> <pre><code>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</code></pre> <p>For more advanced examples, please read the other guides.</p>"},{"location":"introduction/getting-started/#installing-with-olm","title":"Installing with OLM","text":"<p>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.</p>"},{"location":"introduction/getting-started/#uninstalling","title":"Uninstalling","text":"<p>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:</p> <pre><code>kubectl get SecretStores,ClusterSecretStores,ExternalSecrets --all-namespaces\n</code></pre> <p>Once all these resources have been deleted you are ready to uninstall external-secrets.</p>"},{"location":"introduction/getting-started/#uninstalling-with-helm","title":"Uninstalling with Helm","text":"<p>Uninstall the helm release using the delete command.</p> <pre><code>helm delete external-secrets --namespace external-secrets\n</code></pre>"},{"location":"introduction/overview/","title":"API Overview","text":""},{"location":"introduction/overview/#architecture","title":"Architecture","text":"<p>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.</p>"},{"location":"introduction/overview/#resource-model","title":"Resource model","text":"<p>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.</p> <p></p>"},{"location":"introduction/overview/#secretstore","title":"SecretStore","text":"<p>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.</p> <p><pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: secretstore-sample\nspec:\nprovider:\naws:\nservice: SecretsManager\nregion: us-east-1\nauth:\nsecretRef:\naccessKeyIDSecretRef:\nname: awssm-secret\nkey: access-key\nsecretAccessKeySecretRef:\nname: awssm-secret\nkey: secret-access-key\n</code></pre> The <code>SecretStore</code> contains references to secrets which hold credentials to access the external API.</p>"},{"location":"introduction/overview/#externalsecret","title":"ExternalSecret","text":"<p>An ExternalSecret declares what data to fetch. It has a reference to a <code>SecretStore</code> which knows how to access that data. The controller uses that <code>ExternalSecret</code> as a blueprint to create secrets.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: example\nspec:\nrefreshInterval: 1h\nsecretStoreRef:\nname: secretstore-sample\nkind: SecretStore\ntarget:\nname: secret-to-be-created\ncreationPolicy: Owner\ndata:\n- secretKey: secret-key-to-be-managed\nremoteRef:\nkey: provider-key\nversion: provider-key-version\nproperty: provider-key-property\ndataFrom:\n- extract:\nkey: remote-key-in-the-provider\n</code></pre>"},{"location":"introduction/overview/#clustersecretstore","title":"ClusterSecretStore","text":"<p>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.</p>"},{"location":"introduction/overview/#behavior","title":"Behavior","text":"<p>The External Secret Operator (ESO for brevity) reconciles <code>ExternalSecrets</code> in the following manner:</p> <ol> <li>ESO uses <code>spec.secretStoreRef</code> to find an appropriate <code>SecretStore</code>. If it doesn't exist or the <code>spec.controller</code> field doesn't match it won't further process this ExternalSecret.</li> <li>ESO instanciates an external API client using the specified credentials from the <code>SecretStore</code> spec.</li> <li>ESO fetches the secrets as requested by the <code>ExternalSecret</code>, it will decode the secrets if required</li> <li>ESO creates an <code>Kind=Secret</code> based on the template provided by <code>ExternalSecret.target.template</code>. The <code>Secret.data</code> can be templated using the secret values from the external API.</li> <li>ESO ensures that the secret values stay in sync with the external API</li> </ol>"},{"location":"introduction/overview/#roles-and-responsibilities","title":"Roles and responsibilities","text":"<p>The External Secret Operator is designed to target the following persona:</p> <ul> <li>Cluster Operator: The cluster operator is responsible for setting up the External Secret Operator, managing access policies and creating ClusterSecretStores.</li> <li>Application developer: The Application developer is responsible for defining ExternalSecrets and the application configuration</li> </ul> <p>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.</p>"},{"location":"introduction/overview/#access-control","title":"Access Control","text":"<p>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.</p> <p>Design your <code>SecretStore</code>/<code>ClusterSecretStore</code> carefully! Be sure to restrict access of application developers to read only certain keys in a shared environment.</p> <p>You should also consider using Kubernetes' admission control system (e.g. OPA or Kyverno) for fine-grained access control.</p>"},{"location":"introduction/overview/#running-multiple-controller","title":"Running multiple Controller","text":"<p>You can run multiple controllers within the cluster. One controller can be limited to only process <code>SecretStores</code> with a predefined <code>spec.controller</code> field.</p> <p>Testers welcome</p> <p>This is not widely tested. Please help us test the setup and/or document use-cases.</p>"},{"location":"introduction/stability-support/","title":"Stability and Support","text":"<p>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.</p>"},{"location":"introduction/stability-support/#supported-versions","title":"Supported Versions","text":"<p>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.</p> <p>We want to cover the following cases:</p> <ul> <li>regular image rebuilds to update OS dependencies</li> <li>regular go dependency updates</li> <li>backport bug fixes on demand</li> </ul> ESO Version Kubernetes Version Release Date End of Life 0.9.x 1.19 \u2192 1.27 Jun 22, 2023 Release of 1.1 0.8.x 1.19 \u2192 1.26 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":"<p>The following table describes the stability level of each provider and who's responsible.</p> 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 alpha @davidh-cyberark Delinea alpha @michaelsauter"},{"location":"introduction/stability-support/#provider-feature-support","title":"Provider Feature Support","text":"<p>The following table show the support for features across different providers.</p> 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 Generic Webhook x senhasegura DSM x Doppler x x Keeper Security x x x Scaleway x x x x x Conjur x Delinea x x"},{"location":"introduction/stability-support/#support-policy","title":"Support Policy","text":"<p>We provide technical support and security / bug fixes for the above listed versions.</p>"},{"location":"introduction/stability-support/#technical-support","title":"Technical support","text":"<p>We provide assistance for deploying/upgrading etc. on a best-effort basis. You can request support through the following channels:</p> <ul> <li>Kubernetes Slack #external-secrets</li> <li>GitHub Issues</li> <li>GitHub Discussions</li> </ul> <p>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.</p>"},{"location":"provider/1password-automation/","title":"1Password Secrets Automation","text":""},{"location":"provider/1password-automation/#1password-secrets-automation","title":"1Password Secrets Automation","text":"<p>External Secrets Operator integrates with 1Password Secrets Automation for secret management.</p>"},{"location":"provider/1password-automation/#important-note-about-this-documentation","title":"Important note about this documentation","text":"<p>The 1Password API calls the entries in vaults 'Items'. These docs use the same term.</p>"},{"location":"provider/1password-automation/#behavior","title":"Behavior","text":"<ul> <li>How an Item is equated to an ExternalSecret:<ul> <li><code>remoteRef.key</code> is equated to an Item's Title</li> <li><code>remoteRef.property</code> is equated to:<ul> <li>An Item's field's Label (Password type)</li> <li>An Item's file's Name (Document type)</li> <li>If empty, defaults to the first file name, or the field labeled <code>password</code></li> </ul> </li> <li><code>remoteRef.version</code> is currently not supported.</li> <li>One Item in a vault can equate to one Kubernetes Secret to keep things easy to comprehend.</li> </ul> </li> <li>Support for 1Password secret types of <code>Password</code> and <code>Document</code>.<ul> <li>The <code>Password</code> type can get data from multiple <code>fields</code> in the Item.</li> <li>The <code>Document</code> type can get data from files.</li> <li>See creating 1Password Items compatible with ExternalSecrets.</li> </ul> </li> <li>Ordered vaults<ul> <li>Specify an ordered list of vaults in a SecretStore and the value will be sourced from the first vault with a matching Item.</li> <li>If no matching Item is found, an error is returned.</li> <li>This supports having a default or shared set of values that can also be overriden for specific environments.</li> </ul> </li> <li><code>dataFrom</code>:<ul> <li><code>find.path</code> is equated to Item Title.</li> <li><code>find.name.regexp</code> is equated to field Labels.</li> <li><code>find.tags</code> are not supported at this time.</li> </ul> </li> </ul>"},{"location":"provider/1password-automation/#prerequisites","title":"Prerequisites","text":"<ul> <li>1Password requires running a 1Password Connect Server to which the API requests will be made.<ul> <li>External Secrets does not run this server. See Deploy a Connect Server.</li> <li>One Connect Server is needed per 1Password Automation Environment.</li> <li>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.</li> </ul> </li> <li>1Password Connect Server version 1.5.6 or higher.</li> </ul>"},{"location":"provider/1password-automation/#setup-authentication","title":"Setup Authentication","text":"<p>Authentication requires a <code>1password-credentials.json</code> 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.</p> <ol> <li>Setup an Automation Environment at 1Password.com, or via the op CLI.<ul> <li>Note: don't be confused by the <code>op connect server create</code> syntax. This will create an Automation Environment in 1Password, and corresponding credentials for a Connect Server, nothing more.</li> <li>This will result in a <code>1password-credentials.json</code> file to provide to a Connect Server Deployment, and an Access Token to provide as a Secret referenced by a <code>SecretStore</code> or <code>ClusterSecretStore</code>.</li> </ul> </li> <li>Create a Kubernetes secret with the Access Token <pre><code>---\napiVersion: v1\nkind: Secret\nmetadata:\nname: onepassword-connect-token-staging\ntype: Opaque\nstringData:\ntoken: my-token\n</code></pre></li> <li>Reference the secret in a SecretStore or ClusterSecretStore <pre><code>---\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: staging\nspec:\nprovider:\nonepassword:\nconnectHost: https://onepassword-connect-staging\nvaults:\nstaging: 1 # look in this vault first\nshared: 2 # next look in here. error if not found\nauth:\nsecretRef:\nconnectTokenSecretRef:\nname: onepassword-connect-token-staging\nkey: token\n</code></pre></li> <li>Create a Kubernetes secret with the Connect Server credentials <pre><code>---\napiVersion: v1\nkind: Secret\nmetadata:\nname: 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.)\n1password-credentials.json: |-\neyJ2ZXJpZmllciI6eyJzYWx0IjoiZXhhbXBsZSIsImxvY2FsSGFzaCI6ImV4YW1wbGUifSwiZW5jQ3JlZGVudGlhbHMiOnsia2lkIjoiZXhhbXBsZSIsImVuYyI6ImV4YW1wbGUiLCJjdHkiOiJleGFtcGxlIiwiaXYiOiJleGFtcGxlIiwiZGF0YSI6ImV4YW1wbGUifSwidmVyc2lvbiI6IjIiLCJkZXZpY2VVdWlkIjoiZXhhbXBsZSIsInVuaXF1ZUtleSI6eyJhbGciOiJleGFtcGxlIiwiZXh0Ijp0cnVlLCJrIjoiZXhhbXBsZSIsImtleV9vcHMiOlsiZW5jcnlwdCIsImRlY3J5cHQiXSwia3R5Ijoib2N0Iiwia2lkIjoiZXhhbXBsZSJ9fQ==\n</code></pre></li> <li>Reference the secret in a Connect Server Deployment <pre><code>---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\nname: onepassword-connect-staging\nspec:\ntemplate:\nspec:\ncontainers:\n- name: connect-api\nimage: 1password/connect-api:1.5.0\nenv:\n- name: OP_SESSION\nvalueFrom:\nsecretKeyRef:\nname: connect-server-credentials\nkey: 1password-credentials.json\n...\n- name: connect-sync\nimage: 1password/connect-sync:1.5.0\nenv:\n- name: OP_SESSION\nvalueFrom:\nsecretKeyRef:\nname: connect-server-credentials\nkey: 1password-credentials.json\n...\n...\n</code></pre></li> </ol>"},{"location":"provider/1password-automation/#deploy-a-connect-server","title":"Deploy a Connect Server","text":"<ul> <li>Follow the remaining instructions in the Quick Start guide.<ul> <li>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.</li> </ul> </li> <li>The Service's name will be referenced in SecretStores/ClusterSecretStores.</li> <li>Keep in mind the likely need for additional Connect Servers for other Automation Environments when naming objects. For example dev, staging, prod, etc.</li> <li>Unencrypted secret values are passed over the connection between the Operator and the Connect Server. Encrypting the connection is recommended.</li> </ul>"},{"location":"provider/1password-automation/#creating-compatible-1password-items","title":"Creating Compatible 1Password Items","text":"<p>Also see examples below for matching SecretStore and ExternalSecret specs.</p>"},{"location":"provider/1password-automation/#manually-password-type","title":"Manually (Password type)","text":"<ol> <li>Click the plus button to create a new Password type Item.</li> <li>Change the title to what you want <code>remoteRef.key</code> to be.</li> <li>Set what you want <code>remoteRef.property</code> to be in the field sections where is says 'label', and values where it says 'new field'.</li> <li>Click the 'Save' button.</li> </ol>"},{"location":"provider/1password-automation/#manually-document-type","title":"Manually (Document type)","text":"<ul> <li>Click the plus button to create a new Document type Item.</li> <li>Choose the file to upload and upload it.</li> <li>Change the title to match <code>remoteRef.key</code></li> <li>Click the 'Add New File' button to add more files.</li> <li>Click the 'Save' button.</li> </ul>"},{"location":"provider/1password-automation/#scripting-password-type-with-op-cli","title":"Scripting (Password type with op CLI)","text":"<ul> <li>Create <code>file.json</code> with the following contents, swapping in your keys and values. Note: <code>section.name</code>'s and <code>section.title</code>'s values are ignored by the Operator, but cannot be empty for the <code>op</code> CLI <pre><code> {\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</code></pre></li> <li>Run <code>op item create --template file.json</code></li> </ul>"},{"location":"provider/1password-automation/#scripting-document-type","title":"Scripting (Document type)","text":"<ul> <li>Unfortunately the <code>op</code> CLI doesn't seem to support uploading multiple files to the same Item, and the current Go lib has a bug. <code>op</code> 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.</li> </ul>"},{"location":"provider/1password-automation/#in-built-field-labeled-password-on-password-type-items","title":"In-built field labeled <code>password</code> on Password type Items","text":"<ul> <li>TL;DR if you need a field labeled <code>password</code>, use the in-built one rather than the one in a fields Section.</li> </ul> <ul> <li>1Password automatically adds a field labeled <code>password</code> on every Password type Item, whether it's created through a GUI or the API or <code>op</code> CLI.</li> <li>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 <code>op</code> CLI to create Items.)</li> <li>The in-built <code>password</code> field is not otherwise special for the purposes of ExternalSecrets. It can be ignored when not in use.</li> </ul>"},{"location":"provider/1password-automation/#examples","title":"Examples","text":"<p>Examples of using the <code>my-env-config</code> and <code>my-cert</code> Items seen above.</p> <ul> <li>Note: with this configuration a 1Password Item titled <code>my-env-config</code> is correlated to a ExternalSecret named <code>my-env-config</code> that results in a Kubernetes secret named <code>my-env-config</code>, all with matching names for the key/value pairs. This is a way to increase comprehensibility. <pre><code>---\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: staging\nspec:\nprovider:\nonepassword:\nconnectHost: https://onepassword-connect-staging\nvaults:\nstaging: 1 # look in this vault first\nshared: 2 # next look in here. error if not found\nauth:\nsecretRef:\nconnectTokenSecretRef:\nname: onepassword-connect-token-staging\nkey: token\n</code></pre> <pre><code>---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: my-env-config\nspec:\nsecretStoreRef:\nkind: SecretStore\nname: staging\ntarget:\ncreationPolicy: Owner\ndata:\n- secretKey: MY_ENV_VAR1\nremoteRef:\nkey: my-env-config\nproperty: MY_ENV_VAR1\n- secretKey: MY_ENV_VAR2\nremoteRef:\nkey: my-env-config\nproperty: MY_ENV_VAR2\n# OR\ndataFrom:\n- extract:\nkey: my-env-config\nproperty: MY_ENV_VAR1 # optional field Label to match exactly\n# OR\n- find:\npath: my-env-config # optional Item Title to match exactly\nname:\nregexp: \"^MY_ENV_VAR.*\"\n</code></pre> <pre><code>---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: my-cert\nspec:\nsecretStoreRef:\nkind: SecretStore\nname: staging\ntarget:\ncreationPolicy: Owner\ndata:\n- secretKey: cert.crt\nremoteRef:\nkey: my-cert\nproperty: cert.crt\n- secretKey: cert.key\nremoteRef:\nkey: my-cert\nproperty: cert.key\n# OR\ndataFrom:\n- extract:\nkey: my-cert\nproperty: cert.key # optional field Label to match exactly\n# OR\n- find:\npath: my-cert # optional Item Title to match exactly\nname:\nregexp: \"^cert.*\"\n</code></pre></li> </ul>"},{"location":"provider/1password-automation/#additional-notes","title":"Additional Notes","text":""},{"location":"provider/1password-automation/#general","title":"General","text":"<ul> <li>It's intuative 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.</li> </ul>"},{"location":"provider/1password-automation/#why-no-version-history","title":"Why no version history","text":"<ul> <li>1Password only supports version history on their in-built <code>password</code> field. Therefore, implementing version history in this provider would require one Item in 1Password per <code>remoteRef</code> in an ExternalSecret. Additionally <code>remoteRef.property</code> would be pointless/unusable.</li> <li>For example, a Kubernetes secret with 15 keys (say, used in <code>envFrom</code>,) 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:<ul> <li>All Items would have to have unique names which means <code>secretKey</code> couldn't match the Item name the <code>remoteRef</code> is targeting.</li> <li>Maintenance, particularly clean up of no longer used secrets, would be significantly more work.</li> <li>A vault would often become a huge list of unorganized entries as opposed to a much smaller list organized by Kubernetes Secret.</li> </ul> </li> <li>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.</li> </ul>"},{"location":"provider/1password-automation/#keeping-misconfiguration-from-working","title":"Keeping misconfiguration from working","text":"<ul> <li>One instance of the ExternalSecrets Operator can work with many Connect Server instances, but it may not be the best approach.</li> <li>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.)</li> <li>You can run as many 1Password Connect Servers as you need security boundaries to help protect against accidental misconfiguration.</li> </ul>"},{"location":"provider/1password-automation/#patching-externalsecrets-with-kustomize","title":"Patching ExternalSecrets with Kustomize","text":"<ul> <li>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 <code>overlays/staging/kustomization.yaml</code>: <pre><code>---\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n- ../../base/something-with-external-secrets\n- secretStore.staging.yaml\n\npatchesJson6902:\n- target:\nkind: ExternalSecret\nname: \".*\"\npatch: |-\n- op: replace\npath: /spec/secretStoreRef/name\nvalue: staging\n</code></pre></li> </ul>"},{"location":"provider/akeyless/","title":"Akeyless","text":""},{"location":"provider/akeyless/#akeyless-secrets-management-platform","title":"Akeyless Secrets Management Platform","text":"<p>External Secrets Operator integrates with the Akeyless Secrets Management Platform.</p>"},{"location":"provider/akeyless/#create-secret-store","title":"Create Secret Store:","text":"<p>SecretStore resource specifies how to access Akeyless. This resource is namespaced.</p> <p>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.</p> <p>Akeyelss provide several Authentication Methods:</p>"},{"location":"provider/akeyless/#authentication-with-kubernetes","title":"Authentication with Kubernetes:","text":"<p>Options for obtaining Kubernetes credentials include:</p> <ol> <li>Using a service account jwt referenced in serviceAccountRef</li> <li>Using the jwt from a Kind=Secret referenced by the secretRef</li> <li>Using transient credentials from the mounted service account token within the external-secrets operator</li> </ol>"},{"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":"<p><pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: akeyless-secret-store\nspec:\nprovider:\nakeyless:\n# URL of your akeyless API\nakeylessGWApiURL: \"https://api.akeyless.io\"\nauthSecretRef:\nkubernetesAuth:\naccessID: \"p-XXXXXX\"\nk8sConfName: \"my-conf-name\"\n\n# Optional service account field containing the name\n# of a kubernetes ServiceAccount\nserviceAccountRef:\nname: \"my-sa\"\n\n# Optional secret field containing a Kubernetes ServiceAccount JWT\n# used for authenticating with Akeyless\nsecretRef:\nname: \"my-secret\"\nkey: \"token\"\n</code></pre> NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> for <code>serviceAccountRef</code> and <code>secretRef</code> according to the namespaces where the secrets reside.</p>"},{"location":"provider/akeyless/#authentication-with-cloud-identity-or-api-access-key","title":"Authentication With Cloud-Identity or Api-Access-Key","text":"<p>Akeyless providers require an access-id, access-type and access-Type-param To set your SecretStore with an authentication method from Akeyless.</p> <p>The supported auth-methods and their parameters are:</p> accessType accessTypeParam <code>aws_iam</code> - <code>gcp</code> The gcp audience <code>azure_ad</code> azure object id (optional) <code>api_key</code> The access key. <code>k8s</code> 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":"<p>Create a secret containing your credentials using the following example as a guide:</p> <pre><code>apiVersion: v1\nkind: Secret\nmetadata:\nname: akeyless-secret-creds\ntype: Opaque\nstringData:\naccessId: \"p-XXXX\"\naccessType: # gcp/azure_ad/api_key/k8s/aws_iam\naccessTypeParam: # optional: can be one of the following: gcp-audience/azure-obj-id/access-key/k8s-conf-name\n</code></pre>"},{"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":"<p><pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: akeyless-secret-store\nspec:\nprovider:\nakeyless:\n# URL of your akeyless API\nakeylessGWApiURL: \"https://api.akeyless.io\"\nauthSecretRef:\nsecretRef:\naccessID:\nname: akeyless-secret-creds\nkey: accessId\naccessType:\nname: akeyless-secret-creds\nkey: accessType\naccessTypeParam:\nname: akeyless-secret-creds\nkey: accessTypeParam\n</code></pre> NOTE: In case of a <code>ClusterSecretStore</code>, be sure to provide <code>namespace</code> for <code>accessID</code>, <code>accessType</code> and <code>accessTypeParam</code> according to the namespaces where the secrets reside.</p>"},{"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":"<pre><code>....\nspec:\nprovider:\nakeyless:\nakeylessGWApiURL: \"https://your.akeyless.gw:8080/v2\"\n\n# Optional caBundle - PEM/base64 encoded CA certificate\ncaBundle: \"<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\ncaProvider:\ntype: \"Secret/ConfigMap\" # Can be Secret or ConfigMap\nname: \"<name of secret or configmap>\"\nkey: \"<key inside secret>\"\n# namespace is mandatory for ClusterSecretStore and not relevant for SecretStore\nnamespace: \"my-cert-secret-namespace\"\n....\n</code></pre>"},{"location":"provider/akeyless/#creating-an-external-secret","title":"Creating an external secret","text":"<p>To get a secret from Akeyless and create it as a secret on the Kubernetes cluster, a <code>Kind=ExternalSecret</code> is needed.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: database-credentials\nspec:\nrefreshInterval: 1h\n\nsecretStoreRef:\nkind: SecretStore\nname: akeyless-secret-store # Must match SecretStore on the cluster\n\ntarget:\nname: database-credentials # Name for the secret to be created on the cluster\ncreationPolicy: Owner\n\ndata:\n- secretKey: username # Key given to the secret to be created on the cluster\nremoteRef:\nkey: db-username # Full path of the secret on Akeyless\n- secretKey: password # Key given to the secret to be created on the cluster\nremoteRef:\nkey: db-password # Full path of the secret on Akeyless\n</code></pre>"},{"location":"provider/akeyless/#using-datafrom","title":"Using DataFrom","text":"<p>DataFrom can be used to get a secret as a JSON string and attempt to parse it.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: database-credentials\nspec:\nrefreshInterval: 1h\n\nsecretStoreRef:\nkind: SecretStore\nname: akeyless-secret-store # Must match SecretStore on the cluster\n\ntarget:\nname: database-credentials-json # Name for the secret to be created on the cluster\ncreationPolicy: 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\ndataFrom:\n- extract:\nkey: database-credentials # Full path of the secret on Akeyless\n</code></pre>"},{"location":"provider/akeyless/#getting-the-kubernetes-secret","title":"Getting the Kubernetes Secret","text":"<p>The operator will fetch the secret and inject it as a <code>Kind=Secret</code>. <pre><code>kubectl get secret database-credentials -o jsonpath='{.data.db-password}' | base64 -d\n</code></pre></p> <pre><code>kubectl get secret database-credentials-json -o jsonpath='{.data}'\n</code></pre>"},{"location":"provider/alibaba/","title":"Alibaba Cloud","text":""},{"location":"provider/alibaba/#alibaba-cloud-secrets-manager","title":"Alibaba Cloud Secrets Manager","text":"<p>External Secrets Operator integrates with Alibaba Cloud Key Management Service for secrets and Keys management.</p>"},{"location":"provider/alibaba/#authentication","title":"Authentication","text":"<p>We support Access key and RRSA authentication.</p> <p>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.</p>"},{"location":"provider/alibaba/#rrsa-authentication","title":"RRSA authentication","text":"<p>When using RRSA authentication we manually project the OIDC token file to pod as volume</p> <pre><code>extraVolumes:\n- name: oidc-token\nprojected:\nsources:\n- serviceAccountToken:\npath: oidc-token\nexpirationSeconds: 7200 # The validity period of the OIDC token in seconds.\naudience: \"sts.aliyuncs.com\"\n\nextraVolumeMounts:\n- name: oidc-token\nmountPath: /var/run/secrets/tokens\n</code></pre> <p>and provide the RAM role ARN and OIDC volume path to the secret store <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: secretstore-sample\nspec:\nprovider:\nalibaba:\nregionID: ap-southeast-1\nauth:\nrrsa:\noidcProviderArn: acs:ram::1234:oidc-provider/ack-rrsa-ce123456\noidcTokenFilePath: /var/run/secrets/tokens/oidc-token\nroleArn: acs:ram::1234:role/test-role\nsessionName: secrets\n</code></pre></p>"},{"location":"provider/alibaba/#creating-external-secret","title":"Creating external secret","text":"<p>To create a kubernetes secret from the Alibaba Cloud Key Management Service secret a <code>Kind=ExternalSecret</code> is needed.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: example\nspec:\nrefreshInterval: 1h\nsecretStoreRef:\nname: secretstore-sample\nkind: SecretStore\ntarget:\nname: example-secret\ncreationPolicy: Owner\ndata:\n- secretKey: secret-key\nremoteRef:\nkey: ext-secret\n</code></pre>"},{"location":"provider/aws-parameter-store/","title":"AWS Parameter Store","text":""},{"location":"provider/aws-parameter-store/#parameter-store","title":"Parameter Store","text":"<p>A <code>ParameterStore</code> 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 <code>spec.provider.aws.role</code>. This way users of the <code>SecretStore</code> can only access the secrets necessary.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: parameterstore\nspec:\nprovider:\naws:\nservice: ParameterStore\n# define a specific role to limit access\n# to certain secrets\nrole: arn:aws:iam::123456789012:role/external-secrets\nregion: eu-central-1\nauth:\nsecretRef:\naccessKeyIDSecretRef:\nname: awssm-secret\nkey: access-key\nsecretAccessKeySecretRef:\nname: awssm-secret\nkey: secret-access-key\n</code></pre> <p>NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> in <code>accessKeyIDSecretRef</code> and <code>secretAccessKeySecretRef</code> with the namespaces where the secrets reside.</p> <p>API Pricing & Throttling</p> <p>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.</p>"},{"location":"provider/aws-parameter-store/#iam-policy","title":"IAM Policy","text":"<p>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 <code>dev-*</code>. Other operations may require additional permission. For example, finding parameters based on tags will also require <code>ssm:DescribeParameters</code> and <code>tag:GetResources</code> permission with <code>\"Resource\": \"*\"</code>. Generally, the specific permission required will be logged as an error if an operation fails.</p> <p>For further information see AWS Documentation.</p> <pre><code>{\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</code></pre>"},{"location":"provider/aws-parameter-store/#json-secret-values","title":"JSON Secret Values","text":"<p>You can store JSON objects in a parameter. You can access nested values or arrays using gjson syntax:</p> <p>Consider the following JSON object that is stored in the Parameter Store key <code>friendslist</code>: <pre><code>{\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</code></pre></p> <p>This is an example on how you would look up nested keys in the above json object: <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: extract-data\nspec:\n# [omitted for brevity]\ndata:\n- secretKey: my_name\nremoteRef:\nkey: friendslist\nproperty: name.first # Tom\n- secretKey: first_friend\nremoteRef:\nkey: friendslist\nproperty: friends.1.first # Roger\n\n# metadataPolicy to fetch all the tags in JSON format\n- secretKey: tags\nremoteRef:\nmetadataPolicy: Fetch\nkey: database-credentials\n\n# metadataPolicy to fetch a specific tag (dev) from the source secret\n- secretKey: developer\nremoteRef:\nmetadataPolicy: Fetch\nkey: database-credentials\nproperty: dev\n</code></pre></p>"},{"location":"provider/aws-parameter-store/#parameter-versions","title":"Parameter Versions","text":"<p>ParameterStore creates a new version of a parameter every time it is updated with a new value. The parameter can be referenced via the <code>version</code> property</p>"},{"location":"provider/aws-parameter-store/#setsecret","title":"SetSecret","text":"<p>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.</p>"},{"location":"provider/aws-parameter-store/#creating-a-push-secret","title":"Creating a Push Secret","text":"<pre><code>apiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\nname: pushsecret-example # Customisable\nnamespace: default # Same of the SecretStores\nspec:\nrefreshInterval: 10s # Refresh interval for which push secret will reconcile\nsecretStoreRefs: # A list of secret stores to push secrets to\n- name: aws-parameterstore\nkind: SecretStore\nselector:\nsecret:\nname: pokedex-credentials # Source Kubernetes secret to be pushed\ndata:\n- match:\nsecretKey: best-pokemon # Source Kubernetes secret key to be pushed\nremoteRef:\nremoteKey: my-first-parameter # Remote reference (where the secret is going to be pushed)\n</code></pre>"},{"location":"provider/aws-parameter-store/#check-successful-secret-sync","title":"Check successful secret sync","text":"<p>To be able to check that the secret has been succesfully synced you can run the following command:</p> <pre><code>kubectl get pushsecret pushsecret-example\n</code></pre> <p>If the secret has synced successfully it will show the status as \"Synced\".</p>"},{"location":"provider/aws-parameter-store/#test-new-secret-using-aws-cli","title":"Test new secret using AWS CLI","text":"<p>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.</p> <p>Run the following commands to get your synchronized parameter from AWS Parameter Store:</p> <pre><code>aws ssm get-parameter --name=my-first-parameter --region=us-east-1\n</code></pre> <p>You should see something similar to the following output:</p> <pre><code>{\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</code></pre>"},{"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":"<p>Note: If you are using Parameter Store replace <code>service: SecretsManager</code> with <code>service: ParameterStore</code> in all examples below.</p> <p>This is basicially a zero-configuration authentication method that inherits the credentials from the runtime environment using the aws sdk default credential chain.</p> <p>You can attach a role to the pod using IRSA, kiam or kube2iam. When no other authentication method is configured in the <code>Kind=Secretstore</code> this role is used to make all API calls against AWS Secrets Manager or SSM Parameter Store.</p> <p>Based on the Pod's identity you can do a <code>sts:assumeRole</code> before fetching the secrets to limit access to certain keys in your provider. This is optional.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: team-b-store\nspec:\nprovider:\naws:\nservice: SecretsManager\nregion: eu-central-1\n# optional: do a sts:assumeRole before fetching secrets\nrole: team-b\n</code></pre>"},{"location":"provider/aws-parameter-store/#access-key-id-secret-access-key","title":"Access Key ID & Secret Access Key","text":"<p>You can store Access Key ID & Secret Access Key in a <code>Kind=Secret</code> and reference it from a SecretStore.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: team-b-store\nspec:\nprovider:\naws:\nservice: SecretsManager\nregion: eu-central-1\n# optional: assume role before fetching secrets\nrole: team-b\nauth:\nsecretRef:\naccessKeyIDSecretRef:\nname: awssm-secret\nkey: access-key\nsecretAccessKeySecretRef:\nname: awssm-secret\nkey: secret-access-key\n</code></pre> <p>NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> in <code>accessKeyIDSecretRef</code>, <code>secretAccessKeySecretRef</code> with the namespaces where the secrets reside.</p>"},{"location":"provider/aws-parameter-store/#eks-service-account-credentials","title":"EKS Service Account credentials","text":"<p>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.</p> <p>The big advantage of this approach is that ESO runs without any credentials.</p> <pre><code>apiVersion: v1\nkind: ServiceAccount\nmetadata:\nannotations:\neks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/team-a\nname: my-serviceaccount\nnamespace: default\n</code></pre> <p>Reference the service account from above in the Secret Store:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: secretstore-sample\nspec:\nprovider:\naws:\nservice: SecretsManager\nregion: eu-central-1\nauth:\njwt:\nserviceAccountRef:\nname: my-serviceaccount\n</code></pre> <p>NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> for <code>serviceAccountRef</code> with the namespace where the service account resides.</p>"},{"location":"provider/aws-parameter-store/#custom-endpoints","title":"Custom Endpoints","text":"<p>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.</p> <p>Use the following environment variables to point the controller to your custom endpoints. Note: All resources managed by this controller are affected.</p> 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 <code>assumeRole</code> or <code>assumeRoleWithWebIdentity</code> calls."},{"location":"provider/aws-pushsecret/","title":"Aws pushsecret","text":""},{"location":"provider/aws-pushsecret/#push-secret","title":"Push Secret","text":""},{"location":"provider/aws-pushsecret/#iam-policy","title":"IAM Policy","text":""},{"location":"provider/aws-secrets-manager/","title":"AWS Secrets Manager","text":""},{"location":"provider/aws-secrets-manager/#secrets-manager","title":"Secrets Manager","text":"<p>A <code>SecretStore</code> 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 <code>spec.provider.aws.role</code>. This way users of the <code>SecretStore</code> can only access the secrets necessary.</p> <p><pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: aws-secretsmanager\nspec:\nprovider:\naws:\nservice: 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\nrole: arn:aws:iam::123456789012:role/external-secrets\nregion: eu-central-1\nauth:\nsecretRef:\naccessKeyIDSecretRef:\nname: awssm-secret\nkey: access-key\nsecretAccessKeySecretRef:\nname: awssm-secret\nkey: secret-access-key\n</code></pre> NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> in <code>accessKeyIDSecretRef</code> and <code>secretAccessKeySecretRef</code> with the namespaces where the secrets reside.</p>"},{"location":"provider/aws-secrets-manager/#iam-policy","title":"IAM Policy","text":"<p>Create a IAM Policy to pin down access to secrets matching <code>dev-*</code>.</p> <pre><code>{\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</code></pre>"},{"location":"provider/aws-secrets-manager/#json-secret-values","title":"JSON Secret Values","text":"<p>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:</p> <p>Consider the following JSON object that is stored in the SecretsManager key <code>friendslist</code>: <pre><code>{\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</code></pre></p> <p>This is an example on how you would look up nested keys in the above json object:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: example\nspec:\nrefreshInterval: 1m\nsecretStoreRef:\nname: aws-secretsmanager\nkind: SecretStore\ntarget:\nname: friends\ncreationPolicy: Owner\ndata:\n- secretKey: my_name\nremoteRef:\nkey: friendslist\nproperty: name.first # Tom\n- secretKey: first_friend\nremoteRef:\nkey: friendslist\nproperty: friends.1.first # Roger\n\n# metadataPolicy to fetch all the labels in JSON format\n- secretKey: tags\nremoteRef:\nmetadataPolicy: Fetch key: database-credentials\n\n# metadataPolicy to fetch a specific label (dev) from the source secret\n- secretKey: developer\nremoteRef:\nmetadataPolicy: Fetch key: database-credentials\nproperty: dev\n</code></pre>"},{"location":"provider/aws-secrets-manager/#secret-versions","title":"Secret Versions","text":"<p>SecretsManager creates a new version of a secret every time it is updated. The secret version can be reference in two ways, the <code>VersionStage</code> and the <code>VersionId</code>. The <code>VersionId</code> 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 <code>VersionStage</code> is an alias to a <code>VersionId</code>, and can refer to different secret data as the secret is updated. By default, SecretsManager will add the version stages <code>AWSCURRENT</code> and <code>AWSPREVIOUS</code> to every secret, but other stages can be created via the update-secret-version-stage api.</p> <p>The <code>version</code> field on the <code>remoteRef</code> of the ExternalSecret will normally consider the version to be a <code>VersionStage</code>, but if the field is prefixed with <code>uuid/</code>, then the version will be considered a <code>VersionId</code>.</p> <p>So in this example, the operator will request the same secret with different versions: <code>AWSCURRENT</code> and <code>AWSPREVIOUS</code>:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: versioned-api-key\nspec:\nrefreshInterval: 1h\nsecretStoreRef:\nname: aws-secretsmanager\nkind: SecretStore\ntarget:\nname: versioned-api-key\ncreationPolicy: Owner\ndata:\n- secretKey: previous-api-key\nremoteRef:\nkey: \"production/api-key\"\nversion: \"AWSPREVIOUS\"\n- secretKey: current-api-key\nremoteRef:\nkey: \"production/api-key\"\nversion: \"AWSCURRENT\"\n</code></pre> <p>While in this example, the operator will request the secret with <code>VersionId</code> as <code>abcd-1234</code></p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: versioned-api-key\nspec:\nrefreshInterval: 1h\nsecretStoreRef:\nname: aws-secretsmanager\nkind: SecretStore\ntarget:\nname: versioned-api-key\ncreationPolicy: Owner\ndata:\n- secretKey: api-key\nremoteRef:\nkey: \"production/api-key\"\nversion: \"uuid/123e4567-e89b-12d3-a456-426614174000\"\n</code></pre>"},{"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":"<p>Note: If you are using Parameter Store replace <code>service: SecretsManager</code> with <code>service: ParameterStore</code> in all examples below.</p> <p>This is basicially a zero-configuration authentication method that inherits the credentials from the runtime environment using the aws sdk default credential chain.</p> <p>You can attach a role to the pod using IRSA, kiam or kube2iam. When no other authentication method is configured in the <code>Kind=Secretstore</code> this role is used to make all API calls against AWS Secrets Manager or SSM Parameter Store.</p> <p>Based on the Pod's identity you can do a <code>sts:assumeRole</code> before fetching the secrets to limit access to certain keys in your provider. This is optional.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: team-b-store\nspec:\nprovider:\naws:\nservice: SecretsManager\nregion: eu-central-1\n# optional: do a sts:assumeRole before fetching secrets\nrole: team-b\n</code></pre>"},{"location":"provider/aws-secrets-manager/#access-key-id-secret-access-key","title":"Access Key ID & Secret Access Key","text":"<p>You can store Access Key ID & Secret Access Key in a <code>Kind=Secret</code> and reference it from a SecretStore.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: team-b-store\nspec:\nprovider:\naws:\nservice: SecretsManager\nregion: eu-central-1\n# optional: assume role before fetching secrets\nrole: team-b\nauth:\nsecretRef:\naccessKeyIDSecretRef:\nname: awssm-secret\nkey: access-key\nsecretAccessKeySecretRef:\nname: awssm-secret\nkey: secret-access-key\n</code></pre> <p>NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> in <code>accessKeyIDSecretRef</code>, <code>secretAccessKeySecretRef</code> with the namespaces where the secrets reside.</p>"},{"location":"provider/aws-secrets-manager/#eks-service-account-credentials","title":"EKS Service Account credentials","text":"<p>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.</p> <p>The big advantage of this approach is that ESO runs without any credentials.</p> <pre><code>apiVersion: v1\nkind: ServiceAccount\nmetadata:\nannotations:\neks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/team-a\nname: my-serviceaccount\nnamespace: default\n</code></pre> <p>Reference the service account from above in the Secret Store:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: secretstore-sample\nspec:\nprovider:\naws:\nservice: SecretsManager\nregion: eu-central-1\nauth:\njwt:\nserviceAccountRef:\nname: my-serviceaccount\n</code></pre> <p>NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> for <code>serviceAccountRef</code> with the namespace where the service account resides.</p>"},{"location":"provider/aws-secrets-manager/#custom-endpoints","title":"Custom Endpoints","text":"<p>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.</p> <p>Use the following environment variables to point the controller to your custom endpoints. Note: All resources managed by this controller are affected.</p> 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 <code>assumeRole</code> or <code>assumeRoleWithWebIdentity</code> calls."},{"location":"provider/azure-key-vault/","title":"Azure Key Vault","text":""},{"location":"provider/azure-key-vault/#azure-key-vault","title":"Azure Key vault","text":"<p>External Secrets Operator integrates with Azure Key vault for secrets, certificates and Keys management.</p>"},{"location":"provider/azure-key-vault/#authentication","title":"Authentication","text":"<p>We support Service Principals, Managed Identity and Workload Identity authentication.</p> <p>To use Managed Identity authentication, you should use aad-pod-identity to assign the identity to external-secrets operator. To add the selector to external-secrets operator, use <code>podLabels</code> in your values.yaml in case of Helm installation of external-secrets.</p> <p>We support connecting to different cloud flavours azure supports: <code>PublicCloud</code>, <code>USGovernmentCloud</code>, <code>ChinaCloud</code> and <code>GermanCloud</code>. You have to specify the <code>environmentType</code> and point to the correct cloud flavour. This defaults to <code>PublicCloud</code>.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: azure-backend\nspec:\nprovider:\nazurekv:\n# PublicCloud, USGovernmentCloud, ChinaCloud, GermanCloud\nenvironmentType: PublicCloud # default\n</code></pre> <p>Minimum required permissions are <code>Get</code> over secret and certificate permissions. This can be done by adding a Key Vault access policy:</p> <pre><code>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</code></pre>"},{"location":"provider/azure-key-vault/#service-principal-key-authentication","title":"Service Principal key authentication","text":"<p>A service Principal client and Secret is created and the JSON keyfile is stored in a <code>Kind=Secret</code>. The <code>ClientID</code> and <code>ClientSecret</code> should be configured for the secret. This service principal should have proper access rights to the keyvault to be managed by the operator</p>"},{"location":"provider/azure-key-vault/#managed-identity-authentication","title":"Managed Identity authentication","text":"<p>A Managed Identity should be created in Azure, and that Identity should have proper rights to the keyvault to be managed by the operator.</p> <p>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 <code>identityId</code> field.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: azure-store\nspec:\nprovider:\n# provider type: azure keyvault\nazurekv:\nauthType: ManagedIdentity\n# Optionally set the Id of the Managed Identity, if multiple identities are assigned to external-secrets operator\nidentityId: \"<MI_clientId>\"\n# URL of your vault instance, see: https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates\nvaultUrl: \"https://my-keyvault-name.vault.azure.net\"\n</code></pre>"},{"location":"provider/azure-key-vault/#workload-identity","title":"Workload Identity","text":"<p>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 <code>terraform</code>, the Azure Portal or the <code>az</code> cli. We found the azwi cli very helpful. The Azure Workload Identity Quick Start Guide is also good place to get started.</p> <p>This is basically a two step process:</p> <ol> <li>Create a Kubernetes Service Account (guide)</li> </ol> <p><pre><code>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</code></pre> 2. Configure the trust relationship between Azure AD and Kubernetes (guide)</p> <pre><code>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</code></pre> <p>With these prerequisites met you can configure <code>ESO</code> to use that Service Account. You have two options:</p>"},{"location":"provider/azure-key-vault/#mounted-service-account","title":"Mounted Service Account","text":"<p>You run the controller and mount that particular service account into the pod by adding the label <code>azure.workload.identity/use: \"true\"</code>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.</p> <pre><code>apiVersion: v1\nkind: ServiceAccount\nmetadata:\n# this service account was created by azwi\nname: workload-identity-sa\nannotations:\nazure.workload.identity/client-id: 7d8cdf74-xxxx-xxxx-xxxx-274d963d358b\nazure.workload.identity/tenant-id: 5a02a20e-xxxx-xxxx-xxxx-0ad5b634c5d8\n---\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: azure-store\nspec:\nprovider:\nazurekv:\nauthType: WorkloadIdentity\nvaultUrl: \"https://xx-xxxx-xx.vault.azure.net\"\n# note: no serviceAccountRef was provided\n</code></pre>"},{"location":"provider/azure-key-vault/#referenced-service-account","title":"Referenced Service Account","text":"<p>You run the controller without service account (effectively without azure permissions). Now you have to configure the SecretStore and set the <code>serviceAccountRef</code> 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 withour Azure permissions and delegate authentication via service accounts in particular namespaces. Also see our [Multi-Tenancy Guide] for design considerations.</p> <pre><code>apiVersion: v1\nkind: ServiceAccount\nmetadata:\n# this service account was created by azwi\nname: workload-identity-sa\nannotations:\nazure.workload.identity/client-id: 7d8cdf74-xxxx-xxxx-xxxx-274d963d358b\nazure.workload.identity/tenant-id: 5a02a20e-xxxx-xxxx-xxxx-0ad5b634c5d8\n---\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: azure-store\nspec:\nprovider:\nazurekv:\nauthType: WorkloadIdentity\nvaultUrl: \"https://xx-xxxx-xx.vault.azure.net\"\nserviceAccountRef:\nname: workload-identity-sa\n</code></pre>"},{"location":"provider/azure-key-vault/#update-secret-store","title":"Update secret store","text":"<p>Be sure the <code>azurekv</code> provider is listed in the <code>Kind=SecretStore</code></p> <p><pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: azure-store\nspec:\nprovider:\n# provider type: azure keyvault\nazurekv:\n# azure tenant ID, see: https://docs.microsoft.com/en-us/azure/active-directory/fundamentals/active-directory-how-to-find-tenant\ntenantId: \"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\nvaultUrl: \"https://kvtestpushsecret.vault.azure.net\"\nauthSecretRef:\n# points to the secret that contains\n# the azure service principal credentials\nclientId:\nname: azure-secret-sp\nkey: ClientID\nclientSecret:\nname: azure-secret-sp\nkey: ClientSecret\n</code></pre> NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> in <code>clientId</code> and <code>clientSecret</code> with the namespaces where the secrets reside.</p> <p>Or in case of Managed Identity authentication:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: azure-store\nspec:\nprovider:\n# provider type: azure keyvault\nazurekv:\nauthType: ManagedIdentity\n# Optionally set the Id of the Managed Identity, if multiple identities are assigned to external-secrets operator\nidentityId: \"<MI_clientId>\"\n# URL of your vault instance, see: https://docs.microsoft.com/en-us/azure/key-vault/general/about-keys-secrets-certificates\nvaultUrl: \"https://my-keyvault-name.vault.azure.net\"\n</code></pre>"},{"location":"provider/azure-key-vault/#object-types","title":"Object Types","text":"<p>Azure KeyVault manages different object types, we support <code>keys</code>, <code>secrets</code> and <code>certificates</code>. Simply prefix the key with <code>key</code>, <code>secret</code> or <code>cert</code> to retrieve the desired type (defaults to secret).</p> Object Type Return Value <code>secret</code> the raw secret value. <code>key</code> A JWK which contains the public key. Azure KeyVault 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. <code>certificate</code> 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":"<p>To create a kubernetes secret from the Azure Key vault secret a <code>Kind=ExternalSecret</code> is needed.</p> <p>You can manage keys/secrets/certificates saved inside the keyvault , by setting a \"/\" prefixed type in the secret name, the default type is a <code>secret</code>. Other supported values are <code>cert</code> and <code>key</code>.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: database-credentials\nspec:\nrefreshInterval: 1h\nsecretStoreRef:\nkind: SecretStore\nname: azure-store\n\ntarget:\nname: database-credentials\ncreationPolicy: Owner\n\ndata:\n# name of the SECRET in the Azure KV (no prefix is by default a SECRET)\n- secretKey: database-username\nremoteRef:\nkey: database-username\n\n# explicit type and name of secret in the Azure KV\n- secretKey: database-password\nremoteRef:\nkey: secret/database-password\n\n# metadataPolicy to fetch all the tags in JSON format\n- secretKey: database-credentials-metadata\nremoteRef:\nkey: database-credentials\nmetadataPolicy: Fetch\n\n# metadataPolicy to fetch a specific tag which name must be in property\n- secretKey: database-credentials\nremoteRef:\nkey: database-credentials\nmetadataPolicy: Fetch\nproperty: 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\nremoteRef:\nkey: 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\nremoteRef:\nkey: key/encryption-pubkey\n</code></pre> <p>The operator will fetch the Azure Key vault secret and inject it as a <code>Kind=Secret</code>. Then the Kubernetes secret can be fetched by issuing:</p> <pre><code>kubectl get secret secret-to-be-created -n <namespace> -o jsonpath='{.data.dev-secret-test}' | base64 -d\n</code></pre> <p>To select all secrets inside the key vault or all tags inside a secret, you can use the <code>dataFrom</code> directive:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: all-secrets\nspec:\nrefreshInterval: 1h # rate ESO pulls Azure Key Vault\nsecretStoreRef:\nkind: SecretStore\nname: azure-store # name of the SecretStore (or kind specified)\ntarget:\nname: all-secrets # name of the k8s Secret to be created\ncreationPolicy: Owner\ndataFrom:\n# find all secrets starting with dev-\n- find:\nname:\nregexp: \"^dev\"\n# find all secrets with tags\n- find:\ntags:\nenvironment: dev\n\n# extract data from a json value\n- extract:\nkey: database-credentials\n\n# fetch tags from `database-credentials`\n# and store them as individual keys in a secret\n- extract:\nkey: database-credentials\nmetadataPolicy: Fetch\n</code></pre> <p>To get a PKCS#12 certificate from Azure Key Vault and inject it as a <code>Kind=Secret</code> of type <code>kubernetes.io/tls</code>:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: tls-client-credentials\nspec:\nrefreshInterval: 1h\nsecretStoreRef:\nkind: SecretStore\nname: azure-store\ntarget:\ntemplate:\ntype: kubernetes.io/tls\nengineVersion: v2\ndata:\ntls.crt: \"{{ .tls | b64dec | pkcs12cert }}\"\ntls.key: \"{{ .tls | b64dec | pkcs12key }}\"\ndata:\n- secretKey: tls\nremoteRef:\n# Azure Key Vault certificates must be fetched as secret/cert-name\nkey: secret/tls-client-credentials\n</code></pre>"},{"location":"provider/azure-key-vault/#creating-a-pushsecret","title":"Creating a PushSecret","text":"<p>You can push secrets to Keyvault into the different <code>secret</code>, <code>key</code> and <code>certificate</code> APIs.</p>"},{"location":"provider/azure-key-vault/#pushing-to-a-secret","title":"Pushing to a Secret","text":"<p>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 Keyvault: <pre><code>apiVersion: v1\nkind: Secret\nmetadata:\nname: source-secret\nstringData:\nsource-key: \"my-secret\"\n---\napiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\nname: pushsecret-example\nnamespace: default\nspec:\nrefreshInterval: 10s # Refresh interval for which push secret will reconcile\ndeletionPolicy: Delete\nsecretStoreRefs: # A list of secret stores to push secrets to\n- name: azure-store\nkind: SecretStore\nselector:\nsecret:\nname: source-secret # Source Kubernetes secret to be pushed\ndata:\n- match:\nsecretKey: source-key # Source Kubernetes secret key containing the secret\nremoteRef:\nremoteKey: my-azkv-secret-name </code></pre></p> <p>Note</p> <p>In order to create a PushSecret targeting keys, <code>CreateSecret</code> and <code>DeleteSecret</code> actions must be granted to the Service Principal/Identity configured on the SecretStore.</p>"},{"location":"provider/azure-key-vault/#pushing-to-a-key","title":"Pushing to a Key","text":"<p>The first step is to generate a valid Private Key. Supported Formats include <code>PRIVATE KEY</code>, <code>RSA PRIVATE KEY</code> AND <code>EC PRIVATE KEY</code> (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:</p> <pre><code>apiVersion: v1\nkind: Secret\nmetadata:\nname: source-key\ndata:\ntls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlKSndJQkFBS0NBZ0VBcTRJTEFXRkZRdXNCMTFtYk1FQ2ZSRjh2WUJWeVhqYmFBczN5SE5RWXBNbUNWNkt0CmxKOVcrMlRMRUc3WnlhN1hwTGNuTlc1QWtOM3FrYW1zWGNiV0dLMUZIK3BKcXlKK2RkaktrMjlXa1RHYnV2THgKdkNWSGp6cndPN0NFdTVGWmIvV2NxcjMzb2l4YWdwNlBFYVZKR0t6U3hJaFMvZDlXR1JuN0MySnhKRnlaWlBLWgpYY01KOEg0TmZ5UDcrWjVZTjJMaWQ4eWdWUlpDWXgzQktadXdsQmdwMkpjMmpkN0x4WmQrYmx3REdGUEw4VHpPCk5LZjFRT2JndmdWY2E4M0NWVTJLZ3p0R0M0YVhkVDR3TkYrV25Hdmgza1JrVlBqMDRsbms4Z001M0ZJZ0dJV2oKalphRVd2b2RBMFJSWEtwL3IyMFI4aFRRNXlZMGJ4ejVSQVJyTEdkY1BlejRJY3FSZG5nUm10VldkQ29ZMzZNMgphdE9HRnNPd0ZCbEpuRVhUY0dxWXlnbnZYQlVzVXRNSmdYY3pDWlB1czlTODZtTGxjajlZK3BNb3FSY0NpMCtOCjBtd3VvNUt3dG1tSjBURnBXR3RLS0VSVUpOZkduNWIxekZrWGxsZSt5ODMzMkN2Nk9yWXNCemNya0pFOGJHRmUKTytZY1lqYytGblJpN3JhWXpwTzRReDJ5dzUxSGRScis3aldxNnFrejEzUlZya3hSQ1NFVW5wbVE1M0RvSTZjWgpDakN0UjZWZ3VVY0xnYndFM2w0dlluV0VXMHVNNmZjenlQem1LVis5M0RFd1U4Q3pXR09neTJrNjBYcmx2YkJwCjYrbFdlZVZnNzJJZjZEb0oyVFZZQStFZUpOWDBpaHVUTmpDNmk3VVZYdm5KRWNhSnFTRXE1QTY4OUs4Q0F3RUEKQVFLQ0FnQWN3S2x0cXN2OHd2OUZCaDJ4UWpReE55L3ZFTWxpcUJsMmZPWkpGUG1vcnF1dVczUjBSUjVFK1FuZQpFR2RzbTJaRmsvcjd4eWNGNGw1UDJ6MHRYNGRIRGMxWDQyUkVUMzBaN3FWUGdFdm4vWVFaSEYrUVprT1A3SmFYCnV5a1ZkUEdraG0ya1prS2Nxb2psK3dVTE5VV0M0SDVaT20ySGFDaTcvcElLdjQ4dVJHUG0rNURnbWpFUlkyQ0oKM3hPQUxwNmxjbXQ3SUJBRkU3MC9kcDZLaGpKZE1ZdmFac2RiazIxZ0M5ekRUYU9yTVdrd1lUeEVzWis1S0x1bQp2NmxWM1dIbUFTRG1qVXBaNWs5LzlWUUpnN2p4TWxqa2RWeklyaEFIM29BMlhub1Z5S0xlMlpDb3pRSVZhbmJ3CnRFUmJuNjNXVUJmQkdPSkl6aXZlTU9KTkY5eUxoOTBrWmszaDR0N3dqWFNodUR2SGp2ZmVaVzhjOStTVTh3VlUKTlRZQzUxaHFKYXNDdWdHa0NVZGp3V0pucXc4QU1VNGZFQkM0V1JBRWpKMTdYMDVJNmt3c2V2ZVRrNjlmOTNWSgoxS3ZVcmpKTkNpeVVXVWVzc0lrWllacGxJZnYrbExJUWNrTmVpOFdRRjV0RTh0Z09heHJLZXBWMW81NlkvT2tUCmFyYjg1Z2VYb0Z0Tm9NMUd6TkxqQnQrZ2pIY2owcExZakZ5L2Jsa2ZrZnRNMW1hN0U3L3ROK0d2bHBhQXE3RUcKNTc3a2xoNXJGWGQza09meVY1U3E3cmFQWDRZOWlPSU5EaXBVblpXcENHYjRHQS8wSFozdWpacTB6SlQ4Z0NyaQpSQndBRFBVY0J0UzYxUzE0WjJhU0Q1R1NKUmFHbFNGdVRoY1lxR0MrK08xcTllbkRpUUtDQVFFQTJjN21EN2FvClRlcExYRklWMzU0Zk5QTFhGYm9JSXZPZHhLVnYvR25NajZhMVhCd3RPdWhlQTlmNlhacUY2ZXViVmtLK1ZobWgKR1k5dm5nWHd2ZHBiZTIzdmN5d2duYWxTSDVYRGZnaE9LZU5ZMDJSYnhtWlVTMEtvWGRhSStHVDA3QWN6ZFFkaQpMRnBYTWtybmQwZC9taHZGNkVxN0t0Mkw2YkVoSXptQU5sTWMyY1lBeEIwY0UzRjJLQTNqV3dyQjRuMUZrRTlQCnMzby9tbmVXNEswMVlMVEsyMGhPOTlNeG5oNzNTV1h1SWFXdlI3T1pRcHFEMWFtYXBGUGlqY0RlRVpQczVUMFIKNEk3aVczNWF4YTl5WncxSkYrMTV5aEhkTTNHZllGaXJudy8zRlpQL282RzBJeW50YUZLNkFGU0dIaHpMcEs1awphSWRMYWVBbWlMYnpmUUtDQVFFQXlaVExET1h5V2VTZjUwV0oxUzVtTHJDMVJUNUI4K1dvZzhiVSsvSWxZTjF6Cm82eTM2QkVJcTlMWGhUUTl6cGp0MlcwNTRHa3FjU1hKcTJtajFHSEE5Q3FCTGNTaldyNHR6ZHFXTzREcnoxN0gKVCtpaEZqZ016R2praXhNSlpkZ2JoWGprQ3RkVEMzdGJhaFBiNjN4TjJGM0d6aE8xRmRUVWZ6bXM3WkVzWmRhYgpTaFZaaUFBOU40dnpmYWYyZ3I2SlB2azZwbEdpV2hvT2xkclRvVG4zSFRPNGJNYWJxc20vSFNTU2FyNUtXTUlXCnZlSVN4YjFoQTFIL1dTMXcvN1dqVHJ1UUZqWDRtU1BkT2lqL3hZblVWWjcrTjhLN3VKREJZNjcrWXVNM2RQNHgKdUJ2RjcvdDdwd3g0b002QnhBbGpQZExwZ2dxRFFLb3drVk9reFZ3b213S0NBUUJJS0pOdmdVUWhEQTRMZCtabgpQeXQzanp4U3BsOHJ0U24vakErZHdDOVZLQlhOZmtnOXk5M1p5Q1BaL3VkK3A5KytwRDRLcUZNRzlNNDF2Q0lWCnc5R3JBckRocHl6bkRzRjJWVmQrMmFHTG54WStjbkUxT1pHVG5YSEtKTmtiOGRaeW03QWdoV0d3Ny8wVFhGMXkKMXUwZlVUUXYwUkpSRVRUWkp5V2pWZGwwSmZUWThSQXY2TFQwZkJKNUVxRFArTEJqS0wxeklkTjEwbnBmNGw3Sgo4SmhPZ1piekx2RjZpUzFYQlV0SHRjMCt1SFZwZThhNm1oWXpJdzFvZzZINjlIcWR1RFF6ZmhmK0hWaEFsNHZiCkVsVUVieEpZS3dTK1BVemJUamxPNGhGNWtRQjYxWjFMeUxhMUw1N0hnU0MrRzBLVGwxYWdLR1o3ZXRjeExHR1gKeVlUQkFvSUJBRms2NWc3VmtzdTc2aFJqc2JtT0NtbE1pMUVWVi9od2hvR2VlQlQyZ1JrNXJjQ2I2ZVJ0OWRxcApRQUdVdUc5RlByUHFKNTV3cnZyYThVUlJSTlgwVjRjOWNXVWpEL1JSRHRGNm10bklIWm56cUdKMDVTbUNzaGVoCnJ0anBHbFhjcllJTm0xUTVNR2Q2dVdKaFhBNEhQaVl5akpnWUhTYUd5WEZ2eEY1OHpweGR2T3UwTzZkNkE1OGMKOGpHRE1obDU0aUxnQzlnbmRxaFB0SGtkSG1UVjFjODFYOE8ydnAyQkpIbndBR2dEeDhFMldQN0FuZkt0KzgyTwpkR3V6TTd2ZFdXYTJtL2RZK0t4Qk5lSlMxN1ZIWjVobkFyMElGRFNFenpZaTlqUXJ4QmFqbHJxYWdLblVOazRoCnRSdnBqWU9MYkVTbm9mbVFVYjFFR0srYnlPb2IrMVVDZ2dFQUJJTFZ0eVV6cFNobW1FN0crZ3I0aGpBb0UxQlgKTDd2SHVIbGdrMStNbFR6RlNLZXpZUDY4RnFsRjRocEFRT2kxTnN3Sy9zaXppdGEycUdUUDJyd1d3NkJUUW9wawplbkdDaEtWNUp0SHRBeDZ2bEZ0aUxUVzE5QTlvUXZEbEllYmNsaFRob2ZWeHV0NFI4RC8vSXZRQXRxbm5jUFFuCnZ5RzRUakl4VCtsWDZqcXdHbUlwRVI4TlpLdjVXU2EzOVVNdlF0ZUJ3Q1hUZEF6Wnlqc0RjRENodlJVRno3S2YKNVlMZ1pVdEt2cEZnbVNYNGF0b2t1TCt5Nm9LYm93Tld6bVdhNzhHbzRLUlhGK2xxUk5OL0dTM0lkM01MdDNmKwovLzRvcWNZa1lyU0dEbjJPenRabGpFcjFrK0NCQ0Rvc3pFMms2b2ZmN2pBck1YUG5McUVXQXkrWDdBPT0KLS0tLS1FTkQgUlNBIFBSSVZBVEUgS0VZLS0tLS0K\n---\napiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\nname: pushsecret-example\nnamespace: default\nspec:\nrefreshInterval: 10s # Refresh interval for which push secret will reconcile\ndeletionPolicy: Delete\nsecretStoreRefs: # A list of secret stores to push secrets to\n- name: azure-store\nkind: SecretStore\nselector:\nsecret:\nname: source-key # Source Kubernetes secret to be pushed\ndata:\n- match:\nsecretKey: tls.key # Source Kubernetes secret key containing the JWK\nremoteRef:\nremoteKey: key/my-azkv-key-name\n</code></pre> <p>Note</p> <p>In order to create a PushSecret targeting keys, <code>ImportKey</code> and <code>DeleteKey</code> actions must be granted to the Service Principal/Identity configured on the SecretStore.</p>"},{"location":"provider/azure-key-vault/#pushing-to-a-certificate","title":"Pushing to a Certificate","text":"<p>The first step is to generate a valid P12 certificate. Currently, only PKCS1/PKCS8 types are supported. Currently only passwordless P12 certificates are supported.</p> <p>After uploading your P12 certificate to a Kubernetes Secret, the next step is to create a PushSecret manifest with the following configuration <pre><code>apiVersion: v1\nkind: Secret\nmetadata:\nname: source-certificate\ndata:\ncert.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:\nname: pushsecret-example\nnamespace: default\nspec:\nrefreshInterval: 10s # Refresh interval for which push secret will reconcile\ndeletionPolicy: Delete\nsecretStoreRefs: # A list of secret stores to push secrets to\n- name: azure-store\nkind: SecretStore\nselector:\nsecret:\nname: source-certificate # Source Kubernetes secret to be pushed\ndata:\n- match:\nsecretKey: cert.p12 # Source Kubernetes secret key containing the certificate\nremoteRef:\nremoteKey: cert/my-azkv-cert-name\n</code></pre></p> <p>Note</p> <p>In order to create a PushSecret targeting keys, <code>ImportCertificate</code> and <code>DeleteCertificate</code> actions must be granted to the Service Principal/Identity configured on the SecretStore.</p>"},{"location":"provider/cloak/","title":"Cloak End 2 End Encrypted Secrets","text":""},{"location":"provider/cloak/#cloak","title":"Cloak","text":"<p>Sync secrets from the Cloak Encrypted Secrets Platform to Kubernetes using the External Secrets Operator.</p> <p>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.</p>"},{"location":"provider/cloak/#key-setup","title":"Key Setup","text":"<p>From the Cloak user interface create a service account and store the private key on your file system.</p> <p>Now create a kubernetes secret in the same namespace as the External Secrets Operator.</p> <pre><code>HISTIGNORE='*kubectl*' kubectl --namespace=external-secrets \\\ncreate secret generic cloak-key \\\n--from-file=ecdh_private_key=$LOCATION_OF_YOUR_PEM_FILE\n</code></pre>"},{"location":"provider/cloak/#deploy-the-decryption-proxy","title":"Deploy the decryption proxy","text":"<pre><code># The cloak external secrets proxy\napiVersion: apps/v1\nkind: Deployment\nmetadata:\nname: cloak-external-secrets\nnamespace: external-secrets\nspec:\nselector:\nmatchLabels:\napp: cloak-external-secrets\nreplicas: 1\ntemplate:\nmetadata:\nlabels:\napp: cloak-external-secrets\nspec:\ncontainers:\n- name: cloak-external-secrets\nimage: purtontech/cloak-external-secrets:latest\nimagePullPolicy: IfNotPresent\nenv: - name: ECDH_PRIVATE_KEY valueFrom: secretKeyRef: name: cloak-key key: ecdh_private_key ports:\n- containerPort: 7105\n</code></pre> <p>And a Kubernetes Service so External Secrets Operator can access the proxy.</p> <pre><code>apiVersion: v1\nkind: Service\nmetadata:\nname: cloak-external-secrets-service\nnamespace: external-secrets\nspec:\nselector:\napp: cloak-external-secrets\nports:\n- protocol: TCP\nport: 7105\ntargetPort: 7105\n</code></pre>"},{"location":"provider/cloak/#create-a-secret-store","title":"Create a secret store","text":"<p>You can now place the configuration in any Kubernetes Namespace.</p> <pre><code># An External secrets webhookl\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: cloak-backend\nspec:\nprovider:\nwebhook:\nurl: \"http://cloak-external-secrets-service:7105/{{ .remoteRef.key }}\"\nresult:\njsonPath: \"$.value\"\nheaders:\nContent-Type: application/json\n</code></pre>"},{"location":"provider/cloak/#connect-a-secret-to-the-provider","title":"Connect a secret to the provider","text":"<p>Each <code>secretKey</code> reference in the yaml should point to the name of the secret as it is stored in Cloak.</p> <pre><code># Access a secret\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: cloak-example\nspec:\nrefreshInterval: \"15m\"\nsecretStoreRef:\nname: cloak-backend\nkind: SecretStore\ntarget:\nname: example-sync\ndata:\n- secretKey: access-token\nremoteRef:\nkey: PULUMI_ACCESS_TOKEN\n- secretKey: do-access-token\nremoteRef:\nkey: DIGITALOCEAN_ACCESS_TOKEN\n</code></pre>"},{"location":"provider/conjur/","title":"CyberArk Conjur","text":""},{"location":"provider/conjur/#conjur-provider","title":"Conjur Provider","text":"<p>The following sections outline what is needed to get your external-secrets Conjur provider setup.</p>"},{"location":"provider/conjur/#pre-requirements","title":"Pre-requirements","text":"<p>This section contains the list of the pre-requirements before installing the Conjur Provider.</p> <ul> <li>Running Conjur Server<ul> <li>These items will be needed in order to configure the secret-store<ul> <li>Conjur endpoint - include the scheme but no trailing '/', ex: https://myapi.example.com</li> <li>Conjur credentials (hostid, apikey)</li> <li>Certificate for Conjur server is OPTIONAL -- But, when using a self-signed cert when setting up your Conjur server, it is strongly recommended to populate \"caBundle\" with self-signed cert in the secret-store definition</li> </ul> </li> </ul> </li> <li>Kubernetes cluster<ul> <li>External Secrets Operator is installed</li> </ul> </li> </ul>"},{"location":"provider/conjur/#create-external-secret-store-definition","title":"Create External Secret Store Definition","text":"<p>Recommend to save as filename: <code>conjur-secret-store.yaml</code></p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: conjur\nspec:\nprovider:\nconjur:\n# Service URL\nurl: https://myapi.conjur.org\n# [OPTIONAL] base64 encoded string of certificate\ncaBundle: OPTIONALxFIELDxxxBase64xCertxString== auth:\napikey:\n# conjur account\naccount: conjur\nuserRef: # Get this from K8S secret\nname: conjur-creds\nkey: hostid\napiKeyRef: # Get this from K8S secret\nname: conjur-creds\nkey: apikey\n</code></pre>"},{"location":"provider/conjur/#create-external-secret-definition","title":"Create External Secret Definition","text":"<p>Important note: Creds must live in the same namespace as a SecretStore - the secret store may only reference secrets from the same namespace. When using a ClusterSecretStore this limitation is lifted and the creds can live in any namespace.</p> <p>Recommend to save as filename: <code>conjur-external-secret.yaml</code></p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: conjur\nspec:\nrefreshInterval: 10s\nsecretStoreRef:\n# This name must match the metadata.name in the `SecretStore`\nname: conjur\nkind: SecretStore\ndata:\n- secretKey: secret00\nremoteRef:\nkey: data/app1/secret00\n</code></pre>"},{"location":"provider/conjur/#create-kubernetes-secrets","title":"Create Kubernetes Secrets","text":"<p>In order for the ESO Conjur provider to connect to the Conjur server, the creds should be stored as k8s secrets. Please refer to https://kubernetes.io/docs/concepts/configuration/secret/#creating-a-secret for various methods to create secrets. Here is one way to do it using <code>kubectl</code></p> <p>NOTE: \"conjur-creds\" is the \"name\" used in \"userRef\" and \"apikeyRef\" in the conjur-secret-store definition</p> <pre><code># 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</code></pre>"},{"location":"provider/conjur/#create-the-external-secrets-store","title":"Create the External Secrets Store","text":"<pre><code># WARNING: this will create the store configuration in the \"external-secrets\" namespace, adjust this to your own situation\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</code></pre>"},{"location":"provider/conjur/#create-the-external-secret","title":"Create the External Secret","text":"<pre><code># WARNING: this will create the external-secret configuration in the \"external-secrets\" namespace, adjust this to your own situation\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</code></pre>"},{"location":"provider/conjur/#getting-the-k8s-secret","title":"Getting the K8S Secret","text":"<ul> <li>Login to your Conjur server and verify that your secret exists</li> <li>Review the value of your Kubernetes secret to see that it contains the same value from Conjur</li> </ul> <pre><code># 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</code></pre>"},{"location":"provider/conjur/#support","title":"Support","text":"<p>Copyright (c) 2023 CyberArk Software Ltd. All rights reserved.</p> <p>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</p> <p>http://www.apache.org/licenses/LICENSE-2.0</p> <p>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.</p>"},{"location":"provider/delinea/","title":"Delinea","text":""},{"location":"provider/delinea/#delinea-devops-secrets-vault","title":"Delinea DevOps Secrets Vault","text":"<p>External Secrets Operator integrates with Delinea DevOps Secrets Vault.</p> <p>Please note that the Delinea Secret Server product is NOT in scope of this integration.</p>"},{"location":"provider/delinea/#creating-a-secretstore","title":"Creating a SecretStore","text":"<p>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.</p> <p>To acquire client ID and client secret, refer to the policy management and client management documentation.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: secret-store\nspec:\nprovider:\ndelinea:\ntenant: <TENANT>\ntld: <TLD>\nclientId:\nvalue: <CLIENT_ID>\nclientSecret:\nsecretRef:\nname: <NAME_OF_KUBE_SECRET>\nkey: <KEY_IN_KUBE_SECRET>\n</code></pre> <p>Both <code>clientId</code> and <code>clientSecret</code> can either be specified directly via the <code>value</code> field or can reference a kubernetes secret.</p> <p>The <code>tenant</code> 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. <code>tld: eu</code>.</p> <p>If required, the URL template (<code>urlTemplate</code>) can be customized as well.</p>"},{"location":"provider/delinea/#referencing-secrets","title":"Referencing Secrets","text":"<p>Secrets can be referenced by path. Getting a specific version of a secret is not yet supported.</p> <p>Note that because all DSV secrets are JSON objects, you must specify <code>remoteRef.property</code>. You can access nested values or arrays using gjson syntax.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: secret\nspec:\nrefreshInterval: 20s\nsecretStoreRef:\nkind: SecretStore\nname: secret-store\ndata:\n- secretKey: <KEY_IN_KUBE_SECRET>\nremoteRef:\nkey: <SECRET_PATH>\nproperty: <JSON_PROPERTY>\n</code></pre>"},{"location":"provider/doppler/","title":"Doppler","text":""},{"location":"provider/doppler/#doppler-secretops-platform","title":"Doppler SecretOps Platform","text":"<p>Sync secrets from the Doppler SecretOps Platform to Kubernetes using the External Secrets Operator.</p>"},{"location":"provider/doppler/#authentication","title":"Authentication","text":"<p>Doppler Service Tokens are recommended as they restrict access to a single config.</p> <p></p> <p>NOTE: Doppler Personal Tokens are also supported but require <code>project</code> and <code>config</code> to be set on the <code>SecretStore</code> or <code>ClusterSecretStore</code>.</p> <p>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:</p> <p></p> <p>Create the Doppler Token Kubernetes secret with your Service Token value:</p> <pre><code>HISTIGNORE='*kubectl*' kubectl create secret generic \\\ndoppler-token-auth-api \\\n--from-literal dopplerToken=\"dp.st.xxxx\"\n</code></pre> <p>Then to create a generic <code>SecretStore</code>:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: doppler-auth-api\nspec:\nprovider:\ndoppler:\nauth:\nsecretRef:\ndopplerToken:\nname: doppler-token-auth-api\nkey: dopplerToken\n</code></pre> <p>NOTE: In case of a <code>ClusterSecretStore</code>, be sure to set <code>namespace</code> in <code>secretRef.dopplerToken</code>.</p>"},{"location":"provider/doppler/#use-cases","title":"Use Cases","text":"<p>The Doppler provider allows for a wide range of use cases:</p> <ol> <li>Fetch</li> <li>Fetch all</li> <li>Filter</li> <li>JSON secret</li> <li>Name transformer</li> <li>Download</li> </ol> <p>Let's explore each use case using a fictional <code>auth-api</code> Doppler project.</p>"},{"location":"provider/doppler/#1-fetch","title":"1. Fetch","text":"<p>To sync one or more individual secrets:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: auth-api-db-url\nspec:\nsecretStoreRef:\nkind: SecretStore\nname: doppler-auth-api\n\ntarget:\nname: auth-api-db-url\n\ndata:\n- secretKey: DB_URL\nremoteRef:\nkey: DB_URL\n</code></pre> <p></p>"},{"location":"provider/doppler/#2-fetch-all","title":"2. Fetch all","text":"<p>To sync every secret from a config:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: auth-api-all\nspec:\nsecretStoreRef:\nkind: SecretStore\nname: doppler-auth-api\n\ntarget:\nname: auth-api-all\n\ndataFrom:\n- find:\nname:\nregexp: .*\n</code></pre> <p></p>"},{"location":"provider/doppler/#3-filter","title":"3. Filter","text":"<p>To filter secrets by <code>path</code> (path prefix), <code>name</code> (regular expression) or a combination of both:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: auth-api-db\nspec:\nsecretStoreRef:\nkind: SecretStore\nname: doppler-auth-api\n\ntarget:\nname: auth-api-db\n\ndataFrom:\n- find:\npath: DB_\n</code></pre> <p></p>"},{"location":"provider/doppler/#4-json-secret","title":"4. JSON secret","text":"<p>To parse a JSON secret to its key-value pairs:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: auth-api-sa-json\nspec:\nsecretStoreRef:\nkind: SecretStore\nname: doppler-auth-api\n\ntarget:\nname: auth-api-sa-json\n\ndataFrom:\n- extract:\nkey: SA_JSON\n</code></pre> <p></p>"},{"location":"provider/doppler/#5-name-transformer","title":"5. Name transformer","text":"<p>Name transformers format keys from Doppler's UPPER_SNAKE_CASE to one of the following alternatives:</p> <ul> <li>upper-camel</li> <li>camel</li> <li>lower-snake</li> <li>tf-var</li> <li>dotnet-env</li> <li>lower-kebab</li> </ul> <p>Name transformers require a specifically configured <code>SecretStore</code>:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: doppler-auth-api-dotnet-env\nspec:\nprovider:\ndoppler:\nauth:\nsecretRef:\ndopplerToken:\nname: doppler-token-auth-api\nnameTransformer: dotnet-env\n</code></pre> <p>Then an <code>ExternalSecret</code> referencing the <code>SecretStore</code>:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: doppler-auth-api-dotnet-env\nspec:\nsecretStoreRef:\nkind: SecretStore\nname: doppler-auth-api-dotnet-env\n\ntarget:\nname: doppler-auth-api-dotnet-env\ncreationPolicy: Owner\n\ndataFrom:\n- find:\nname:\nregexp: .*\n</code></pre> <p></p>"},{"location":"provider/doppler/#6-download","title":"6. Download","text":"<p>A single <code>DOPPLER_SECRETS_FILE</code> key is set where the value is the secrets downloaded in one of the following formats:</p> <ul> <li>json</li> <li>dotnet-json</li> <li>env</li> <li>env-no-quotes</li> <li>yaml</li> </ul> <p>Downloading secrets requires a specifically configured <code>SecretStore</code>:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: doppler-auth-api-json-file\nspec:\nprovider:\ndoppler:\nauth:\nsecretRef:\ndopplerToken:\nname: doppler-token-auth-api\nkey: dopplerToken\nformat: json\n</code></pre> <p>Then an <code>ExternalSecret</code> referencing the <code>SecretStore</code>:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: auth-api-json-file\nspec:\nsecretStoreRef:\nkind: SecretStore\nname: doppler-auth-api-json-file\n\ntarget:\nname: auth-api-json-file\n\ndataFrom:\n- find:\npath: DOPPLER_SECRETS_FILE\n</code></pre> <p></p>"},{"location":"provider/fake/","title":"Fake","text":"<p>We provide a <code>fake</code> implementation to help with testing. This provider returns static key/value pairs and nothing else. To use the <code>fake</code> provider simply create a <code>SecretStore</code> or <code>ClusterSecretStore</code> and configure it like in the following example:</p> <p>Note</p> <p>The provider returns static data configured in <code>value</code> or <code>valueMap</code>. You can define a <code>version</code>, too. If set the <code>remoteRef</code> from an ExternalSecret must match otherwise no value is returned.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\nname: fake\nspec:\nprovider:\nfake:\ndata:\n- key: \"/foo/bar\"\nvalue: \"HELLO1\"\nversion: \"v1\"\n- key: \"/foo/bar\"\nvalue: \"HELLO2\"\nversion: \"v2\"\n- key: \"/foo/baz\"\nvalueMap:\nfoo: example\nother: thing\n</code></pre> <p>Please note that <code>value</code> is intended for exclusive use with <code>data</code> and <code>valueMap</code> for <code>dataFrom</code>. Here is an example <code>ExternalSecret</code> that displays this behavior:</p> <p>Warning</p> <p>This provider supports specifying different <code>data[].version</code> configurations. However, <code>data[].property</code> is ignored.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: example\nspec:\nrefreshInterval: 1h\nsecretStoreRef:\nname: fake\nkind: ClusterSecretStore\ntarget:\nname: secret-to-be-created\ndata:\n- secretKey: foo_bar\nremoteRef:\nkey: /foo/bar\nversion: v1\ndataFrom:\n- extract:\nkey: /foo/baz\n</code></pre> <p>This results in the following secret:</p> <pre><code>apiVersion: v1\nkind: Secret\nmetadata:\nname: secret-to-be-created\nnamespace: default\ndata:\nfoo_bar: SEVMTE8x # HELLO1 (via data)\nfoo: ZXhhbXBsZQ== # example (via dataFrom)\nother: dGhpbmc= # thing (via dataFrom)\n</code></pre>"},{"location":"provider/gitlab-variables/","title":"GitLab Variables","text":""},{"location":"provider/gitlab-variables/#gitlab-variables","title":"GitLab Variables","text":"<p>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.</p>"},{"location":"provider/gitlab-variables/#configuring-gitlab","title":"Configuring GitLab","text":"<p>The GitLab API requires an access token, project ID and/or groupIDs.</p> <p>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).</p> <p></p> <p>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. </p>"},{"location":"provider/gitlab-variables/#access-token-secret","title":"Access Token secret","text":"<p>Create a secret containing your access token:</p> <pre><code>apiVersion: v1\nkind: Secret\nmetadata:\nname: gitlab-secret\nlabels: type: gitlab\ntype: Opaque stringData:\ntoken: \"**access token goes here**\"\n</code></pre>"},{"location":"provider/gitlab-variables/#configuring-the-secret-store","title":"Configuring the secret store","text":"<p>Be sure the <code>gitlab</code> provider is listed in the <code>Kind=SecretStore</code> and the ProjectID is set. If you are not using <code>https://gitlab.com</code>, you must set the <code>url</code> field as well.</p> <p>In order to sync group variables <code>inheritFromGroups</code> must be true or <code>groupIDs</code> have to be defined.</p> <p>In case you have defined multiple environments in Gitlab, the secret store should be constrained to a specific <code>environment_scope</code>.</p> <p><pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: gitlab-secret-store\nspec:\nprovider:\n# provider type: gitlab\ngitlab:\n# url: https://gitlab.mydomain.com/\nauth:\nSecretRef:\naccessToken:\nname: gitlab-secret\nkey: token\nprojectID: \"**project ID goes here**\"\ngroupIDs: \"**groupID(s) go here**\"\ninheritFromGroups: \"**automatically looks for variables in parent groups**\"\nenvironment: \"**environment scope goes here**\"\n</code></pre> NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> in <code>accessToken</code> with the namespace where the secret resides.</p> <p>Your project ID can be found on your project's page. </p>"},{"location":"provider/gitlab-variables/#creating-external-secret","title":"Creating external secret","text":"<p>To sync a GitLab variable to a secret on the Kubernetes cluster, a <code>Kind=ExternalSecret</code> is needed.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: gitlab-external-secret-example\nspec:\nrefreshInterval: 1h\n\nsecretStoreRef:\nkind: SecretStore\nname: gitlab-secret-store # Must match SecretStore on the cluster\n\ntarget:\nname: gitlab-secret-to-create # Name for the secret to be created on the cluster\ncreationPolicy: Owner\n\ndata:\n- secretKey: secretKey # Key given to the secret to be created on the cluster\nremoteRef: key: myGitlabVariable # Key of the variable on Gitlab\n</code></pre>"},{"location":"provider/gitlab-variables/#using-datafrom","title":"Using DataFrom","text":"<p>DataFrom can be used to get a variable as a JSON string and attempt to parse it.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: gitlab-external-secret-example\nspec:\nrefreshInterval: 1h\n\nsecretStoreRef:\nkind: SecretStore\nname: gitlab-secret-store # Must match SecretStore on the cluster\n\ntarget:\nname: gitlab-secret-to-create # Name for the secret to be created on the cluster\ncreationPolicy: Owner\n\n# each secret name in the KV will be used as the secret key in the SECRET k8s target object\ndataFrom:\n- extract:\nkey: \"myJsonVariable\" # Key of the variable on Gitlab\n</code></pre>"},{"location":"provider/gitlab-variables/#getting-the-kubernetes-secret","title":"Getting the Kubernetes secret","text":"<p>The operator will fetch the project variable and inject it as a <code>Kind=Secret</code>. <pre><code>kubectl get secret gitlab-secret-to-create -o jsonpath='{.data.secretKey}' | base64 -d\n</code></pre></p>"},{"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":"<p>External Secrets Operator integrates with GCP Secret Manager for secret management.</p>"},{"location":"provider/google-secrets-manager/#authentication","title":"Authentication","text":""},{"location":"provider/google-secrets-manager/#workload-identity","title":"Workload Identity","text":"<p>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.</p>"},{"location":"provider/google-secrets-manager/#creating-workload-identity-service-accounts","title":"Creating Workload Identity Service Accounts","text":"<p>You can find the documentation for Workload Identity here. We will walk you through how to navigate it here.</p> <p>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 <code>external-secrets</code> SA or create a new one that fits your needs.</p> <ul> <li><code>CLUSTER_NAME</code>: The name of your cluster</li> <li><code>PROJECT_ID</code>: Your project ID (not your Project number nor your Project name)</li> <li><code>K8S_NAMESPACE</code>: For us following these steps here it will be <code>es</code>, but this will be the namespace where you deployed the external-secrets operator</li> <li><code>KSA_NAME</code>: external-secrets (if you are not creating a new one to attach to the deployment)</li> <li><code>GSA_NAME</code>: external-secrets for simplicity, or something else if you have to follow different naming conventions for cloud resources</li> <li><code>ROLE_NAME</code>: should be <code>roles/secretmanager.secretAccessor</code> - so you make the pod only be able to access secrets on Secret Manager</li> </ul>"},{"location":"provider/google-secrets-manager/#using-service-accounts-directly","title":"Using Service Accounts directly","text":"<p>Let's assume you have created a service account correctly and attached a appropriate workload identity. It should roughly look like this:</p> <pre><code>apiVersion: v1\nkind: ServiceAccount\nmetadata:\nname: external-secrets\nnamespace: es\nannotations:\niam.gke.io/gcp-service-account: example-team-a@my-project.iam.gserviceaccount.com\n</code></pre> <p>You can reference this particular ServiceAccount in a <code>SecretStore</code> or <code>ClusterSecretStore</code>. It's important that you also set the <code>projectID</code>, <code>clusterLocation</code> and <code>clusterName</code>. The Namespace on the <code>serviceAccountRef</code> is ignored when using a <code>SecretStore</code> resource. This is needed to isolate the namespaces properly.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\nname: gcp-store\nspec:\nprovider:\ngcpsm:\nprojectID: alphabet-123\nauth:\nworkloadIdentity:\n# name of the cluster region\nclusterLocation: europe-central2\n# name of the GKE cluster\nclusterName: alpha-cluster-42\n# projectID of the cluster (if omitted defaults to spec.provider.gcpsm.projectID)\nclusterProjectID: my-cluster-project\n# reference the sa from above\nserviceAccountRef:\nname: team-a\nnamespace: team-a\n</code></pre> <p>You need to give the Google service account the <code>roles/iam.serviceAccountTokenCreator</code> role so it can generate a service account token for you (not necessary in the Pod-based Workload Identity bellow)</p>"},{"location":"provider/google-secrets-manager/#using-pod-based-workload-identity","title":"Using Pod-based Workload Identity","text":"<p>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 <code>serviceAccountName</code> field.</p> <p>For this example we will assume that you installed ESO using helm and that you named the chart installation <code>external-secrets</code> and the namespace where it lives <code>es</code> like:</p> <pre><code>helm install external-secrets external-secrets/external-secrets --namespace es\n</code></pre> <p>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:</p> <pre><code># ...\ncontainers:\n- image: ghcr.io/external-secrets/external-secrets:vVERSION\nname: external-secrets\nports:\n- containerPort: 8080\nprotocol: TCP\nrestartPolicy: Always\nschedulerName: default-scheduler\nserviceAccount: external-secrets\nserviceAccountName: external-secrets # <--- here\n</code></pre> <p>The pod now has the identity. Now you need to configure the <code>SecretStore</code>. You just need to set the <code>projectID</code>, all other fields can be omitted.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: gcp-store\nspec:\nprovider:\ngcpsm:\nprojectID: alphabet-123\n</code></pre>"},{"location":"provider/google-secrets-manager/#gcp-service-account-authentication","title":"GCP Service Account authentication","text":"<p>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 <code>Kind=Secret</code>. 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 <code>IAM & Admin</code> web UI, click <code>ADD ANOTHER ROLE</code> button, add <code>Secret Manager Secret Accessor</code> role to this service account. The <code>Secret Manager Secret Accessor</code> role is required to access secrets.</p> <pre><code>apiVersion: v1\nkind: Secret\nmetadata:\nname: gcpsm-secret\nlabels:\ntype: gcpsm\ntype: Opaque\nstringData:\nsecret-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</code></pre>"},{"location":"provider/google-secrets-manager/#update-secret-store","title":"Update secret store","text":"<p>Be sure the <code>gcpsm</code> provider is listed in the <code>Kind=SecretStore</code></p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: gcp-store\nnamespace: example\nspec:\nprovider:\ngcpsm: # gcpsm provider\nauth:\nsecretRef:\nsecretAccessKeySecretRef:\nname: gcpsm-secret # secret name containing SA key\nkey: secret-access-credentials # key name containing SA key\nprojectID: alphabet-123 # name of Google Cloud project\n</code></pre> <p>NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> for <code>SecretAccessKeyRef</code> with the namespace of the secret that we just created.</p>"},{"location":"provider/google-secrets-manager/#creating-external-secret","title":"Creating external secret","text":"<p>To create a kubernetes secret from the GCP Secret Manager secret a <code>Kind=ExternalSecret</code> is needed.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: database-credentials\nspec:\nrefreshInterval: 1h # rate SecretManager pulls GCPSM\nsecretStoreRef:\nkind: SecretStore\nname: gcp-store # name of the SecretStore (or kind specified)\ntarget:\nname: database-credentials # name of the k8s Secret to be created\ncreationPolicy: Owner\ndata:\n- secretKey: database_username\nremoteRef:\nkey: database_username # name of the GCPSM secret key\n- secretKey: database_password\nremoteRef:\nkey: database_password # name of the GCPSM secret key\n</code></pre> <p>The operator will fetch the GCP Secret Manager secret and inject it as a <code>Kind=Secret</code> <pre><code>kubectl get secret secret-to-be-created -n <namespace> | -o jsonpath='{.data.dev-secret-test}' | base64 -d\n</code></pre></p>"},{"location":"provider/hashicorp-vault/","title":"HashiCorp Vault","text":""},{"location":"provider/hashicorp-vault/#hashicorp-vault","title":"Hashicorp Vault","text":"<p>External Secrets Operator integrates with HashiCorp Vault for secret management.</p> <p>The KV Secrets Engine is the only one supported by this provider. For other secrets engines, please refer to the Vault Generator.</p>"},{"location":"provider/hashicorp-vault/#example","title":"Example","text":"<p>First, create a SecretStore with a vault backend. For the sake of simplicity we'll use a static token <code>root</code>:</p> <p><pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: vault-backend\nspec:\nprovider:\nvault:\nserver: \"http://my.vault.server:8200\"\npath: \"secret\"\n# Version is the Vault KV secret engine version.\n# This can be either \"v1\" or \"v2\", defaults to \"v2\"\nversion: \"v2\"\nauth:\n# points to a secret that contains a vault token\n# https://www.vaultproject.io/docs/auth/token\ntokenSecretRef:\nname: \"vault-token\"\nkey: \"token\"\n---\napiVersion: v1\nkind: Secret\nmetadata:\nname: vault-token\ndata:\ntoken: cm9vdA== # \"root\"\n</code></pre> NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> for <code>tokenSecretRef</code> with the namespace of the secret that we just created.</p> <p>Then create a simple k/v pair at path <code>secret/foo</code>:</p> <pre><code>vault kv put secret/foo my-value=s3cr3t\n</code></pre> <p>Can check kv version using following and check for <code>Options</code> column, it should indicate [version:2]:</p> <pre><code>vault secrets list -detailed\n</code></pre> <p>If you are using version: 1, just remember to update your SecretStore manifest appropriately</p> <p>Now create a ExternalSecret that uses the above SecretStore:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: vault-example\nspec:\nrefreshInterval: \"15s\"\nsecretStoreRef:\nname: vault-backend\nkind: SecretStore\ntarget:\nname: example-sync\ndata:\n- secretKey: foobar\nremoteRef:\nkey: foo\nproperty: my-value\n\n# metadataPolicy to fetch all the labels in JSON format\n- secretKey: tags\nremoteRef:\nmetadataPolicy: Fetch key: foo\n\n# metadataPolicy to fetch a specific label (dev) from the source secret\n- secretKey: developer\nremoteRef:\nmetadataPolicy: Fetch key: foo\nproperty: dev\n\n---\n# will create a secret with:\nkind: Secret\nmetadata:\nname: example-sync\ndata:\nfoobar: czNjcjN0\n</code></pre> <p>Keep in mind that fetching the labels with <code>metadataPolicy: Fetch</code> only works with KV sercrets engine version v2.</p>"},{"location":"provider/hashicorp-vault/#fetching-raw-values","title":"Fetching Raw Values","text":"<p>You can fetch all key/value pairs for a given path If you leave the <code>remoteRef.property</code> empty. This returns the json-encoded secret value for that path.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: vault-example\nspec:\n# ...\ndata:\n- secretKey: foobar\nremoteRef:\nkey: /dev/package.json\n</code></pre>"},{"location":"provider/hashicorp-vault/#nested-values","title":"Nested Values","text":"<p>Vault supports nested key/value pairs. You can specify a gjson expression at <code>remoteRef.property</code> to get a nested value.</p> <p>Given the following secret - assume its path is <code>/dev/config</code>: <pre><code>{\n\"foo\": {\n\"nested\": {\n\"bar\": \"mysecret\"\n}\n}\n}\n</code></pre></p> <p>You can set the <code>remoteRef.property</code> to point to the nested key using a gjson expression. <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: vault-example\nspec:\n# ...\ndata:\n- secretKey: foobar\nremoteRef:\nkey: /dev/config\nproperty: foo.nested.bar\n---\n# creates a secret with:\n# foobar=mysecret\n</code></pre></p> <p>If you would set the <code>remoteRef.property</code> to just <code>foo</code> then you would get the json-encoded value of that property: <code>{\"nested\":{\"bar\":\"mysecret\"}}</code>.</p>"},{"location":"provider/hashicorp-vault/#multiple-nested-values","title":"Multiple nested Values","text":"<p>You can extract multiple keys from a nested secret using <code>dataFrom</code>.</p> <p>Given the following secret - assume its path is <code>/dev/config</code>: <pre><code>{\n\"foo\": {\n\"nested\": {\n\"bar\": \"mysecret\",\n\"baz\": \"bang\"\n}\n}\n}\n</code></pre></p> <p>You can set the <code>remoteRef.property</code> to point to the nested key using a gjson expression. <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: vault-example\nspec:\n# ...\ndataFrom:\n- extract:\nkey: /dev/config\nproperty: foo.nested\n</code></pre></p> <p>That results in a secret with these values: <pre><code>bar=mysecret\nbaz=bang\n</code></pre></p>"},{"location":"provider/hashicorp-vault/#getting-multiple-secrets","title":"Getting multiple secrets","text":"<p>You can extract multiple secrets from Hashicorp vault by using <code>dataFrom.Find</code></p> <p>Currently, <code>dataFrom.Find</code> allows users to fetch secret names that match a given regexp pattern, or fetch secrets whose <code>custom_metadata</code> tags match a predefined set.</p> <p>Warning</p> <p>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.</p> <p>Given the following secret - assume its path is <code>/dev/config</code>: <pre><code>{\n\"foo\": {\n\"nested\": {\n\"bar\": \"mysecret\",\n\"baz\": \"bang\"\n}\n}\n}\n</code></pre></p> <p>Also consider the following secret has the following <code>custom_metadata</code>: <pre><code>{\n\"environment\": \"dev\",\n\"component\": \"app-1\"\n}\n</code></pre></p> <p>It is possible to find this secret by all the following possibilities: <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: vault-example\nspec:\n# ...\ndataFrom:\n- find: #will return every secret with 'dev' in it (including paths)\nname:\nregexp: dev\n- find: #will return every secret matching environment:dev tags from dev/ folder and beyond\ntags:\nenvironment: dev\n</code></pre> will generate a secret with: <pre><code>{\n\"dev_config\":\"{\\\"foo\\\":{\\\"nested\\\":{\\\"bar\\\":\\\"mysecret\\\",\\\"baz\\\":\\\"bang\\\"}}}\"\n}\n</code></pre></p> <p>Currently, <code>Find</code> operations are recursive throughout a given vault folder, starting on <code>provider.Path</code> definition. It is recommended to narrow down the scope of search by setting a <code>find.path</code> variable. This is also useful to automatically reduce the resulting secret key names: <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: vault-example\nspec:\n# ...\ndataFrom:\n- find: #will return every secret from dev/ folder\npath: dev\nname:\nregexp: \".*\"\n- find: #will return every secret matching environment:dev tags from dev/ folder\npath: dev\ntags:\nenvironment: dev\n</code></pre> Will generate a secret with: <pre><code>{\n\"config\":\"{\\\"foo\\\": {\\\"nested\\\": {\\\"bar\\\": \\\"mysecret\\\",\\\"baz\\\": \\\"bang\\\"}}}\"\n}\n</code></pre></p>"},{"location":"provider/hashicorp-vault/#authentication","title":"Authentication","text":"<p>We support five different modes for authentication: token-based, appRole, kubernetes-native, ldap, userPass, jwt/oidc and awsAuth, each one comes with it's own trade-offs. Depending on the authentication method you need to adapt your environment.</p>"},{"location":"provider/hashicorp-vault/#token-based-authentication","title":"Token-based authentication","text":"<p>A static token is stored in a <code>Kind=Secret</code> and is used to authenticate with vault.</p> <p><pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: vault-backend\nnamespace: example\nspec:\nprovider:\nvault:\nserver: \"https://vault.acme.org\"\npath: \"secret\"\nversion: \"v2\"\nauth:\n# points to a secret that contains a vault token\n# https://www.vaultproject.io/docs/auth/token\ntokenSecretRef:\nname: \"my-secret\"\nkey: \"vault-token\"\n</code></pre> NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> in <code>tokenSecretRef</code> with the namespace where the secret resides.</p>"},{"location":"provider/hashicorp-vault/#approle-authentication-example","title":"AppRole authentication example","text":"<p>AppRole authentication reads the secret id from a <code>Kind=Secret</code> and uses the specified <code>roleId</code> to aquire a temporary token to fetch secrets.</p> <p><pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: vault-backend\nnamespace: example\nspec:\nprovider:\nvault:\nserver: \"https://vault.acme.org\"\npath: \"secret\"\nversion: \"v2\"\nauth:\n# VaultAppRole authenticates with Vault using the\n# App Role auth mechanism\n# https://www.vaultproject.io/docs/auth/approle\nappRole:\n# Path where the App Role authentication backend is mounted\npath: \"approle\"\n# RoleID configured in the App Role authentication backend\nroleId: \"db02de05-fa39-4855-059b-67221c5c2f63\"\n# Reference to a key in a K8 Secret that contains the App Role SecretId\nsecretRef:\nname: \"my-secret\"\nkey: \"secret-id\"\n</code></pre> NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> in <code>secretRef</code> with the namespace where the secret resides.</p>"},{"location":"provider/hashicorp-vault/#kubernetes-authentication","title":"Kubernetes authentication","text":"<p>Kubernetes-native authentication has three options of obtaining credentials for vault:</p> <ol> <li>by using a service account jwt referenced in <code>serviceAccountRef</code></li> <li>by using the jwt from a <code>Kind=Secret</code> referenced by the <code>secretRef</code></li> <li>by using transient credentials from the mounted service account token within the external-secrets operator</li> </ol> <p><pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: vault-backend\nnamespace: example\nspec:\nprovider:\nvault:\nserver: \"https://vault.acme.org\"\npath: \"secret\"\nversion: \"v2\"\nauth:\n# Authenticate against Vault using a Kubernetes ServiceAccount\n# token stored in a Secret.\n# https://www.vaultproject.io/docs/auth/kubernetes\nkubernetes:\n# Path where the Kubernetes authentication backend is mounted in Vault\nmountPath: \"kubernetes\"\n# A required field containing the Vault Role to assume.\nrole: \"demo\"\n# Optional service account field containing the name\n# of a kubernetes ServiceAccount\nserviceAccountRef:\nname: \"my-sa\"\n# Optional secret field containing a Kubernetes ServiceAccount JWT\n# used for authenticating with Vault\nsecretRef:\nname: \"my-secret\"\nkey: \"vault\"\n</code></pre> NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> in <code>serviceAccountRef</code> or in <code>secretRef</code>, if used.</p>"},{"location":"provider/hashicorp-vault/#ldap-authentication","title":"LDAP authentication","text":"<p>LDAP authentication uses username/password pair to get an access token. Username is stored directly in a <code>Kind=SecretStore</code> or <code>Kind=ClusterSecretStore</code> resource, password is stored in a <code>Kind=Secret</code> referenced by the <code>secretRef</code>.</p> <p><pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: vault-backend\nnamespace: example\nspec:\nprovider:\nvault:\nserver: \"https://vault.acme.org\"\npath: \"secret\"\nversion: \"v2\"\nauth:\n# VaultLdap authenticates with Vault using the LDAP auth mechanism\n# https://www.vaultproject.io/docs/auth/ldap\nldap:\n# Path where the LDAP authentication backend is mounted\npath: \"ldap\"\n# LDAP username\nusername: \"username\"\nsecretRef:\nname: \"my-secret\"\nkey: \"ldap-password\"\n</code></pre> NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> in <code>secretRef</code> with the namespace where the secret resides.</p>"},{"location":"provider/hashicorp-vault/#userpass-authentication","title":"UserPass authentication","text":"<p>UserPass authentication uses username/password pair to get an access token. Username is stored directly in a <code>Kind=SecretStore</code> or <code>Kind=ClusterSecretStore</code> resource, password is stored in a <code>Kind=Secret</code> referenced by the <code>secretRef</code>.</p> <p><pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: vault-backend\nnamespace: example\nspec:\nprovider:\nvault:\nserver: \"https://vault.acme.org\"\npath: \"secret\"\nversion: \"v2\"\nauth:\n# VaultUserPass authenticates with Vault using the UserPass auth mechanism\n# https://www.vaultproject.io/docs/auth/userpass\nuserPass:\n# Path where the UserPass authentication backend is mounted\npath: \"userpass\"\nusername: \"username\"\nsecretRef:\nname: \"my-secret\"\nkey: \"password\"\n</code></pre> NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> in <code>secretRef</code> with the namespace where the secret resides.</p>"},{"location":"provider/hashicorp-vault/#jwtoidc-authentication","title":"JWT/OIDC authentication","text":"<p>JWT/OIDC uses either a JWT token stored in a <code>Kind=Secret</code> and referenced by the <code>secretRef</code> or a temporary Kubernetes service account token retrieved via the <code>TokenRequest</code> API. Optionally a <code>role</code> field can be defined in a <code>Kind=SecretStore</code> or <code>Kind=ClusterSecretStore</code> resource.</p> <p><pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: vault-backend\nnamespace: example\nspec:\nprovider:\nvault:\nserver: \"https://vault.acme.org\"\npath: \"secret\"\nversion: \"v2\"\nauth:\n# VaultJwt authenticates with Vault using the JWT/OIDC auth mechanism\n# https://www.vaultproject.io/docs/auth/jwt\njwt:\n# Path where the JWT authentication backend is mounted\npath: \"jwt\"\n# JWT role configured in a Vault server, optional.\nrole: \"vault-jwt-role\"\n\n# Retrieve JWT token from a Kubernetes secret\nsecretRef:\nname: \"my-secret\"\nkey: \"jwt-token\"\n\n# ... or retrieve a Kubernetes service account token via the `TokenRequest` API\nkubernetesServiceAccountToken:\nserviceAccountRef:\nname: \"my-sa\"\n# `audiences` defaults to `[\"vault\"]` it not supplied\naudiences:\n- vault\n# `expirationSeconds` defaults to 10 minutes if not supplied\nexpirationSeconds: 600\n</code></pre> NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> in <code>secretRef</code> with the namespace where the secret resides.</p>"},{"location":"provider/hashicorp-vault/#aws-iam-authentication","title":"AWS IAM authentication","text":"<p>AWS IAM uses either a set of AWS Programmatic access credentials stored in a <code>Kind=Secret</code> and referenced by the <code>secretRef</code> or by getting the authentication token from an IRSA enabled service account</p>"},{"location":"provider/hashicorp-vault/#access-key-id-secret-access-key","title":"Access Key ID & Secret Access Key","text":"<p>You can store Access Key ID & Secret Access Key in a <code>Kind=Secret</code> and reference it from a SecretStore.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: vault-backend-aws-iam\nspec:\nprovider:\nvault:\nserver: \"http://my.vault.server:8200\"\npath: secret\nversion: v2\nnamespace: <vault_namespace>\nauth:\niam:\n# Path where the AWS auth method is enabled in Vault, e.g: \"aws/\". Defaults to aws\npath: aws\n# AWS Region. Defaults to us-east-1\nregion: us-east-1\n# optional: assume role before fetching secrets\nrole: 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\nvaultRole: 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\nvaultAwsIamServerID: example-vaultAwsIamServerID\nsecretRef: #Use this method when you have static AWS creds.\naccessKeyIDSecretRef:\nname: vault-iam-creds-secret\nkey: access-key\nsecretAccessKeySecretRef:\nname: vault-iam-creds-secret\nkey: secret-access-key\nsessionTokenSecretRef:\nname: vault-iam-creds-secret\nkey: secret-session-token\n</code></pre> <p>NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> in <code>accessKeyIDSecretRef</code>, <code>secretAccessKeySecretRef</code> with the namespaces where the secrets reside.</p>"},{"location":"provider/hashicorp-vault/#eks-service-account-credentials","title":"EKS Service Account credentials","text":"<p>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.</p> <p>The big advantage of this approach is that ESO runs without any credentials.</p> <pre><code>apiVersion: v1\nkind: ServiceAccount\nmetadata:\nannotations:\neks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/my-irsa-enabled-role\nname: my-serviceaccount\nnamespace: default\n</code></pre> <p>Reference the service account from above in the Secret Store:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: vault-backend-aws-iam\nspec:\nprovider:\nvault:\nserver: \"http://my.vault.server:8200\"\npath: secret\nversion: v2\nnamespace: <vault_namespace>\nauth:\niam:\n# Path where the AWS auth method is enabled in Vault, e.g: \"aws/\". Defaults to aws\npath: aws\n# AWS Region. Defaults to us-east-1\nregion: 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\nvaultRole: 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\nvaultAwsIamServerID: example-vaultAwsIamServerID\njwt:\nserviceAccountRef:\nname: my-serviceaccount #Provide service account with IRSA enabled\n</code></pre>"},{"location":"provider/hashicorp-vault/#controllers-pod-identity","title":"Controller's Pod Identity","text":"<p>This is basicially a zero-configuration authentication approach that inherits the credentials from the controller's pod identity</p> <p>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)</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: vault-backend-aws-iam\nspec:\nprovider:\nvault:\nserver: \"http://my.vault.server:8200\"\npath: secret\nversion: v2\nnamespace: <vault_namespace>\nauth:\niam:\n# Path where the AWS auth method is enabled in Vault, e.g: \"aws/\". Defaults to aws\npath: aws\n# AWS Region. Defaults to us-east-1\nregion: 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\nvaultRole: 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\nvaultAwsIamServerID: example-vaultAwsIamServerID\n</code></pre> <p>NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> for <code>serviceAccountRef</code> with the namespace where the service account resides.</p> <p><pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: vault-backend\nnamespace: example\nspec:\nprovider:\nvault:\nserver: \"https://vault.acme.org\"\npath: \"secret\"\nversion: \"v2\"\nauth:\n# VaultJwt authenticates with Vault using the JWT/OIDC auth mechanism\n# https://www.vaultproject.io/docs/auth/jwt\njwt:\n# Path where the JWT authentication backend is mounted\npath: \"jwt\"\n# JWT role configured in a Vault server, optional.\nrole: \"vault-jwt-role\"\n\n# Retrieve JWT token from a Kubernetes secret\nsecretRef:\nname: \"my-secret\"\nkey: \"jwt-token\"\n\n# ... or retrieve a Kubernetes service account token via the `TokenRequest` API\nkubernetesServiceAccountToken:\nserviceAccountRef:\nname: \"my-sa\"\n# `audiences` defaults to `[\"vault\"]` it not supplied\naudiences:\n- vault\n# `expirationSeconds` defaults to 10 minutes if not supplied\nexpirationSeconds: 600\n</code></pre> NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> in <code>secretRef</code> with the namespace where the secret resides.</p>"},{"location":"provider/hashicorp-vault/#pushsecret","title":"PushSecret","text":"<p>Vault supports PushSecret features which allow you to sync a given kubernetes secret key into a hashicorp vault secret. In order to do so, it is expected that the secret key is a valid JSON object.</p> <p>In order to use PushSecret, you need to give <code>create</code>, <code>read</code> and <code>update</code> permissions to the path where you want to push secrets to for both <code>data</code> and <code>metadata</code> of the secret. Use it with care!</p> <p>Here is an example on how to set it up: <pre><code>apiVersion: v1\nkind: Secret\nmetadata:\nname: source-secret\nnamespace: default\nstringData:\nsource-key: \"{\\\"foo\\\":\\\"bar\\\"}\" # Needs to be a JSON\n---\napiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\nname: pushsecret-example\nnamespace: default\nspec:\nrefreshInterval: 10s # Refresh interval for which push secret will reconcile\nsecretStoreRefs: # A list of secret stores to push secrets to\n- name: vault-secretstore\nkind: SecretStore\nselector:\nsecret:\nname: source-secret # Source Kubernetes secret to be pushed\ndata:\n- match:\nsecretKey: source-key # Source Kubernetes secret key containing the vault secret (in JSON format)\nremoteRef:\nremoteKey: vault/secret # path to vault secret. This path is appended with the vault-store path.\n</code></pre></p>"},{"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":"<p>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.</p> <p>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.</p>"},{"location":"provider/hashicorp-vault/#vault-namespaces","title":"Vault Namespaces","text":"<p>Vault namespaces are an enterprise feature that support multi-tenancy. You can specify a vault namespace using the <code>namespace</code> property when you define a SecretStore:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: vault-backend\nspec:\nprovider:\nvault:\nserver: \"http://my.vault.server:8200\"\n# See https://www.vaultproject.io/docs/enterprise/namespaces\nnamespace: \"ns1\"\npath: \"secret\"\nversion: \"v2\"\nauth:\n# ...\n</code></pre>"},{"location":"provider/hashicorp-vault/#read-your-writes","title":"Read Your Writes","text":"<p>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.</p> <p>A method supported in versions Vault 1.7 and later is to utilize the <code>X-Vault-Index</code> 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.</p>"},{"location":"provider/hashicorp-vault/#forward-inconsistent","title":"Forward Inconsistent","text":"<p>Vault also supports proxying inconsistent requests to the current cluster leader for immediate read-after-write consistency.</p> <p>Vault 1.10.0 and later support a replication configuration that detects when forwarding should occur and does it transparently to the client.</p> <p>In Vault 1.7 forwarding can be achieved by setting the <code>X-Vault-Inconsistent</code> header to <code>forward-active-node</code>. By default, this behavior is disabled and must be explicitly enabled in the server's replication configuration.</p>"},{"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":"<p>External Secrets Operator integrates with IBM Cloud Secret Manager for secret management.</p>"},{"location":"provider/ibm-secrets-manager/#authentication","title":"Authentication","text":"<p>We support API key and trusted profile container authentication for this provider.</p>"},{"location":"provider/ibm-secrets-manager/#api-key-secret","title":"API key secret","text":"<p>To generate your key (for test purposes we are going to generate from your user), first got to your (Access IAM) page:</p> <p></p> <p>On the left, click \"API Keys\", then click on \"Create\"</p> <p></p> <p>Pick a name and description for your key:</p> <p></p> <p>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.</p> <p></p> <p>Create a secret containing your apiKey:</p> <pre><code>kubectl create secret generic ibm-secret --from-literal=apiKey='API_KEY_VALUE'\n</code></pre>"},{"location":"provider/ibm-secrets-manager/#trusted-profile-container-auth","title":"Trusted Profile Container Auth","text":"<p>To create the trusted profile, first got to your (Access IAM) page:</p> <p></p> <p>On the left, click \"Access groups\":</p> <p></p> <p>Pick a name and description for your group:</p> <p></p> <p>Click on \"Access\", and then on \"Assign\":</p> <p></p> <p>Click on \"Assign Access\", select \"IAM services\", and pick \"Secrets Manager\" from the pick-list:</p> <p></p> <p>Scope to \"All resources\" or \"Resources based on selected attributes\":</p> <p></p> <p>Select the \"SecretsReader\" service access policy:</p> <p></p> <p>Click \"Add\" and \"Assign\" to save the access group.</p> <p>Next, on the left, click \"Trusted profiles\":</p> <p></p> <p>Press \"Create\" and pick a name and description for your profile:</p> <p></p> <p>Scope the profile's access.</p> <p>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.</p> <p></p> <p>Click \"Add\" next to the previously created access group and then \"Create\", to associate the necessary service permissions.</p> <p></p> <p>To use the container-based authentication, it is necessary to map the API server <code>serviceAccountToken</code> auth token to the \"external-secrets\" and \"external-secrets-webhook\" deployment descriptors. Example below:</p> <pre><code>...\nspec:\n...\ntemplate:\n...\nspec:\ncontainers:\n...\nvolumeMounts:\n- mountPath: /var/run/secrets/tokens\nname: sa-token\n...\nvolumes:\n- name: sa-token\nprojected:\ndefaultMode: 420\nsources:\n- serviceAccountToken:\naudience: iam\nexpirationSeconds: 3600\npath: sa-token\n...\n</code></pre>"},{"location":"provider/ibm-secrets-manager/#update-secret-store","title":"Update secret store","text":"<p>Be sure the <code>ibm</code> provider is listed in the <code>Kind=SecretStore</code></p> <p><pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: ibm-store\nspec:\nprovider:\nibm:\nserviceUrl: \"https://<SECRETS_MANAGER_ID>.<REGION>.secrets-manager.appdomain.cloud\"\nauth:\ncontainerAuth:\nprofile: \"test container auth profile\"\ntokenLocation: \"/var/run/secrets/tokens/sa-token\"\niamEndpoint: \"https://iam.cloud.ibm.com\"\nsecretRef:\nsecretApiKeySecretRef:\nname: ibm-secret\nkey: apiKey\n</code></pre> NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> in <code>secretApiKeySecretRef</code> with the namespace where the secret resides.</p> <p>NOTE: Only <code>secretApiKeySecretRef</code> or <code>containerAuth</code> should be specified, depending on authentication method being used.</p> <p>To find your <code>serviceURL</code>, under your Secrets Manager resource, go to \"Endpoints\" on the left.</p> <p>See here for a list of publicly available endpoints.</p> <p></p>"},{"location":"provider/ibm-secrets-manager/#secret-types","title":"Secret Types","text":"<p>We support the following secret types of IBM Secrets Manager:</p> <ul> <li><code>arbitrary</code></li> <li><code>username_password</code></li> <li><code>iam_credentials</code></li> <li><code>imported_cert</code></li> <li><code>public_cert</code></li> <li><code>private_cert</code></li> <li><code>kv</code></li> </ul> <p>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 <code>arbitrary</code>:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: ibm-sample\nspec:\n# [...]\ndata:\n- secretKey: test\nremoteRef:\n# defaults to type=arbitrary\nkey: xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n- secretKey: usr_pass\nremoteRef:\nkey: username_password/yyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy\nproperty: username\n- secretKey: iam_cred\nremoteRef:\nkey: iam_credentials/zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz\n- secretKey: imp_cert\nremoteRef:\nkey: imported_cert/zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz\nproperty: certificate\n- secretKey: pub_cert\nremoteRef:\nkey: public_cert/zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz\nproperty: certificate\n- secretKey: prvt_cert\nremoteRef:\nkey: private_cert/zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz\nproperty: certificate\n- secretKey: kv_without_key\nremoteRef:\nkey: kv/zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz\n- secretKey: kv_key\nremoteRef:\nkey: kv/zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz\nproperty: 'keyid'\n- secretKey: kv_key_with_path\nremoteRef:\nkey: kv/zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz\nproperty: 'key.path'\n</code></pre> <p>The behavior for the different secret types is as following:</p>"},{"location":"provider/ibm-secrets-manager/#arbitrary","title":"arbitrary","text":"<ul> <li><code>remoteRef</code> retrieves a string from secrets manager and sets it for specified <code>secretKey</code></li> <li><code>dataFrom</code> 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</li> </ul>"},{"location":"provider/ibm-secrets-manager/#username_password","title":"username_password","text":"<ul> <li><code>remoteRef</code> requires a <code>property</code> to be set for either <code>username</code> or <code>password</code> to retrieve respective fields from the secrets manager secret and set in specified <code>secretKey</code></li> <li><code>dataFrom</code> retrieves both <code>username</code> and <code>password</code> fields from the secrets manager secret and sets appropriate key:value pairs in the resulting Kubernetes secret</li> </ul>"},{"location":"provider/ibm-secrets-manager/#iam_credentials","title":"iam_credentials","text":"<ul> <li><code>remoteRef</code> retrieves an apikey from secrets manager and sets it for specified <code>secretKey</code></li> <li><code>dataFrom</code> retrieves an apikey from secrets manager and sets it for the <code>apikey</code> Kubernetes secret key</li> </ul>"},{"location":"provider/ibm-secrets-manager/#imported_cert-public_cert-and-private_cert","title":"imported_cert, public_cert, and private_cert","text":"<ul> <li><code>remoteRef</code> requires a <code>property</code> to be set for either <code>certificate</code>, <code>private_key</code> or <code>intermediate</code> to retrieve respective fields from the secrets manager secret and set in specified <code>secretKey</code></li> <li><code>dataFrom</code> retrieves all <code>certificate</code>, <code>private_key</code> and <code>intermediate</code> fields from the secrets manager secret and sets appropriate key:value pairs in the resulting Kubernetes secret</li> </ul>"},{"location":"provider/ibm-secrets-manager/#kv","title":"kv","text":"<ul> <li>An optional <code>property</code> field can be set to <code>remoteRef</code> to select requested key from the KV secret. If not set, the entire secret will be returned</li> <li><code>dataFrom</code> 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</li> </ul> <pre><code>{\n\"key1\": \"val1\",\n\"key2\": \"val2\",\n\"key3\": {\n\"keyA\": \"valA\",\n\"keyB\": \"valB\"\n},\n\"special.key\": \"special-content\"\n}\n</code></pre> <pre><code>data:\n- secretKey: key3_keyB\nremoteRef:\nkey: 'kv/aaaaa-bbbb-cccc-dddd-eeeeee'\nproperty: 'key3.keyB'\n- secretKey: special_key\nremoteRef:\nkey: 'kv/aaaaa-bbbb-cccc-dddd-eeeeee'\nproperty: 'special.key'\n- secretKey: key_all\nremoteRef:\nkey: 'kv/aaaaa-bbbb-cccc-dddd-eeeeee'\n\ndataFrom:\n- key: 'kv/aaaaa-bbbb-cccc-dddd-eeeeee'\nproperty: 'key3'\n</code></pre> <p>results in</p> <pre><code>data:\n# secrets from data\nkey3_keyB: ... #valB\nspecial_key: ... #special-content\nkey_all: ... #{\"key1\":\"val1\",\"key2\":\"val2\", ...\"special.key\":\"special-content\"}\n\n# secrets from dataFrom\nkeyA: ... #valA\nkeyB: ... #valB\n</code></pre>"},{"location":"provider/ibm-secrets-manager/#creating-external-secret","title":"Creating external secret","text":"<p>To create a kubernetes secret from the IBM Secrets Manager, a <code>Kind=ExternalSecret</code> is needed. Below example creates a kubernetes secret based on ID of the secret in Secrets Manager.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: database-credentials\nspec:\nrefreshInterval: 60m\nsecretStoreRef:\nname: ibm-store\nkind: SecretStore\ntarget:\nname: database-credentials\ncreationPolicy: Owner\ndata:\n- secretKey: username\nremoteRef:\nkey: username_password/<SECRET_ID>\nproperty: username\n- secretKey: password\nremoteRef:\nkey: username_password/<SECRET_ID>\nproperty: password\n</code></pre> <p>Alternatively, secret name can be specified instead of secret ID.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: database-credentials\nspec:\nrefreshInterval: 60m\nsecretStoreRef:\nname: ibm-store\nkind: SecretStore\ntarget:\nname: database-credentials\ncreationPolicy: Owner\ndata:\n- secretKey: username\nremoteRef:\nkey: username_password/<SECRET_NAME>\nproperty: username\n- secretKey: password\nremoteRef:\nkey: username_password/<SECRET_NAME>\nproperty: password\n</code></pre>"},{"location":"provider/ibm-secrets-manager/#getting-the-kubernetes-secret","title":"Getting the Kubernetes secret","text":"<p>The operator will fetch the IBM Secret Manager secret and inject it as a <code>Kind=Secret</code> <pre><code>kubectl get secret secret-to-be-created -n <namespace> | -o jsonpath='{.data.test}' | base64 -d\n</code></pre></p>"},{"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":"<p>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.</p> <p>In order for the user to opt-in to adding metadata to secret, an existing optional field <code>spec.dataFrom.extract.metadataPolicy</code> can be be set to <code>Fetch</code>, its default value being <code>None</code>. In addition to this, templating provided be ESO can be leveraged to specify the key-value pairs of the resultant secrets' labels and annotation.</p> <p>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 <code>template.metadata.labels</code> or <code>template.metadata.annotations</code>. 2. The required secret data should be specified under <code>template.data</code>. 3. The spec.dataFrom.extract should be specified with details of the Secrets Manager secret with <code>spec.dataFrom.extract.metadataPolicy</code> set to <code>Fetch</code>. Below is an example, where <code>secret_id</code> and <code>updated_at</code> are the metadata of a secret in IBM Secrets Manager:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: database-credentials\nnamespace: external-secrets\nspec:\ndataFrom:\n- extract:\nkey: username_password/<SECRET_ID>\nmetadataPolicy: Fetch # leveraging optional parameter, defaults to None\nsecretKey: username\nsecretStoreRef:\nkind: SecretStore\nname: ibm-store\ntarget:\nname: database-credentials\ntemplate:\nengineVersion: v2\ndata:\nsecret: \"{{ .password }}\"\nmetadata:\nannotations:\nsecret_id: \"{{ .id }}\" # adding metadata key whose value would be added to the secret as a label\nupdated_at: \"{{ .updated_at }}\"\n</code></pre> <p>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:</p> <pre><code>apiVersion: v1\ndata:\nsecret: OHE0MFV5MGhQb2FmRjZTOGVva3dPQjRMeVZXeXpWSDlrSWgyR1BiVDZTMyc=\nimmutable: false\nkind: Secret\nmetadata:\nannotations:\nreconcile.external-secrets.io/data-hash: 02217008d13ed228e75cf6d26fe74324\ncreationTimestamp: \"2023-05-04T08:41:24Z\"\nannotations:\nsecret_id: 1234\nupdated_at: 2023-05-04T08:57:19Z\nname: database-credentials\nnamespace: external-secrets\nownerReferences:\n- apiVersion: external-secrets.io/v1beta1\nblockOwnerDeletion: true\ncontroller: true\nkind: ExternalSecret\nname: database-credentials\nuid: c2a018e7-1ac3-421b-bd3b-d9497204f843\nresourceVersion: \"1803567\"\nuid: f5dff604-611b-4d41-9d65-b860c61a0b8d\ntype: Opaque\n</code></pre>"},{"location":"provider/keeper-security/","title":"Keeper Security","text":""},{"location":"provider/keeper-security/#keeper-security","title":"Keeper Security","text":"<p>External Secrets Operator integrates with Keeper Security for secret management by using Keeper Secrets Manager.</p>"},{"location":"provider/keeper-security/#authentication","title":"Authentication","text":""},{"location":"provider/keeper-security/#secrets-manager-configuration-smc","title":"Secrets Manager Configuration (SMC)","text":"<p>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.</p>"},{"location":"provider/keeper-security/#creating-secrets-manager-configuration","title":"Creating Secrets Manager Configuration","text":"<p>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</p> <p>Once you have created your SMC, you will get a config.json file or a base64 json encoded string containing the following keys:</p> <ul> <li><code>hostname</code></li> <li><code>clientId</code></li> <li><code>privateKey</code></li> <li><code>serverPublicKeyId</code></li> <li><code>appKey</code></li> <li><code>appOwnerPublicKey</code></li> </ul> <p>This base64 encoded jsong string will be required to create your secretStores</p>"},{"location":"provider/keeper-security/#important-note-about-this-documentation","title":"Important note about this documentation","text":"<p>The KepeerSecurity calls the entries in vaults 'Records'. These docs use the same term.</p>"},{"location":"provider/keeper-security/#update-secret-store","title":"Update secret store","text":"<p>Be sure the <code>keepersecurity</code> provider is listed in the <code>Kind=SecretStore</code></p> <pre><code>---\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: keeper\nspec:\nprovider:\nkeepersecurity:\nauthRef: # Refer to a kubernetes secret which holds the base64 encoded json string for the configuration\nname: keeper-configuration\nkey: auth\nfolderID: 1qdsiewFW-U # Folder ID where the secrets can be pushed. It requires write permissions\n</code></pre> <p>NOTE 1: <code>folderID</code> target the folder ID where the secrets should be pushed to. It requires write permissions within the folder</p> <p>NOTE 2: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> for <code>SecretAccessKeyRef</code> with the namespace of the secret that we just created.</p>"},{"location":"provider/keeper-security/#external-secrets","title":"External Secrets","text":""},{"location":"provider/keeper-security/#behavior","title":"Behavior","text":"<ul> <li>How a Record is equated to an ExternalSecret:<ul> <li><code>remoteRef.key</code> is equated to a Record's ID</li> <li><code>remoteRef.property</code> is equated to one of the following options:<ul> <li>Fields: Record's field's Type</li> <li>CustomFields: Record's field's Label</li> <li>Files: Record's file's Name</li> <li>If empty, defaults to the complete Record in JSON format</li> </ul> </li> <li><code>remoteRef.version</code> is currently not supported.</li> </ul> </li> <li><code>dataFrom</code>:<ul> <li><code>find.path</code> is currently not supported.</li> <li><code>find.name.regexp</code> is equated to one of the following options:<ul> <li>Fields: Record's field's Type</li> <li>CustomFields: Record's field's Label</li> <li>Files: Record's file's Name</li> </ul> </li> <li><code>find.tags</code> are not supported at this time.</li> </ul> </li> </ul>"},{"location":"provider/keeper-security/#creating-external-secret","title":"Creating external secret","text":"<p>To create a kubernetes secret from the GCP Secret Manager secret a <code>Kind=ExternalSecret</code> is needed.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: example\nspec:\nrefreshInterval: 1h # rate SecretManager pulls KeeperSrucity\nsecretStoreRef:\nkind: SecretStore\nname: example # name of the SecretStore (or kind specified)\ntarget:\nname: secret-to-be-created # name of the k8s Secret to be created\ncreationPolicy: Owner\ndataFrom:\n- extract:\nkey: OqPt3Vd37My7G8rTb-8Q # ID of the Keeper Record\n---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: regcred\nnamespace: external-secrets\nspec:\nrefreshInterval: 1m\nsecretStoreRef:\nname: keeper\nkind: ClusterSecretStore\ntarget:\nname: regcred\ncreationPolicy: Owner\ntemplate:\nengineVersion: v2\ntype: kubernetes.io/dockerconfigjson\ndata:\n.dockerconfigjson: \"{\\\"auths\\\":{\\\"registry.example.com\\\":{\\\"username\\\":\\\"{{ .username }}\\\",\\\"password\\\":\\\"{{ .password }}\\\",\\\"auth\\\":\\\"{{(printf \\\"%s:%s\\\" .username .password) | b64enc }}\\\"}}}\"\ndata:\n- secretKey: username\nremoteRef:\nkey: OqPt3Vd37My7G8rTb-8Q\nproperty: login\n- secretKey: password\nremoteRef:\nkey: OqPt3Vd37My7G8rTb-8Q\nproperty: password\n---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: config\nnamespace: external-secrets\nspec:\nrefreshInterval: 1m\nsecretStoreRef:\nname: keeper\nkind: ClusterSecretStore\ntarget:\nname: credentials\ncreationPolicy: Owner\ntemplate:\nengineVersion: v2\ndata:\nusername: \"{{ .login }}\"\npassword: \"{{ .password }}\"\ndata:\n- secretKey: login\nremoteRef:\nkey: OqPt3Vd37My7G8rTb-8Q\nproperty: login\n- secretKey: password\nremoteRef:\nkey: OqPt3Vd37My7G8rTb-8Q\nproperty: password\n</code></pre> <p>The operator will fetch the Keeper Secret Manager secret and inject it as a <code>Kind=Secret</code> <pre><code>kubectl get secret secret-to-be-created -n <namespace> | -o jsonpath='{.data.dev-secret-test}' | base64 -d\n</code></pre></p>"},{"location":"provider/keeper-security/#limitations","title":"Limitations","text":"<p>There are some limitations using this provider.</p> <ul> <li>Keeper Secret Manager does not work with <code>General</code> Records types nor legacy non-typed records</li> <li>Using tags <code>find.tags</code> is not supported by KSM</li> <li>Using path <code>find.path</code> is not supported at the moment</li> </ul>"},{"location":"provider/keeper-security/#push-secrets","title":"Push Secrets","text":"<p>Push Secret will only work with a custom KeeperSecurity Record type <code>ExternalSecret</code></p>"},{"location":"provider/keeper-security/#behavior_1","title":"Behavior","text":"<ul> <li><code>selector</code>:</li> <li><code>secret.name</code>: name of the kubernetes secret to be pushed</li> <li><code>data.match</code>:</li> <li><code>secretKey</code>: key on the selected secret to be pushed</li> <li><code>remoteRef.remoteKey</code>: Secret and key to be created on the remote provider<ul> <li>Format: SecretName/SecretKey</li> </ul> </li> </ul>"},{"location":"provider/keeper-security/#creating-push-secret","title":"Creating push secret","text":"<p>To create a Keeper Security record from kubernetes a <code>Kind=PushSecret</code> is needed.</p> <pre><code>apiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\nname: example\nspec:\nsecretStoreRefs:\n- name: keeper\nkind: SecretStore\nrefreshInterval: \"1h\"\ndeletionPolicy: Delete\nselector:\nsecret:\nname: secret-name # k8s secret to be pushed\ndata:\n- match:\nsecretKey: secret-key # k8s key within the secret to be pushed\nremoteRef:\nremoteKey: remote-secret-name/remote-secret-key # This will create a record called \"remote-secret-name\" with a key \"remote-secret-key\"\n</code></pre>"},{"location":"provider/keeper-security/#limitations_1","title":"Limitations","text":"<ul> <li>Only possible to push one key per secret at the moment</li> <li>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</li> </ul>"},{"location":"provider/kubernetes/","title":"Kubernetes","text":"<p>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.</p> <p>A <code>SecretStore</code> 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.</p> <p>The <code>SecretStore</code> reconciler checks if you have read access for secrets in that namespace using <code>SelfSubjectRulesReview</code>. See below on how to set that up properly.</p>"},{"location":"provider/kubernetes/#external-secret-spec","title":"External Secret Spec","text":"<p>This provider supports the use of the <code>Property</code> 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.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: database-credentials\nspec:\nrefreshInterval: 1h\nsecretStoreRef:\nkind: SecretStore\nname: k8s-store # name of the SecretStore (or kind specified)\ntarget:\nname: database-credentials # name of the k8s Secret to be created\ndata:\n- secretKey: username\nremoteRef:\nkey: database-credentials\nproperty: username\n\n- secretKey: password\nremoteRef:\nkey: database-credentials\nproperty: password\n\n# metadataPolicy to fetch all the labels and annotations in JSON format\n- secretKey: tags\nremoteRef:\nmetadataPolicy: Fetch\nkey: database-credentials\n\n# metadataPolicy to fetch all the labels in JSON format\n- secretKey: labels\nremoteRef:\nmetadataPolicy: Fetch\nkey: database-credentials\nproperty: labels\n\n# metadataPolicy to fetch a specific label (dev) from the source secret\n- secretKey: developer\nremoteRef:\nmetadataPolicy: Fetch\nkey: database-credentials\nproperty: labels.dev\n</code></pre>"},{"location":"provider/kubernetes/#find-by-tag-name","title":"find by tag & name","text":"<p>You can fetch secrets based on labels or names matching a regexp:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: fetch-tls-and-nginx\nspec:\nrefreshInterval: 1h\nsecretStoreRef:\nkind: SecretStore\nname: k8s-store\ntarget:\nname: fetch-tls-and-nginx\ndataFrom:\n- find:\nname:\n# match secret name with regexp\nregexp: \"tls-.*\"\n- find:\ntags:\n# fetch secrets based on label combination\napp: \"nginx\"\n</code></pre>"},{"location":"provider/kubernetes/#target-api-server-configuration","title":"Target API-Server Configuration","text":"<p>The servers <code>url</code> can be omitted and defaults to <code>kubernetes.default</code>. You have to provide a CA certificate in order to connect to the API Server securely. For your convenience, each namespace has a ConfigMap <code>kube-root-ca.crt</code> that contains the CA certificate of the internal API Server (see <code>RootCAConfigMap</code> 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 <code>caBundle</code> property.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: k8s-store-default-ns\nspec:\nprovider:\nkubernetes:\n# with this, the store is able to pull only from `default` namespace\nremoteNamespace: default\nserver:\nurl: \"https://myapiserver.tld\"\ncaProvider:\ntype: ConfigMap\nname: kube-root-ca.crt\nkey: ca.crt\n</code></pre>"},{"location":"provider/kubernetes/#authentication","title":"Authentication","text":"<p>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.</p> <p>NOTE: <code>SelfSubjectRulesReview</code> permission is required in order to validation work properly. Please use the following role as reference:</p> <pre><code>apiVersion: rbac.authorization.k8s.io/v1\nkind: Role\nmetadata:\nnamespace: default\nname: eso-store-role\nrules:\n- apiGroups: [\"\"]\nresources:\n- secrets\nverbs:\n- get\n- list\n- watch\n- apiGroups:\n- authorization.k8s.io\nresources:\n- selfsubjectrulesreviews\nverbs:\n- create\n</code></pre>"},{"location":"provider/kubernetes/#authenticating-with-bearertoken","title":"Authenticating with BearerToken","text":"<p>Create a Kubernetes secret with a client token. There are many ways to acquire such a token, please refer to the Kubernetes Authentication docs.</p> <pre><code>apiVersion: v1\nkind: Secret\nmetadata:\nname: my-token\ndata:\ntoken: \"....\"\n</code></pre> <p>Create a SecretStore: The <code>auth</code> section indicates that the type <code>token</code> will be used for authentication, it includes the path to fetch the token. Set <code>remoteNamespace</code> to the name of the namespace where your target secrets reside.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: k8s-store-token-auth\nspec:\nprovider:\nkubernetes:\n# with this, the store is able to pull only from `default` namespace\nremoteNamespace: default\nserver:\n# ...\nauth:\ntoken:\nbearerToken:\nname: my-token\nkey: token\n</code></pre>"},{"location":"provider/kubernetes/#authenticating-with-serviceaccount","title":"Authenticating with ServiceAccount","text":"<p>Create a Kubernetes Service Account, please refer to the Service Account Tokens Documentation on how they work and how to create them.</p> <pre><code>$ kubectl create serviceaccount my-store\n</code></pre> <p>This Service Account needs permissions to read <code>Secret</code> and create <code>SelfSubjectRulesReview</code> resources. Please see the above role.</p> <pre><code>$ kubectl create rolebinding my-store --role=eso-store-role --serviceaccount=default:my-store\n</code></pre> <p>Create a SecretStore: the <code>auth</code> section indicates that the type <code>serviceAccount</code> will be used for authentication.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: k8s-store-sa-auth\nspec:\nprovider:\nkubernetes:\n# with this, the store is able to pull only from `default` namespace\nremoteNamespace: default\nserver:\n# ...\nauth:\nserviceAccount:\nname: \"my-store\"\n</code></pre>"},{"location":"provider/kubernetes/#authenticating-with-client-certificates","title":"Authenticating with Client Certificates","text":"<p>Create a Kubernetes secret which contains the client key and certificate. See Generate Certificates Documentations on how to create them.</p> <pre><code>$ kubectl create secret tls tls-secret --cert=path/to/tls.cert --key=path/to/tls.key\n</code></pre> <p>Reference the <code>tls-secret</code> in the SecretStore</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: k8s-store-cert-auth\nspec:\nprovider:\nkubernetes:\n# with this, the store is able to pull only from `default` namespace\nremoteNamespace: default\nserver:\n# ...\nauth:\ncert:\nclientCert:\nname: \"tls-secret\"\nkey: \"tls.crt\"\nclientKey:\nname: \"tls-secret\"\nkey: \"tls.key\"\n</code></pre>"},{"location":"provider/kubernetes/#pushsecret","title":"PushSecret","text":"<p>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.</p> <p>To configure the PushSecret resource, you need to specify the following parameters:</p> <ul> <li> <p>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.</p> </li> <li> <p>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.</p> </li> <li> <p>RemoteRef.Property: In addition to the above parameters, the Kubernetes provider requires you to set the <code>remoteRef.property</code> field. This field specifies the key of the remote Secret resource where the replicated value should be stored.</p> </li> </ul> <p>Here's an example:</p> <pre><code>apiVersion: external-secrets.io/v1alpha1\nkind: PushSecret\nmetadata:\nname: example\nspec:\nrefreshInterval: 10s\nsecretStoreRefs:\n- name: k8s-store-remote-ns\nkind: SecretStore\nselector:\nsecret:\nname: pokedex-credentials\ndata:\n- match:\nsecretKey: best-pokemon\nremoteRef:\nremoteKey: remote-best-pokemon\nproperty: best-pokemon\n</code></pre> <p>To utilize the PushSecret feature effectively, the referenced <code>SecretStore</code> requires specific permissions on the target cluster. In particular it requires <code>create</code>, <code>read</code>, <code>update</code> and <code>delete</code> permissions on the Secret resource:</p> <pre><code>apiVersion: rbac.authorization.k8s.io/v1\nkind: Role\nmetadata:\nnamespace: remote\nname: eso-store-push-role\nrules:\n- apiGroups: [\"\"]\nresources:\n- secrets\nverbs:\n- get\n- list\n- watch\n- create\n- update\n- patch\n- delete\n- apiGroups:\n- authorization.k8s.io\nresources:\n- selfsubjectrulesreviews\nverbs:\n- create\n</code></pre>"},{"location":"provider/kubernetes/#implementation-considerations","title":"Implementation Considerations","text":"<p>When utilizing the PushSecret feature and configuring the permissions for the SecretStore, consider the following:</p> <ul> <li> <p>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.</p> </li> <li> <p>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.</p> </li> <li> <p>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.</p> </li> </ul>"},{"location":"provider/oracle-vault/","title":"Oracle Vault","text":""},{"location":"provider/oracle-vault/#oracle-vault","title":"Oracle Vault","text":"<p>External Secrets Operator integrates with OCI API to sync secret on the Oracle Vault to secrets held on the Kubernetes cluster.</p>"},{"location":"provider/oracle-vault/#authentication","title":"Authentication","text":"<p>If <code>auth</code> is not specified, the operator uses the instance principal.</p> <p>For using a specific user credentials, 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.</p> <p>See url for what region you you are accessing. </p> <p>Select tenancy in the top right to see your user OCID as shown below. </p> <p>Select your user in the top right to see your user OCID as shown below. </p>"},{"location":"provider/oracle-vault/#service-account-key-authentication","title":"Service account key authentication","text":"<p>Create a secret containing your private key and fingerprint:</p> <pre><code>apiVersion: v1\nkind: Secret\nmetadata:\nname: oracle-secret\nlabels: type: oracle\ntype: Opaque\nstringData:\nprivateKey: fingerprint: </code></pre> <p>Your fingerprint will be attatched to your API key, once it has been generated. Found on the same page as the user OCID. </p> <p>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. </p>"},{"location":"provider/oracle-vault/#update-secret-store","title":"Update secret store","text":"<p>Be sure the <code>oracle</code> provider is listed in the <code>Kind=SecretStore</code>.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: example-instance-principal\nspec:\nprovider:\noracle:\nvault: # The vault OCID\nregion: # The vault region\n\n---\n\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: example-auth\nspec:\nprovider:\noracle:\nvault: # The vault OCID\nregion: # The vault region\nauth:\nuser: # A user OCID\ntenancy: # A user's tenancy\nsecretRef:\nprivatekey:\nname: oracle-secret\nkey: privateKey\nfingerprint:\nname: oracle-secret\nkey: fingerprint\n</code></pre> <p>NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> in <code>privatekey</code> and <code>fingerprint</code> with the namespaces where the secrets reside.</p>"},{"location":"provider/oracle-vault/#creating-external-secret","title":"Creating external secret","text":"<p>To create a kubernetes secret from the Oracle Cloud Interface secret a<code>Kind=ExternalSecret</code> is needed.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: example\nspec:\nrefreshInterval: 0.03m\nsecretStoreRef:\nkind: SecretStore\nname: example # Must match SecretStore on the cluster\ntarget:\nname: secret-to-be-created # Name for the secret on the cluster\ncreationPolicy: Owner\ndataFrom:\n- extract:\nkey: the-secret-name\n</code></pre>"},{"location":"provider/oracle-vault/#getting-the-kubernetes-secret","title":"Getting the Kubernetes secret","text":"<p>The operator will fetch the project variable and inject it as a <code>Kind=Secret</code>. <pre><code>kubectl get secret oracle-secret-to-create -o jsonpath='{.data.dev-secret-test}' | base64 -d\n</code></pre></p>"},{"location":"provider/scaleway/","title":"Scaleway","text":""},{"location":"provider/scaleway/#scaleway-secret-manager","title":"Scaleway Secret Manager","text":"<p>External Secrets Operator integrates with Scaleway's Secret Manager.</p>"},{"location":"provider/scaleway/#creating-a-secretstore","title":"Creating a SecretStore","text":"<p>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.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: secret-store\nspec:\nprovider:\nscaleway:\nregion: <REGION>\nprojectId: <PROJECT_UUID>\naccessKey:\nvalue: <ACCESS_KEY>\nsecretKey:\nsecretRef:\nname: <NAME_OF_KUBE_SECRET>\nkey: <KEY_IN_KUBE_SECRET>\n</code></pre>"},{"location":"provider/scaleway/#referencing-secrets","title":"Referencing Secrets","text":"<p>Secrets can be referenced by name or by id, using the prefixes <code>\"name:\"</code> and <code>\"id:\"</code> respectively.</p> <p>A PushSecret resource can only use a name reference.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: secret\nspec:\nrefreshInterval: 20s\nsecretStoreRef:\nkind: SecretStore\nname: secret-store\ndata:\n- secretKey: <KEY_IN_KUBE_SECRET>\nremoteRef:\nkey: id:<SECRET_UUID>\nversion: latest_enabled\n</code></pre>"},{"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":"<p>External Secrets Operator integrates with senhasegura DevOps Secrets Management (DSM) module to sync application secrets to secrets held on the Kubernetes cluster.</p>"},{"location":"provider/senhasegura-dsm/#authentication","title":"Authentication","text":"<p>Authentication in senhasegura uses DevOps Secrets Management (DSM) application authorization schema</p> <p>You need to create an Kubernetes Secret with desired auth parameters, for example:</p> <p>Instructions to setup authorizations and secrets in senhasegura DSM can be found at senhasegura docs for DSM and senhasegura YouTube channel</p> <pre><code>---\napiVersion: v1\nkind: Secret\nmetadata:\nname: senhasegura-dsm-auth\nstringData:\nCLIENT_SECRET: \"CHANGEME\"\n</code></pre>"},{"location":"provider/senhasegura-dsm/#examples","title":"Examples","text":"<p>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</p>"},{"location":"provider/senhasegura-dsm/#secretstore","title":"SecretStore","text":"<pre><code>---\napiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: senhasegura\nspec:\nprovider:\nsenhasegura:\nurl: \"https://senhasegura.changeme.com\"\nmodule: DSM # Select senhasegura DSM module to sync secrets\nauth:\nclientId: \"CHANGEME\"\nclientSecretSecretRef:\nname: senhasegura-dsm-auth\nkey: CLIENT_SECRET\nignoreSslCertificate: false # Optional\n</code></pre>"},{"location":"provider/senhasegura-dsm/#clustersecretstore","title":"ClusterSecretStore","text":"<pre><code>---\napiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\nname: senhasegura\nspec:\nprovider:\nsenhasegura:\nurl: \"https://senhasegura.changeme.com\"\nmodule: DSM # Select senhasegura DSM module to sync secrets\nauth:\nclientId: \"CHANGEME\"\nclientSecretSecretRef:\nname: senhasegura-dsm-auth\nkey: CLIENT_SECRET\nnamespace: senhasegura # Namespace of Secret \"senhasegura-dsm-auth\"\nignoreSslCertificate: false # Optional\n</code></pre>"},{"location":"provider/senhasegura-dsm/#syncing-secrets","title":"Syncing secrets","text":"<p>In examples below, consider that three secrets (api-settings, db-settings and hsm-settings) are defined in senhasegura DSM</p> <p>Secret Identifier: api-settings</p> <p>Secret data: </p> <pre><code>URL=https://example.com/api/example\nTOKEN=example-token-value\n</code></pre> <p>Secret Identifier: db-settings</p> <p>Secret data: </p> <pre><code>DB_HOST='db.example'\nDB_PORT='5432'\nDB_USERNAME='example'\nDB_PASSWORD='example'\n</code></pre> <p>Secret Identifier: hsm-settings</p> <p>Secret data: </p> <pre><code>HSM_ADDRESS='hsm.example'\nHSM_PORT='9223'\n</code></pre>"},{"location":"provider/senhasegura-dsm/#sync-dsm-secrets-using-secret-identifiers","title":"Sync DSM secrets using Secret Identifiers","text":"<p>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.</p> <p>If you only need a specific key, you can select it using remoteRef.property as the key name.</p> <p>In this method, you can overwrites data name in Kubernetes Secret object (e.g API_SETTINGS and API_SETTINGS_TOKEN)</p> <pre><code>---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: example-secret\nspec:\nrefreshInterval: \"30s\"\nsecretStoreRef:\nname: senhasegura\nkind: SecretStore\ntarget:\nname: example-secret\ndata:\n# Define API_SETTINGS Kubernetes Secret key, with json-encoded values from senhasegura secret with identifier \"api-settings\"\n- secretKey: API_SETTINGS\nremoteRef:\nkey: 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\nremoteRef:\nkey: api-settings # Secret Identifier in senhasegura\nproperty: TOKEN # Optional, Key name within secret\n</code></pre> <p>Kubernetes Secret will be create with follow <code>.data.X</code></p> <pre><code>API_SETTINGS='[{\"TOKEN\":\"example-token-value\",\"URL\":\"https://example.com/api/example\"}]'\nAPI_SETTINGS_TOKEN='example-token-value'\n</code></pre>"},{"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":"<p>If your app requires multiples secrets, it is not required to create multiple ExternalSecret resources, you can aggregate secrets using a single ExternalSecret resource</p> <p>In this method, every secret data in senhasegura creates an Kubernetes Secret <code>.data.X</code> field</p> <pre><code>---\napiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: example-secret\nspec:\nrefreshInterval: \"30s\"\nsecretStoreRef:\nname: senhasegura\nkind: SecretStore\ntarget:\nname: example-secret\ndataFrom:\n# Define Kubernetes Secret key with any k/v pair in senhasegura Secret with identifier \"api-settings\" or \"db-settings\"\n- extract:\nkey: api-settings\n- extract:\nkey: db-settings\n</code></pre> <p>Kubernetes Secret will be create with follow <code>.data.X</code></p> <pre><code>URL='https://example.com/api/example'\nTOKEN='example-token-value'\nDB_HOST='db.example'\nDB_PORT='5432'\nDB_USERNAME='example'\nDB_PASSWORD='example'\n</code></pre>"},{"location":"provider/webhook/","title":"Webhook","text":""},{"location":"provider/webhook/#generic-webhook","title":"Generic Webhook","text":"<p>External Secrets Operator can integrate with simple web apis by specifying the endpoint</p>"},{"location":"provider/webhook/#example","title":"Example","text":"<p>First, create a SecretStore with a webhook backend. We'll use a static user/password <code>root</code>:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: webhook-backend\nspec:\nprovider:\nwebhook:\nurl: \"http://httpbin.org/get?parameter={{ .remoteRef.key }}\"\nresult:\njsonPath: \"$.args.parameter\"\nheaders:\nContent-Type: application/json\nAuthorization: Basic {{ print .auth.username \":\" .auth.password | b64enc }}\nsecrets:\n- name: auth\nsecretRef:\nname: webhook-credentials\n---\napiVersion: v1\nkind: Secret\nmetadata:\nname: webhook-credentials\ndata:\nusername: dGVzdA== # \"test\"\npassword: dGVzdA== # \"test\"\n</code></pre> <p>NB: This is obviously not practical because it just returns the key as the result, but it shows how it works</p> <p>NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> in all <code>secrets</code> references with the namespaces where the secrets reside.</p> <p>Now create an ExternalSecret that uses the above SecretStore:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: webhook-example\nspec:\nrefreshInterval: \"15s\"\nsecretStoreRef:\nname: webhook-backend\nkind: SecretStore\ntarget:\nname: example-sync\ndata:\n- secretKey: foobar\nremoteRef:\nkey: secret\n---\n# will create a secret with:\nkind: Secret\nmetadata:\nname: example-sync\ndata:\nfoobar: c2VjcmV0\n</code></pre>"},{"location":"provider/webhook/#limitations","title":"Limitations","text":"<p>Webhook does not support authorization, other than what can be sent by generating http headers</p> <p>Note</p> <p>If a webhook endpoint for a given <code>ExternalSecret</code> returns a 404 status code, the secret is considered to have been deleted. This will trigger the <code>deletionPolicy</code> set on the <code>ExternalSecret</code>.</p>"},{"location":"provider/webhook/#templating","title":"Templating","text":"<p>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.</p> <p>The provider inserts the secret to be retrieved in the object named <code>remoteRef</code>.</p> <p>In addition, secrets can be added as named objects, for example to use in authorization headers. Each secret has a <code>name</code> property which determines the name of the object in the templating engine.</p>"},{"location":"provider/webhook/#all-parameters","title":"All Parameters","text":"<pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ClusterSecretStore\nmetadata:\nname: statervault\nspec:\nprovider:\nwebhook:\n# Url to call. Use templating engine to fill in the request parameters\nurl: <url>\n# http method, defaults to GET\nmethod: <method>\n# Timeout in duration (1s, 1m, etc)\ntimeout: 1s\nresult:\n# [jsonPath](https://jsonpath.com) syntax, which also can be templated\njsonPath: <jsonPath>\n# Map of headers, can be templated\nheaders:\n<Header-Name>: <header contents>\n# Body to sent as request, can be templated (optional)\nbody: <body>\n# List of secrets to expose to the templating engine\nsecrets:\n# Use this name to refer to this secret in templating, above\n- name: <name>\nsecretRef:\nnamespace: <namespace> # Only used in ClusterSecretStores\nname: <name>\n# Add CAs here for the TLS handshake\ncaBundle: <base64 encoded cabundle>\ncaProvider:\ntype: Secret or COnfigMap\nname: <name of secret or configmap>\nnamespace: <namespace> # Only used in ClusterSecretStores\nkey: <key inside secret>\n</code></pre>"},{"location":"provider/yandex-certificate-manager/","title":"Yandex Certificate Manager","text":""},{"location":"provider/yandex-certificate-manager/#yandex-certificate-manager","title":"Yandex Certificate Manager","text":"<p>External Secrets Operator integrates with Yandex Certificate Manager for secret management.</p>"},{"location":"provider/yandex-certificate-manager/#prerequisites","title":"Prerequisites","text":"<ul> <li>External Secrets Operator installed</li> <li>Yandex.Cloud CLI installed</li> </ul>"},{"location":"provider/yandex-certificate-manager/#authentication","title":"Authentication","text":"<p>At the moment, authorized key authentication is only supported:</p> <ul> <li>Create a service account in Yandex.Cloud: <pre><code>yc iam service-account create --name eso-service-account\n</code></pre></li> <li>Create an authorized key for the service account and save it to <code>authorized-key.json</code> file: <pre><code>yc iam key create \\\n--service-account-name eso-service-account \\\n--output authorized-key.json\n</code></pre></li> <li>Create a k8s secret containing the authorized key saved above: <pre><code>kubectl create secret generic yc-auth --from-file=authorized-key=authorized-key.json\n</code></pre></li> <li>Create a SecretStore pointing to <code>yc-auth</code> k8s secret: <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: secret-store\nspec:\nprovider:\nyandexcertificatemanager:\nauth:\nauthorizedKeySecretRef:\nname: yc-auth\nkey: authorized-key\n</code></pre></li> </ul> <p>NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> in all <code>authorizedKeySecretRef</code> with the namespace where the secret resides.</p>"},{"location":"provider/yandex-certificate-manager/#creating-external-secret","title":"Creating external secret","text":"<p>To make External Secrets Operator sync a k8s secret with a Certificate Manager certificate:</p> <ul> <li>Create a Certificate Manager certificate (follow the instructions), if not already created.</li> <li>Assign the <code>certificate-manager.certificates.downloader</code> role for accessing the certificate content to the service account used for authentication (<code>*****</code> is the certificate ID): <pre><code>yc cm certificate add-access-binding \\\n--id ***** \\\n--service-account-name eso-service-account \\\n--role certificate-manager.certificates.downloader\n</code></pre> Run the following command to ensure that the correct access binding has been added: <pre><code>yc cm certificate list-access-bindings --id *****\n</code></pre></li> <li>Create an ExternalSecret pointing to <code>secret-store</code> and the certificate in Certificate Manager: <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: external-secret\nspec:\nrefreshInterval: 1h\nsecretStoreRef:\nname: secret-store\nkind: SecretStore\ntarget:\nname: k8s-secret # the target k8s secret name\ntemplate:\ntype: kubernetes.io/tls\ndata:\n- secretKey: tls.crt # the target k8s secret key\nremoteRef:\nkey: ***** # the certificate ID\nproperty: chain\n- secretKey: tls.key # the target k8s secret key\nremoteRef:\nkey: ***** # the certificate ID\nproperty: privateKey\n</code></pre> The following property values are possible:<ul> <li><code>chain</code> \u2013 to fetch PEM-encoded certificate chain</li> <li><code>privateKey</code> \u2013 to fetch PEM-encoded private key</li> <li><code>chainAndPrivateKey</code> or missing property \u2013 to fetch both chain and private key</li> </ul> </li> </ul> <p>The operator will fetch the Yandex Certificate Manager certificate and inject it as a <code>Kind=Secret</code> <pre><code>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</code></pre></p>"},{"location":"provider/yandex-lockbox/","title":"Yandex Lockbox","text":""},{"location":"provider/yandex-lockbox/#yandex-lockbox","title":"Yandex Lockbox","text":"<p>External Secrets Operator integrates with Yandex Lockbox for secret management.</p>"},{"location":"provider/yandex-lockbox/#prerequisites","title":"Prerequisites","text":"<ul> <li>External Secrets Operator installed</li> <li>Yandex.Cloud CLI installed</li> </ul>"},{"location":"provider/yandex-lockbox/#authentication","title":"Authentication","text":"<p>At the moment, authorized key authentication is only supported:</p> <ul> <li>Create a service account in Yandex.Cloud: <pre><code>yc iam service-account create --name eso-service-account\n</code></pre></li> <li>Create an authorized key for the service account and save it to <code>authorized-key.json</code> file: <pre><code>yc iam key create \\\n--service-account-name eso-service-account \\\n--output authorized-key.json\n</code></pre></li> <li>Create a k8s secret containing the authorized key saved above: <pre><code>kubectl create secret generic yc-auth --from-file=authorized-key=authorized-key.json\n</code></pre></li> <li>Create a SecretStore pointing to <code>yc-auth</code> k8s secret: <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: secret-store\nspec:\nprovider:\nyandexlockbox:\nauth:\nauthorizedKeySecretRef:\nname: yc-auth\nkey: authorized-key\n</code></pre></li> </ul> <p>NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> in all <code>authorizedKeySecretRef</code> with the namespace where the secret resides.</p>"},{"location":"provider/yandex-lockbox/#creating-external-secret","title":"Creating external secret","text":"<p>To make External Secrets Operator sync a k8s secret with a Lockbox secret:</p> <ul> <li>Create a Lockbox secret, if not already created: <pre><code>yc lockbox secret create \\\n--name lockbox-secret \\\n--payload '[{\"key\": \"password\",\"textValue\": \"p@$$w0rd\"}]'\n</code></pre></li> <li>Assign the <code>lockbox.payloadViewer</code> role for accessing the <code>lockbox-secret</code> payload to the service account used for authentication: <pre><code>yc lockbox secret add-access-binding \\\n--name lockbox-secret \\\n--service-account-name eso-service-account \\\n--role lockbox.payloadViewer\n</code></pre> Run the following command to ensure that the correct access binding has been added: <pre><code>yc lockbox secret list-access-bindings --name lockbox-secret\n</code></pre></li> <li>Create an ExternalSecret pointing to <code>secret-store</code> and <code>lockbox-secret</code>: <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: ExternalSecret\nmetadata:\nname: external-secret\nspec:\nrefreshInterval: 1h\nsecretStoreRef:\nname: secret-store\nkind: SecretStore\ntarget:\nname: k8s-secret # the target k8s secret name\ndata:\n- secretKey: password # the target k8s secret key\nremoteRef:\nkey: ***** # ID of lockbox-secret\nproperty: password # (optional) payload entry key of lockbox-secret\n</code></pre></li> </ul> <p>The operator will fetch the Yandex Lockbox secret and inject it as a <code>Kind=Secret</code> <pre><code>kubectl get secret k8s-secret -n <namespace> | -o jsonpath='{.data.password}' | base64 -d\n</code></pre></p>"},{"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":"<p>Note: If you are using Parameter Store replace <code>service: SecretsManager</code> with <code>service: ParameterStore</code> in all examples below.</p> <p>This is basicially a zero-configuration authentication method that inherits the credentials from the runtime environment using the aws sdk default credential chain.</p> <p>You can attach a role to the pod using IRSA, kiam or kube2iam. When no other authentication method is configured in the <code>Kind=Secretstore</code> this role is used to make all API calls against AWS Secrets Manager or SSM Parameter Store.</p> <p>Based on the Pod's identity you can do a <code>sts:assumeRole</code> before fetching the secrets to limit access to certain keys in your provider. This is optional.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: team-b-store\nspec:\nprovider:\naws:\nservice: SecretsManager\nregion: eu-central-1\n# optional: do a sts:assumeRole before fetching secrets\nrole: team-b\n</code></pre>"},{"location":"snippets/provider-aws-access/#access-key-id-secret-access-key","title":"Access Key ID & Secret Access Key","text":"<p>You can store Access Key ID & Secret Access Key in a <code>Kind=Secret</code> and reference it from a SecretStore.</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: team-b-store\nspec:\nprovider:\naws:\nservice: SecretsManager\nregion: eu-central-1\n# optional: assume role before fetching secrets\nrole: team-b\nauth:\nsecretRef:\naccessKeyIDSecretRef:\nname: awssm-secret\nkey: access-key\nsecretAccessKeySecretRef:\nname: awssm-secret\nkey: secret-access-key\n</code></pre> <p>NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> in <code>accessKeyIDSecretRef</code>, <code>secretAccessKeySecretRef</code> with the namespaces where the secrets reside.</p>"},{"location":"snippets/provider-aws-access/#eks-service-account-credentials","title":"EKS Service Account credentials","text":"<p>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.</p> <p>The big advantage of this approach is that ESO runs without any credentials.</p> <pre><code>apiVersion: v1\nkind: ServiceAccount\nmetadata:\nannotations:\neks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/team-a\nname: my-serviceaccount\nnamespace: default\n</code></pre> <p>Reference the service account from above in the Secret Store:</p> <pre><code>apiVersion: external-secrets.io/v1beta1\nkind: SecretStore\nmetadata:\nname: secretstore-sample\nspec:\nprovider:\naws:\nservice: SecretsManager\nregion: eu-central-1\nauth:\njwt:\nserviceAccountRef:\nname: my-serviceaccount\n</code></pre> <p>NOTE: In case of a <code>ClusterSecretStore</code>, Be sure to provide <code>namespace</code> for <code>serviceAccountRef</code> with the namespace where the service account resides.</p>"},{"location":"snippets/provider-aws-access/#custom-endpoints","title":"Custom Endpoints","text":"<p>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.</p> <p>Use the following environment variables to point the controller to your custom endpoints. Note: All resources managed by this controller are affected.</p> 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 <code>assumeRole</code> or <code>assumeRoleWithWebIdentity</code> calls."}]}
|