title: Docker registry (distribution) token authentication setup
body: <p>i have a problem setting up a token authentication with docker registry (distribution).</p>
  
  <pre><code>openssl ecparam -genkey -name prime256v1 -noout -out auth.key
  </code></pre>
  
  <p>which generate key (so you can reproduce):</p>
  
  <pre><code>-----BEGIN EC PRIVATE KEY-----
  MHcCAQEEIGCvEkodk5s6cKFvOwybUxRWp1XOw4a6r/AVWnQwr+DDoAoGCCqGSM49
  AwEHoUQDQgAE3qYoQnX4Bd3dIRGcYZQhyg9W1n5x/i51FdpcdFxFDaO1gEgNwnru
  P1hYG5ditEusCMKwYA0iChYHQetOyEAV7A==
  -----END EC PRIVATE KEY-----
  </code></pre>
  
  <p>Then i generate a certificate:</p>
  
  <pre><code>openssl req -new -x509 -subj "/CN=localhost" -key auth.key -out auth.cert -days 360
  </code></pre>
  
  <p>a public key:</p>
  
  <pre><code>openssl ec -in auth.key -pubout -outform DER -out auth.pub.der
  </code></pre>
  
  <p>and "kid" field, as <a href="https://docs.docker.com/registry/spec/auth/jwt/" rel="noreferrer">described in documentation</a></p>
  
  <pre><code>cat auth.pub.der | sha256sum | cut -c -30 | xargs echo -n | base32
  =&gt;HA3GCZRUMRSWCZTGGJRDINBYGU4DQNJTGE4WIYRSMVQWEODG
  </code></pre>
  
  <p>Then i start a docker registry from a docker-compose:</p>
  
  <pre><code>version: '2'
  
  services:
    registry:
      image: registry:2
      container_name: jwt-registry
      ports:
        - 5000:5000
      environment:
        REGISTRY_LOG_LEVEL: debug
        REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /var/lib/registry
        REGISTRY_AUTH: token
        REGISTRY_AUTH_TOKEN_REALM: http://localhost:8080/jwt/token
        REGISTRY_AUTH_TOKEN_SERVICE: "localhost"
        REGISTRY_AUTH_TOKEN_ISSUER: "localhost"
        REGISTRY_AUTH_TOKEN_ROOTCERTBUNDLE: /certs/auth.cert
      volumes:
        - ./registry:/var/lib/registry
        - ./certs:/certs
  </code></pre>
  
  <p>Then i tried to login with docker login command:</p>
  
  <pre><code>docker login -u "email@example.com" -p test http://127.0.0.1:5000
  </code></pre>
  
  <p>and from auth server i return a response:</p>
  
  <pre><code>HTTP/1.1 200 OK
  Server: ""
  Content-Type: text/plain
  Date: Sun, 24 Jul 2016 19:59:38 GMT
  Content-Length: 493
  
  {"token":"eyJraWQiOiJIQTNHOkNaUlU6TVJTVzpDWlRHOkdKUkQ6SU5CWTpHVTREOlFOSlQ6R0U0VzpJWVJTOk1WUVc6RU9ERyIsInR5cCI6IkpXVCIsImFsZyI6IkVTMjU2In0.eyJpc3MiOiJsb2NhbGhvc3QiLCJzdWIiOiJkb2NrZXIiLCJhdWQiOiJsb2NhbGhvc3QiLCJleHAiOjE0NjkzOTM5NTIsImlhdCI6MTQ2OTM5MDM1MiwianRpIjoidnRqdjRwMzFkYjZncXBiMm05Y3NwczhjcXEiLCJhY2Nlc3MiOlt7InR5cGUiOiJyZXBvc2l0b3J5IiwibmFtZSI6InRlc3QvdGVzdCIsImFjdGlvbnMiOlsicHVsbCIsInB1c2giXX1dfQ.a3b6alE8M9L2rvfJtgOMx5GpJy7vUrHz1gaUU3lGl7bzt4scuVODyoes-f02lst-CasPupL84-ltSw6QzHN1yA"}
  </code></pre>
  
  <p>which has this header inside:</p>
  
  <pre><code>{"kid":"HA3G:CZRU:MRSW:CZTG:GJRD:INBY:GU4D:QNJT:GE4W:IYRS:MVQW:EODG","typ":"JWT","alg":"ES256"}
  </code></pre>
  
  <p>and this payload inside:</p>
  
  <pre><code>{"iss":"localhost","sub":"docker","aud":"localhost","exp":1469393952,"iat":1469390352,"jti":"vtjv4p31db6gqpb2m9csps8cqq","access":[{"type":"repository","name":"test/test","actions":["pull","push"]}]}
  </code></pre>
  
  <p>and i sing it with the <code>nimbus-jose-jwt</code> library:</p>
  
  <pre><code>JWSObject jwsObject = new JWSObject(header, payload);
  jwsObject.sign(new ECDSASigner(privateKey));
  String compactJWS = jwsObject.serialize();
  </code></pre>
  
  <p>and from repository i get "401 Unauthorized" and this error in docker registry logs</p>
  
  <pre><code>token signed by untrusted key with ID: \"HA3G:CZRU:MRSW:CZTG:GJRD:INBY:GU4D:QNJT:GE4W:IYRS:MVQW:EODG\"
  </code></pre>
  
  <p>full log:</p>
  
  <pre><code>time="2016-07-24T19:45:29.406060112Z" level=debug msg="authorizing request" go.version=go1.6.2 http.request.host="127.0.0.1:5000" http.request.id=482bdbac-395e-447e-aa47-28e2a4226879 http.request.method=GET http.request.remoteaddr="172.18.0.1:58344" http.request.uri="/v2/" http.request.useragent="docker/1.11.2 go/go1.5.4 git-commit/b9f10c9 kernel/4.4.0-31-generic os/linux arch/amd64 UpstreamClient(Docker-Client/1.11.2 \\(linux\\))" instance.id=1b060844-3264-45f2-83fb-83c91c3cb5c1 service=registry version=v2.4.1 
  time="2016-07-24T19:45:29.406234284Z" level=warning msg="error authorizing context: authorization token required" go.version=go1.6.2 http.request.host="127.0.0.1:5000" http.request.id=482bdbac-395e-447e-aa47-28e2a4226879 http.request.method=GET http.request.remoteaddr="172.18.0.1:58344" http.request.uri="/v2/" http.request.useragent="docker/1.11.2 go/go1.5.4 git-commit/b9f10c9 kernel/4.4.0-31-generic os/linux arch/amd64 UpstreamClient(Docker-Client/1.11.2 \\(linux\\))" instance.id=1b060844-3264-45f2-83fb-83c91c3cb5c1 service=registry version=v2.4.1 
  172.18.0.1 - - [24/Jul/2016:19:45:29 +0000] "GET /v2/ HTTP/1.1" 401 87 "" "docker/1.11.2 go/go1.5.4 git-commit/b9f10c9 kernel/4.4.0-31-generic os/linux arch/amd64 UpstreamClient(Docker-Client/1.11.2 \\(linux\\))"
  time="2016-07-24T19:45:31.257993258Z" level=debug msg="authorizing request" go.version=go1.6.2 http.request.host="127.0.0.1:5000" http.request.id=3fe3dfd0-47de-48ae-b443-15d1896dd902 http.request.method=GET http.request.remoteaddr="172.18.0.1:58352" http.request.uri="/v2/" http.request.useragent="docker/1.11.2 go/go1.5.4 git-commit/b9f10c9 kernel/4.4.0-31-generic os/linux arch/amd64 UpstreamClient(Docker-Client/1.11.2 \\(linux\\))" instance.id=1b060844-3264-45f2-83fb-83c91c3cb5c1 service=registry version=v2.4.1 
  time="2016-07-24T19:45:31.2582134Z" level=error msg="token signed by untrusted key with ID: \"HA3G:CZRU:MRSW:CZTG:GJRD:INBY:GU4D:QNJT:GE4W:IYRS:MVQW:EODG\"" 
  time="2016-07-24T19:45:31.258328324Z" level=warning msg="error authorizing context: invalid token" go.version=go1.6.2 http.request.host="127.0.0.1:5000" http.request.id=3fe3dfd0-47de-48ae-b443-15d1896dd902 http.request.method=GET http.request.remoteaddr="172.18.0.1:58352" http.request.uri="/v2/" http.request.useragent="docker/1.11.2 go/go1.5.4 git-commit/b9f10c9 kernel/4.4.0-31-generic os/linux arch/amd64 UpstreamClient(Docker-Client/1.11.2 \\(linux\\))" instance.id=1b060844-3264-45f2-83fb-83c91c3cb5c1 service=registry version=v2.4.1 
  172.18.0.1 - - [24/Jul/2016:19:45:31 +0000] "GET /v2/ HTTP/1.1" 401 87 "" "docker/1.11.2 go/go1.5.4 git-commit/b9f10c9 kernel/4.4.0-31-generic os/linux arch/amd64 UpstreamClient(Docker-Client/1.11.2 \\(linux\\))"
  </code></pre>
  
  <p>do you know what i am doing wrong? Maybe the library sign it somehow different than registry want to. Do you know how to sign header and payload from command line to verify?</p>