Kubernetes dockerconfigjson from Operator controlled secret

I have a doppler secret that contains the dockerconfigjson value needed to pull gitlab images.
The secret is formatted like this (abstracting separate USER and TOKEN secrets)

{
  "auths": {
    "registry.gitlab.com": {
      "username":  "{{ GITLAB_DOCKER_REGISTRY_USER }}"
      "password": "{{ GITLAB_DOCKER_REGISTRY_TOKEN }}",
      "email": "k8s-deploy@mycompany.com",
      "auth":  "{{ base64_encode (print GITLAB_DOCKER_REGISTRY_USER ":" GITLAB_DOCKER_REGISTRY_TOKEN") }}"
    }
  }
}

The Doppler Operator pulls this secret in (as gitlab-registry-secret-from-doppler ) and encodes it exactly like I need, but I’m having some issues getting the gitlab-registry-cred secret to populate from the doppler secret.
How do I format the secret manifest to know that the secret I need is in in the gitlab-registry-secret-from-doppler as DOCKER_CONFIG_JSON ?

Is what’s discussed in this post what you’re after? If not, let me know and I’ll see what else we can figure out here!

I found that post this morning and am feeling like I took a step back… On Friday, my code below was generating a secret in the dev namespace with a base64 encoded .dockerconfigjson (as my original post suggests),
my secret is defined in Doppler as:

{ "auths": {
  "registry.gitlab.com": {
    "username": "${GITLAB_DOCKER_REGISTRY_USER}",
    "password": "${GITLAB_DOCKER_REGISTRY_TOKEN}",
    "email": "your-email@example.com",
    "auth": "{{ base64_encode (print GITLAB_DOCKER_REGISTRY_USER ":" GITLAB_DOCKER_REGISTRY_TOKEN) }}"
} } }

and this kubernetes manifest snippet:

---
apiVersion: v1
kind: Secret
metadata:
  name: deltacm-dev-doppler-token
  namespace: doppler-operator-system
type: Opaque
stringData:
  serviceToken: "<redacted>"
---
apiVersion: secrets.doppler.com/v1alpha1
kind: DopplerSecret
metadata:
  name: deltacm-dev-doppler-secret
  namespace: "doppler-operator-system"
spec:
  tokenSecret: 
    name: deltacm-dev-doppler-token
  managedSecret:
    name: deltacm-dev-registry-cred
    namespace: dev
    type: kubernetes.io/dockerconfigjson
  secrets:
    - GITLAB_DOCKER_CONFIG_JSON
    - GITLAB_DOCKER_REGISTRY_USER
    - GITLAB_DOCKER_REGISTRY_TOKEN
  processors:
    GITLAB_DOCKER_CONFIG_JSON:
      type: plain
      asName: ".dockerconfigjson"

I’m getting the following error on deploy:

$ kubectl describe -n doppler-operator-system dopplersecret deltacm-dev-doppler-secret
Name:         deltacm-dev-doppler-secret
Namespace:    doppler-operator-system
Labels:       <none>
Annotations:  <none>
API Version:  secrets.doppler.com/v1alpha1
Kind:         DopplerSecret
Metadata:
  Creation Timestamp:  2024-11-04T16:45:25Z
  Generation:          1
  Resource Version:    139657308
  UID:                 eaf2c086-6b23-4c84-af75-60602acc6a86
Spec:
  Host:  https://api.doppler.com
  Managed Secret:
    Name:       deltacm-dev-registry-cred
    Namespace:  dev
    Type:       kubernetes.io/dockerconfigjson
  Processors:
    GITLAB_DOCKER_CONFIG_JSON:
      As Name:     .dockerconfigjson
      Type:        plain
  Resync Seconds:  60
  Secrets:
    GITLAB_DOCKER_CONFIG_JSON
  Token Secret:
    Name:      deltacm-dev-doppler-token
  Verify TLS:  true
Status:
  Conditions:
    Last Transition Time:  2024-11-04T16:45:26Z
    Message:               Secret update failed: Failed to create Kubernetes secret: Secret "deltacm-dev-registry-cred" is invalid: data[.dockerconfigjson]: Invalid value: "<secret contents redacted>": invalid character ':' after object key:value pair
    Reason:                Error
    Status:                False
    Type:                  secrets.doppler.com/SecretSyncReady
    Last Transition Time:  2024-11-04T16:45:26Z
    Message:               Deployment reload has been stopped due to secrets sync failure
    Reason:                Stopped
    Status:                False
    Type:                  secrets.doppler.com/DeploymentReloadReady
Events:                    <none>

Backing up from all the code, what we’re trying to do is have just the GITLAB_USER and GITLAB_TOKEN as Doppler Secrets and have a single secret that contains the resulting .dockerconfigjson.
I thought I had the Docker-side piece working, but apparently not… I’m pretty sure the issue is in the auth line, but am not sure…

@binnsr Sorry for the delay responding here! I’m pretty sure the primary issue is with auth as well:

{{ base64_encode (print GITLAB_DOCKER_REGISTRY_USER ":" GITLAB_DOCKER_REGISTRY_TOKEN) }}

Doppler doesn’t have any kind of templating language like this inside secret values. So, that secret is synced over literally as it appears in plaintext with no additional evaluation or substitutions being made. Additionally, our secret referencing uses ${}, not {{ }}, so those substitutions aren’t really being made when syncing over either.

We don’t currently have any kind of in-line functions to do things like base64 encoding, so probably your best bet would be to add a new secret called GITLAB_DOCKER_CONFIG_AUTH or similar and set the value to the base64 encoded value of ${GITLAB_USER}:${GITLAB_TOKEN} (which you’d evaluate outside of Doppler before setting it). Then your GITLAB_DOCKER_CONFIG_JSON secret would look like this:

{
  "auths": {
    "registry.gitlab.com": {
      "username":  "${GITLAB_DOCKER_REGISTRY_USER}"
      "password": "${GITLAB_DOCKER_REGISTRY_TOKEN}",
      "email": "k8s-deploy@mycompany.com",
      "auth":  "${GITLAB_DOCKER_CONFIG_AUTH}"
    }
  }
}

In the code sample that I shared previously the {{ base64_encode(${USER}:${PASSWORD}) }} segment was being parsed on the opentofu side to generate the actual value. Somewhere along the way, that stopped happening.
I was able to work around the issue by removing the auths: and email: lines as the registry will actually upload on just the username/password fields.

My current secret, which is working in our environment looks like this:

{
  "auths": {
    "registry.gitlab.com": {
      "username":  "${GITLAB_DOCKER_REGISTRY_USER}"
      "password": "${GITLAB_DOCKER_REGISTRY_TOKEN}"
    }
  }
}