Add governed test plane and close T04/T08

Encode fail-closed admission, target registrations, and a credential
broker that never returns secret values. Calibrate audit-core shaped
probes in-process. Send no packets and request no live credentials.

Assistant: grok
Assistant-Session: 01a02670-3345-76f2-a014-70fde8e2a2bb
This commit is contained in:
tegwick 2026-08-22 00:44:21 +02:00
parent 0aab0cb4c6
commit 95129d7a35
35 changed files with 1599 additions and 103 deletions

View file

@ -18,6 +18,23 @@ and to produce a finding against the fixture with its tenant predicate removed.
`evidence/offline-calibration.json` is calibration evidence, not target
assurance.
## Test plane
Live execution is gated by [`docs/test-plane.md`](test-plane.md). Before any
target run:
```sh
PYTHONPATH=src python3 -m whitehat_security.cli validate-targets targets
PYTHONPATH=src python3 -m whitehat_security.cli kill-switch
```
`admit-plane` must succeed against a **new** engagement ID. The default live
broker is unconnected and fails closed without requesting a credential.
Create `plane/KILL` to abort independently of the runner.
Cancelled IDs `WH-ENG-20260821-AUDIT-E2` and `WH-ENG-20260821-TENANT-E2` are
retired.
## Prepare a target run
1. Select the target's probe pack and review every route with its owner.
@ -27,10 +44,11 @@ assurance.
4. Provision only the two disposable tenants/objects named in the record.
5. Obtain the ordinary modeled credential through its custody lane. Do not put
its value in the record or shell history.
6. Validate within the approved window:
6. Validate within the approved window, then admit the plane:
```sh
PYTHONPATH=src python3 -m whitehat_security.cli validate-engagement engagements/<record>.json
PYTHONPATH=src python3 -m whitehat_security.cli admit-plane engagements/<record>.json targets/<target>.json
```
7. Confirm target identity/revision and probe attribution before the first
@ -61,7 +79,9 @@ unexpected response by broadening routes, identities, discovery, or privilege.
proven; otherwise `pass`.
- Validate the record against `schemas/run-report.schema.json`.
- Route both passing and finding target reports to `risk-nexus`; never assign
severity. The message formatter is `whitehat risk-message <report.json>`.
severity. Queue the delivery with `whitehat deliver <report.json>` (fixture
calibration is refused). The message formatter is
`whitehat risk-message <report.json>`.
- Schedule the next run from the target's declared cadence.
No target run is complete until its dated report and risk-nexus delivery are

View file

@ -18,6 +18,13 @@ The reporter does not edit risk-nexus grading fields. `risk-nexus` decides
whether an observation is a finding or note, and owns severity, disclosure,
review cadence and escalation.
Offline calibration stays in this repository and is plainly labeled
`evidence_class: fixture`; it is not sent as if it were a target result.
Queue a target report without assigning severity:
```sh
PYTHONPATH=src python3 -m whitehat_security.cli deliver evidence/<run>.json --outbox outbox
```
Offline calibration stays in this repository and is plainly labeled
`evidence_class: fixture`; it is not sent as if it were a target result. The
deliver command refuses fixture evidence.

View file

@ -2,7 +2,7 @@
Status: **accepted**
Version: 0.1
Version: 0.2
Date: 2026-08-18
@ -137,7 +137,24 @@ known-bad fixture pass is a finding until independently explained. Every live
probe must first fail against its known-bad fixture and pass against the
known-good fixture in the same revision.
## 10. Approval
## 10. Governed test plane
Live runs are admitted only through the test plane documented in
[`test-plane.md`](test-plane.md): dedicated namespace, default-deny networking,
projected short-lived identities, registered target, kill switch, rate watcher
and lease cleanup. The plane is a control, not authorization.
`fixture-e2` is the in-process class already permitted by §1. `live-e2` still
requires the dated engagement record, target-owner acknowledgement and
technique-specific operator approval required by §1, plus plane admission.
`e3`, recovery, saturation and destructive techniques keep separate explicit
approval classes and are not admitted by the E2 plane.
Cancelled engagement identifiers are terminal and must not be reused.
This section authorizes no live target and no packet.
## 11. Approval
Approved by: **repository operator**, by explicit approval in the coordinating
session
@ -149,3 +166,6 @@ Approved scope: these rules are accepted as the operating boundary for
fixture work. It does **not** authorize a live target or a packet to any target.
Every live run still requires the engagement record, target-owner
acknowledgement and any technique-specific operator approval required by §1.
v0.2 (2026-08-22) adds §10. It tightens admission; it does not expand
authorization or replace the 2026-08-21 acceptance.

View file

@ -76,3 +76,10 @@ each run:
Resume only with new engagement IDs after that plane can issue the correct test
identities and enforce the complete envelope. The existing workplan remains the
backlog: T01 and T02 are done; T03, T04, T05, T06, and T07 remain in progress.
## Progress after cutoff
On 2026-08-22 the plane contract was encoded in this repository:
[`docs/test-plane.md`](test-plane.md), `targets/`, `plane/`, and
`whitehat_security.plane`. No live packet was sent. No credential was
requested. Cancelled engagement IDs remain terminal.

View file

@ -1,10 +1,12 @@
# Target applicability for WHITEHAT-WP-0001
Status: active review, 2026-08-22
Status: encoded in `targets/`, 2026-08-22
The E2 attacker model requires an authenticated identity that is legitimately
authorized for tenant A and not tenant B. A target name alone is insufficient;
the target must expose a boundary where that identity exists.
the target must expose a boundary where that identity exists. Machine-readable
records live in [`targets/`](../targets/README.md). The test plane will not
admit a `not_applicable` or `pending` target.
## audit-core — applicable

48
docs/test-plane.md Normal file
View file

@ -0,0 +1,48 @@
# Governed test plane
This is the missing control from the 2026-08-22 cutoff. It is a fail-closed
admission path, not a standing authorization to probe.
## What the plane is
A live E2 run is admitted only when every item below is true:
1. The target is registered in `targets/` with `applicability: applicable`.
2. Known-bad calibration for that target has already failed in-process.
3. The engagement is complete, in window, owner-acknowledged, and not a
retired ID.
4. `approval_class` is `live-e2` (or `fixture-e2` for in-process only).
5. The runner namespace is `whitehat`, the image digest is pinned, and
engagement labels are present.
6. The custody broker projected exactly two identity *handles* (owner and
attacker). Credential values are not returned to the operator or agent.
7. The kill switch is clear.
8. The rate watcher is attached. Cleanup revokes the lease.
If any item is false, `whitehat admit-plane` exits 2 and no identity is
requested.
## What the plane is not
- Not authorization. Rules of engagement §1 still apply.
- Not a packet. Manifests in `plane/` are a contract for `ops-mason`.
- Not a secret broker. `UnconnectedCustodyBroker` is the default for every
non-fixture environment and raises before any custody call.
- Not a way to finish tenant-engine E2. That target is `not_applicable`.
## Operator commands
```sh
PYTHONPATH=src python3 -m whitehat_security.cli validate-targets targets
PYTHONPATH=src python3 -m whitehat_security.cli admit-plane engagements/<record>.json targets/<target>.json
PYTHONPATH=src python3 -m whitehat_security.cli kill-switch
PYTHONPATH=src python3 -m whitehat_security.cli deliver evidence/<run>.json --outbox outbox
```
Create `plane/KILL` to abort independently of the runner process.
## Retired identifiers
`WH-ENG-20260821-AUDIT-E2` and `WH-ENG-20260821-TENANT-E2` are terminal. A new
live run needs a new ID after the cluster plane exists and the custody broker
can project identities without exposing values.