DD-0043 — The retained Themelio as the themelio-compat service
Related ADR: ADR-0043.
Status: Draft for review. Qualified on the authorised dev-ikons dev box;
other dev boxes remain pending. Staging and production do not run it.
Date: 2026-10-14.
Scope and responsibilities
This is infrastructure configuration, stage 4 of decision 0040, for the legacy source relocated under decision 0042. There is no new business context, aggregate, command API, event or subscription.
Application and manifests
Every dev box installs the themelio-compat Application
(gitops/apps/base/themelio-compat.yaml) on wave 4, after GitLab and Waldur.
apps/overlays/devbox sets its path, and apps/base patches Waldur's Application
with the Identity Bridge setting. When the new Themelio replaces it, it becomes an
optional component again (ADR-0045). An
earlier saved themelio-compat profile is still accepted and has no effect.
The Application installs gitops/manifests/themelio-compat/overlays/devbox:
base/holds plain manifests, one file per workload or concern, aslegacy/gitops/manifests/themeliodoes. ItsconfigMapGeneratornames the configuration with a content hash, so a change rolls the pods that read it at start. Superseded ConfigMaps carryIgnoreExtraneous, so they stay (the root does not prune) without marking the service OutOfSync.overlays/devbox/merges the dev box's public origins into that configuration.
check_platform_gitops.py builds the service as Argo does with the root's images.
Every container image must be a digest, and the docker.io/pharos/themelio-compat-*
ones must be the digests of the in-cluster builds. Without them the build fails
the check. model.application_errors accepts only kustomize.images on this
Application.
Images
The web, gitlab-root-actor and k8s-root-actor targets are entries of the
image catalogue, built in the cluster from the delivered commit
(DD-0045). The Dockerfile copies all of
compat/themelio, so a change anywhere in it rebuilds all three. The root passes
their digests as the Application's kustomize.images.
The web pins Next.js 15.5.7. Its loopback rewrite matches 127.x.x.x anywhere in a
URL, so themelio-compat.pharos.127.0.0.1.sslip.io became
...pharos.localhost.sslip.io and the OIDC redirect URI no longer matched.
Next.js 16 anchors the rule to the host. No 15.5 release does.
compat/themelio/next-loopback.cjs applies the anchored rule to the 27 affected
files before the build and fails on any other version or count, so an upgrade is
reviewed.
Data and credentials
PostgreSQL 17 and Valkey 8.1 run in the namespace on Ceph block volumes, pinned by digest. A Sync hook creates the generated Secrets once: the PostgreSQL administrator, migrator and runtime passwords, the Valkey password, the web's session secret and the actors' internal token. The provision Job alone reads the administrator password and creates the two roles. The migration Job runs DDL as the migrator, and the Kubernetes root actor runs as the runtime role.
The provider tokens are the exception in ADR-0043.
While Argo installs the services, make deploy waits for GitLab and Waldur to be
Synced and Healthy. It then:
- creates root's
themelio-compat-root-actortoken (api,sudo), revoking earlier ones, for the GitLab root actor only; - creates the password-less staff user
themelio-compatand its single token, for the web only.
The values reach GitLab, Waldur and Kubernetes only on stdin. Each token expires after 30 days. A deploy rotates it when fewer than seven days remain and restarts only the workload that reads it.
Sign-in, Waldur and routes
Themelio signs in through the shared AAI's pharos-control-plane client, which
gains its callback. aai-client.yaml makes make deploy render the client and the
AAI CA into the themelio-oidc Secret. Every Themelio process trusts that CA,
which also signs the edge. The web requests only the scopes the AAI defines:
openid, voperson_id, email, profile, voperson_external_affiliation,
schac_home_organization and entitlements.
On sign-in, the web creates or updates the user in Waldur through the Identity
Bridge. Waldur's wrapper chart gains pharos.settings, Constance settings declared
in the synced pharos-settings ConfigMap. Its PostSync bootstrap applies them with
waldur override_constance_settings. Argo runs the hook only when a synced
resource changes, so the settings cannot live in the hook alone. The command skips
a setting it cannot save and still succeeds, so the hook fails on its report. The
apps set FEDERATED_IDENTITY_SYNC_ENABLED, and Waldur keeps it set if the service
is later removed.
The catalogue route themelio-compat.pharos reaches the web. Network policies
deny ingress except from the namespace and the gateway's paired policy, and apply
before the data servers start.
Qualification and remaining boundaries
On dev-ikons:
- Sign-in: alice and bob sign in through the AAI in Chromium, which trusts only
the AAI CA, and land on the dashboard (
dx/common/scripts/service-login.sh themelio-compat). - Waldur: the bootstrap reports
FEDERATED_IDENTITY_SYNC_ENABLED has been set to True, and the web syncs alice and bob into Waldur on sign-in. The check requires the setting on every dev box. - GitLab: alice and bob are GitLab users with the
openid_connectidentity.
Not exercised: a first sync of a user Waldur does not yet know, action execution (spaces, inference services, Slurm jobs), egress isolation, fresh-VM and reboot qualification, and other dev boxes.
Page source
Source snapshot · Revision f928834c8.