Keycloak is a modern and efficient way to deal with identity and access management. It allows for single sign-on, user federation across multiple user directories. It is also compliant with standard authentication protocols like OpenID Connect, OAuth2 or SAML. All details are available on its website. This blogpost will go through steps to deploy Keycloack and Grafana on Clever Cloud.
How to deploy Keycloak
Setup
Keycloak is written in Java, and gives a JAR file in their release, which means we will use a a JAVA runtime with a JAR deployment. It also requires a PostgreSQL Database, which means we will deploy a PostgreSQL addon.
# Get lastest Keycloak release
wget https://github.com/keycloak/keycloak/releases/download/17.0.1/keycloak-17.0.1.zip
# Extract the archive
unzip keycloak-17.0.1.zip
# Go to the folder
cd keycloak-17.0.1
# Create the jar application
clever create --type jar keycloak-server
export KEYCLOAK_DOMAIN=$(clever domain | xargs)
# Create the PG addon
clever addon create postgresql-addon --plan s_sml --addon-version 10 keycloak-postgres
# Link the addon
clever service link-addon keycloak-postgres
Configure
For now we will configure Keycloak through environment variables. Note that you can also do configure Keycloak through its CLI or through a file, as stated in its documentation.
Note: For the configuration through environment variables; the pattern to use is
KC_
and the uppercase name of any configuration key, separated by underscores.
# Export env for templating purpose
export $(clever env | sed '/^#/d;s/\"//g')
clever env set CC_JAR_PATH lib/quarkus-run.jar
clever env set CC_JAVA_VERSION 11
clever env set CC_RUN_COMMAND "bin/kc.sh start --auto-build"
clever env set KC_DB postgres
clever env set KC_DB_USERNAME $POSTGRESQL_ADDON_USER
clever env set KC_DB_PASSWORD $POSTGRESQL_ADDON_PASSWORD
clever env set KC_DB_URL "jdbc:postgresql://$POSTGRESQL_ADDON_HOST:$POSTGRESQL_ADDON_PORT/$POSTGRESQL_ADDON_DB"
clever env set KC_HOSTNAME $KEYCLOAK_DOMAIN
clever env set KC_HTTP_ENABLED true
clever env set KC_PROXY passthrough
clever env set KC_PROXY_ADDRESS_FORWARDING true
Note: Consider setting KC_DB_POOL_MAX_SIZE at a lower value (default is 100) regarding the database size you ordered earlier. You can find the connection limit here. If you used the S_SML size that is in the command earlier, you can ignore this message. You can also fine tune the database connection pool using KC_DB_POOL_INITIAL_SIZE and KC_DB_POOL_MIN_SIZE
Now, you need to define KEYCLOAK_ADMIN and KEYCLOAK_ADMIN_PASSWORD :
clever env set KEYCLOAK_ADMIN <choose an admin username>
clever env set KEYCLOAK_ADMIN_PASSWORD <choose an admin password>
Deploy
Deploy Keycloak on Clever Cloud:
# Init a git repository
git init
# Add your files
git add .
# Create the first commit
git commit -m "clever init"
# Deploy the application
clever deploy
# Open Keycloak in your browser
clever open
Validate the configuration
You can follow the Keycloak documentation starting here to ensure Keycloak works as expected. It will take you through a realm (tenant) creation, user creation and client creation/test.
Create an Initial Keycloak configuration
In the keycloak UI, ensure you create a Realm called “myrealm” (hover “Master” on the top left corner). Ensure the realm “myrealm
” is selected.
Then, go to Users > Add a User. Fill the Username, Email, First Name and Last Name fields, then hit save.
In the credentials tab of the user, add the password of your choice and deselect “Temporary”, the set password.
You’re all set.
A real world scenario
Let’s see how we can use Keycloak in the real world: as an SSO Proxy for Grafana, using Oauth 2.
Setup Grafana on Clever Cloud
If you need a in-depth guide on how to use or deploy Grafana please read this article, the following is a helper to illustrate the usages of Keycloak.
Let’s use the grafana-example on Clever Cloud’s Github repository.
# Clone the repository
git clone https://github.com/CleverCloud/grafana-example.git
# Enter the directory
cd grafana-example
# Create a NodeJS Application
clever create --type node grafana
export GRAFANA_DOMAIN=$(clever domain | xargs)
# Configure Grafana
clever env set GRAFANA_VERSION 8.5.2
clever env set GRAFANA_PLUGINS "grafana-worldmap-panel"
clever env set GF_PLUGIN_DIR ./data/plugins
clever env set GF_SERVER_HTTP_PORT 8080
clever env set GF_SERVER_ROOT_URL "https://$GRAFANA_DOMAIN"
Note: In this section you need to set the GRAFANA_SHA_256 variable yourself. You can find the SHA256SUM required here, next to “Standalone Linux Binaries”
clever env set GRAFANA_SHA_256 <SHA256SUM>
Configure Keycloak for OAuth 2
Note: In this section, you need to replace
with the value you exported in the last section. You can find this value by running the following command:
$GRAFANA_DOMAIN
clever domain
In the Keyloak UI, Go to Configure > Clients > Create
Create a new client with these configurations:
Client ID: $GRAFANA_DOMAIN
Client Protocol: openid-connect
Root URL: https://$GRAFANA_DOMAIN
Further make these configurations:
Access Type: confidentials // The OAuth client must use a client id and secret.
Root URL: ${authBaseUrl}
Valid Redirect URIs: https://$GRAFANA_DOMAIN/login/generic_oauth
Base URL: /login/generic_oauth
Clear Admin URL and Web Origins.
Click save and open the Credentials tab. Copy the Secret into a separate note, we will need it in the second and third part of this tutorial.
Open the tab Roles and click Add Role. Create a new role with name admin
. This role defines the access level for Grafana.
Head over to Scope tab and set Full Scope Allowed to OFF
. We do not want to share any other details about the realm in the client token.
Then, we are going to configure a client mapper for the roles property. We must ensure that Grafana can extract the access role from the JWT token. Open the Mappers tab and click on Create. Create an entry with these options:
Name: Roles
Mapper Type: User Client Role
Client ID: $GRAFANA_DOMAIN
Token Claim Name: roles
Claim JSON type: string
Finally, assign the client role to your Keycloak user: Go to Users > View All Users and click on the ID of your user. Click on the Role Mapping tab, then in the Client Roles selector, select $GRAFANA_DOMAIN. In the Available Roles section, select admin
and click Add selected.
Configure Grafana for OAuth 2
# Configure appropriate env vars
clever env set GF_SERVER_DOMAIN $GRAFANA_DOMAIN
clever env set GF_SERVER_ROOT_URL "https://$GRAFANA_DOMAIN"
clever env set GF_AUTH_GENERIC_OAUTH_ENABLED true
clever env set GF_AUTH_GENERIC_OAUTH_NAME Keycloak
clever env set GF_AUTH_GENERIC_OAUTH_ALLOW_SIGN_UP true
clever env set GF_AUTH_GENERIC_OAUTH_CLIENT_ID $GRAFANA_DOMAIN
clever env set GF_AUTH_GENERIC_OAUTH_SCOPES profile
clever env set GF_AUTH_GENERIC_OAUTH_AUTH_URL "https://$KEYCLOAK_DOMAIN/realms/myrealm/protocol/openid-connect/auth"
clever env set GF_AUTH_GENERIC_OAUTH_TOKEN_URL "https://$KEYCLOAK_DOMAIN/realms/myrealm/protocol/openid-connect/token"
clever env set GF_AUTH_GENERIC_OAUTH_API_URL "https://$KEYCLOAK_DOMAIN/realms/myrealm/protocol/openid-connect/userinfo"
clever env set GF_AUTH_GENERIC_OAUTH_ROLE_ATTRIBUTE_PATH "contains(roles[*], 'admin') && 'Admin' || contains(roles[*], 'editor') && 'Editor' || 'Viewer'"
Note: In this section, you need to define GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET yourself, using the value in Keycloak UI, under Client > $GRAFANA_URL > Credentials
clever env set GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET <KEYCLOAK_CLIENT_SECRET>
You can now deploy Grafana:
# Deploy grafana
clever deploy
# Open grafana and try the Login with Keycloak button !
clever open
Now hit login with Keycloak, and use the username and password you defined for the user you created Earlier in Keycloak.
Using the same procedure describe earlier to create the first user, you can now create more users and roles. Create the roles “editor” and/or “viewer” and assign them to your new users within Keycloak. Try to connect with those on Grafana and you will see the roles are propagated to Grafana.
Sources: