ExternalSecrets and dockerconfigjson

I’m new to Vault and trying to understand how to pull a GCR image using an ExternalSecret. We do this currently using regular secrets, but I would like to move this into Vault to be more secure.

The current (working) setup is as follows:
Original secret:

---
apiVersion: v1
kind: Secret
metadata:
  name: gcr-credentials
  namespace: <snip>
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: <snip base64 encoded json>

The deployment implimentation:

spec:
  containers:
  - name: test-container
    image: gcr.io/test-container:latest
    imagePullPolicy: Always
  imagePullSecrets:
  - name: gcr-credentials

This is my current (failed) attempt at making a working secret:

---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: docker-key-example
spec:
  refreshInterval: 1h
  secretStoreRef:
    kind: ClusterSecretStore
    name: non-production
  target:
    name: docker-key-example
    creationPolicy: Owner
    deletionPolicy: Retain
    template:
      type: kubernetes.io/dockerconfigjson
      data:
        .dockerconfigjson: "{{ .dockerhash | toString }}"
  data:
    - secretKey: dockerhash
      remoteRef:
        key: gcr-credentials
        property: dockerhash

I had a lot of issues getting my key/value saved in a way that Kubernetes would accept. Originally it was stored as a json key/value pair like so:

{
  "dockerhash":"<base64 encoded string>"
}

This caused an error because it was expecting the data to start with “{” as I figured out. Now its stored as follows:

{
  "dockerhash": {
    "auth_provider_x509_cert_url": "<snip>",
    "auth_uri": "<snip>",
    "client_email": "<snip>",
    "client_id": "<snip>",
    "client_x509_cert_url": "<snip>",
    "private_key": "<snip>",
    "private_key_id": "<snip>",
    "project_id": "<snip>",
    "token_uri": "<snip>",
    "type": "service_account"
  }
}

This ExternalSecret actually passes validation, but the key does not work when pulling the secret.

Its my understanding that this should be a base64 encoded string, but saving this value in vault as a base64 encoded string causes the ExternalSecret to fail, as i guess its expecting a json formatted string. Can someone help put me on the right track here?

To fix your setup, ensure the secret stored in Vault is the entire .docker/config.json content, base64-encoded. Adjust your ExternalSecret to fetch this base64 string from Vault directly, without additional encoding or JSON structuring. This way, your Kubernetes cluster can use the secret for GCR image pulls securely. Verify the stored secret format in Vault and the ExternalSecret configuration match precisely.