The sandboxed-local cluster can authenticate users via the production Keycloak at keycloak.rijksapp.nl, which in turn uses SSO-Rijk. This provides real government SSO authentication in a local development environment.
SSO is optional. Without it, the sandbox works with a local admin user only (admin@sandbox.rijksapp.dev).
User login (sandbox)
→ Sandbox Keycloak (keycloak.sandbox.rijksapp.dev)
→ Production Keycloak (keycloak.rijksapp.nl / rig-platform realm)
→ SSO-Rijk (government identity provider)
The sandbox Keycloak is configured with an OIDC identity provider (sso-rijk) that points to the production Keycloak's rig-platform realm. When a user logs in, they are redirected through this chain to SSO-Rijk for authentication.
A shared OIDC client called development-clusters is registered in the production Keycloak's rig-platform realm. This client is used by both local Kind clusters and sandbox clusters to authenticate against the production Keycloak.
Allowed redirect URIs:
https://keycloak.kind/*(local Kind cluster)https://keycloak.sandbox.rijksapp.dev/*(sandbox cluster)http://localhost:*/*(local development)
The client secret is generated by the production Keycloak and must be obtained manually from the admin console.
SSO-Rijk attributes (email, name, organization) are passed through the entire chain:
- SSO-Rijk issues SAML/OIDC assertions with user attributes
- Production Keycloak maps these to the
custom_attributes_passthroughclient scope - The
development-clustersclient includes this scope by default - Sandbox Keycloak receives the attributes via OIDC and maps them to local user attributes
When running task sandbox:setup, you will be prompted:
=========================================
SSO Configuration (Optional)
=========================================
The sandbox can use the production Keycloak (keycloak.rijksapp.nl) for real
SSO-Rijk authentication. This requires the client secret for the
'development-clusters' client in the production rig-platform realm.
Without SSO, the sandbox still works using a local Keycloak admin user.
Applications deployed in the sandbox will use Keycloak but cannot use SSO.
Do you want to configure SSO? [y/N]:
If you choose y, you will be asked for the client secret. This is stored in .env.sandboxed-local.secrets (gitignored) and encrypted via SOPS into a Kubernetes Secret.
- Log into the production Keycloak admin console:
https://keycloak.rijksapp.nl - Select the
rig-platformrealm - Go to Clients > development-clusters
- Go to the Credentials tab
- Copy the Client secret
If you skipped SSO during initial setup, you can add it later:
-
Run the interactive SSO configuration:
task sandbox:configure-sso
-
Encrypt the secret and create the Kubernetes Secret:
task sandbox:generate-env-secrets
-
Apply the updated secret to the cluster:
task sandbox:sync
-
Restart the Operations Manager to pick up the new secret:
kubectl rollout restart deployment/operations-manager -n rig-system
You can also configure SSO manually by creating the secrets file directly:
cat > operations-manager/python/.env.sandboxed-local.secrets << 'EOF'
# Sandbox SSO secrets
KEYCLOAK_MASTER_OIDC_CLIENT_SECRET=<your-client-secret-here>
EOFThen run task sandbox:generate-env-secrets to encrypt it.
.env.sandboxed-local.secrets (gitignored plaintext file)
→ task sandbox:generate-env-secrets
→ SOPS-encrypted K8s Secret (operations-manager-env-secrets.yaml)
→ Synced to in-cluster Forgejo
→ ArgoCD deploys to cluster
→ OPI reads KEYCLOAK_MASTER_OIDC_CLIENT_SECRET env var
- The plaintext secret lives in
operations-manager/python/.env.sandboxed-local.secrets(gitignored) task sandbox:generate-env-secretsreads this file and creates a SOPS-encrypted Kubernetes Secret atbootstrap/rig-system/kustomize/operations-manager/overlays/sandboxed-local/operations-manager-env-secrets.yaml- The encryption uses the sandbox AGE key (
security/sandbox-key.txt) - This encrypted secret is synced to the in-cluster Forgejo and deployed by ArgoCD
- ArgoCD's CMP plugin decrypts the SOPS secret during deployment
- The Operations Manager reads the secret as an environment variable
| Variable | Value | Source |
|---|---|---|
KEYCLOAK_MASTER_OIDC_CLIENT_ID |
development-clusters |
Configmap |
KEYCLOAK_MASTER_OIDC_DISCOVERY_URL |
https://keycloak.rijksapp.nl/realms/rig-platform/.well-known/openid-configuration |
Configmap |
KEYCLOAK_MASTER_OIDC_CLIENT_SECRET |
(from production Keycloak) | SOPS-encrypted Secret |
| File | Purpose |
|---|---|
operations-manager/python/.env.sandboxed-local.secrets |
Plaintext secrets (gitignored) |
bootstrap/.../overlays/sandboxed-local/operations-manager-env-secrets.yaml |
SOPS-encrypted K8s Secret |
bootstrap/.../overlays/sandboxed-local/configmap.yaml |
Non-secret configuration |
bootstrap/.../overlays/sandboxed-local/patches/deployment.yaml |
Mounts the secret as env var |
operations-manager/python/opi/configs/keycloak/bootstrap-sandbox.yaml |
Keycloak bootstrap config for sandbox |
| Task | Description |
|---|---|
sandbox:configure-sso |
Interactive prompt to configure SSO client secret |
sandbox:generate-env-secrets |
Encrypt .env.sandboxed-local.secrets into SOPS-encrypted K8s Secret |
Verify the sandbox Keycloak hostname is in the development-clusters client's redirect URIs in the production Keycloak. It should include https://keycloak.sandbox.rijksapp.dev/*.
The client secret may have been regenerated in the production Keycloak. Re-run task sandbox:configure-sso and task sandbox:generate-env-secrets.
Check that the custom_attributes_passthrough client scope is assigned as a default scope on the development-clusters client in the production Keycloak.
If KEYCLOAK_MASTER_OIDC_CLIENT_SECRET is empty, the Operations Manager falls back to local admin authentication only. The SSO identity provider is not configured in the sandbox Keycloak without a valid upstream client secret.