Security

What it protects, and how

What it protects, from whom, and how. And, just as plainly, what it doesn't do yet.

In development, and not yet released. It has had internal adversarial review (by AI reviewers, each given one area), and is tested end to end on Ubuntu with systemd, but it hasn't been independently reviewed.

What it promises

  1. Only main's newest commit that passed CI is ever deployed.
  2. Nothing a message says becomes a command.
  3. GitHub, or someone in it, can't get into the server.
  4. One product can't read or change another's code, data, or keys, or the server's.
  5. A bad deploy doesn't take a product down.

Each is kept by the measures below, tested, and checked end to end on Ubuntu with systemd.

How

AgainstWhat it does
A forged deploy messageEach product has its own secret; every message must carry a valid HMAC-SHA256 signature of its exact body, compared in constant time
A message for anything but a passed CI run on mainOnly a finished, successful run of the product's CI workflow, for a push to main, in its own repository, deploys
An old message sent againOnly main's newest commit is ever deployed, and a commit that failed isn't tried again by a message, only by hand
A message that names something to runThe listener runs nothing: it leaves a request holding a known product's name and a commit checked to be 40 hex characters
Someone in GitHub, the repository, or a workflowGitHub holds no key to the server, only the webhook secret, which no workflow can read
A server pretending to be GitHubGitHub's host keys are fetched from GitHub's API over HTTPS at install; nothing is trusted on first use
A product reaching another, or the serverIts own user; a read-only system and code; private /tmp; no new privileges; other users' processes hidden; the server's keys out of reach; write access to its own data only
A package's install scriptDependencies installed exactly as the lockfile says, with install scripts off, by a separate user
A repository's own npm or git settingsIts .npmrc is removed before npm runs, and npm's and git's settings are pinned, so nothing it carries chooses what runs
A build reaching another productEach product has its own build user, which alone can read its deploy key and its copy of the repository
A build that ran code of its ownAll the build user's processes stopped after every step, before root touches its files; each deploy starts it clean; hard links refused
A commit filling the shared diskReleases over 1GB or 200,000 files refused, sizes counted before anything is written, and 1GB always kept free
A bad deployThe product is checked once started, and the version before comes back if it doesn't answer
An unsafe servercheck looks at SSH, automatic updates, and what's listening, and install and add refuse until it's fixed
A key committed to this public repositoryCI fails on IP addresses, private keys, and tokens

The threat model has every threat, its measure, and where in the code it lives.

What it doesn't do yet

  • The server is only as safe as its setup. modest-host checks the main points, but can't see everything, such as a provider's firewall.
  • Products trust their dependencies. Install scripts are off, but a compromised package still runs when the product does, inside its sandbox.
  • A product that's been broken into could listen on another port, to the outside or on another product's port while that one restarts. systemd can stop this, but Ubuntu's systemd is built without the part it needs. The firewall from "Before you install" blocks the outside, and check and the nightly run report it; products on Unix sockets are on the roadmap.
  • A fetch isn't limited in size, so someone who can push to a product's main could fill the disk as it's fetched. Deploys stop once less than 1GB is free.
  • The deploy service runs as root, to own releases and restart products. It runs git and npm as a separate user, and takes only a checked name and commit from a request.

How the project stays secure

  • No runtime dependencies, and CI fails if one is added, or if anything but Node's own modules is imported.
  • CI refuses invisible or direction-changing characters in code, and any address, key, or token committed.
  • CodeQL checks every change, OpenSSF Scorecard grades the project weekly, and GitHub Actions are pinned to exact commits.
  • An end-to-end test runs it on Ubuntu with systemd: install, launch, deploy, sandbox, rollback, and backups.

Reporting a vulnerability

Please don't describe it in public. Use the repository's Security tab, then Report a vulnerability, with what you found, how to make it happen, and what an attacker could do with it. You'll hear back within 5 working days.