Skip to content

PushSecret

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 either name or labelSelector, not both.
  • kind (string, optional): SecretStore or ClusterSecretStore. Defaults to SecretStore.
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's Unicode strategy)
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.