Skip to content

deploy: make the OTP-signup broker + route survive redeploys#78

Open
Alexgodoroja wants to merge 5 commits into
mainfrom
deploy/otpsignup-broker-durable
Open

deploy: make the OTP-signup broker + route survive redeploys#78
Alexgodoroja wants to merge 5 commits into
mainfrom
deploy/otpsignup-broker-durable

Conversation

@Alexgodoroja

Copy link
Copy Markdown
Collaborator

The signup broker (cmd/otpsignup-broker, added in #77) and its public nginx route were configured by hand on the broker VM. A broker redeploy regenerates broker.conf, which wiped the route — signup requests then fell through to the managed-key broker ({"error":"unknown app: didit"}).

This folds both into the managed deploy so redeploys and fresh VMs recreate them:

  • startup.sh — builds cmd/otpsignup-broker and installs a systemd unit that runs only when broker-env metadata carries an OTPSIGNUP_* block (a broker VM that doesn't offer signup skips it). Every app/provider/host specific + secret comes from broker-env metadata; only a non-secret listen/DB default is in the unit.
  • setup-broker-tls.sh — injects operator-provided nginx location blocks (from broker-extra-locations metadata) before location /, so the signup route survives every regeneration. No app-specific route is baked into the repo.

Secrets and app/host specifics live in instance metadata, not the repo. Validated on the live VM: regenerating broker.conf from scratch re-injects the route and the endpoint answers from the signup broker. Merging this triggers a redeploy that stands the whole thing up cleanly.

Alex Godoroja added 5 commits July 7, 2026 16:39
Add the broker-signup pattern: obtain a per-user provider API key that a
provider gates behind an email OTP, with NO email input from the user and no
key held on our side after handoff.

- internal/otpmail: a receive-only mail server (catch-all SMTP for one domain
  + token-authed control API for provision/read-OTP/teardown). Keeps mail only
  for provisioned addresses, tmpfs maildir, never logs the code or body.
- internal/otpsignup: a signed HTTP broker that provisions a mailbox, drives the
  provider register→OTP→verify handshake, mints the key, and returns it. Reuses
  the shared broker's ed25519 caller-identity verify; idempotent per caller with
  an AES-GCM encrypted-at-rest ledger; per-IP Sybil cap.
- scaffold: a new signup `step: broker` (the adapter signs one keyless call to
  the broker and caches {email,api_key} to secrets.json; ops stay byo) plus a
  `step: account` local reader to retrieve the cached account. Emits the signer +
  a broker_signup.go runtime; grants key.sign + net.dial-broker.

All provider- and host-specifics are configuration; nothing is compiled in.
Tests cover SMTP delivery, OTP parse, control API, the full signed mint,
idempotency, encryption at rest, the per-IP cap, and generated-project compile.
didit.signup {} now mints the per-user Didit key via the Pilot broker in one
call (no email, no code); adds didit.account to retrieve the cached account;
drops the two-step register/verify. Help + long description updated.
…deploy

The signup broker (cmd/otpsignup-broker) and its public nginx route were set up
by hand, so a broker redeploy (which regenerates broker.conf) wiped the route.
Fold both into startup.sh + setup-broker-tls.sh so redeploys and fresh VMs
recreate them:

- Build cmd/otpsignup-broker; add a systemd unit that runs ONLY when broker-env
  metadata carries an OTPSIGNUP_* block (a broker VM without signup skips it).
  All app/provider/host specifics + secrets come from broker-env metadata; only
  a non-secret listen/DB default is in the unit.
- setup-broker-tls.sh injects operator-provided nginx location blocks (from
  broker-extra-locations metadata) before the default `location /`, so the
  signup route survives every config regeneration. No app-specific route is
  baked into the repo.

Validated on the live VM: regenerating broker.conf from scratch re-injects the
route and the endpoint answers from the signup broker.
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