Tracking issue for the P2 hardening that follows launch. #1 covered the P0 and P1 work and is closed; everything here improves assurance rather than closing a reachable hole.
This issue closes when its children close. That is now possible, because each child below has a deliverable and a line saying what “done” is, rather than a property that would have to hold forever.
Supply chain
- #93 P2: Publish a software bill of materials with each release — done when the
release attaches it beside
SHA256SUMSanddocs/releases.mddescribes it. - #94 P2: Sign release artifacts and document how to verify them — done when a signature covers the artifacts, the public key is published, and tampering fails a documented check.
- #95 P2: Check dependency licences and show dependency changes to reviewers —
done when
verifyfails on a licence outside the allowlist and the log names the modules a change request added or removed.
Fuzzing
- #96 P2: Fuzz the SSH command parser, Git HTTP routing, and the LFS pkt-line parser
- #97 P2: Fuzz the metadata and workflow parsers
- #98 P2: Fuzz the path validators and the Markdown sanitizer
Each is done when its targets merge, their seed corpus runs under go test ./...
in verify, and one documented 60-second run per target was clean on a stated
date. “Fuzzers stay clean” is not a finish line and is not claimed here; the
targets are the deliverable.
Load and soak
- #99 P2: Add a load-test harness that runs against a real instance — done when one command prints a table with throughput, latency percentiles, and peak RSS, file descriptors, goroutines, and processes.
- #100 P2: Load the anonymous read path — done when every listed route has a number at a stated concurrency.
- #101 P2: Load the paths that cost the server work: sign-in and uploads — same.
- #102 P2: Soak a staging instance and record bounded memory, file descriptors,
and processes — done when one run is recorded and
docs/operations.mdsays what the limits were measured at.
A measurement is a snapshot: these close on a recorded number, and the number is re-checked by a person when someone changes a limit.
Observability, recovery, and response
- #103 P2: Emit security events in one shape and document the alerts to wire up —
done when the events are emitted in a documented shape with a test pinning
their fields, and the alert table is in
docs/operations.md. Alerting itself belongs to the operator’s monitoring. - #104 P2: Run a restore-from-backup drill and record it — done when a dated record exists and the operations page matches what the drill required.
- #105 P2: Write the incident response runbook — done when the page exists, is linked, and names commands for each scenario.
Outside a change request
- #106 P2: Commission an external review of runner isolation and the browser sign-in flow — done when the report is received and every finding is an issue or a recorded accepted risk.
What does not live here
So that this issue can end, the properties go where they are enforced:
- Per push,
verifytakes on the licence check (#95) and the fuzz corpus (#96–#98).govulncheck,go vet, and-raceare already there. - Per tag,
releasetakes on the SBOM (#93) and the signature (#94), beside the checks it already runs. - Neither: Vole workflows trigger on a push to a branch or a tag, and there is no schedule, so no soak or drill can be automated here. Those stay date-stamped records (#102, #104) that a person re-runs.
- Outside Vole: alerting (#103) is the operator’s monitoring.
When the last child closes, close this issue. If hardening still needs a
permanent home then, it is a “before you tag” checklist in docs/releases.md: a
document can be kept current in a way an open issue cannot.