This repository contains the External Secrets Operator for Red Hat OpenShift. The operator runs in the external-secrets-operator namespace and deploys and manages the upstream external-secrets application on OpenShift clusters using static YAML manifests embedded as bindata.
The External Secrets Operator operates as a cluster-wide service that integrates external secrets management systems -- such as AWS Secrets Manager, HashiCorp Vault, Google Secrets Manager, Azure Key Vault, IBM Cloud Secrets Manager, and AWS Systems Manager Parameter Store -- with the OpenShift Container Platform, performing secret fetching, refreshing, and provisioning within the cluster.
Using the External Secrets Operator ensures the following:
- Decouples applications from the secret-lifecycle management.
- Centralizes secret storage to support compliance requirements.
- Enables secure and automated secret rotation.
- Supports multi-cloud secret sourcing with fine-grained access control.
- Centralizes and audits access control.
The operator uses two singleton custom resources (both named cluster) for configuration:
| Custom Resource | Purpose |
|---|---|
ExternalSecretsConfig (esc) |
Operand installation and configuration |
ExternalSecretsManager (esm) |
Status aggregation and global settings |
Three controllers handle the operator lifecycle:
| Controller | Responsibility |
|---|---|
external_secrets |
Installs and manages the external-secrets application based on user-defined configuration in the ExternalSecretsConfig CR. |
external_secrets_manager |
Reconciles the ExternalSecretsManager CR, provides aggregated status from other controllers, and auto-creates the default cluster CR. |
crd_annotator |
Adds cert-manager.io/inject-ca-from annotations to external-secrets CRDs. Activates only when cert-manager is installed. |
The operand manifests are pre-rendered from upstream Helm charts at build time (hack/update-external-secrets-manifests.sh) and embedded via openshift/build-machinery-go into pkg/operator/assets/bindata.go.
| Component | Version |
|---|---|
| Go | 1.26 (workspace mode via go.work) |
| Kubernetes libraries | v0.35.6 |
| controller-runtime | v0.23.3 |
| cert-manager | v1.18.5 |
| External Secrets (operand) | v2.5.0 |
| Container tool | podman (default; override with CONTAINER_TOOL=docker) |
api/ API type definitions (ExternalSecretsConfig, ExternalSecretsManager)
cmd/ Operator entry point
pkg/
controller/ Controller implementations (external_secrets, external_secrets_manager, crd_annotator)
operator/ Operand lifecycle, asset management, bindata
config/ Kustomize overlays, CRD bases, RBAC, samples
bindata/ Embedded operand manifests (source for bindata.go)
test/ Test suites (e2e/, apis/, utils/)
hack/ Build and codegen scripts
docs/ Product/user docs, anti-patterns, OpenSpec notes
harness-evals/harness-docs/ Domain guidelines, architecture, ADRs, development workflows
bundle/ OLM bundle manifests
tools/ Build tooling module
images/ Container image definitions
vendor/ Vendored Go dependencies
- Go 1.26+
- podman (or docker) 17.03+
- kubectl v1.32.1+ / oc
- Access to a Kubernetes v1.32.1+ / OpenShift cluster
make build # Full build: manifests, generate, fmt, vet, then compile
make build-operator # Compile the operator binary only (no codegen or checks)
make image-build # Build the container image with podmanTo build and push a custom image:
make image-build image-push IMG=<registry>/external-secrets-operator:<tag>Install CRDs and deploy the operator:
make install # Install CRDs
make deploy IMG=<registry>/external-secrets-operator:<tag> # Deploy the operator
kubectl apply -k config/samples/ # Create sample CRsTo uninstall:
kubectl delete -k config/samples/
make uninstall
make undeploymake build-installer IMG=<registry>/external-secrets-operator:<tag>
# Produces dist/install.yaml containing all resources
kubectl apply -f dist/install.yaml| Make Target | Description |
|---|---|
make test |
Run all non-e2e tests (test-apis + test-unit); no cluster required. |
make test-unit |
Run unit tests (excludes test/e2e, test/apis, test/utils). |
make test-apis |
Run API integration tests (Ginkgo + envtest). |
make test-e2e |
Run end-to-end tests against a live cluster. |
E2E tests support label filtering for provider-specific or scenario-specific runs:
make test-e2e E2E_GINKGO_LABEL_FILTER="Provider:Vault"For full E2E details including prerequisites, suite-specific commands, and cross-platform labels, see test/e2e/README.md.
Detailed testing conventions (unit test style, table-driven patterns, envtest setup) are documented in harness-evals/harness-docs/testing-guidelines.md.
Before submitting a PR, run the CI gate check:
make verify # Runs vet, fmt, deps, bindata, generated files, govulncheck, markdownlint, and git diff
make lint # Run golangci-lint
make lint-fix # Run golangci-lint with auto-fix
make lint-markdown # Run markdownlint-cli2 on docs (also invoked by make verify)make verify is the single gate that CI enforces. It catches generated-file drift, dependency inconsistencies, formatting issues, markdown style problems, and vulnerability scan failures.
Several files in this repository are generated and must not be hand-edited:
| File | Regenerate With |
|---|---|
pkg/operator/assets/bindata.go |
make update-bindata |
pkg/controller/client/fakes/fake_ctrl_client.go |
go generate ./pkg/controller/client/... |
**/zz_generated.deepcopy.go |
make generate |
CRD YAML in config/crd/bases/ |
make manifests |
To regenerate everything at once:
make update # generate + manifests + update-operand-manifests + update-bindata + bundle + docsDetailed rules, architecture deep-dives, ADRs, and development workflows are in harness-evals/harness-docs/:
| Guideline | Scope |
|---|---|
| Security | CEL validation, annotation/label restrictions, container hardening, RBAC, network policies, TLS |
| Performance | Label-filtered caches, change detection, event predicates, requeue strategy, concurrency |
| Error Handling | Error classification, status conditions, requeue matrix, events |
| API Contracts | Singleton enforcement, field immutability, CEL rules, .testsuite.yaml patterns |
| Testing | Unit tests, API integration tests, E2E with Ginkgo labels |
| Integration | cert-manager, OLM, proxy, trusted CA, console, metrics, multi-arch, webhooks |
harness-evals/harness-docs/ESO_DEVELOPMENT.md-- Development workflows, build targets, common tasksharness-evals/harness-docs/ESO_TESTING.md-- Test suites, patterns, E2E labelsharness-evals/harness-docs/architecture/-- Controller internals, resource management, bindata pipelineharness-evals/harness-docs/domain/-- API documentation for ExternalSecretsConfig and ExternalSecretsManagerharness-evals/harness-docs/decisions/-- Component-specific architectural decision recordsharness-evals/harness-docs/references/-- Enhancement proposals catalog and ecosystem links
If you are an AI agent or LLM-based tool working on this repository, start with AGENTS.md. It indexes critical patterns and deeper documentation in harness-evals/harness-docs/. Claude Code–specific build commands and behavioral preferences are in CLAUDE.md.
Recommended reading order: AGENTS.md → relevant harness-evals/harness-docs/*-guidelines.md → domain/ → architecture/ → decisions/ → ESO_DEVELOPMENT.md
We welcome contributions from the community! See CONTRIBUTING.md for the full workflow (setup, conventions, PR checklist, and testing expectations).
In short: fork, branch from main, run make verify / make test / make lint, and open a PR that explains what changed and why.
To report a vulnerability, see SECURITY.md. Do not open a public GitHub issue for security reports.
- External Secrets Operator on OpenShift (Red Hat docs)
- external-secrets upstream project
- cert-manager Operator for Red Hat OpenShift
- Enhancement: ESO on OpenShift
- Kubebuilder Documentation
Copyright 2025-2026.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.