Repository navigation
fix(install): the low findings of the review on the installer, the image and the data - #21
Merged
Merged
Conversation
…t keys git trusted every SSH host on first use (accept-new): a machine in the path of the first connection to github.com could answer in its place, and be pinned. - apps/api/known_hosts holds the host keys GitHub (api.github.com/meta), GitLab (its docs) and Bitbucket (bitbucket.org/site/ssh) publish, checked against their published fingerprints; ssh reads it as its global known_hosts, so these hosts are reached with these keys only, even the first time, and a different key is refused. Other hosts are still trusted on first use, then pinned.
… change - The data directory is mode 700 (the entrypoint and the installer set it): the containers that mount parts of it do not go through it. Rendered compose files, which hold the secret variables, job logs and archived logs are written 0600; Traefik's route files, which hold no secret, 0644, so that Traefik reads them without the capabilities of root. The entrypoint makes the route files of older versions readable. - The code of the image belongs to root: Spawner, which runs as node, cannot change it. pnpm stays in the build stage, and Prisma's telemetry is off (CHECKPOINT_DISABLE).
… to lose data Low findings of the 2026-10-08 review on the installer and the stack. - No bootstrap token unless SPAWNER_BOOTSTRAP_TOKEN is given: it had every scope, no user and no expiry. Installations that have one keep it. - A version older than the installed one is refused (its database only migrates forward) unless --allow-downgrade, after restoring a backup. - SPAWNER_DATA_DIR other than the installation's is refused, and so are relative paths, "..", and the directories of the system, for the data and the installation directories (--purge deletes them). - An installation whose .env lost SPAWNER_SECRET or POSTGRES_PASSWORD stops the installer instead of getting new ones, which would lock the data out; .env and dns.env are written in one move, and read back with the "=" their values end with. - An upgrade never goes on without a backup: Postgres is started for it. - --purge says it deletes the backups too; the DNS credentials typed are not shown; --tls off warns that it serves plain HTTP on every interface. - Traefik runs without capabilities but NET_BIND_SERVICE, with no-new-privileges; Postgres (1g) and Traefik (512m) have memory limits. - The development stack listens on 127.0.0.1 unless SPAWNER_HTTP_BIND (the engine end-to-end test sets 0.0.0.0, and reads the data directory, now 700, through a container). - The installer's end-to-end test checks the refused downgrade and data directory, the modes, Traefik's capabilities and the code's owner.
Flosk6
force-pushed
the
fix/install-hardening
branch
2 times, most recently
from
October 9, 2026 21:24
d44c453 to
51499ef
Compare
Docker Hub limits the anonymous pulls of an address, and the runners share theirs: every job that pulls (the image's base, Postgres, Traefik, the examples) failed with 429 Too Many Requests. Google's mirror does not help the runners' Docker 28 (it gets "unauthorized" from it as a mirror, then falls back to Docker Hub), only BuildKit. - The jobs that pull log in to Docker Hub with a read-only token of the repository's secrets (DOCKERHUB_USERNAME, DOCKERHUB_TOKEN), and the installer's job logs root in too, since install.sh pulls as root. Without the secrets (Dependabot's pull requests unless they are given to it too), the jobs pull anonymously, as before. - buildx asks mirror.gcr.io first.
Flosk6
force-pushed
the
fix/install-hardening
branch
from
October 9, 2026 22:45
51499ef to
596e85f
Compare
This was referenced Oct 10, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The low findings of the 2026-10-08 review on the installer, the image and the data directory. The code's findings come in a separate pull request.
The installer
SPAWNER_BOOTSTRAP_TOKENis given: it had every scope, no user and no expiry. Installations that have one keep it.--allow-downgradeafter restoring a backup.SPAWNER_DATA_DIRother than the installation's is refused. So are relative paths,.., and the directories of the system, for both the data and the installation directories, which--purgedeletes..envlostSPAWNER_SECRETorPOSTGRES_PASSWORDstops the installer, instead of getting new ones that would lock the data out..envanddns.envare written in one move, and read back with the=their values end with (IFS='=' readdropped it).--purgesays it deletes the backups too, the DNS credentials typed are not shown, and--tls offwarns that it serves plain HTTP on every interface.The stack and the image
NET_BIND_SERVICE, withno-new-privileges. Postgres (1g) and Traefik (512m) have memory limits.node, cannot change it. pnpm stays in the build stage, and Prisma's telemetry is off (CHECKPOINT_DISABLE).ubuntu). Changing it would break the sources that containers running as uid 1000 write into.security.mdsays to treat that account as an admin.SPAWNER_HTTP_BINDsays otherwise.Git
apps/api/known_hostsand checked against their published fingerprints, even on the first connection; a different key is refused. Other hosts are still trusted on first use.Upgrading
/opt/spawner/.env.--allow-downgrade, after restoring its backup.Tests
scripts/e2e-engine.shpasses. It reads the data directory through a container, since the directory is now 700, and listens on 0.0.0.0 for its firewall check.scripts/e2e-installer.sh(CI only) now also checks the refused downgrade and data directory, the 700 / 600 / 644 modes, Traefik's capabilities, the code's owner, and the HTTP warning.