NodehouseDocs

Security#

Nodehouse is a small self-hosted service, not a hardened identity platform. Operate it with a narrow network surface and unique credentials.

Required controls#

  • Set NODE_ENV=production on every exposed instance.
  • Use a unique SysOp password of at least 12 characters.
  • Reset any historical or shared SysOp password before exposure.
  • Serve the browser terminal, Control Desk and packet links through HTTPS.
  • Restrict allowed WebSocket origins to the real site.
  • Keep the database and environment file readable only by the service operator.
  • Back up persistent storage before upgrades and administrative bulk changes.

Telnet warning#

Raw Telnet is plaintext. It exposes account credentials and all session content to the network path. Keep it private, tunnel it through a protected channel, or tell callers to use unique low-value board passwords.

Administrative access#

The Control Desk at /admin admits any account at access level 100 or above. Level 100 to 199 is a moderator: they review Front Porch submissions, work the moderation queue, delete any public message, read the audit trail, and list every caller card — including cards their owners have kept hidden — which they can hide but not publish. Only level 200 and above manages accounts, resets passwords and edits bulletins. Grant level 100 deliberately; it is a real administrative role.

Admin sessions are bearer tokens stored by the browser until logout or expiry, and every request re-checks the account's current access level. Demoting an account, deleting it or resetting its password ends that account's admin sessions immediately. The last remaining SysOp account cannot be demoted or deleted, and an operator cannot delete the account they are signed in with.

Administrative actions — user updates, deletions, password resets, message and bulletin changes, Front Porch decisions and moderation outcomes — are recorded in an audit trail visible in the Control Desk. Treat it as an operational record, not a tamper-proof log: an account with SysOp access can also delete the underlying data.

Passwords set through an administrative reset must be at least 12 characters. Self-service caller registration still accepts 8, so a caller password is not equivalent to an operator password.

Requesting a packet prints a URL of the form /transfers/packet/<format>/<token>. That link is the only credential: anyone who holds it can download the caller's unread mail and messages, or post replies as that caller. Links expire 15 minutes after they are issued and work once.

  • Serve them over HTTPS. A URL travels in browser history, terminal scrollback and reverse-proxy access logs; keep proxy logging in line with that.
  • Tell callers not to paste a packet link into a public conference or chat.
  • Each caller may hold two unused links per packet format in each direction, and may generate at most six download packets in 15 minutes.
  • Uploads are capped at 4 MB, must be a well-formed archive within its entry and expansion limits, must target a conference the caller can already reach, and are rejected if the same packet content has already been imported. A reply that names a parent message must name one in the same conference.

Staged packets are written to data/transfers with owner-only permissions, removed when downloaded, and swept periodically once expired.

Caller privacy#

  • Caller cards are hidden until the caller opts in. Existing profiles carried forward from an earlier release stay hidden until their owner opts in. Hidden means absent from the caller directory, not invisible to the Control Desk.
  • Moderators can hide a card from the directory. They cannot publish one on a caller's behalf.
  • Front Porch posts from callers below level 100 are held for moderation before they appear; operator posts publish directly.
  • Presence has Available, Away, Busy and Do Not Disturb. Pages are invitations: private node chat opens only after the recipient accepts, and Do Not Disturb refuses pages outright.
  • Telegrams are delivered as ordinary local E-Mail, so they persist in the recipient's mailbox and in your backups.

Caller-supplied text — profile fields, ANSI avatars, Front Porch posts and node messages — has terminal control sequences stripped before display, keeping only colour selection. Gallery artwork is subject to the same restriction, plus a 256 KB file cap and an 80-column check.

Application boundaries#

Login, registration and admin login attempts are rate-limited, and node pages and telegrams carry their own cooldowns, but none of that replaces a firewall or upstream denial-of-service controls. Use a trusted browser and log out after administration.

The narrated dungeon can send caller input to its configured model provider. Disable it by omitting the provider key when that disclosure is not acceptable.

Federated packet exchange with other boards is not part of this release. Offline packets move between a caller and this board only.

Verify#

From outside the host, confirm only intended ports are reachable. Check that HTTP redirects to HTTPS, the browser WebSocket accepts the site origin, the Control Desk rejects an unauthenticated request, a used packet link returns a failure on a second attempt, and /healthz reveals no secret or filesystem path.

If it does not work#

Symptom Check Recovery
A port you did not intend is reachable The published ports from outside the host Close it first, then work out how it was opened
HTTP does not redirect to HTTPS The proxy configuration Callers signing in over plaintext expose credentials
The Control Desk accepts an unauthenticated request Treat this as an incident. Take the board off the public network before investigating
A used packet link succeeds twice Single-use enforcement See An offline packet link fails for the inverse symptom
/healthz reveals a path or secret What the body contains It should reveal neither; record the exact output before changing anything