Skip to content

PushSecret fails to push PKCS#12 certs to Azure Key Vault due to binary data corruption in template engine #5010

@prismatic-koi

Description

@prismatic-koi

Describe the bug

When using a PushSecret to push a cert-manager generated TLS secret to Azure Key Vault as a PKCS#12 certificate, the operation fails with a parsing error. This happens because the templating engine incorrectly handles binary data returned from functions like b64dec. Specifically, it casts the raw binary bytes of the PFX bundle to a string, which corrupts the data before it's passed to the Azure provider's validation logic. The PushSecret status shows the following error:

set secret failed: could not write remote ref pfx-output-data to target secretstore azure-keyvault-push-store: value from secret is not a valid certificate: could not parse certificate value as PKCS#12, DER or PEM

To Reproduce

Steps to reproduce the behavior:

  1. provide all relevant manifests

source secret is in this format

apiVersion: v1
kind: Secret
metadata:
  name: my-app-tls-secret
  namespace: networking
type: kubernetes.io/tls   
data:
  tls.crt: xxx #note, contains leaf and root certs
  tls.key: xxx

pushsecret looks like this:

apiVersion: external-secrets.io/v1alpha1
kind: PushSecret
metadata:
  name: my-app-tls-cert-push
  namespace: networking
spec:
  refreshInterval: 1h
  selector:
    secret:
      # The source secret created by cert-manager
      name: my-app-tls-secret
  secretStoreRefs:
  - name: azure-keyvault-push-store
    kind: ClusterSecretStore
  data:
  - match:
      secretKey: pfx-output-data
      remoteRef:
        # The destination certificate object in Key Vault
        remoteKey: cert/my-app-certificate
  template:
    engineVersion: v2
    data:
      pfx-output-data: |
        {{ fullPemToPkcs12 (index . "tls.crt") (index . "tls.key") | b64dec }}
  1. provide the Kubernetes and ESO version
  • Kubernetes version: v1.32.5
  • External Secrets Operator Version: v0.18.0

Expected behavior

The PushSecret should successfully create the PKCS#12 bundle, and the Azure provider should push it to Key Vault without error.

Screenshots

n/A

Additional context

I've locally tested putting the output of fullPemToPkcs12 into getCertificateFromValue and found that to work fine.

I suspect the root cause to be in the v2 template engine in pkg/template/v2/template.go.

The valueScopeApply function processes the template. I think it is correctly executing the template and getting the raw binary bytes of the PFX bundle from the execute function, but then it casts the binary data to a string, which I think would corrupt its structure.

func valueScopeApply(tplMap, data map[string][]byte, target esapi.TemplateTarget, secret *corev1.Secret) error {
	for k, v := range tplMap {
		val, err := execute(k, string(v), data)
		if err != nil {
			return fmt.Errorf(errExecute, k, err)
		}
		applyToTarget(k, string(val), target, secret) // problem maybe here? in the string(val)
	}
	return nil
}

The corrupted data is then passed to the azure providers validation function getCertificateFromValue which fails to parse it as any valid certificate format.

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/bugCategorizes issue or PR as related to a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions