Skip to content

feat(nimbus): password resets are delivered, from an origin nobody can forge - #4

Merged
savvaniss merged 1 commit into
mainfrom
deep-research
Jul 29, 2026
Merged

feat(nimbus): password resets are delivered, from an origin nobody can forge#4
savvaniss merged 1 commit into
mainfrom
deep-research

Conversation

@savvaniss

Copy link
Copy Markdown
Contributor

Summary

Part of an estate-wide remediation of the 49-ticket defect register in audit.md, sequenced by the phase plan in upgrade.md. Each ticket was resolved against its own Done when boxes, then handed to an independent reviewer told to assume it was not fixed and to walk the ticket's How it fails scenario through the new code.

Verification

  • pnpm typecheck passes across every workspace in this repo.
  • Each ticket carries a reproduction of its documented failure, then evidence that it no longer occurs.
  • Findings that survived adversarial review were sent back for a repair pass before landing.

What has NOT been verified

Stated plainly so review effort goes to the right places:

  • No end-to-end run of the assembled stack. Typechecks and unit tests are not the same as driving the feature. docker compose build returns exit 0 while cancelling every target, so a green build here would prove nothing anyway.
  • Some tickets in the wider programme came back partial or INCOMPLETE; where any of those touch this repo they are listed in the commit body rather than hidden.
  • Documentation corrections were verified against source, but the estate has a history of docs drifting from code — treat prose changes as claims to check, not conclusions.

🤖 Generated with Claude Code

…n forge

The delivery seam has been a documented no-op since it was written: a
self-service reset minted a valid token and dropped it on the floor, and the
only working path was an operator handing a link over out of band. It now
sends over generic SMTP — nodemailer behind SMTP_HOST/PORT/SECURE/USER/PASS/
FROM — so Brevo, Gmail, Resend, SendGrid or a self-hosted relay all work
with no code change. Unconfigured remains a supported mode, not a degraded
one: no send, and the console path as before.

Wiring delivery is what made an existing weakness live. The link was built
from the request Host header, so anyone who knew an address could have this
deployment mail them a correctly-branded link pointing at a host of their
choosing. It is now minted from NIMBUS_PUBLIC_URL regardless of how the
request was addressed, with an audit line when the two disagree — not a
refusal, because refusing tells a prober which hosts are real. The route
also answers before the SMTP conversation: awaiting it split response time
10ms for an unknown address against 6015ms for a known one, which is an
enumeration oracle read off a stopwatch.

CF-17 — the token is no longer written to the log stream by the request
serializer, and it travels in the fragment, which browsers keep to
themselves.
CF-16 — the RSA signing key is encrypted at rest and has a rotation path.
CF-36 — refresh rotation has a reuse grace window, and sign-out revokes by
family so a raced rotation cannot orphan a live token.
CF-47 — the portal origin derives from the configured apex.
CF-34 — the console can abandon a stuck withdrawal.
CF-33 — withdrawals are fetched by status rather than filtered client-side.
CF-35 — treasury and withdrawal load failures no longer render as
reassuring empty text.
CF-37 — the public roadmap matches the code.
CF-46 — the pay-proxy rationale is correct in both files.

Co-Authored-By: Claude <noreply@anthropic.com>
@savvaniss
savvaniss merged commit 2f35c64 into main Jul 29, 2026
3 checks passed
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