What is UDS Identity Config?
UDS Identity Config supplies the configuration for Keycloak to UDS Core.
This is the multi-page printable view of this section. Click here to print.
UDS Identity Config supplies the configuration for Keycloak to UDS Core.
These docs are intended for demonstrating how to customize the uds-core Identity (Keycloak) deployment by updating/changing the config image.
# create a dev image uds-core-config:keycloak
uds run dev-build
# optionally, retag and publish to temporary registry for testing
docker tag uds-core-config:keycloak ttl.sh/uds-core-config:keycloak
docker push ttl.sh/uds-core-config:keycloak
The custom image reference will need to be update in a few places in the uds-core
repository:
configImage
in Keycloak values.yaml# build and deploy uds-core
uds run test-uds-core
See UDS Core for further details
Adding additional jars to Keycloak’s deployment is as simple as adding that jar to the src/extra-jars directory.
Adding new jars will require building a new identity-config image for uds-core.
See Testing custom image in UDS Core for building, publishing, and using the new image with uds-core
.
Once uds-core
has sucessfully deployed with your new image, viewing the Keycloak pod can provide insight into a successful deployment or not. Also describing the Keycloak pod, should display your new image being pulled instead of the default image defined here in the events section.
Changes can be made to the src/theme directory. At this time only Account and Login themes are included, but could be changed to include email, admin, and welcome themes as well.
To test the identity-config
theme changes, a local running Keycloak instance is required.
Don’t have a local Keycloak instance? The simplest testing path is utilizing uds-core, specifically the dev-identity
task. This will create a k3d cluster with Istio, Pepr, Keycloak, and Authservice.
Once that cluster is up and healthy and after making theme changes:
Execute this command:
uds run dev-theme
View the changes in the browser
The UDS Identity
realm is defined in the realm.json found in src/realm.json. This can be modified and will require a new uds-identity-config
image for uds-core
.
Be aware that changing values in the realm may also need be to updated throughout the configuration of Keycloak and Authservice in uds-core
. For example, changing the realm name will break a few different things within Keycloak unless those values are changed in uds-core
as well.
See the Testing custom image in UDS Core for building, publishing, and using the new image with uds-core
.
Keycloak supports using environment variables within the realm configuration, see docs.
These environment variables have default values set in the realm.json that uses the following syntax:
${REALM_GOOGLE_IDP_ENABLED:false}
In the uds-core keycloak values.yaml, the realmInitEnv
defines set of environment variables that can be used to configure the realm different from default values.
These environment variables will be created with a prefix REALM_
to avoid collisions with keycloak environment variables. If necessary to add additional template variables within the realm.json must be prefixed with REALM_
.
For example, this bundle override contains all the available overrides:
overrides:
keycloak:
keycloak:
values:
path: realmInitEnv
value:
GOOGLE_IDP_ENABLED: true
GOOGLE_IDP_ID: <fill in value here>
GOOGLE_IDP_SIGNING_CERT: <fill in value here>
GOOGLE_IDP_NAME_ID_FORMAT: <fill in value here>
GOOGLE_IDP_CORE_ENTITY_ID: <fill in value here>
GOOGLE_IDP_ADMIN_GROUP: <fill in value here>
GOOGLE_IDP_AUDITOR_GROUP: <fill in value here>
EMAIL_VERIFICATION_ENABLED: true
OTP_ENABLED: true
TERMS_AND_CONDITIONS_ENABLED: true
PASSWORD_POLICY: <fill in value here>
X509_OCSP_FAIL_OPEN: true
These environment variables can be found in the realm.json
identityProviders
section.
The default truststore is configured in a script and excuted in the Dockerfile. There is a few different ways the script could be customized.
authorized_certs.zip
Utilizing the regenerate-test-pki
task, you can create a test authorized_certs.zip
to use for the truststore.
To use the regenerate-test-pki
task:
Create csr.conf
[req]
default_bits = 2048
default_keyfile = key.pem
distinguished_name = req_distinguished_name
req_extensions = req_ext
x509_extensions = v3_ext
[req_distinguished_name]
countryName = Country Name (2 letter code)
countryName_default = US
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Colorado
localityName = Locality Name (eg, city)
localityName_default = Colorado Springs
organizationName = Organization Name (eg, company)
organizationName_default = Defense Unicorns
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_default = uds.dev
[req_ext]
subjectAltName = @alt_names
[v3_ext]
subjectAltName = @alt_names
[alt_names]
DNS.0 = *.uds.dev
# Generates new authorized_certs.zip
uds run regenerate-test-pki
Update CA_ZIP_URL
in Dockerfile to refer to the generated authorized_certs.zip
ARG CA_ZIP_URL=authorized_certs.zip
Build config image
# build image
uds run dev-build
If you’re getting errors from the ca-to-jks.sh script, verify your zip folder is in the correct directory.
# In `uds-core` create cacert from the new identity-config image
uds run -f src/keycloak/tasks.yaml cacert --set IMAGE_NAME=<identity config image> --set VERSION=<identity config image version>
# Update tenant and admin gateway with generated cacerts
uds run -f src/keycloak/tasks.yaml dev-cacert
See Testing custom image in UDS Core
# Verify the "Acceptable client certificate CA names"
openssl s_client -connect sso.uds.dev:443
This isn’t recommended, however can be achieved if necessary
Making these changes iteratively and importing into Keycloak to create a new realm can help to alleviate typo’s and mis-configurations. This is also the quickest solution for testing without having to create,build,deploy with new images each time.
The plugin provides the auth flows that keycloak uses for x509 (CAC) authentication as well as some of the surrounding registration flows.
One nuanced auth flow is the creation of a Mattermost ID attribute for users. CustomEventListener is responsible for generating the unique ID.
When creating a user via ADMIN API or ADMIN UI, the ‘REGISTER’ event is not triggered, resulting in no Mattermost ID attribute generation. This will need to be done manually via click ops or the api. An example of how the attribute can be set via api can be seen here.
See PLUGIN.md.
In addition, modify the realm for keycloak, otherwise the realm will require plugin capabilities for registering and authenticating users. In the current realm.json there is a few sections specifically using the plugin capabilities. Here is the following changes necessary:
Remove all of the UDS ...
authenticationFlows:
UDS Authentication
UDS Authentication Browser - Conditional OTP
UDS Registration
UDS Reset Credentials
UDS registration form
Make changes to authenticationExecutions from the browser
authenticationFlow:
auth-cookie
auth-spnego
identity-provider-redirector
"requirement": "REQUIRED"
"flowAlias": "Authentication"
Remove registration-profile-action
authenticationExecution from the registration form
authenticationFlow
Update the realm flows:
"browserFlow": "browser"
"registrationFlow": "registration"
"resetCredentialsFlow": "reset credentials"
If desired the Plugin can be removed from the identity-config image by commenting out these lines in the Dockerfile:
COPY plugin/pom.xml .
COPY plugin/src ../src
RUN mvn clean package
Once satisfied with changes and tested that they work, see Testing custom image in UDS Core for building, publishing, and using the new image with uds-core
.
For convenience, a Zarf package definition has been included to simplify custom image transport and install in air-gapped systems.
Use the included UDS task to build the custom image and package it with Zarf:
uds run build-zarf-pkg
The plugin provides the auth flows that keycloak uses for x509 (CAC) authentication as well as some of the surrounding registration flows.
One nuanced auth flow is the creation of a Mattermost ID attribute for users. CustomEventListener is responsible for generating the unique ID.
When creating a user via ADMIN API or ADMIN UI, the REGISTER
event is not triggered, resulting in no Mattermost ID attribute generation. This will need to be done manually via click ops or the api. An example of how the attribute can be set via api can be seen here.
Working on the plugin requires JDK17+ and Maven 3.5+.
# local java version
java -version
# loval maven version
mvn -version
After making changes to the plugin code and verifying that unit tests are passing ( and hopefully writing some more ), test against Keycloak.
See the New uds-identity-config Image
section in the CUSTOMIZE.md for building, publishing, and using the new image with uds-core
.
The maven surefire and jacoco plugins are configured in the pom.xml.
mvn
commands will need to be executed from inside of the src/plugin
directory
There is a uds-cli task for running the mvn clean verify
command: uds run dev-plugin
.
Some important commands that can be used when developing/testing on the plugin:
Command | Description |
---|---|
mvn clean install | Cleans up build artifacts and then builds and installs project into local maven repository. |
mvn clean test | Cleans up build artifacts and then compiles the source code and runs all tests in the project. |
mvn clean test -Dtest=com.defenseunicorns.uds.keycloak.plugin.X509ToolsTest | Same as mvn clean test but instead of running all tests in project, only runs the tests in designated file. |
mvn surefire-report:report | This command will run the mvn clean test and then generate the surefire-report.html file in target/site |
mvn clean verify | Clean project, run tests, and generate both surefire and jacoco reports |
# maven command from src/plugin directory
mvn clean verify
Open the src/plugin/target/site/surefire-report.html
file in your browser to view the surefire test report.
Open the src/plugin/target/site/jacoco/index.html
file in your browser to view the unit test coverage report generated by jacoco.
Both reports will hot reload each time they are regenerated, no need to open each time.
Cypress Web Flow/Integration Testing Docs
Test Name (link) | Test Description |
---|---|
Login Existing User | Login in existing user that is created in the testing realm.json |
Login Nonexistant User / Incorrect creds | User cannot login / authenticate with incorrect creds or without account |
Successfuly CAC Registration | New user can successfully register with CAC |
CAC User Login | New user can successfully login with CAC |
Duplicate User Registration | User cannot register more than once |
Password check for special characters | User registration requires password special characters |
Password check for length | User registration requires password length check |
Using uds-cli task uds-core-integration-tests
.
Task explanation:
uds-core
necessary for setting up k3d cluster to test againstuds-core
istio gatewaysuds-core
(istio, keycloak, pepr, zarf)Cypress testing requires that a ca.cer be created and put into an authorized_certs.zip, done by using the regenerate-test-pki
uds task, which is then utilized by the Dockerfile. Once a docker image has been created another command is used for pulling that cacert, uds task cacert
, from the image using it’s value to configure uds-core’s gateways, uds-core-gateway-cacert
uds task . Eventually cypress will require a pfx cert for its CAC testing.
Our cypress testing utilizes static certs that are created and saved to limit the need for constantly rebuilding and importing those certs.
Follow these steps to update the certs for cypress:
uds run regenerate-test-pki
to regenerate the necessary certs and authorized_certs.zipdocker build --build-arg CA_ZIP_URL="authorized_certs.zip" -t uds-core-config:keycloak --no-cache src
to create docker imageuds run cacert
to extract cacert from docker image for the tls_cacert.yaml filemv test.pfx tls_cacert.yaml src/authorized_certs.zip src/cypress/certs/