writing / 2026-07-02

A client portal with zero dependencies

Clients shouldn't have to email "any update?" — and I shouldn't have to run a SaaS subscription to prevent it. So this site now has a client portal, and the whole thing is built with what Node and Next.js ship in the box.

The constraints

This repo has a standing rule: no new runtime dependencies without a human signing off. It's a small site on managed hosting; every package is a future security patch I owe. So the portal had to work with:

  • node:crypto for the actual security
  • the filesystem for storage — no database
  • Next.js route handlers for the gate

How it works

Each client gets a passcode, handed over out-of-band. The repo stores only a scrypt hash. Logging in sets an HMAC-signed, HTTP-only cookie; every portal request re-verifies the signature server-side.

Deliverables live outside the public folder, so the static server can never touch them. Downloads go through an authenticated route that checks the session, pins the path to that client's folder, and refuses traversal. Pentest reports get the same treatment with a separate vault section, because confidential findings deserve visible ceremony.

What clients see

A status timeline ("parts ordered", "firmware v0.2 flashed"), a bench notes feed written in markdown, and their files. Updating any of it is a git push — which means every client-visible change is versioned, and rollback is git revert.

The trade

This won't scale to a thousand users, and it isn't trying to. For a solo shop with a handful of concurrent projects, boring cryptographic primitives plus the filesystem beat a database and four dependencies — and there's nothing to patch on a Tuesday night three years from now.