UNCLASSIFIED - NO CUI

Skip to content
Snippets Groups Projects
Commit a9904e6d authored by Wyatt Fry's avatar Wyatt Fry Committed by Christopher O'Connell
Browse files

Refresh Keycloak Architecture Docs

parent c11acf7e
No related branches found
No related tags found
1 merge request!5153Refresh Keycloak Architecture Docs
......@@ -8,190 +8,69 @@
```mermaid
graph LR
urlkc(Keycloak URL) -->|HTTPS| pg
urlpr(Prometheus URL) -->|HTTPS| ig
urlkc(Keycloak URL) -->|HTTPS| ig
urlpr(Prometheus URL) -->|HTTPS| ig
subgraph "Keycloak Ingress"
ig(Gateway) -->|TLS Passthrough| servkc{{"Service<BR>Keycloak"}}
ig(Gateway) -->|HTTP| servpr{{"Service<BR>Prometheus"}}
end
subgraph "Monitoring"
servpr --> prom(Prometheus)
prom(Prometheus) --> monitor
monitor(Service Monitor) --> servkc
end
subgraph "Keycloak Cluster"
servkc <--> pod0("Keycloak Pod 0")
servkc <--> pod1("Keycloak Pod 1")
end
subgraph "Database"
pod0 --> db[(Keycloak DB)]
pod1 --> db[(Keycloak DB)]
end
```
## Integration w/ Big Bang
Big Bang's integration with Keycloak requires special considerations and configuration compared to other applications. This document will help you set it up.
subgraph "Istio System"
ig(Public Gateway)
pg(Passthrough Gateway)
end
### Keycloak with Other Apps
subgraph "Monitoring"
ig --> servpr("Service<BR>Prometheus") --> prom
prom(Prometheus)
end
subgraph "Keycloak"
pg --> servkc("Service<BR>Keycloak") --> pod0("Keycloak Pod 0")
prom --> monitor(Service Monitor CRD) --> servkc
end
> The `admin` subdomain is only used when Keycloak is enabled
### Keycloak's Custom Image
The upstream [Keycloak Helm chart](https://repo1.dso.mil/big-bang/product/packages/keycloak) has customizations for use in Platform One, such as its [registration plugin](https://repo1.dso.mil/big-bang/product/plugins/keycloak-p1-auth-plugin). Additional customization can be added through Helm input values. For example:
```yaml
addons:
keycloak:
# Setup TLS key pair
# An alternative to this is to create a secret namged `tlskey` and `tlscert` using Kustomize in the customer template. Then use the volume and volumemount configuration below to mount the files. In this case, the `ingress.key` and `ingress.cert` would be left blank.
ingress:
key: |-
{insert keycloak TLS key}
cert: |-
{insert keycloak TLS cert}
values:
secrets:
# The `env` secret is used to add environmental variables to the keycloak pod
env:
stringData:
# Keycloak will use the `customreg.yaml` for configuring the custom registration process.
CUSTOM_REGISTRATION_CONFIG: /opt/jboss/keycloak/customreg.yaml
# Keycloak will load a custom realm defined in `realm.json`
KEYCLOAK_IMPORT: /opt/jboss/keycloak/realm.json
# Keycloak will load a custom set of certificate authorities
X509_CA_BUNDLE: /etc/x509/https/cas.pem
# The `certauthority` secret holds the certificate authority keys.
# Using the customer template, kustomize could be used to create the secret instead of using the keycloak chart via values
certauthority:
stringData:
cas.pem: |-
{insert CAS.PEM content}
# The `customreg` secret holds the configuration for customer registration.
# Using the customer template, kustomize could be used to create the secret instead of using the keycloak chart via values
customreg:
stringData:
customreg.yaml: |-
{insert customreg.yaml content}
# The `realm` secret holds the custom realm configuration.
# Using the customer template, kustomize could be used to create the secret instead of using the keycloak chart via values
realm:
stringData:
realm.json: |-
{insert realm.json content}
# Create volumes for each secret above
extraVolumes: |-
- name: certauthority
secret:
secretName: {{ include "keycloak.fullname" . }}-certauthority
- name: customreg
secret:
secretName: {{ include "keycloak.fullname" . }}-customreg
- name: realm
secret:
secretName: {{ include "keycloak.fullname" . }}-realm
# Volume mount each volume in the appropriate location
extraVolumeMounts: |-
- name: certauthority
mountPath: /etc/x509/https/cas.pem
subPath: cas.pem
readOnly: true
- name: customreg
mountPath: /opt/jboss/keycloak/customreg.yaml
subPath: customreg.yaml
readOnly: true
- name: realm
mountPath: /opt/jboss/keycloak/realm.json
subPath: realm.json
readOnly: true
pod0("Keycloak Pod 0") --> db[(Keycloak DB)]
```
### Keycloak Admin password
Big Bang creates a default admin user for logging into the admin console. To override the default admin credentials in Keycloak, set the following in Big Bang's `values.yaml`:
## Integration with Big Bang
```yaml
addons:
keycloak:
values:
secrets:
env:
stringData:
KEYCLOAK_ADMIN: "your_admin_username"
KEYCLOAK_ADMIN_PASSWORD: "your_admin_password"
```
### Keycloak TLS
To properly configure Keycloak TLS, you must provide Keycloak a certificate in `addons.keycloak.ingress` that does not overlap with any TLS terminated app certificate. See [the details](#certificate-overlap-problem) for further information on why this is a problem.
In the Big Bang implementation, [core apps use the `admin` subdomain](#keycloak-with-other-apps). You need two wildcard SAN certificates, one for `*.admin.yourdomain` and one for `*.yourdomain` for this implementation. The `*.admin.yourdomain` cert goes into `istio.ingress` and the `*.yourdomain` cert goes into `addons.keycloak.ingress`.
In the following example for Big Bang, we provide a certificate for `*.admin.bigbang.dev` to TLS terminated apps and a `*.bigbang.dev` certificate to Keycloak.
```yaml
hostname: bigbang.dev
istio:
ingress:
key: |-
<Private Key for *.admin.bigbang.dev>
cert: |-
<Certificate for *.admin.bigbang.dev>
addons:
keycloak:
enabled: true
ingress:
key: |-
<Private key for *.bigbang.dev>
cert: |-
<Certificate for *.bigbang.dev>
```
#### Certificate Overlap Problem
> This problem automatically worked around by Big Bang if you have non-overlapping certificates as [recommended above](#keycloak-tls). You can skip this section unless you want the gritty details.
Modern browsers will reuse established TLS connections when the destination's IP and port are the same and the current certificate is valid. See the [HTTP/2 spec](https://httpwg.org/specs/rfc7540.html#rfc.section.9.1.1) for details. If our cluster has a single load balancer and listens on port 443 for multiple apps, then the IP address and port for all apps in the cluster will be the same from the browser's point of view. Normally, this isn't a problem because Big Bang uses TLS termination for all applications. The encryption occurs between Istio and the browser no matter which hostname you use, so the connection can be reused without problems.
Big Bang's integration with Keycloak requires special considerations and configuration compared to other applications. This document will help you set it up.
With Keycloak, we need to passthrough TLS rather than terminate it at Istio. If we have other apps, like Kiali, that are TLS terminated, Istio needs two server entries in its Gateway to passthrough TLS for hosts matching `keycloak.bigbang.dev` and to terminate TLS for other hosts. If the certificate used for TLS is valid for both Keycloak and other apps (e.g. the cert includes a SAN of `*.bigbang.dev`), then the browser thinks it can reuse connections between the applications (the IP, port, and cert are the same). If you access a TLS terminated app first (e.g. `kiali.bigbang.dev`), then try to access `keycloak.bigbang.dev`, the browser tries to reuse the connection to the terminated app, resulting in a [data leak](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-11767) to the terminated app and a 404 error in the browser. Istio is [supposed to handle this](https://github.com/istio/istio/issues/13589) situation, but does not.
## Configuration
To work around this situation, you have to isolate the applications by IP, port, or certificate so the browser will not reuse the connection between them. You can use external load balancers or different ingress ports to create unique IPs or ports for the applications. Or you can create non-overlapping certs for the applications. This does not prevent you from using wildcard certs, since you could have one cert for `*.bigbang.mil` and another for `*.admin.bigbang.mil` that don't overlap. Alternatively, you can create one cert for `kiali.bigbang.mil` and other TLS terminated apps and another cert for `keycloak.bigbang.mil`.
See [Keycloak Configuration](https://repo1.dso.mil/big-bang/product/packages/keycloak/-/blob/main/docs/configuration.md) in the Big Bang Keycloak Helm chart repo for help configuring the following:
> All the core and addon apps are TLS terminated except Keycloak.
* TLS Certificates
* Custom Admin Password
* Registration Plugin
* Keycloak Helm values
## Big Bang Touch-points
### GUI
Keycloak has two main end point URLs:
[https://keycloak.bigbang.dev](https://keycloak.bigbang.dev) for authentication.
[https://keycloak.bigbang.dev/auth/admin](https://keycloak.bigbang.dev/auth/admin) for administration.
<https://keycloak.yourdomain.com> for authentication.
<https://keycloak.yourdomain.com/auth/admin> for administration.
The `bigbang.dev` domain name can be customized by setting the `hostname` in `values.yaml`
The `yourdomain.com` domain name can be customized by setting the value `domain` in Big Bang's `values.yaml`
### Database
An external shared database is required for Keycloak operation in production. It should be setup according to [the Keycloak database configuration documentation](https://www.keycloak.org/docs/latest/server_installation/#_database).
An external shared database is required for Keycloak operation in production. It should be setup according to [the Keycloak database configuration documentation](https://www.keycloak.org/server/db).
> For development ad test, a Postgres database is provided inside the cluster. This should **NOT** be used in production.
> For development and testing, a Postgres database is provided inside the cluster. This should **NOT** be used in production.
The following values can be customized in `values.yaml` to connect to your external database:
The following values can be customized in Big Bang's `values.yaml` to connect to your external database:
```yaml
addons:
keycloak:
database:
host: mydb.mydomain.com
type: postgres
port: 5432
database: keycloak
username: kcuser
password: p@ssw0rd
values:
database:
hostname: yourdb.yourdomain.com
vendor: postgres
port: 5432
database: keycloak
username: kcuser
password: p@ssw0rd
```
### Logging
......@@ -236,20 +115,20 @@ Keycloak is available under the [Apache License 2.0](https://github.com/keycloak
## High Availability
By default, Big Bang deploys Keycloak with two replicas in a high availability cluster configuration. It is already configured to support cache sharing, anti-affinity, fail-overs, and rolling updates. If you wish to increase or decrease the number of replicas you must first make sure you are pointed to an external database, and then the replicas can be increased, all of which can be set in `values.yaml`:
By default, Big Bang deploys Keycloak via a stateful set with one replica. It is already configured to support cache sharing, anti-affinity, fail-overs, and rolling updates. If you wish to increase the number of replicas you must first make sure you are pointed to an external database, and then the replicas can be increased, all of which can be set in `values.yaml`:
```yaml
addons:
keycloak:
database:
host: ""
type: ""
port: ""
database: ""
username: ""
password: "in-encrypted-values"
values:
replicas: 3
replicas: 3 # Override the default
database:
host: ""
type: ""
port: ""
database: ""
username: ""
password: "in-encrypted-values"
```
The Keycloak package also comes with a HorizontalPodAutoscaler resource which can be enabled. Enabling the HPA will overwrite the `replicas` key shown above:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment