Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions audits/DOCKIFY-AUDIT-FABLE-5.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,43 @@ deploy in flight; (4) run `update.sh`; (5) after start: `journalctl -u dockify`
the migration log, `/api/apps` lists 26 apps, both workers show their routes on disk,
one staging redeploy succeeds.

## 10. Wave 7 result — re-audit of `main` after Waves 0–5 (2026-10-15)

Merged, in order, each reviewed and re-verified in a temporary worktree before merge:
#87 (Wave 0), #88 (Wave 1), #89 (Wave 2), #90 (Wave 3), #91 (Wave 4), #92 (Wave 5).
Code by Claude Opus 5.5 sessions, review and merge by Fable 5.1. Final `main`:
`1d79787`.

### Verification on final main

| Check | Result |
|---|---|
| `go build`, `go vet`, `gofmt -l cmd internal`, `go test -race ./...` | clean, all 11 packages pass |
| `govulncheck ./...` | 0 reachable vulnerabilities (x/crypto 0.56, Go 1.26 latest patch in CI) |
| CI (`build` job on PRs and `main`) | green on every wave PR |
| Mock-mode end-to-end with the final binary (curl / raw sockets) | CSP + nosniff + referrer headers; login 302; cross-site POST 403; cross-origin WebSocket handshake 403, same-origin 101, no cookie 302; server created without key returns `public_key`, init → online; app with `"`, space, `$`, `#` in an env value and a mixed-case domain deploys → running, domain lowercased; bad domain / `..` path / bad env key → 400; second redeploy while one runs → 409; `/static/htmx.min.js` served, `/static/` 404; export carries `domains`; undeploy → 404 afterwards; server delete 200 once empty; 11th bad login → 429; SIGTERM → clean shutdown |
| Vendored assets | sha256 of the four files re-checked against unpkg/jsdelivr: identical |
| Real workers (staging root/Photon, prod-heavy-1 dockify/Debian), `/tmp` only | TOFU pins the host key, reconnect accepted, a different key is rejected with "host key mismatch"; `WriteFile` round-trips byte-identical with mode 0600 for both users |
| Real compose parsers (v2.18.1 standalone, v5.3.1 plugin) | the new quoted `.env` yields the same values as the old unquoted format for plain, spaces, inner quotes, `$`, backslash; `#` after a space is kept (was truncated), newlines now work |
| Migration against a consistent copy of the production DB (twice, Wave 2 binary and final binary) | 14 s, `integrity_check` ok, 0 FK violations, routes 57 → 25 with no duplicates, all other counts unchanged, indexes created, dead server deletable, server with apps refused |

### Findings status

- Closed: S1–S15, S17, B1–B22, A1, A2, A4–A7. S14 was done in Wave 2.
- Not scheduled (by design): S16 (secrets at rest), P1/P2/A3 (Wave 6, only if measured; `PRAGMA synchronous=NORMAL` is the one-liner to start with).
- Verified only in mock mode / unit tests, to confirm after the release: B14 (live stats after a container restart), B11 (init against a worker that has a foreign Caddy), S7 (`systemd-run` self-update on the real controller; it also needs the first release that ships `dockify-linux-amd64.sha256`).

### Release checklist (0.6.22 → 0.7.0)

1. On the controller, before updating: `systemctl stop dockify`, copy `/var/lib/dockify/dockify.db` and its `-wal`/`-shm` files aside (5.7 GB free, the DB grows to ~350 MB during the rebuild), `systemctl start dockify`.
2. Add to `/opt/dockify/.env`: `DOCKIFY_TRUST_PROXY=true` (Caddy is in front: without it every browser shares the client key `127.0.0.1` and ten bad logins lock everyone out for 15 minutes) and `DOCKIFY_HOST=127.0.0.1` (Caddy already proxies to it; closes the plain-HTTP port 8080 to the internet).
3. Make sure no deploy is running, then from `main`: `./scripts/release.sh minor`; wait for the tag workflow (binary + `.sha256` + image).
4. Update the controller with `curl -fsSL https://raw.githubusercontent.com/coderbuzz/dockify/main/scripts/update.sh | bash` (verifies the checksum) or the Settings page.
5. After start: `journalctl -u dockify` shows `migrating database from version 0 to 4` … `database at version 4` and `pinned host key for …` on the first connections; `/api/apps` lists 26 apps; the dead server `production-1` can now be deleted from the UI.
6. Redeploy one staging app and compare the container's env with the previous values (the 24 values with quotes/spaces/`$`/`#` are now written quoted); then check that `/opt/dockify/caddy/config.json` on that worker contains its routes.
7. Optional on both workers: delete `~/.ssh/dockify` and `~/.ssh/dockify.pub` (the private keys generated by the old setup script); keep their lines in `authorized_keys`.
8. Docker-compose installs (none in production) must re-download `docker-compose.yml` to pick up B10.

## 8. Repository hygiene done during this audit

- Deleted remote branch `claude/trusting-volta-c2xw1b` (merged in PR #79) and, on
Expand Down
Loading