spec icon indicating copy to clipboard operation
spec copied to clipboard

What is a valid JSON for `CNB_REGISTRY_AUTH`?

Open ajdergute opened this issue 3 years ago • 10 comments

The registry authentication chapter (ihttps://github.com/buildpacks/spec/blob/main/platform.md#registry-authentication) mentions CNB_REGISTRY_AUTH as a way to provide authentication to a registry. Unfortunately I didn't find how exactly this JSON is structured. Is there a schema?

I try to push an image to a local registry with podman on my machine. This is a testing step before integration into our GitLab CI.

ajdergute avatar Dec 13 '21 18:12 ajdergute

@ajdergute Here's an example using docker.io:

CNB_REGISTRY_AUTH='{"index.docker.io":"Basic YWVt<redacted>="}'

aemengo avatar Dec 13 '21 20:12 aemengo

Thank you very much. Is this something which should be mentioned in an appendix?

ajdergute avatar Dec 14 '21 11:12 ajdergute

@ajdergute the spec does specify the structure of CNB_REGISTRY_AUTH -

MUST be valid JSON object and MAY contain any number of <regsitry> to <auth-header> mappings. If CNB_REGISTRY_AUTH is set and <registry> matches the registry of an image reference, the lifecycle SHOULD set the value of the Authorization HTTP header to <auth-header> when attempting to read or write the image located at the given reference.

However, reading through that block of text, I do understand how that can be confusing. Would you like to make a PR to the spec repo with the appendix structure/example? That would be much appreciated!

sambhav avatar Dec 14 '21 12:12 sambhav

We need a better documentation and examples please ! @natalieparellano

cmoulliard avatar Jun 22 '23 05:06 cmoulliard

I experiment an issue to try to set the credential using an internal container registry running on openshift cluster where tekton is deployed.

I can log successfully using the same credential kubeadmin:$(oc whoami -t) from a pod running inside the cluster

oc debug nodes/ocp-sscpc-master-0   
Temporary namespace openshift-debug-wn7hv is created for debugging node...
Starting pod/ocp-sscpc-master-0-debug ...
To use host binaries, run `chroot /host`
Pod IP: 172.208.1.223
If you don't see a command prompt, try pressing enter.
sh-4.4# chroot /host
...
sh-4.4# podman login -u kubeadmin -p "sha256~57f0OvttQJfknOt5LdPoPmhoLe3raITNrRWlgNbai2g" image-registry.openshift-image-registry.svc:5000
Login Succeeded!

but that fails ERROR: failed to initialize analyzer: validating registry read access: ensure registry read access to image-registry.openshift-image-registry.svc:5000/quarkus-hello using such a JSON string

{"image-registry.openshift-image-registry.svc:5000":"Basic a3ViZWFkbWluOnNoYTI1Nn41N2YwT3Z0dFFKZmtuT3Q1TGRQb1BtaG9MZTNyYUlUTnJSV2xnTmJhaTJnCg=="}

passed to CNB_REGISTRY_AUTH as ENV VAR

    - name: analyze
      image: $(params.CNB_LIFECYCLE_IMAGE)
      imagePullPolicy: Always
      command: ["/cnb/lifecycle/analyzer"]
      env:
        - name: CNB_REGISTRY_AUTH
          valueFrom:
            configMapKeyRef:
              name: registry-creds
              key: auth.json

If you decode using base64 the string a3ViZWFkbWluOnNoYTI1Nn41N2YwT3Z0dFFKZmtuT3Q1TGRQb1BtaG9MZTNyYUlUTnJSV2xnTmJhaTJnCg== you can see that we are passing the same user:password as executing podman login ... command

echo "a3ViZWFkbWluOnNoYTI1Nn41N2YwT3Z0dFFKZmtuT3Q1TGRQb1BtaG9MZTNyYUlUTnJSV2xnTmJhaTJnCg==" | base64 -d
kubeadmin:sha256~57f0OvttQJfknOt5LdPoPmhoLe3raITNrRWlgNbai2g

Remark: That also fails if we pass directly the json string

      env:
        - name: CNB_REGISTRY_AUTH
          value: '{"image-registry.openshift-image-registry.svc:5000":"Basic a3ViZWFkbWluOnNoYTI1Nn41N2YwT3Z0dFFKZmtuT3Q1TGRQb1BtaG9MZTNyYUlUTnJSV2xnTmJhaTJnCg=="}'

NOTE: I created a test case which can be used with tekton on ocp4 to reproduce that: https://github.com/redhat-buildpacks/testing/blob/011bc65f841bdab5667c59b329ac5d84f4c5f173/k8s/test.sh

cmoulliard avatar Jun 22 '23 08:06 cmoulliard

The encoded password contains a newline at the end. I think it should be: {"image-registry.openshift-image-registry.svc:5000":"Basic a3ViZWFkbWluOnNoYTI1Nn41N2YwT3Z0dFFKZmtuT3Q1TGRQb1BtaG9MZTNyYUlUTnJSV2xnTmJhaTJn"}. The structure looks fine though.

modulo11 avatar Jun 22 '23 09:06 modulo11

I think it should be:

I did a test using your string and error is still there ! I truncated the string to be sure that no new line is included: https://github.com/redhat-buildpacks/testing/blob/76ace8b9a75e8eb81d2cb72f31aff1167bf867a4/k8s/test.sh#L82

I dont think that a newline is included end of the string

$ cat <<EOF > auth.json
{"image-registry.openshift-image-registry.svc:5000":"Basic $(echo "kubeadmin:$(oc whoami -t)" | tr -d '\n' | base64)"}
EOF

$ cat auth.json
{"image-registry.openshift-image-registry.svc:5000":"Basic a3ViZWFkbWluOnNoYTI1Nn41N2YwT3Z0dFFKZmtuT3Q1TGRQb1BtaG9MZTNyYUlUTnJSV2xnTmJhaTJn"}

$ echo "a3ViZWFkbWluOnNoYTI1Nn41N2YwT3Z0dFFKZmtuT3Q1TGRQb1BtaG9MZTNyYUlUTnJSV2xnTmJhaTJn" | base64 -d
$ kubeadmin:sha256~57f0OvttQJfknOt5LdPoPmhoLe3raITNrRWlgNbai2g% 

$ oc whoami -t
sha256~57f0OvttQJfknOt5LdPoPmhoLe3raITNrRWlgNbai2g

NOTE: That works too if I authenticate using crane tool: https://gist.github.com/cmoulliard/005c1233de626d157d73320820431914

@natalieparellano Could the problem not been related to the Authentication itself but instead to a HTTPS (= certificate) issue - https://github.com/buildpacks/lifecycle/blob/3f1a3461ca9171e677ac95100a06b8fa8882b0d2/cmd/lifecycle/main.go#L141-L150 ?

cmoulliard avatar Jun 22 '23 09:06 cmoulliard

The newline was also the first thing I noticed. It was part of your value before, which would cause issues.

A certificate issue could be your issue for sure. Does your registry respond to http or https? If https Is the cert self-signed? We don't yet support insecure registries but are spec'd to be able to.

jabrown85 avatar Jun 22 '23 13:06 jabrown85

Would it be possible when we set -log-level to log the following information within the code ?

  • HTTP Request
  • HTTP response Code
  • Raw error message

otherwise it is really hard to figure out why by example here we have such an issue as the messgae logged is too generic ERROR: failed to initialize analyzer: validating registry read access: ensure registry read access

Screenshot 2023-06-22 at 16 12 50

Code - https://github.com/buildpacks/imgutil/blob/main/remote/remote.go#L531

func (i *Image) CheckReadAccess() bool {
	_, err := i.found()
	if err != nil {
                // Log information when debug mode is set !!!
		if transportErr, ok := err.(*transport.Error); ok {
			return transportErr.StatusCode != http.StatusUnauthorized &&
				transportErr.StatusCode != http.StatusForbidden
		}
		return false
	}
	return true
}

cmoulliard avatar Jun 22 '23 14:06 cmoulliard

Note, the verbose log messages will be available in lifecycle 0.17.0

natalieparellano avatar Jul 05 '23 18:07 natalieparellano