Build authorization-gated tenancy evidence harness
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a0260c-4067-7052-9647-ad000d576e38
This commit is contained in:
parent
2c8e1d41ad
commit
beab2a04d1
32 changed files with 1816 additions and 11 deletions
28
docs/e3-cadence.md
Normal file
28
docs/e3-cadence.md
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
# E3 conformance cadence
|
||||
|
||||
The E3 detection interval is **24 hours**, so the declared maximum exposure
|
||||
window is **24 hours plus run and reporting latency**. A run is also required
|
||||
before deployment promotion following any schema migration, RLS policy change,
|
||||
role/grant change, security-definer function change, or posture-mechanism
|
||||
change. The event-triggered run does not reset the daily schedule.
|
||||
|
||||
This is a detection control, not prevention. A migration can introduce an
|
||||
unprotected table between runs; the interval states how long that condition
|
||||
can remain unnoticed under normal scheduling.
|
||||
|
||||
The executable plan is available with:
|
||||
|
||||
```sh
|
||||
PYTHONPATH=src python3 -m whitehat_security.cli e3-plan
|
||||
```
|
||||
|
||||
The run checks the conformance view, unset-GUC reads, wrong-tenant reads and
|
||||
writes, `BYPASSRLS` on the runtime identity, and unsafe `SECURITY DEFINER`
|
||||
paths. The SQL-compromise reset probe is recorded as `inconclusive` under E3:
|
||||
changing the GUC after gaining SQL execution demonstrates E3's documented
|
||||
limit and must not be mislabeled a failed E3-A control.
|
||||
|
||||
Every database run requires its own approved target/database/window. It uses
|
||||
one ordinary runtime connection, sets `application_name` to the engagement id,
|
||||
and never uses an owner, superuser or `BYPASSRLS` role for convenience.
|
||||
|
||||
27
docs/noisy-neighbour-runbook.md
Normal file
27
docs/noisy-neighbour-runbook.md
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Noisy-neighbour characterization
|
||||
|
||||
There is no standing authorization or default ceiling for this technique. A
|
||||
run requires a separate operator-approved target, namespace, time window,
|
||||
aggressor allowance, concurrency/resource ceilings, service classes, headroom
|
||||
threshold, and abort thresholds.
|
||||
|
||||
For each co-resident consumer the artifact records a quiet baseline and a
|
||||
loaded sample: latency, error rate, throughput and the declared service class.
|
||||
The aggressor may reach but never exceed its own allowance. The artifact also
|
||||
records whether the governor bound, peak versus ceiling, aggregate headroom,
|
||||
and each neighbour's measured degradation.
|
||||
|
||||
Zero degradation is not the expected assertion on shared infrastructure.
|
||||
Whether measured degradation is acceptable belongs to the responsible owner;
|
||||
whitehat records the observation. A governor that does not bind, an exceeded
|
||||
probe ceiling, missing neighbour samples, or an abort threshold produces a
|
||||
finding/abort rather than a stronger retry.
|
||||
|
||||
The evaluator is calibrated offline with:
|
||||
|
||||
```sh
|
||||
PYTHONPATH=src python3 -m whitehat_security.cli capacity-fixture
|
||||
```
|
||||
|
||||
That command generates no load and is not P1/P2 target evidence.
|
||||
|
||||
69
docs/operator-runbook.md
Normal file
69
docs/operator-runbook.md
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
# Operator runbook
|
||||
|
||||
This runbook does not authorize a target. Read and follow
|
||||
[`rules-of-engagement.md`](rules-of-engagement.md) first.
|
||||
|
||||
## Offline calibration
|
||||
|
||||
The calibration is safe to run without target authorization. It opens no
|
||||
socket and uses only synthetic in-process services created by this repository.
|
||||
|
||||
```sh
|
||||
make check
|
||||
make fixture-evidence
|
||||
```
|
||||
|
||||
Success requires every read/write probe to pass against the enforcing fixture
|
||||
and to produce a finding against the fixture with its tenant predicate removed.
|
||||
`evidence/offline-calibration.json` is calibration evidence, not target
|
||||
assurance.
|
||||
|
||||
## Prepare a target run
|
||||
|
||||
1. Select the target's probe pack and review every route with its owner.
|
||||
2. Copy `engagements/template.json` to a dated record. Resolve every field;
|
||||
placeholders are invalid.
|
||||
3. Record operator approval and a target-owner acknowledgement after approval.
|
||||
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:
|
||||
|
||||
```sh
|
||||
PYTHONPATH=src python3 -m whitehat_security.cli validate-engagement engagements/<record>.json
|
||||
```
|
||||
|
||||
7. Confirm target identity/revision and probe attribution before the first
|
||||
hostile operation. If either is uncertain, abort.
|
||||
|
||||
## Execute
|
||||
|
||||
Execution adapters are target-specific because identity binding is part of
|
||||
the property under test. An adapter must implement the `DifferentialProbe`
|
||||
contract: owner request, attacker request, absent-object reference, fixture
|
||||
markers, and (for writes) a tenant-B state oracle. It must call
|
||||
`Engagement.permits()` immediately before each route and obey the recorded
|
||||
rate/concurrency limit.
|
||||
|
||||
Run owner and absent controls before the attacker request. Keep response bodies
|
||||
only in memory. Persist the observation produced by `execute()`: status,
|
||||
content type, count, schema paths, run-local digest and fixture-match count.
|
||||
|
||||
Stop immediately on any abort condition in the rules. Do not investigate an
|
||||
unexpected response by broadening routes, identities, discovery, or privilege.
|
||||
|
||||
## Close and report
|
||||
|
||||
- Delete only recorded fixtures and verify their absence.
|
||||
- Revoke the lease or record its bounded expiry.
|
||||
- Set the overall outcome to `finding` if any probe finds exposure or mutation;
|
||||
`aborted` on an abort; `inconclusive` when controls or cleanup cannot be
|
||||
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>`.
|
||||
- Schedule the next run from the target's declared cadence.
|
||||
|
||||
No target run is complete until its dated report and risk-nexus delivery are
|
||||
both recorded.
|
||||
|
||||
23
docs/reporting.md
Normal file
23
docs/reporting.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# Reporting contract
|
||||
|
||||
Every target run—pass, finding, inconclusive or abort—uses
|
||||
`schemas/run-report.schema.json`. Reports include authorization and engagement
|
||||
ids, target revision, posture/model, timestamps, sanitized observations,
|
||||
cleanup and credential disposition. They never include response bodies,
|
||||
credentials or severity.
|
||||
|
||||
A finding is routed to `risk-nexus` with supported facts and provenance. A
|
||||
passing report is routed too because its date and target revision define the
|
||||
freshness of the limited assurance. Generate the message body with:
|
||||
|
||||
```sh
|
||||
PYTHONPATH=src python3 -m whitehat_security.cli risk-message evidence/<run>.json
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue