Skip to content

feat(make): make all from vault42 credentials alone, and prove it - #193

Merged
LESdylan merged 9 commits into
mainfrom
feat/make-all-from-vault
Nov 5, 2026
Merged

LESdylan merged 9 commits into
mainfrom
feat/make-all-from-vault

Conversation

@LESdylan

@LESdylan LESdylan commented Nov 5, 2026 •

Copy link
Copy Markdown
Member

On a clean clone, make all needed the VM to exist already, and it could report success while the people lists and the public API docs were broken.

Why

The deployment had to work from vault42 credentials alone, with every service on localhost and nothing of production touched. Clean-clone runs and an independent audit also found failures no check saw:

Found Effect Why it stayed hidden
Nothing wrote tools/seeds/.agency-people.env People lists empty The bridge health stays green
NFS checkout under rootless Docker Bridge EACCES, /docs/ and /openapi.json 403 Root reads the file; the reach suite skipped the status of API entries
nginx.conf has no MIME types Browsers refuse docs.css and docs.js: unstyled page, also outside NFS The edge test checked the status only
Auto-start runs from the clone that built the VM Deleting that clone stops the VM coming back Cron errors go unread

What changed

  • datacenter-gate runs first: it reads the vault and stops up front saying what must be set. It installs 42ctl if absent and restores the keystore.
  • An absent VM is built through born2root from a terminal, and only for the default alias. Other aliases are never reinstalled.
  • grobase is checked against the pin and the local plan, and repaired through make grobase. A failed repair prints the failing checks.
  • datacenter-binds writes the roster from the accounts in the VM, read-only there, and copies what an NFS checkout cannot serve.
  • datacenter-verify runs before the URLs: plan health, pages over verified TLS, bind mounts, the roster from inside the bridge, then browsers. A run that passes by skipping fails, and a run with no terminal prints SKIP instead of claiming the browsers.
  • /docs/ sends real types, in that location only.
  • Pins: grobase 21c132b6, born2root 34001b51.

Structure

flowchart LR
  G[gate: vault readable?] --> S[pull secrets] --> V[VM: build or repair] --> L[link, models]
  L --> B[binds: roster, NFS copy] --> F[frontends, Mail, Calendar] --> C[verify] --> U[URLs]
Loading

scripts/lib/ gains datacenter-gate.sh, -build.sh, -verify.sh and -binds.sh. tools/seeds/agency-roster.sh holds the roster the seed and the data center path now share.

Trade-offs

  • Credentials stay on demand rather than global, so nothing secret sits in every shell.
  • GROOT_READ_BINDS adds a copy on local disk. The alternative of refusing NFS checkouts would rule out /sgoinfre, where this project lives. Only the data center path sets it: the local pipeline on NFS keeps the bug.
  • Mail and Calendar open without Google sign-in, which needs a public domain.

Production

With GROOT_READ_BINDS unset, docker compose --profile "*" config is byte-identical before and after (1936 lines). PACKAGE_max and the shared dc-tunnel default are unchanged. The /docs/ location does change for every deployment, which is the fix.

Evidence

  • Clean clone at 86933ce2, plain make all, existing VM: make-all-exit=0, verified: the plan, the pages, the mounts and the browsers.
  • Reach 42 passed, end-to-end 23 passed, 0 skipped.
  • Wiped VM (0 containers, volumes and images, /opt/grobase empty), clean clone: make all found grobase missing, reinstalled it at the pin and stopped at the seed. With 58a49635 it seeded 44 tenants and 40 accounts, applied 40 migrations with 0 failed, and exited 0: reach 42 passed, end-to-end 23 passed, 0 skipped. The two parts ran as two invocations, not one.
  • scripts/tests/datacenter.bats 99/99, tests/api-docs-edge 6/6.
  • make all syncs submodules, so apps/opposite-osiris and apps/hydrawn ran a few commits past their gitlinks. vendor/born2root stays at its gitlink.

Visible change

/docs/ goes from an unstyled page to the styled one. No screenshots attached.

Merging

Depends on Univers42/grobase feat/max-every-plane and Univers42/born2root fix/localhost-max-profile. Merge those first with merge commits, then re-pin here if their commits change.

🤖 Generated with Claude Code

LESdylan and others added 8 commits November 5, 2026 15:00
A fresh clone holding only vault42 credentials now ends with the stack up.
datacenter-gate runs first and proves the vault can be read, naming what to
set when it cannot; half-set credentials stop instead of going local.
datacenter-vm builds a VM that provably does not exist, repairs this machine's
own grobase onto its pin and plan, and never touches another alias.
datacenter-verify fails on anything short of the whole plan healthy, a page
that is not 200, a broken bind mount, or a browser run that fails or skips.

`make all GROBASE_DATACENTER=local` took the data center path; it is now the
opt-out it reads as. Reverses ADR 0047's "groot never builds the VM" (devil,
PROCEED-WITH-CONDITIONS); grobase's max and the server profile stay as
production has them, so the local plan and -dc-tunnel live here.

Credentials stay per step rather than global, because docker builds run under
make's environment.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The prod tree is 29.5 MB, over the transport ceiling, and the object store is
named only in config.json, which a new machine does not have: the gate passed
and the pull stopped. Found by the first run from a true zero state.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A download failure was reported as an ssh problem with a serial log that did
not exist. Pins born2root 7cc91436, whose downloads retry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tall

grobase.conf holds an unquoted value with spaces, so sourcing it ran `engines`
as a command and lost the addons, and the check judged services that had just
restarted. Pins grobase 21c132b6, where Prometheus can scrape Vault.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Nothing on this path wrote tools/seeds/.agency-people.env, so Docker bound an
empty directory, the bridge answered every people list with nothing, and its
health stayed green. The roster now comes from the accounts in the VM, read-only
there, and verification reads it from inside the bridge.

A repair that fails now prints the checks that failed, and a run that skips the
browsers no longer says it verified them. Both come from the independent audit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The block runs from the clone that built the VM. Deleting that clone left cron
failing on its cd every minute, so the VM would never come back after a login.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On an NFS checkout under rootless Docker, container users other than root map
to subuids the server refuses. The bridge got EACCES on its roster and nginx
answered 403 on /docs/ and /openapi.json, while the health checks stayed green
and the reach suite passed, since it skipped the status of API entries.

Those sources now get a copy on the disk Docker runs from, chosen by
GROOT_READ_BINDS. Unset, the compose config is byte-identical, so production
does not change. API docs are now asserted as a page, here and in verify.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
nginx.conf loads no mime.types, so docs.css and docs.js went out as text/plain
and nosniff made every browser refuse them: the public page rendered unstyled
with no script. The edge test only checked the status. The types are set in this
location alone, so proxied routes do not change. The empty favicon stops the CSP
refusal Firefox reports on each load.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

A wiped VM reinstalled cleanly, then make all stopped at the seed: the vault42
plane creates a tenant on install, so an empty platform read as data of unknown
origin. That tenant has no account behind it, and now it does not count.

born2root refuses the same row, so the seed is forced, on this user's own VM and
only when Postgres answered zero. A seed replaces the tenants, so the plane is
provisioned again afterwards.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sonarqubecloud

sonarqubecloud Bot commented Nov 5, 2026

Copy link
Copy Markdown

@LESdylan
LESdylan marked this pull request as ready for review November 5, 2026 16:31
@LESdylan
LESdylan merged commit 3eaf8ce into main Nov 5, 2026
38 checks passed
@LESdylan
LESdylan deleted the feat/make-all-from-vault branch November 5, 2026 16:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant