Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What is a valid JSON for CNB_REGISTRY_AUTH? #277

Open
ajdergute opened this issue Dec 13, 2021 · 10 comments
Open

What is a valid JSON for CNB_REGISTRY_AUTH? #277

ajdergute opened this issue Dec 13, 2021 · 10 comments
Labels
api/platform enhancement New feature or request

Comments

@ajdergute
Copy link

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.

@aemengo
Copy link
Contributor

aemengo commented Dec 13, 2021

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

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

@ajdergute
Copy link
Author

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

@samj1912
Copy link
Member

samj1912 commented Dec 14, 2021

@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!

@cmoulliard
Copy link

We need a better documentation and examples please ! @natalieparellano

@cmoulliard
Copy link

cmoulliard commented Jun 22, 2023

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

@modulo11
Copy link
Contributor

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.

@cmoulliard
Copy link

cmoulliard commented Jun 22, 2023

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 ?

@jabrown85
Copy link
Contributor

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.

@cmoulliard
Copy link

cmoulliard commented Jun 22, 2023

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
}

@natalieparellano
Copy link
Member

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

@natalieparellano natalieparellano added the enhancement New feature or request label Nov 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api/platform enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

8 participants