Aller au contenu

Keycloak - OIDC Secret propagation#

Provisioning clients#

For each OIDC client provisioned in keycloak the corresponding client_id and client_secret is store in vault in path secret/oidc/<application_name>.

The contents of the secret is a JSON object of the form:

{
    "id": "<client_id>",
    "secret": "<client_secret>"
}
The provisioning of OIDC client is done with terraform. For example here is the definition of the client for Grafana.

For each client the generated secret is store in Vault. For example here.

It also configure a way for the application to retrieve its client_id and client_secret. Most of the Caascad applications are running in Kubernetes so we use the Kubernetes auth backend of Vault.

A role is created in Vault for the application to allow it to read it's secret. The role is bound to the service account name and the namespace of the application. A specific policy is associated to the role. The policy describe which paths the role can access in Vault. In this case we only allow read access on the path secret/oidc/<application_name>.

The clients are provisioned on infra and cloud zones.

Application configuration#

To retrieve it's client_id and client_secret the application needs to authenticate against Vault and read the secret at path secret/oidc/<application_name>.

In Kubernetes this should be done using vault-injector.

By adding some annotations to the application pod the vault-injector controller will inject automagically an init container to the application pod. This init container will authenticate against vault using the serviceaccount token of the pod and retrieve the secret from Vault.

Beware that the annotations must be placed on the pod and not on the deployment.

Here is an example with the grafana pod:

Annotations:

  • vault.hashicorp.com/agent-inject: "true"
  • vault.hashicorp.com/role: "grafana"
  • vault.hashicorp.com/tls-skip-verify: "true"
  • vault.hashicorp.com/agent-pre-populate-only: "true"
  • vault.hashicorp.com/agent-inject-secret-keycloak-client-secret: "secret/oidc/grafana"

Explications:

  • vault.hashicorp.com/agent-inject: "true": enable vault-injector for this pod
  • vault.hashicorp.com/role: "grafana": name of the role used in the authentication process
  • vault.hashicorp.com/agent-pre-populate-only: "true": only injects an init container
  • vault.hashicorp.com/agent-inject-secret-keycloak-client-secret: "secret/oidc/grafana": specify the path of the secret to retrieve and the name of the file that will be created in the pod You can read more about theses annotations here.

After that the secret secret/oidc/grafana will be available in /vault/keycloak-client-secret file in the pod FS.

vault-injector stores secrets in files only, it won't expose them as environment variables.

This file contains by default the JSON representation of the secret but it is possible to pass a template in the annotations to format the file as needed by the application. You can read more about this here.