Disciplines · Security

Pre-GA Penetration Test Signoff Record

Each engagement adds a new row to the table below.

5sections2 minread

On this page

This file is the formal release-blocker controlled by V1/TODOS.md §28.20. A GA release is not authorised unless every cell below is filled in with a real engagement record. CI parses this file (see scripts/security/pentest/verify-signoff.mjs) and rejects a release tag when any of the required fields are missing or stale.

Engagement record schema#

Each engagement adds a new row to the table below. Rows are append-only — never edit a past row. The fields:

Field Notes
engagement_id Vendor's reference for the engagement (e.g. ACME-2026-04).
scope_version Version of pre-ga-scope.md the engagement was run against.
window_start ISO date the active testing window opened.
window_end ISO date the active testing window closed.
findings_count critical/high/medium/low/info counts at engagement close.
open_at_release Count still open at the release tag (must be 0 critical, ≤1 high, no AuthN/RBAC/privacy regardless of severity).
release_tag The release this engagement signs off. Must match the Git tag being cut, e.g. vN.M.P.
signoff_sec Name + ISO date – head of security.
signoff_eng Name + ISO date – head of engineering.
signoff_priv Name + ISO date – head of privacy (required if any privacy-tagged finding).

Engagements#

engagement_id scope_version window_start window_end findings_count open_at_release release_tag signoff_sec signoff_eng signoff_priv
none yet

Release gate rules#

A release tag is valid only if the most recent engagement row satisfies all of the following:

  1. release_tag exactly matches the tag being cut.
  2. open_at_release.critical == 0.
  3. open_at_release.high <= 1.
  4. No open finding in the AuthN, RBAC, or privacy categories regardless of severity. This cannot be read off the row, so it is carried by a mandatory tags-summary: footer below the table (see "Category footer"). A missing, empty, or incomplete footer fails the gate — absence is not a clean result.
  5. signoff_sec and signoff_eng are non-empty. signoff_priv is required whenever the footer declares any privacy state other than privacy:none.
  6. Each non-empty signoff date is within 14 days of window_end. The gate runs while the tag is being cut and so cannot read a tag date; window_end is the anchor it enforces, and it is what keeps a signature from being older than the engagement it signs.

Failing any rule above prints the failing rule to stderr and exits with a non-zero code — the release pipeline then refuses to flip the traffic gate.

Every engagement row must be followed by one machine-readable line declaring a state for each of the three blocking categories:

text
tags-summary: authn:closed, rbac:closed, privacy:none

Permitted states are open, closed, and none (no finding in that category was raised). <category>:open blocks the release under rule 4. Any privacy state other than privacy:none makes signoff_priv mandatory under rule 5.

Red-team exercises#

See ../red-team/scenarios.md for the matching red-team scenario set; the red-team result file references this record by engagement_id.