whitehat-security/docs/rules-of-engagement.md

174 lines
7.7 KiB
Markdown
Raw Permalink Normal View History

# Rules of engagement for tenancy evidence
Status: **accepted**
Version: 0.2
Date: 2026-08-18
Owner: NetKingdom / whitehat-security
These rules authorize nothing outside their recorded scope. A probe without a
matching authorization record is prohibited, even if technically possible.
## 1. Authorization classes
| Target class | Required authorization |
| --- | --- |
| Offline known-good/known-bad fixtures created by this repo | This reviewed document |
| Estate build environment, non-destructive API differential probe | Standing estate authorization plus a dated engagement record naming the target owner |
| Any live Kubernetes workload, database credential, recovery or saturation probe | Separate operator approval for the named target, namespace, window and technique |
| Production | Production-specific written authorization; build-mode consent never carries over |
| Infrastructure not owned by the estate | Written authorization from its responsible party, per engagement, before any packet |
Public reachability, a commercial relationship, and an assumption that an
owner would agree are never authorization.
## 2. Engagement record
Every run begins with a committed or operator-approved record containing:
- engagement id, authorizer, approval timestamp and expiry
- target service, responsible repo/party, environment and namespace
- source location and network position of the probe
- exact API routes or database names in scope
- tenant fixtures and object identifiers created for the run
- credential lane, audience, role and maximum TTL (never the value)
- permitted techniques, prohibited techniques and concurrency/rate ceilings
- start/end window, operator contact and abort contact
- posture axis/claim and attacker model being tested
- finding destination in `risk-nexus`
An expired, incomplete or mismatched record fails closed. Discovery of an
adjacent target is recorded and not followed.
## 3. Initial authorized target envelope
After personal approval of this document, offline fixtures may be built. No
live target is pre-authorized by this section. The first proposed live
engagements are:
- `tenant-engine`: HTTP read/write differential using two disposable tenants
- `audit-core`: HTTP append/read differential using two disposable tenants
- `flex-auth`: decision differential for relationship inheritance across two
disposable tenants
Each still needs its own dated engagement record and target-owner
acknowledgement. `databases/platform-pg` and `databases/apps-pg` are not in the
initial API-probe envelope; RLS, recovery and saturation work require separate
operator windows.
## 4. Hard prohibitions
- no destructive operation against data not created for the engagement
- no collection or exfiltration of real tenant row values; record only count,
schema shape, stable test-fixture ids and salted/one-run digests
- no denial-of-service, saturation, lock exhaustion, connection exhaustion or
large payload against shared substrate outside an explicitly approved window
- no superuser, `BYPASSRLS`, owner credential or standing privilege unless the
specific attacker model is testing detection of that misgrant
- no credential reuse outside its named audience/target and no credential
value in Git, evidence, State Hub, logs or chat
- no persistence, implant, account creation, lateral movement, vulnerability
chaining or follow-on discovery beyond the recorded technique
- no weakening alerting, backup, audit or retention controls to make a test pass
## 5. Credentials and attribution
Credentials are short-lived and obtained through the sanctioned custody lane.
The engagement records only the catalog/role reference, TTL and lease id if it
is safe metadata. The facility holds the same privilege as the modelled
workload—never broader privilege for convenience.
HTTP probes send `User-Agent: whitehat-security/<engagement-id>` and a stable
correlation id. Database probes set `application_name` to the engagement id.
The operator must be able to identify and terminate a probe from access logs or
`pg_stat_activity` without asking whether it is hostile traffic.
## 6. Rate, concurrency and data controls
API differential runs default to one in-flight request and at most 60 requests
per minute. A target owner may set a lower number. Test data uses two newly
created disposable tenants and deterministic synthetic values. Responses are
evaluated in memory; evidence stores status, count, content type, schema keys
and a salted run-local digest—not bodies.
Database conformance defaults to one connection. Noisy-neighbour work has no
default: its connection/query/CPU ceiling must be written in the individual
operator-approved window.
## 7. Abort and cleanup
Any of these immediately aborts a run:
- target latency/error rate crosses the engagement threshold
- a response appears to contain non-fixture tenant data
- scope, authorization, credential audience or target identity is uncertain
- operator/target owner requests stop
- audit attribution is absent
- an unexpected adjacent system responds
The runner stops issuing work, closes HTTP/database sessions, revokes or lets
the bounded lease expire, and records the abort without attempting further
diagnosis. Cleanup deletes only fixtures whose ids are in the engagement
record. If cleanup cannot be proven, it becomes a finding; the runner does not
broaden privilege to force it.
## 8. Evidence and reporting
Every attempted run—pass, fail or abort—records:
- authorization and engagement ids
- target revision/digest where observable without privilege escalation
- start/end timestamps and attacker model
- attempted operation count and response-shape comparison
- outcome: `pass`, `finding`, `inconclusive`, or `aborted`
- cleanup and credential-revocation outcome
- the statement: “Pass means only that the attacks attempted in this run did
not work; it is not proof that the tenant boundary always holds.”
Findings route unchanged to `risk-nexus`; this repo assigns no severity and
does not fix the target.
## 9. Change control
Probe logic is security-sensitive. A change that makes a previously failing
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. 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`, `fixture-e3` and `fixture-capacity` are in-process classes
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. Live `e3` additionally names the
database and uses one ordinary runtime role with no `BYPASSRLS`. Live
`capacity` additionally names an aggressor ceiling and a substrate window.
Recovery and destructive techniques remain outside this 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
Approval date: **2026-08-21**
Approved scope: these rules are accepted as the operating boundary for
`whitehat-security`. This approval permits documentation and non-networked
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.