|The early logo was fun. Then it grew up and went all corporate.|
Keycloak is a versatile open source identity and access management project with an API-first approach which makes it highly suited to modern application environments. I used it to build the identity management back-end for an entreprise cloud-service catalogue back in 2016 and it did everything we asked of it... more or less.
If I remember it did get a bit messy when we were trying to do Kerberos authentication from two different Active Directory domains within the same realm, although the account federation part worked fine the SSO only worked on one domain due to field mapping limitations. I also cobbled together a Keycloak module for bit.ly's OAuth reverse proxy but I was too ashamed to tweet about it as I didn't have time to write the test module in Go.
Anyway, this post is about getting Keycloak 10 up and running in a docker container so we can mess around with the latest features. So let's get into it. I'm using a Mac for this but well obviously, it should be the same on any other OS - that's kind of the point of Docker.
As I write this a new version of Keycloak (10.1) has been released so that's what I'll be using.
First of all get the latest container image with
~ % docker pull jboss/keycloak
To get Keycloak up and running with the configuration I want I need to assemble a fairly long docker run command.
The options I use are :
- -p 8080:8080 for the http port forwarding
- -p 8443:8443 for https
- -e KEYCLOAK_USER=<adminuser> -e KEYCLOAK_PASSWORD=<password>
to create the initial user. This can be done in other ways as described on the Keycloak dockerhub readme and of course you can be more secure than sticking your password on the command line. This is just for fun. Also, don't quote your user and password or things get weird.
- --mount type=bind,source=./<tls.key>,target=/etc/x509/https/tls.key --mount type=bind,source=./<tls.crt>,target=/etc/x509/https/tls.crt
I'm going to be accessing this Keycloak instance from other systems and vms, so I need a hostname other than localhost, and preferably a TLS certificate to match. At this point I add the CN of the certificate to my hosts file so that we can access a URL with a matching certificate.
The bind mount replaces a file in the container image with a file on your host OS. Super useful for fiddling with configuration files in the image, but in this case the easiest way to push the tls key and cert into the container. Generate your key pair with whatever tool or quantum-resistant black magic you prefer.
- -e KEYCLOAK_LOGLEVEL='DEBUG'Finally, debug logs. If we're going to be messing about with authentication protocols then this is a must.
The final command looks something like this :
~ % docker run \
-e KEYCLOAK_USER=<adminuser> \
-e KEYCLOAK_PASSWORD=<password> \
-e KEYCLOAK_LOGLEVEL='DEBUG' \
-p 8080:8080 -p 8443:8443 \
--mount type=bind,source="/<path>/<tls.key>",target=/etc/x509/https/tls.key \
--mount type=bind,source="/<path>/<tls.crt>",target=/etc/x509/https/tls.crt \
When Keycloak has finished starting then you should see this in your console :
21:03:36,552 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0060: Http management interface listening on http://127.0.0.1:9990/management
21:03:36,552 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0051: Admin console listening on http://127.0.0.1:9990
21:03:36,552 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: Keycloak 10.0.1 (WildFly Core 11.1.1.Final) started in 33748ms - Started 692 of 997 services (708 services are lazy, passive or on-demand)
Keycloak is up. TLS error because my cert isn't signed. I imported it into the OS trusted certs list to make Chrome stop complaining.
Log in with the username and password defined above.
And we're in. Next post, creating a client and Webauthn authentication flow.