Skip to content

6 Setup a service OIDC

Onyxia requires a OIDC serivce for the user authentication. In this tutorial, we will install a keycloak as onyxia OIDC service

6.1 Introduction

We don't recommend to use the embedded postgresql deployment of this helm chart. It's hard to configure it. So we install a postgresql server by using the bitnami chart. You can find the complete doc here. After installing PostgreSQL, we can start to install [Keycloak]. Here we use the helm chart of codecentric. The detailed configuration can be found in keycloak.yaml. This configuration file will deploy an instance of keycloak with the following features:

  • Version 19.0.1-legacy;
  • Ingress on https://auth.casd.local;
  • Connection to PostgreSQL database;
  • adding local CA certificate;
  • Custom realm import with custom clients for Onyxia, MinIO, and Vault.

6.2 Setting Secrets

We need to create five secrets this time:

  • keycloak-ca: the CA root certificate of the cluster;
  • wildcard: TLS certificate for the Keycloak endpoint, should be the same as the nginx-ingress one;
  • postgresql-creds: PostgreSQL credentials to access the database;
  • keycloak-creds: Keycloak credentials to log in to the console;

These secrets are registered under the keycloak namespace.

# create secret for root ca
kubectl create secret generic casd-ca \
    --namespace keycloak \
    --from-file=ca.crt=ca.pem

# create secret for wildcard
kubectl create secret tls casd-wildcard-tls-secret \
    --namespace keycloak \
    --key wildcard.key \
    --cert wildcard.crt

# create secret for postgres connection
# This can be omitted if you already have a secret when you create the postgresql server
kubectl create secret generic postgresql-creds \
    --namespace keycloak \
    --from-literal=user=keycloak \
    --from-literal=password=keycloak-postgres

# create secret for keycloak admin account
kubectl create secret generic keycloak-admin-creds \
  --namespace keycloak \
  --from-literal=user=admin \
  --from-literal=password=YVqs7p4bJaim3rQ2FSI8

The root CA certificate and wildcard may not be in the same namespace of the keycloak. So you may need to sync/copy them from other namespace. You can use this doc as a guide.

6.3 Keycloak Installation

We use the codecentric Helm chart to deploy a keycloak instance, with the provided configuration in keycloak.yaml. Below are the commands:

# create a namespace for keycloak
kubectl create namespace keycloak

# add repo
helm repo add codecentric https://codecentric.github.io/helm-charts

# install chart
helm install keycloak codecentric/keycloak -n keycloak --values keycloak.yaml

# update chart
helm upgrade keycloak codecentric/keycloak -n keycloak --values keycloak.yaml

This installation makes the Keycloak console accessible through https://auth.casd.local.

6.4 Configuration explanation

You can find the official doc here.

The default values.yaml is a good start as a base config. In our case, we rename it as keycloak.yaml file.

6.4.1 Resources and images

Keycloak's image is version fixed to 19.0.1-legacy. The default value is the version of the chart. Its resources are also limited to not overflow the resources of the cluster.

image:
  tag: "19.0.1-legacy"

resources:
  requests:
    cpu: "500m"
    memory: "1024Mi"
  limits:
    cpu: "800m"
    memory: "2048Mi"

6.4.2 Mount secrets

By using extraVolumes and extraVolumeMounts, we can mount the secrets to the Keycloak deployment. Once they're mounted, we add them as environment variables to access the console and the PostgreSQL database.

# Mounting the volumes
extraVolumeMounts: |
  - name: certs
    mountPath: /etc/x509/https
    readOnly: true
  - name: db-creds
    mountPath: /secrets/db-creds
    readOnly: true
  - name: kc-creds
    mountPath: /secrets/kc-creds
    readOnly: true

# Extra volumes for the secrets
extraVolumes: |
  - name: certs
    secret:
      secretName: casd-ca
  - name: db-creds
    secret:
      secretName: postgresql-creds
  - name: kc-creds
    secret:
      secretName: keycloak-admin-creds

6.4.3 Setup env var

To set up high availability with Keycloak, we decided to enable autoscaling which scales the number of pods relatively to the traffic. KUBE_PING is used to discover the other Keycloak pods, no matter their number.

extraEnv: |
# setup env var for network
  - name : KEYCLOAK_HTTP_PORT 
    value : "80"
  - name: KEYCLOAK_HTTPS_PORT
    value: "443"
  - name : KEYCLOAK_HOSTNAME
    value : auth.casd.local
  - name: PROXY_ADDRESS_FORWARDING
    value: "true"
  - name: JGROUPS_DISCOVERY_PROTOCOL
    value: kubernetes.KUBE_PING
  - name: KUBERNETES_NAMESPACE
    valueFrom:
      fieldRef:
        apiVersion: v1
        fieldPath: metadata.namespace
  - name: CACHE_OWNERS_COUNT
    value: "2"
  - name: CACHE_OWNERS_AUTH_SESSIONS_COUNT
    value: "2"
# Set the env var for secrets
  - name: KEYCLOAK_USER_FILE
    value: /secrets/kc-creds/user
  - name: KEYCLOAK_PASSWORD_FILE
    value: /secrets/kc-creds/password
  - name: X509_CA_BUNDLE
    value: /etc/x509/https/ca.crt
  - name: DB_VENDOR
    value: postgres
  - name: DB_ADDR
    value: keycloak-postgres-postgresql
  - name: DB_PORT
    value: "5432"
  - name: DB_DATABASE
    value: keycloak
  - name: DB_USER_FILE
    value: /secrets/db-creds/user
  - name: DB_PASSWORD_FILE
    value: /secrets/db-creds/password

6.4.3 Ingress

To expose the Keycloak console, we need to create an Ingress resource. This is done in the keycloak.yaml file under the ingress section, managed by Helm.

ingress:
  enabled: true
  ingressClassName: "nginx"
  annotations:
    ## Resolve HTTP 502 error using ingress-nginx:
    ## See https://www.ibm.com/support/pages/502-error-ingress-keycloak-response
    nginx.ingress.kubernetes.io/proxy-buffer-size: 128k
  rules:
    - host: "auth.casd.local"
      paths:
        - path: /
          pathType: Prefix
  tls:
    - hosts:
        - "auth.casd.local"

Don't foget to change the root password

6.5 Configure keycloak for onxyia

Now you need to configure keycloak to secure onyxia

Step 1. Login to the admin console

Go to the Keycloak Admin Console and login with the username and password you created earlier in the values.yaml.

The url is the host name in the values.yaml. In our case, it should be https://keycloak.datalab.casd.local/

Step 2. Create a realm

A realm in Keycloak is the equivalent of a tenant. It allows creating isolated groups of applications and users. By default, there is a single realm in Keycloak called master. This is dedicated to manage Keycloak and should not be used for your own applications.

Let’s create our first realm. Open the Keycloak Admin Console

  1. Hover the mouse over the dropdown in the top-left corner where it says Master, then click on Add realm

  2. Fill in the form with the following values:

    Name: casd-onyxia
    
  3. Click Create

Step 3. Create a user

Initially there are no users in a new realm, so let’s create one: Open the Keycloak Admin Console

  1. Click Users (left-hand menu). Then Click Add user (top-right corner of table)

  2. Fill in the form with the following values:

    • Username: john

    • First Name: john

    • Last Name: doe

  3. Click Save

Onyxia does only allow username with alphanumeric [a-z][0-9] characters. Special characters and space are not allowed

Step 4. Setup initial password for user

  1. Click Credentials (top of the page)

  2. Fill in the Set Password form with a password

  3. Click ON next to Temporary to prevent having to update password on first login

  4. Click on button set password to confirm.

Step 5. Login to account console

Let’s now try to log in to the account console to verify the user is configured correctly.

  1. Open the Keycloak Account Console(https://keycloak.datalab.casd.local/realms/casd-onyxia/account/#/)

  2. Login with john and the password you created earlier

You should now be logged-in to the account console where users can manage their accounts.

Step 6. Create a client for onyxia

To secure onyxia with keycloak, we need to create a specific client in our realm, as shown in below Figure. kc-create-client

A client in Keycloak represents a resource that particular users can access, whether for authenticating a user, requesting identity information, or validating an access token.

Follow below step to register a new client :

  1. Open the Keycloak Admin Console (http://keycloak.datalab.casd.local/admin/master/console/)

  2. Click 'Clients'

  3. Fill in the form with the following values:

    • Client ID: onyxia-client

    • Client Protocol: openid-connect

    • Root URL: https://datalab.casd.local

    • Valid redirect URIs : https://datalab.casd.local/, http://datalab.casd.local/

    • Web-origins : https://datalab.casd.local, http://datalab.casd.local

  4. Click Save

Clients Access Type

The access type of onyxia-client must be public.

For other client, you can set the access type to confidential. You can see a more detailed form as shown in below figure.

kc-create-client-detail

  • Change Access Type: set its value to confidential.

  • Advance settings: Set access token lifeSpan

kc-client-advance-setting

  • Authentication flow overrides: set Direct Grant Flow value to direct grant.

kc-client-auth-flow

  • update the client's credentials: Use Client Id and Secret for Client Authenticator field.

kc-client-creds

Step 7. Test the created client

Note there is modification for the endpoint that generate the JWT token.

# For keycloak >= 17.0. The new endpoint is:
https://$HOSTNAME/realms/$REALM_NAME/protocol/openid-connect/token

# For keycloak < 17.0. The legacy endpoint is
https://$HOSTNAME/auth/realms/$REALM_NAME/protocol/openid-connect/token

Now we can test our newly created client through the REST API to simulate a simple login. Base on your keycloak version, the authentication URL could be in below form:

# Before 17.0
http://localhost:8080/auth/realms/pengfei-test/protocol/openid-connect/token

# Since 17.0
http://localhost:8080/realms/pengfei-test/protocol/openid-connect/token

Fill out the parameters and set our client_id and client_secret with our username and password:

In our case, client_id=pengfei-dv-app client_secret=enifviJDIpbN5230yfcPo7h2zsifTa2z username=pengfei password=toto

curl -L -X POST 'http://localhost:8080/auth/realms/pengfei-test/protocol/openid-connect/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=pengfei-dv-app' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'client_secret=enifviJDIpbN5230yfcPo7h2zsifTa2z' \
--data-urlencode 'scope=openid' \
--data-urlencode 'username=pengfei' \
--data-urlencode 'password=toto'

Or you can check some example scripts in ../command.

6.6 Disable keycloak https check

In the master realm, over login tab. Change Require SSL property to none.

If you can not access locally to keycloak and it is configured with a database for instance Postgres, then execute the following SQL sentence.

update REALM set ssl_required = 'NONE' where id = 'master';

It is necessary to restart keycloak

6.7 Some key information

After all the above configuration, you need to note below information:

realm id: casd-onyxia client id: onyxia-client keycloak url: https://keycloak.datalab.casd.local/auth