Skip to content

Support mergeStrategy: patch on destination to preserve keys not managed by VSO #1235

@Fiv3H3ad

Description

@Fiv3H3ad

Is your feature request related to a problem? Please describe.
When using VaultStaticSecret to sync Vault data into a pre-existing Kubernetes Secret, the operator replaces the entire .data map on every sync cycle. This destroys any keys that were written by other controllers or applications at runtime.

Our concrete case: ArgoCD stores its configuration in a single argocd-secret. Some keys are static and should come from Vault (OIDC credentials, admin password, server secret key), while others are generated at runtime by ArgoCD itself (e.g. accounts.<user>.tokens). ArgoCD's ConfigMap uses $key substitution which is hardcoded to read from argocd-secret — there is no way to redirect it to a different secret.

Every VSO refresh cycle wipes the ArgoCD-generated tokens because VSO replaces the full .data map rather than patching only its managed keys.

Describe the solution you'd like

A mergeStrategy field (or similar) on spec.destination:

spec:
  destination:
    name: argocd-secret
    create: false
    mergeStrategy: patch
    transformation:
      templates:
        admin.password:
          text: '{{ .Secrets.adminPassword }}'
Strategy Sync Behavior
replace (default, current) Replace entire .data with synced keys
patch / merge Only add/update the keys VSO manages, leave all other keys untouched

Describe alternatives you've considered

  • Separate secret + envFrom: Doesn't work for ArgoCD because $key substitution is hardcoded to argocd-secret.
  • Including all keys in Vault templates: Not possible when keys are generated at runtime with dynamic data (UUIDs, timestamps).
  • External Secrets Operator: Supports creationPolicy: Merge which solves this. Switching operators is a heavy migration though.
  • ricoberger/vault-secrets-operator: Supports reconcileStrategy: Merge. Same migration concern.

Additional context

Related issues that touch on this but don't address preserving pre-existing keys during ongoing sync:

This is a blocker for any application that uses a single shared secret for both static config and runtime-generated data with hardcoded secret references (ArgoCD, Grafana, etc.).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions