Targeting Custom Resources
Maturity
At the time of this writing (1.11.2025) this feature is in heavy alpha status. Please consider the following documentation with the limitations and guardrails described below.
External Secrets Operator can create and manage resources beyond Kubernetes Secrets. When you need to populate ConfigMaps or Custom Resource Definitions with secret data from your external provider, you can use the manifest target feature.
Security Consideration
Custom resources are not encrypted at rest by Kubernetes. Only use this feature when you need to populate resources that do not contain sensitive credentials, or when the target resource is encrypted by other means.
This feature must be explicitly enabled in your deployment using the --unsafe-allow-generic-targets flag.
Namespaced Resources Only
With this feature you can only target namespaced resources - and resources can only be managed by an ExternalSecret in the same namespace as the resource.
Performance
Using generic targets or custom resources at the moment of this writing is ~20% slower than handling secrets due to certain missing features yet to be implemented. We recommend not overusing this feature without too many objects until further performance improvement are implemented.
Basic ConfigMap Example
The simplest use case is creating a ConfigMap from external secrets. This is useful when applications expect configuration in ConfigMaps rather than Secrets, or when the data is not sensitive.
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: application-config
spec:
refreshInterval: 1h
secretStoreRef:
name: vault-backend
kind: SecretStore
target:
name: app-config
manifest:
apiVersion: v1
kind: ConfigMap
data:
- secretKey: database-host
remoteRef:
key: config/database/host
- secretKey: api-endpoint
remoteRef:
key: config/api/endpoint
This creates a ConfigMap named app-config with the data populated from your secret provider.
Custom Resource Definitions
You can target any custom resource that exists in your cluster. This example creates an Argo CD Application resource:
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: argocd-app
spec:
refreshInterval: 15m
secretStoreRef:
name: vault-backend
kind: SecretStore
target:
name: my-application
manifest:
apiVersion: argoproj.io/v1alpha1
kind: Application
dataFrom:
- extract:
key: argocd/applications/my-app
The operator will create or update the Application resource with the data from your external secret provider.
Templating with Custom Resources
Templates work with custom resources just as they do with Secrets. You can use the template.data field to create structured configuration:
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: templated-config
spec:
refreshInterval: 1h
secretStoreRef:
name: vault-backend
kind: SecretStore
target:
name: database-config
manifest:
apiVersion: v1
kind: ConfigMap
template:
engineVersion: v2
data:
database.yaml: |
host: {{ .dbHost }}
port: 5432
database: {{ .dbName }}
connection_string: "postgresql://user:{{ .dbPassword }}@{{ .dbHost }}:5432/{{ .dbName }}"
data:
- secretKey: dbHost
remoteRef:
key: database/hostname
- secretKey: dbName
remoteRef:
key: database/name
- secretKey: dbPassword
remoteRef:
key: database/password
Advanced Path Targeting
When working with custom resources that have complex structures, you can use target to specify where template output should be placed. This is particularly useful for resources with nested specifications.
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: custom-resource-config
spec:
refreshInterval: 1h
secretStoreRef:
name: vault-backend
kind: SecretStore
target:
name: app-settings
manifest:
apiVersion: config.example.com/v1
kind: AppConfig
template:
engineVersion: v2
templateFrom:
- literal: |
host: {{ .dbHost }}
port: {{ .dbPort }}
credentials:
username: {{ .dbUser }}
password: {{ .dbPassword }}
target: spec.database
- literal: |
level: info
format: json
target: spec.logging
data:
- secretKey: dbHost
remoteRef:
key: database/host
- secretKey: dbPort
remoteRef:
key: database/port
- secretKey: dbUser
remoteRef:
key: database/username
- secretKey: dbPassword
remoteRef:
key: database/password
The target field accepts dot-notation paths like spec.database or spec.logging to place the rendered template output at specific locations in the resource structure. When target is not specified it defaults to Data for backward compatibility with Secrets.
Drift Detection
The operator automatically detects and corrects manual changes to managed custom resources. If you modify a ConfigMap or custom resource that is managed by an ExternalSecret, the operator will restore it to the desired state immediately. This is achieved with informers watching the relevant GVK of the Resource.
Metadata and Labels
You can add labels and annotations to your target resources using the template metadata:
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: labeled-config
spec:
refreshInterval: 1h
secretStoreRef:
name: vault-backend
kind: SecretStore
target:
name: labeled-configmap
manifest:
apiVersion: v1
kind: ConfigMap
template:
engineVersion: v2
metadata:
labels:
app: myapp
environment: production
annotations:
description: "Managed by External Secrets Operator"
data:
config.json: |
{
"feature_flags": {
"new_ui": {{ .featureNewUI }},
"beta_api": {{ .featureBetaAPI }}
}
}
data:
- secretKey: featureNewUI
remoteRef:
key: features/new-ui
- secretKey: featureBetaAPI
remoteRef:
key: features/beta-api
The operator automatically adds the externalsecrets.external-secrets.io/managed: "true" label to track which resources it manages.
RBAC Requirements
When using custom resource targets, ensure the External Secrets Operator has appropriate RBAC permissions to create and manage those resources. The Helm chart provides configuration options to enable these permissions:
nonSecretTargets:
enabled: true
rbac:
configMaps: true
customResources:
- apiGroups: ["config.example.com"]
resources: ["appconfigs"]
Without these permissions, the operator will not be able to create or update your target resources.