credentials-web — the human face of the vault
Mirrored from the fleet knowledge base: wi/components/credentials-web.md
Updated
Mirrored verbatim from
utopia-models/knowledgewi/components/credentials-web.mdby the allowlisted publish pipeline. Edit it there, not here.
component: credentials-web
serves: all
runs-on: novaserver
adrs: []
owns:
- credentials-web.service
- 0.0.0.0:3940credentials-web — the human face of the vault
WHAT IT IS
An admin UI over infisical, at credentials.utopiamodels.ai. It exists because Infisical's own UI
was judged too raw for the people who actually need it: Tyler and the owners see real secret values, add
and edit credentials, and read the per-agent access matrix without learning projects, environments and
paths.
🔴 It is a view, not a second store. Infisical remains the one store. A master reads through
infisical-get.sh and never through this UI — if a run ever "checks the credentials page", that run is
doing it wrong.
Its source is a separate private repo, utopia-models/credentials-ui, and it is the fleet's clearest
example of a surface that is neither Vercel nor in this repo: it deploys as a systemd user unit straight
onto novaserver.
HOW IT WORKS TODAY
flowchart TD
T["Tyler / an owner<br/>(phone or laptop)"] --> CF["Cloudflare edge<br/>credentials.utopiamodels.ai"]
CF --> TUN["cloudflared tunnel (novaserver)"]
TUN --> S["credentials-web.service (user nova)<br/>WorkingDirectory=~/dev/utopia-models/credentials-ui<br/>PORT=3940 · NODE_ENV=production · npm start"]
S --> E["EnvironmentFile=.env<br/>chmod 600, gitignored, nova-local — NEVER in git"]
S --> G{"Google OIDC sign-in"}
G -- "not signed in" --> X["HTTP 200 carrying a refusal page"]
G -- "signed in" --> I["Infisical API on :8085"]Its own secrets are nova-local, not vaulted. The unit reads an EnvironmentFile inside the checkout,
chmod 600 and gitignored. That is the deliberate shape: the thing that fronts the vault cannot depend on
the vault to boot.
Sign-in is Google OIDC, configured from a client id/secret pair held in the utopia Infisical project
(infisical-get.sh --keys utopia prod / | grep CREDENTIALS_UI names them; the values are never printed).
The tunnel is what makes it public, and that is intentional — Tyler reaches it from his phone, so its
protection is its own auth, not the tailnet. Contrast infisical itself, which is firewalled to the
tailnet and reachable by no browser off it.
🔴 Read the body, not the status code. Signed out, this app answers HTTP 200 with a refusal page — a 200 here means "the tunnel and the process are alive", never "a human is authenticated" and never "the backend is reachable".
BOUND VALUES
Everything this component runs on is off-repo: the source is another repository, the unit and its
EnvironmentFile live under nova's home. So the only claim bindable from here is the registry's
units: field — the field CI executes — and it is empty:
- 🔴
credentials-web— nounits:binding, so nothing proves its ExecStart target still exists (#4742)
DETERMINE CURRENT STATE
Four questions, and none of them is answered by the first status code alone (see HOW IT WORKS TODAY):
# public surface, through Cloudflare
curl -s -o /dev/null -m8 -w '%{http_code}\n' https://credentials.utopiamodels.ai/
# the app itself, on the box
curl -s -o /dev/null -m5 -w '%{http_code}\n' http://127.0.0.1:3940/
# the unit
ssh nova@localhost 'systemctl --user status credentials-web.service --no-pager'
# what is deployed
gh repo view utopia-models/credentials-ui --json pushedAt,defaultBranchRefKNOWN BROKEN
- 🔴
components.yaml'scredentials-webrow carries nounits:binding, socredentials-web.serviceis outsideverify-unit-execstart.py's daily sweep. Measured this session, same shape asinfisical's row. - 🔴 The older reference doc's liveness test is the wrong test. It reads "Public hostname returned 200 on 2026-08-01… resolving 200 proves the tunnel and the app" — and then correctly warns that a broken backend renders an empty matrix. Both halves are in tension: a 200 is returned by the signed-out refusal page too, so the status code alone distinguishes none of the three states (tunnel up / app up / Infisical reachable). Grade this surface by its body.
- ⚠ A dated "returned 200" line is a measurement, and it rots. This doc states no such date on purpose:
the
curlabove is the claim. - ⚠ An exit-143 (SIGTERM) failure alert is usually collateral, not a crash. The process is a
next-serverowned bynova, the same unix user the nova master's dispatched runs execute as (each master is its own unix user on novaserver), so a nova run that cleans up its own preview with a class-widepkill -f next-serverkills this too.Restart=alwaysbrings it back in ~6s and fleet-notify files the failure (#8180, 2026-09-29: a sibling run'spkill -f 'next-server' -u novaat 16:48:53.214Z, exit 143 the same second). Find the killer by grepping the box's session transcripts for the kill at that timestamp, not the app's logs. Since fleet-doctrine 0.73.0 (utopia-models/fleet-plugins#93)pretooluse-broad-kill-guard.shrefuses a pkill/killall aimed at a whole process class or user on every master. - 🔴 Anything this surface displays is a real secret value. Never screenshot it into an issue, never paste it into a commit, never pipe it to a log. That is the one hard stop, and this is the one component in the fleet that renders secrets to a screen by design.