-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Description
Hi all,
Thanks for putting together and maintaining this project. I'm working with my friend @danpastori and we're running into some issues with integrating authentication between the Docker registry and a Laravel PHP application.
Our goals
We want to have a Laravel application manage the authentication for a Docker regisry using the "token" authentication method.
Error we're seeing
We have every thing connected but when we run docker login
, this error appears in the logs for the registry container:
token signed by untrusted key with ID: "RBND:K6XB:4IRB:VEDH:NYDG:TO5G:J2PJ:5LGY:NXJO:ONXG:FNLG:QJ76"
Steps we're following
This is how we are configuring our services. Some things have been simplified to minimize confusion.
Step 1: Configure Laravel app & Docker registry via Docker Compose
Here is a simple version of our Docker configuration
docker-compose.yml:
version: '3.8'
services:
traefik:
image: traefik:v2.9
networks:
development:
aliases:
- laravel.dev.test
- registry.dev.test
ports:
- 80:80
- 443:443
mariadb:
image: mariadb:10.11
environment:
MYSQL_ROOT_PASSWORD: "rootpassword"
MYSQL_DATABASE: "mylaravelapp"
MYSQL_USER: "mysqluser"
MYSQL_PASSWORD: "mysqlpassword"
php:
image: serversideup/php:8.2-fpm-nginx
networks:
- development
labels:
- "traefik.enable=true"
- "traefik.http.routers.laravel.rule=HostRegexp(`laravel.dev.test`)"
- "traefik.http.routers.laravel.entrypoints=websecure"
- "traefik.http.routers.laravel.tls=true"
- "traefik.http.services.laravel.loadbalancer.server.port=443"
- "traefik.http.services.laravel.loadbalancer.server.scheme=https"
registry:
image: registry:2
networks:
- development
labels:
- "traefik.enable=true"
- "traefik.http.routers.registry.rule=HostRegexp(`registry.dev.test`)"
- "traefik.http.routers.registry.entrypoints=websecure"
- "traefik.http.routers.registry.tls=true"
- "traefik.http.services.registry.loadbalancer.server.port=5000"
- "traefik.http.services.registry.loadbalancer.server.scheme=http"
networks:
development:
Step 2: Configure Registry to authenticate with Laravel PHP
This is what we are running for our registry configuration (some things have been removed to minimize confusion):
/etc/docker/registry/config.yml:
version: 0.1
log:
level: debug
http:
addr: :5000
secret: mysecret
auth:
token:
realm: https://laravel.dev.test/registry-token
service: registry.dev.test
issuer: mylaravelapp
rootcertbundle: /certs/rootcertbundle.crt
Step 3: Generate "rootcertbundle.crt"
We've seen a lot of discussion how to do this.
We've tried:
- Generating a certificate keypair, setting
rootcertbundle
to our public CA certificate. - Generating a certificate keypair, setting
rootcertbundle
to the public certificate (not the CA) - Generating a certificate keypair, creating a custom CA, signing the key with the CA, combining the public certificate of the CA and the generated certificate into a single bundle, then setting
rootcertbundle
to the CA Public Certificate + JWT Public Certificate
Related comments:
Step 4: Attempt to authenticate with Laravel
Here is the PHP code that we are using to generate a JWT token with a kid
signature.
auth.php:
<?php
namespace App\Services\Registry;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Base32\Base32;
class CreateAccessTokenFirebaseJwt
{
public function create()
{
$privateKey = file_get_contents( storage_path('keys/private.key') );
$publicKey = file_get_contents( storage_path('keys/private.key') );
$payload = [
"iss" => "mylarvalapp",
"aud" => "registry.dev.test",
"iat" => time(),
"nbf" => time(),
"exp" => time() + 3600,
"sub" => "myuser",
"jti" => strtoupper(bin2hex(openssl_random_pseudo_bytes(16))),
"access" => [
[
"type" => "repository",
"name" => "serversideup/financial-freedom",
"actions" => [
"pull",
"push"
]
]
]
];
$jwt = JWT::encode($payload, $privateKey, 'ES256', $this->getKid( $publicKey ));
return response()->json([
'token' => $jwt
]);
}
private function getKid( $publicKey )
{
return implode(':', array_slice(
str_split(
rtrim(
Base32::encode( hash('sha256', $publicKey, true) ), '='
), 4
), 0, 12)
);
}
}
Docs we've been following
We've been using these docs trying to answer our questions as well but continue to see this error whenever we use docker login
from a fresh docker client.
Questions
- Are we generating the JWT and
kid
correctly? - What exactly is
rootcertbundle
expecting?
If anyone has any experience or areas they can point us in, that would be great! We've been working on this issue for days and are pretty stumped.
Thank you for your help! 🙌