Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/vole.git

Write over SSH with a registered key:

git clone ssh://git@rodent.software:2222/vole.git

A free and open-source forge that lives in your Git repo.

#14

P2: Add supply-chain, fuzzing, load, and observability hardening

closed · opened by keenan 13d ago

keenan opened this 13d ago

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 SHA256SUMS and docs/releases.md describes 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 verify fails 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.md says 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, verify takes on the licence check (#95) and the fuzz corpus (#96–#98). govulncheck, go vet, and -race are already there.
  • Per tag, release takes 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.

Comments (1)

keenan 10d ago

This issue is now a tracking issue. Its seven bullets became fourteen issues that each fit in one change request, filed in dependency order.

Supply chain

  • #93 P2: Publish a software bill of materials with each release
  • #94 P2: Sign release artifacts and document how to verify them
  • #95 P2: Check dependency licences and show dependency changes to reviewers

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

Load and soak

  • #99 P2: Add a load-test harness that runs against a real instance
  • #100 P2: Load the anonymous read path — depends on #99
  • #101 P2: Load the paths that cost the server work: sign-in and uploads — depends on #99
  • #102 P2: Soak a staging instance and record bounded memory, file descriptors, and processes — depends on #99

Observability, recovery, response

  • #103 P2: Emit security events in one shape and document the alerts to wire up
  • #104 P2: Run a restore-from-backup drill and record it
  • #105 P2: Write the incident response runbook

Outside a change request

  • #106 P2: Commission an external review of runner isolation and the browser sign-in flow

Four notes on the split:

  • The fuzzers are three issues, not one, because each is a separate parser family with its own assertions, and each lands as its own change request. They stay cheap on a normal push: the seed corpus runs under go test ./..., and only the longer budget is a separate command.
  • The load work is one harness (#99) and three users of it. The harness is the change request that has to be right; the others add scenarios and record numbers, and both read-path and soak numbers are what #1’s definition of done asked for. #1 is now closed and those two lines belong here.
  • The three bullets about alerts are one issue (#103) that emits the events and documents the alerts together, because the field names and the alert table have to agree, and splitting them is how they drift.
  • The external review does not fit a change request, so it is #106 rather than a line on this issue. It closes on triage of the report, which gives this issue a reachable end: when the last child closes, close this one.

Suggested order: #93 and #95 first (the release workflow is already the place both touch), then the fuzzers while they are cheap, then #99 as the larger piece, then the load and soak issues, then the recovery and response writing, which need no code.