Add example for using SPIRE for mTLS with Keycloak (#248)

* Add example for using Spire for mTLS with Keycloak

Signed-off-by: Moritz Schmitz von Hülst <[email protected]>

* Minor improvement to the README.md

Signed-off-by: Moritz Schmitz von Hülst <[email protected]>

* But I still need to learn GitHub Markdown format

Signed-off-by: Moritz Schmitz von Hülst <[email protected]>

* Make it more obvious that it works without a (correct) password

Signed-off-by: Moritz Schmitz von Hülst <[email protected]>

* Add warning for Kubernetes 1.29+ feature

Signed-off-by: Moritz Schmitz von Hülst <[email protected]>

* Move ghostunnel into an initContainer with restartPolicy=Always

Signed-off-by: Moritz Schmitz von Hülst <[email protected]>

* Apply suggestions from code review

Co-authored-by: kfox1111 <[email protected]>
Signed-off-by: Moritz Schmitz von Hülst <[email protected]>

* Move java-spiffe-helper-properties into extraDeploy of the Keycloak chart and pin node version to it has a matching rancher/kubectl image

Signed-off-by: Moritz Schmitz von Hülst <[email protected]>

---------

Signed-off-by: Moritz Schmitz von Hülst <[email protected]>
Co-authored-by: kfox1111 <[email protected]>
This commit is contained in:
Moritz Schmitz von Hülst
2024-02-19 04:33:01 -08:00
committed by GitHub
co-authored by kfox1111
parent cc8ec897bf
commit 43a72a22ff
4 changed files with 311 additions and 0 deletions
@@ -0,0 +1,67 @@
# keycloak-config-cli using spire
> [!WARNING]
> This example uses
> the [`SidecarContainers`](https://kubernetes.io/docs/concepts/workloads/pods/sidecar-containers/#enabling-sidecar-containers)
> feature. This is only enabled by default in Kubernetes 1.29+.
This example shows how to leverage SPIRE in establishing an mTLS connection
between [Keycloak](https://www.keycloak.org/) and [keycloak-config-cli](https://github.com/adorsys/keycloak-config-cli),
a tool to configure Keycloak.
## Setup
1. Create a local cluster for testing
```shell
kind create cluster --image kindest/node:v1.29.0
```
2. Install CRDs
```shell
helm upgrade --install -n spire-server spire-crds ../../charts/spire-crds --create-namespace
```
3. Install `spire-server`
```shell
helm upgrade --install -n spire-server spire ../../charts/spire --create-namespace -f spire-values.yaml
```
4. Install `keycloak` (this also configures Keycloak for client certificate authentication)
```shell
helm upgrade --install keycloak oci://registry-1.docker.io/bitnamicharts/keycloak -f keycloak-values.yaml
```
5. Install `keycloak-config-cli`
```shell
kubectl apply -f keycloak-config-cli.yaml
```
6. Verify the realm config at the bottom of [keycloak-config-cli.yaml](./keycloak-config-cli.yaml) has been created!
7. Cleanup
```shell
kind delete cluster
```
## Notes
### java-spiffe-helper as Keycloak initContainer
This example uses [java-spiffe-helper](https://github.com/spiffe/java-spiffe/tree/main/java-spiffe-helper) as an
initContainer for Keycloak. It fetches the certificates from the `spire-agent` and conveniently provides them to
Keycloak in `pkcs12` format.
> [!IMPORTANT]
> Keycloak does not rotate the certificates like SPIRE does. If you want to run the `keycloak-config-cli`
> job again, you need to make sure Keycloak is also restarted/provided with non-expired certificates.
### Common name as username
This example is configured to read the username from the common name (`CN`) from the client certificate. Keycloak has
some options there, this looked like the easiest one. SPIRE joins the values from `dnsNameTemplates` in the
common name section of the certificate, so make sure you can somehow extract the username from it.