Vault is also used by Onyxia as the persistance layer for all saved configuration. If Vault is not configured, all user settings will be stored in the browser's local storage.
Onyxia-web use vault as a storage for two kinds of secrets:
1. secrets or information generate by Onyxia to store differents values (S3 sources configuration)
2. user secrets\
Onyxia use the KV version 2 secret engine.Vault must be configured with JWT or OIDC authentification methods.
As Vault needs to be initialized with a master key, it can't be directly configured with all parameters such as oidc or access policies and roles. So first step we create a vault with dev mode (do not use this in production and do your initialization with any of the recommanded configuration: Shamir, gcp, another vault).
From Keycloak, create a client called "vault" (realm "datalab" as usually in this documentation)
Root URL: https://vault.lab.my-domain.net/
Valid redirect URIs: https://vault.lab.my-domain.net/* and https://datalab.my-domain.net/*
Web origins: *
The expected value for the audience (aud) field of the JWT token by Vault is vault. You need to configure this in Keycloak.
Create a new Client scope: vault
Add Mapper by configuration
Choose Audience
Name: Audience for Vault
Included Client Audience: vault
Save
Choose Clients: vault
Add Client Scope: vault
We will now configure Vault to enable JWT support, set policies for users permissions and initialize the secret engine.
You will need the Vault CLI. You can either download it here and configure VAULT_ADDR=https://vault.lab.my-domain.net and VAULT_TOKEN=root or exec into the vault pod kubectl exec -it vault-0 -n vault -- /bin/sh which will have vault CLI installed and pre-configured.
First, we start by creating a JWT endpoint in Vault, and writing information about Keycloak to the configuration. We use the same realm as usually in this documentation.
Onyxia uses only one single role for every user in Vault. This is in this tutorial onyxia-user`. To provide an authorization mechanism a policy is used that will depend on claims inside the JWT token.
First you need to get the identifier (mount accessor) for the JWT authentification just created. You can use :
vault auth list -format=json | jq -r '.["jwt/"].accessor'
which should provide you something like auth_jwt_xyz. You will need it to write a proper policy by replacing the auth_jwt_xyz content with your own value.
Setting up a policy
Create locally a file named onyxia-policy.hcl.
You can notice that this policy is written for a KV version 2 secret engine mounted to the onyxia-kv path. The following policy is only working for personnal access because the entity name will be the preferred username in the JWT token.
You can include access to any secret engine in the policy, which will be accessible within the services, though the Onyxia interface wonât utilize these permissions. If you have a use case where it would be beneficial for the Onyxia interface to access other secret engines, please let us know on Slack.
Allowing personal Vault tokens to access group storage in Vault is a bit more complex. We will map the group from the token into the entityâs metadata. The following policy maps the first 10 groups statically.
If you have suggestions for a better authorization mechanism within Vault, please share them with us on Slack, as the current approach is not ideal.