Both sides added to the same two places — the environment-variable list in
server.js and the settings table in the README — because the forge work and
the PIN work each documented a new setting. Everything from both is kept.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The passcode machinery existed but could only be set by hand in a config
file, so in practice every install left admin open to anyone on the
network. It is now a PIN you set from the admin page itself.
- Six digits, stored as a scrypt hash in this machine's proddash.json —
never in the clear, since that file gets copied between machines.
- The unlock card takes the PIN and submits itself on the sixth digit.
Five wrong tries from one address locks it out for 30 seconds, and the
right PIN is refused during the lockout.
- Changing or turning off the PIN asks for the current one, so a browser
left open on the admin page cannot be used to take the machine over.
Whoever sets it keeps their session rather than being bounced to the
card they just built.
- This is the shell's own PIN and guards /admin and the admin API only.
Dashboards stay open, and it is unrelated to a module's PIN — Slack's
4-8 digit send PIN still guards sending, separately and independently.
- Ways back in if it is forgotten: PRODDASH_PASSCODE in the environment
(which overrides the PIN), or delete adminPin from proddash.json and
restart. Both are in the README and on the page itself.
- The older free-text adminPasscode still works, so an existing install
keeps running.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>