PushSecret

The PushSecret is namespaced and it describes what data should be pushed to the secret provider.
- tells the operator what secrets should be pushed by using
spec.selector. - you can specify what secret keys should be pushed by using
spec.data. - you can bulk-push secrets using pattern matching with
spec.dataTo. - you can also template the resulting property values using templating.
Example
Below is an example of the PushSecret in use.
---
# The source secret that will be pushed to the destination secret by PushSecret.
apiVersion: v1
kind: Secret
metadata:
name: pushsecret-example
stringData:
best-pokemon-src: "Pikachu"
---
apiVersion: external-secrets.io/v1alpha1
kind: PushSecret
metadata:
name: pushsecret-example # Customisable
namespace: default # Same of the SecretStores
spec:
updatePolicy: Replace # Policy to overwrite existing secrets in the provider on sync
deletionPolicy: Delete # the provider' secret will be deleted if the PushSecret is deleted
refreshInterval: 1h0m0s # Refresh interval for which push secret will reconcile
secretStoreRefs: # A list of secret stores to push secrets to
- name: aws-parameterstore
kind: SecretStore
selector:
secret:
name: pokedex-credentials # Source Kubernetes secret to be pushed
# Alternatively, you can point to a generator that produces values to be pushed
generatorRef:
apiVersion: generators.external-secrets.io/v1alpha1
kind: ECRAuthorizationToken
name: prod-registry-credentials
template:
metadata:
annotations: { }
labels: { }
data:
# If the key source secret key has dashes, then it cannot be accessed directly,
# and the "index" function should be used.
best-pokemon: "{{ index . \"best-pokemon-src\" | toString | upper }} is the really best!"
# Also, it's possible to use an existing template from configmap where Secret is fetched,
# merged and templated within the referenced configMap data.
# It does not update the configmap, it creates a secret with: data["config.yml"] = ...result...
templateFrom:
- configMap:
name: application-config-tmpl
items:
- key: config.yml
data:
- conversionStrategy: None # Also supports the ReverseUnicode strategy
match:
# The secretKey is used within PushSecret (it should match key under spec.template.data)
secretKey: best-pokemon
remoteRef:
remoteKey: destination-secret # The destination secret object name (where the secret is going to be pushed)
property: best-pokemon-dst # The key within the destination secret object.
The result of the created Secret object will look like:
# The destination secret that will be templated and pushed by PushSecret.
apiVersion: v1
kind: Secret
metadata:
name: destination-secret
stringData:
best-pokemon-dst: "PIKACHU is the really best!"
DataTo
The spec.dataTo field enables bulk pushing of secrets without explicit per-key configuration. This is useful when you need to push multiple related secrets and want to avoid verbose YAML.
Basic Example
apiVersion: external-secrets.io/v1alpha1
kind: PushSecret
metadata:
name: push-db-secrets
spec:
secretStoreRefs:
- name: aws-secret-store
selector:
secret:
name: app-secrets
dataTo:
- storeRef:
name: aws-secret-store
match:
regexp: "^db-.*" # Push all keys starting with "db-"
rewrite:
- regexp:
source: "^db-"
target: "myapp/database/" # db-host -> myapp/database/host
Fields
storeRef (required)
Specifies which SecretStore to push to. Each dataTo entry must include a storeRef to target a specific store.
name(string, optional): Name of the SecretStore to target.labelSelector(object, optional): Select stores by label. Use eithernameorlabelSelector, not both.kind(string, optional):SecretStoreorClusterSecretStore. Defaults toSecretStore.
dataTo:
# Target a specific store by name
- storeRef:
name: aws-secret-store
# Target stores by label
- storeRef:
labelSelector:
matchLabels:
env: production
storeRef vs spec.data
Unlike spec.data entries which can omit store targeting, every dataTo entry requires a storeRef.
This prevents accidental "push to all stores" behavior. The storeRef must reference a store
listed in spec.secretStoreRefs.
match (optional)
Defines which keys to select from the source Secret.
regexp(string, optional): Regular expression pattern to match keys. If omitted, all keys are matched.
Examples:
# Match all keys
dataTo:
- storeRef:
name: my-store
# Match keys starting with "db-"
dataTo:
- storeRef:
name: my-store
match:
regexp: "^db-.*"
# Match keys ending with "-key"
dataTo:
- storeRef:
name: my-store
match:
regexp: ".*-key$"
rewrite (array, optional)
Array of rewrite operations to transform key names. Operations are applied sequentially.
Each rewrite can be either:
Regexp Rewrite:
rewrite:
- regexp:
source: "^db-" # Regex pattern to match
target: "app/db/" # Replacement string (supports capture groups like $1, $2)
Transform Rewrite (Go Template):
rewrite:
- transform:
template: "secrets/{{ .value | upper }}" # .value contains the key name
Chained Rewrites:
rewrite:
- regexp: {source: "^db-", target: ""} # Remove "db-" prefix
- regexp: {source: "^", target: "prod/"} # Add "prod/" prefix
metadata (object, optional)
Provider-specific metadata to attach to all pushed secrets. Structure depends on the provider.
dataTo:
- storeRef:
name: my-store
match:
regexp: "^db-.*"
metadata:
labels:
app: myapp
env: production
conversionStrategy (string, optional)
Strategy for converting secret key names before matching and rewriting. The conversion is applied to keys (not values), and match patterns and rewrite operations operate on the converted key names. Default: "None"
"None": No conversion"ReverseUnicode": Reverse Unicode escape sequences in key names (useful when paired with ExternalSecret'sUnicodestrategy)
dataTo:
- storeRef:
name: my-store
conversionStrategy: ReverseUnicode
Combining dataTo with data
You can use both dataTo and data fields. Explicit data entries override dataTo for the same source key:
spec:
secretStoreRefs:
- name: my-store
dataTo:
- storeRef:
name: my-store # Push all keys with original names
data:
- match:
secretKey: db-host
remoteRef:
remoteKey: custom-db-host # Override for db-host only
In this example, all keys are pushed via dataTo, but db-host uses the custom remote key from data instead.
Multiple dataTo Entries
You can specify multiple dataTo entries with different patterns:
spec:
secretStoreRefs:
- name: my-store
dataTo:
# Push db-* keys with database/ prefix
- storeRef:
name: my-store
match:
regexp: "^db-.*"
rewrite:
- regexp: {source: "^db-", target: "database/"}
# Push api-* keys with api/ prefix
- storeRef:
name: my-store
match:
regexp: "^api-.*"
rewrite:
- regexp: {source: "^api-", target: "api/"}
Error Handling
- Invalid regular expression: PushSecret enters error state with details in status
- Duplicate remote keys: Operation fails if rewrites produce duplicate keys
- No matching keys: Warning logged, PushSecret remains Ready
See the PushSecret dataTo guide for more examples and use cases.
Template
When the controller reconciles the PushSecret it will use the spec.template as a blueprint to construct a new property.
You can use golang templates to define the blueprint and use template functions to transform the defined properties.
You can also pull in ConfigMaps that contain golang-template data using templateFrom.
See advanced templating for details.