Compare commits

...

3 commits

Author SHA1 Message Date
348738ba73 Register whitehat-security and align operating boundaries
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a0260c-4067-7052-9647-ad000d576e38
2026-08-21 22:52:37 +02:00
0ce9f44ff9 NetKingdom owns this; and a targeting rule, because scope widened
Operator decision: whitehat is a NetKingdom facility, framed offensively -
offence is how you find out, and a control is believed until someone tries it.
Our own estate is one target among those we choose, not the only one.

I had argued for the-custodian on independence grounds. The counter-argument is
better: offensive security is security work and belongs with the security repo.
The residual tension is real and recorded rather than argued away - NetKingdom
now owns both the Tenancy Posture framework and the facility that tests
conformance to it, which is NetKingdom assessing NetKingdom. The mitigation is
that findings leave for risk-nexus under separate ownership rather than being
resolved in place. Proportionate, not perfect, and worth revisiting if
conformance findings start getting quietly closed.

The reframe changes what this repo must guard against, and that is the
substantial part of this commit. A facility that can be pointed at
infrastructure we do not own is the single thing that could turn this repo from
an asset into a liability, so the targeting rule is structural rather than
cultural.

No target without recorded authorization from whoever is responsible for it.
Own estate in build mode has standing authorization; production needs its own,
because the blast radius differs and so does the decision; anything we do not
own needs written per-engagement authorization recorded here before a packet is
sent.

Three non-authorizations written down because each is a way teams talk
themselves into it: a commercial relationship with the target, the target being
publicly reachable, and believing the owner would obviously be fine with it.
Unauthorized probing is criminal in most jurisdictions regardless of intent,
and a white-hat facility that gets this wrong is an attacker with better
paperwork.

Two consequences. The authorization record is part of the finding - a report
that cannot name what it ran under is not a finding, it is an incident. And
scope creep during an engagement is prohibited: a probe that discovers an
adjacent system stops at the boundary, because following the interesting thing
is how an authorized test becomes an unauthorized one.

Findings routing now forks. Our estate goes to risk-nexus and on to the owning
repo. Any other target goes to that infrastructure's responsible party on the
engagement's agreed terms, with risk-nexus still recording that it happened.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 18:01:01 +02:00
77f574f50e Seed INTENT and WP-0001: adversarial evidence facility
Answers the Tenancy Posture question that has been unowned since the framework
was drafted - who verifies a consumer's tenant boundary. Two repos were asked
and both correctly declined as fleet-scope work. The work needed a home.

Independence is the load-bearing property, not a nicety. rapp-postgres wrote
fifteen probes against its own isolation model and found four real defects,
which is good work and still the author checking their own homework. The probes
worth having are the ones the author would not think to write, because the
assumption that produced the defect produces the blind spot.

That argues against NetKingdom owning this even though it owns the security
canon: a facility verifying conformance to a framework must not report to the
repo that owns the framework, or self-grading just moves up a level. Proposed
owner is the-custodian, consistent with policy and risk. Needs confirmation.

Two things stated because overclaiming is the failure this estate keeps
catching in itself. "Automated" has a ceiling - the highest-impact cross-tenant
findings need someone who understands what the data means, since a response can
be well-formed, 200, fast, and contain another tenant's rows; so automate the
reproducible and flag the irreducible for dated review. And a passing suite
proves the attacks we thought of did not work, not that the boundary holds. The
gap between those sentences is where breaches live.

WP-0001 gates everything behind rules of engagement, because an automated
facility probing systems without written scope is indistinguishable from the
threat it models. No standing privilege, no BYPASSRLS, no superuser - an
attacker would not have them and a probe holding them proves nothing. No
exfiltration of real tenant data even as proof; a count and a schema shape are
proof enough. And no saturation probing outside a declared window, because with
a six-consumer connection ceiling that is an outage for every co-resident.

T04 exists because a probe that has only ever passed is not evidence. Every
probe must be shown failing against a known-bad fixture before it is trusted
passing - the same discipline rapp-postgres used when it verified its drift
check by deliberately re-pinning to a bad digest.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 16:41:36 +02:00
9 changed files with 869 additions and 1 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
.repo-manager/

29
.repo-classification.yaml Normal file
View file

@ -0,0 +1,29 @@
repo_classification:
standard: Repo Classification Standard
version: "1.0"
classified_at: "2026-08-21"
classified_by: codex
category: tooling
domain: infotech
secondary_domains: []
capability_tags:
- access-control
- evidence
- traceability
- compliance
- risk
- audit
- observability
- operations
business_stake:
- technology
- operations
- legal
- automation
business_mechanics:
- control
- operation
- adaptation
notes: >-
NetKingdom offensive-security tooling that produces independently operated,
authorization-bound adversarial evidence and routes findings to risk-nexus.

123
AGENTS.md Normal file
View file

@ -0,0 +1,123 @@
# whitehat-security — Agent instructions
## Repository identity
**Purpose:** Authorization-bound offensive-security tooling that produces
adversarial evidence about security claims and routes findings to the
responsible party.
**Owner:** NetKingdom
**Domain:** infotech
**Repo slug:** `whitehat-security`
**Topic ID:** `cee7bedf-2b48-46ef-8601-006474f2ad7a`
**Workplan prefix:** `WHITEHAT-WP-`
## Orient before working
1. Read `INTENT.md` and `SCOPE.md`.
2. Read `docs/rules-of-engagement.md` before designing or executing probes.
3. Read `.custodian-brief.md` when present and scan `workplans/`.
4. Check the repository inbox:
`curl -s "http://127.0.0.1:8000/messages/?to_agent=whitehat-security&unread_only=true"`
5. Check the worktree before editing; preserve unrelated user changes.
## Non-negotiable safety boundary
- The rules of engagement are pending personal operator approval. Until they
are approved, perform only documentation work and non-networked fixture
design. Send no packets to a target.
- Even after approval, no live run starts without a dated engagement record
naming authorization, target owner, exact scope, window, technique,
credentials, rate/concurrency ceiling, abort contact and finding destination.
- Never broaden scope after discovery. Record an adjacent system and stop.
- Never collect real tenant row values or credentials as evidence.
- Never use superuser, owner or `BYPASSRLS` privilege for convenience.
- Never perform destructive, persistence, lateral-movement or denial-of-service
activity outside an explicitly authorized technique and window.
- A pass means only that the attempted attacks did not work. Every probe must
first fail against a known-bad fixture.
- This repository finds and reports; it does not fix targets or assign severity.
## State Hub integration
State Hub is the coordination index; repository files remain authoritative.
| Context | URL |
| --- | --- |
| Local workstation | `http://127.0.0.1:8000` |
| Remote tunnel | `http://127.0.0.1:18000` |
| Optional edge relay | `http://127.0.0.1:18080` |
Use `/state/health` for health checks. After changing workplan files, run:
`statehub fix-consistency`
If the command reports C-06/C-11 because this host is not the identifier
registrar, do not set `STATEHUB_REGISTRAR` manually. Commit and push the
file-backed work, then use the scoped fallback once:
`uv run --project ~/repo-manager rmgr registrar-reconcile --path . --confirm-primary --push`
At session close, ensure file task statuses reflect reality and record
significant progress in State Hub. Actionable residuals from a finished
workplan must become live work records rather than remaining only in prose.
## Credential routing
Before requesting credentials, API keys, SSH access or database passwords:
`warden route find "<describe the need>" --json`
`ops-warden` issues SSH certificates only. Other secret material belongs to the
custody route returned by `warden`. Never put credentials in Git, State Hub,
workplans, logs, evidence or chat.
## Workplan convention
Workplans live at `workplans/WHITEHAT-WP-NNNN-<slug>.md`. Finished plans may
move to
`workplans/archived/YYMMDD-WHITEHAT-WP-NNNN-<slug>.md` without changing their
frontmatter ID.
Required frontmatter:
```yaml
---
id: WHITEHAT-WP-NNNN
type: workplan
title: "..."
domain: infotech
repo: whitehat-security
status: proposed | ready | active | blocked | backlog | finished | archived
owner: ...
topic_slug: ...
created: "YYYY-MM-DD"
updated: "YYYY-MM-DD"
state_hub_workstream_id: "<uuid>" # written by reconciliation; do not edit
---
```
Each task uses one machine-readable block:
````markdown
```task
id: WHITEHAT-WP-NNNN-T01
status: wait | todo | progress | done | cancel
priority: high | medium | low
state_hub_task_id: "<uuid>" # written by reconciliation; do not edit
```
````
Use `proposed` for drafts, `ready` after review, `active` once work has begun,
and `finished` only when all required work is complete or residuals have live
owners. Task progression is `todo``progress``done`; `wait` is for work
that cannot currently proceed and `cancel` is terminal.
Small, low-risk work completed directly may use
`workplans/ADHOC-YYYY-MM-DD.md`. Anything requiring analysis, approval,
dependencies or multiple phases needs a normal workplan.
<!-- REPO-AGENTS-EXTENSIONS -->
<!-- Add repository-specific instructions below this marker. -->

193
INTENT.md Normal file
View file

@ -0,0 +1,193 @@
# INTENT — whitehat-security
## Why this repo exists
`whitehat-security` is **NetKingdom's offensive security facility**. It attacks
IT infrastructure and surfaces we choose to point it at — our own estate among
them — and reports what it finds to whoever is responsible for fixing it.
The discipline is offensive because offence is how you find out. A control is
believed until someone tries it. Everything else in the estate's security work
describes what should be true; this repo establishes what is.
It was seeded to close a specific gap, which remains its first job. NetKingdom's *Tenancy Posture* standard
splits evidence into two kinds: **mechanical** — a structural assertion a
machine can make, which belongs in each repo's own CI — and **adversarial**
a semantic claim that requires setting up hostile conditions and observing what
happens. Every repo can produce the first. **No repo can honestly produce the
second about itself**, and the framework's most severe open question has been
sitting unowned for exactly that reason: who verifies that a consumer's tenant
boundary actually holds.
Two repos were asked and both correctly declined, on the grounds that a service
which grows fleet responsibilities because it happened to be nearby is how
boundaries erode. They were right. The work needed a home of its own.
## Owner: NetKingdom
`whitehat-security` is a NetKingdom capability, alongside the IAM Profile,
SSO/MFA and the canonical security architecture. Offensive security is security
work, and it belongs with the repo that owns security.
**Separation of concerns still applies, one level down.** A repo testing its own
boundary grades its own homework. `rapp-postgres` wrote fifteen adversarial
probes against its own isolation model and found four real defects in its own
provisioning SQL — good work, and still the author checking their own work. The
probes most worth having are the ones an author would not think to write,
because the assumption that produced the defect produces the blind spot. So:
- This facility does not take a repo's declared posture as true. It tests it.
- It does not decide how bad its own findings are. Severity and disclosure are
`risk-nexus`'s, which is `the-custodian`'s, not NetKingdom's.
**One residual tension, recorded rather than argued away.** NetKingdom owns the
Tenancy Posture framework *and* this facility. When whitehat tests conformance
to that framework, NetKingdom is assessing NetKingdom. The mitigation is the
routing above: findings leave for `risk-nexus` under separate ownership rather
than being resolved inside NetKingdom. That is proportionate, not perfect, and
worth revisiting if conformance findings ever start getting quietly closed.
## What it owns
- **Adversarial evidence artifacts.** The tests that produce the evidence the
Tenancy Posture ladders require but no repo can self-certify:
cross-tenant read and write attempts (E2), row-level-security conformance
under attack (E3), per-tenant credential confinement (E4),
noisy-neighbour characterisation (P1/P2), erasure verification (R4).
- **The attacker model.** What an adversary is assumed to hold at each level —
a leaked runtime credential, SQL execution, a compromised process — written
down, so a probe can be judged against a threat rather than against taste.
- **Cadence.** How often each probe runs. This is not a scheduling detail: for
any control whose guarantee is *detection rather than prevention*, the
interval between runs **is** the exposure window. `rapp-postgres` ADR-0003
says so explicitly and leaves the number to be set here.
- **Differential testing between tenant contexts.** Running the same request as
two tenants and comparing responses is the mechanically reproducible core of
cross-tenant testing, and it is this repo's principal technique.
- **Target selection and authorization.** Which infrastructure or surface the
facility is pointed at, and the authorization that permits it. See the
targeting rule below — this is the repo's most important control.
- **Rules of engagement.** What may be probed, where, with what credentials,
and what must never be done. An automated facility without this is
indistinguishable from the threat it models.
- **Findings delivery to the responsible party.** For our own estate that is
`risk-nexus`, which routes to the owning repo. For any other target it is
whoever is responsible for that infrastructure, on the terms agreed in the
engagement.
## What it does not own
- **Fixing anything.** A finding routes through `risk-nexus` to the repo that
owns the defect. A security facility that fixes things becomes a second
engineering team with no boundary and no reviewer.
- **Severity, disclosure and timing.** `risk-nexus`. This repo says what is
true; that repo says how much it matters and who hears about it.
- **Mechanical CI evidence.** Schema assertions, unit tests and provisioning
checks stay with the repo that owns the code. This repo does not take over
anyone's test suite.
- **Deciding what the security model should be.** NetKingdom's canon says what
good looks like. This repo says whether we have it.
- **Blocking delivery.** In build mode a finding is information. If that
changes it will be a recorded decision, not a habit that accretes.
## The targeting rule
The facility can be pointed at infrastructure we do not own. That is the point
of it, and it is also the single thing that could turn this repo from an asset
into a liability, so the rule is structural rather than cultural.
**No target is probed without recorded authorization from whoever is
responsible for it. No exceptions.**
- **Our own estate, build mode** — standing estate authorization is necessary
but not sufficient. Every live run still needs the dated engagement record,
target-owner acknowledgement and technique-specific scope required by the
rules of engagement. No live target is pre-authorized by this intent.
- **Our own estate, production** — a separate recorded authorization. Build-mode
standing consent does not carry across; the blast radius is different and so
is the decision.
- **Anything we do not own** — written authorization from the responsible party,
per engagement, recorded in this repo *before a packet is sent*. Scope,
window, permitted techniques, and named contacts on both sides.
Three things that do **not** constitute authorization, written down because
each is a way teams talk themselves into it: a commercial relationship with the
target; the target being publicly reachable; and a belief that the owner "would
obviously be fine with it". Unauthorized probing may be unlawful regardless of
intent, and a white-hat facility that gets this wrong is simply an attacker
with better paperwork.
**The authorization record is part of the finding.** A report that cannot name
the authorization it ran under is not a finding — it is an incident, and it
gets treated as one.
**Scope creep during an engagement is prohibited.** A probe that discovers an
adjacent system stops at the boundary and reports what it saw. Following the
interesting thing is exactly how an authorized test becomes an unauthorized
one.
## Honest limits on "automated"
The word in the repo's description is *automated*, and it must not be oversold
— overclaiming is the failure this estate keeps catching in itself.
External testing practice is consistent that the highest-impact cross-tenant
findings concentrate in access control, business logic and tenant isolation:
precisely the categories that need someone who understands what the data
*means* to recognise that a response is wrong. A response can be well-formed,
200, fast, and contain another tenant's rows.
So:
- **Automate the reproducible.** Structural conformance, differential responses
between tenant contexts, credential confinement, resource saturation. This is
most of the surface and it should run without anyone remembering to run it.
- **Flag the irreducible.** Where a finding requires semantic judgement, the
facility's job is to set up the conditions, capture the evidence, and mark it
for review with a date — not to return green.
- **A passing suite is not proof of isolation.** It is proof that the attacks
we thought of did not work. State it that way in every report, because the
gap between those two sentences is where breaches live.
## The failure this repo must avoid
**A probe that has only ever passed is not evidence.** `rapp-postgres` verified
its own drift check by deliberately breaking the thing it watched and
confirming the check failed. Every probe here inherits that obligation: it must
be shown to fail against a known-bad fixture before it is trusted against a
real system.
The second failure is subtler. A probe that starts passing because it was
weakened is worse than a deleted probe, because it reports safety. Probe
changes are therefore reviewed as security changes, and a probe that begins
passing after a change to *itself* rather than to the system is treated as a
finding.
## Relationship to the rest of the estate
```
whitehat-security → risk-nexus → policy-nexus
finds triages publishes
(severity, (permanent,
disclosure) addressable)
```
For our own estate it reads posture claims and canon from the repos that own
them, attacks the running systems those claims describe, and hands findings to
`risk-nexus`. For any other target, findings go to that infrastructure's
responsible party on the engagement's agreed terms; `risk-nexus` still records
that the engagement happened and what it means for us.
It publishes nothing directly and fixes nothing, in either case.
The first work is already specified and waiting: the E2 cross-tenant evidence
artifact, which is Tenancy Posture's highest-severity unowned gap, and the
noisy-neighbour characterisation, which the framework had to reword once
already because its first draft asserted something shared infrastructure cannot
provide.
## What good looks like
The estate knows which of its security claims have been tested, when, and by
what attacker model — and can tell the difference between a property that has
been verified and one that has merely never failed.

View file

@ -1,3 +1,26 @@
# whitehat-security
Automated white hat it-security, pen-testing and isolation-probing.
NetKingdom's offensive security facility. Automated white hat IT-security,
pen-testing and isolation-probing — pointed at infrastructure we choose,
including our own.
The estate's **adversarial evidence facility**: it attacks our own systems, on
a schedule, to find out whether the security properties they claim are actually
true.
It exists because a repo testing its own boundary grades its own homework. The
probes most worth having are the ones an author would not think to write.
- **Independent in operation.** It does not take a declared posture as true.
NetKingdom owns both the security canon and this facility, so findings leave
through `risk-nexus` under separate ownership rather than being resolved here.
- **It finds; it does not fix.** Findings route to `risk-nexus`, which owns
severity and disclosure. The repo that owns the defect owns the repair.
- **A pass means the attacks we tried did not work** — not that the boundary
holds. Reports say so.
- Intent: [`INTENT.md`](INTENT.md)
- Scope: [`SCOPE.md`](SCOPE.md)
- Workplans: [`workplans/`](workplans/)
- Rules of engagement (pending operator approval):
[`docs/rules-of-engagement.md`](docs/rules-of-engagement.md)

87
SCOPE.md Normal file
View file

@ -0,0 +1,87 @@
# Scope
## One-liner
`whitehat-security` is NetKingdom's authorization-bound offensive-security
tooling for producing adversarial evidence about security claims.
## Core idea
The repository turns stated security properties into dated, reproducible attack
attempts. It remains separate from the systems it tests, reports findings
without grading their severity, and never treats a passing probe as proof that a
boundary always holds.
## In scope
- Attacker models for tenant isolation, credential confinement, noisy-neighbour
behavior and erasure verification.
- Differential probes that compare behavior across controlled tenant contexts.
- Known-bad and known-good fixtures that demonstrate every probe can fail.
- Rules of engagement, target authorization, engagement records, abort
controls and evidence minimization.
- Probe cadence and the resulting assurance/exposure window.
- Delivery of findings and passing-run evidence to `risk-nexus`.
## Out of scope
- Fixing defects in target repositories.
- Assigning severity, disclosure policy or remediation deadlines.
- Replacing mechanical checks owned by a target repository's CI.
- Defining the estate's security model or publishing permanent policy.
- Probing any target without the authorization and engagement records required
by [the rules of engagement](docs/rules-of-engagement.md).
- Blocking build-mode delivery without a separately recorded decision.
## Safety invariants
- Until the rules of engagement receive personal operator approval, only
documentation and non-networked fixture design may proceed.
- No live target is authorized by this scope document.
- Every live run names its authorization, target, owner, window, technique,
credential lane, rate ceiling, abort contact and finding destination.
- A probe stops at the recorded boundary and never follows an adjacent system.
- Evidence records response shape and counts, never real tenant row values or
credentials.
- Findings leave this repository; repairs do not enter it.
## Relevant when
- A service claims a Tenancy Posture evidence level that requires adversarial
rather than mechanical evidence.
- A boundary must be tested using a leaked runtime credential or hostile tenant
context.
- The estate needs to know when a probe last ran, what attacker it modeled, and
whether it was proven against a known-bad fixture.
## Not relevant when
- A repository needs unit, schema or provisioning tests for its own code.
- A finding needs triage, severity or disclosure handling; use `risk-nexus`.
- Permanent policy needs publication; use `policy-nexus`.
- The desired activity falls outside an approved engagement boundary.
## Current state
- Repository status: active.
- Active plan: `WHITEHAT-WP-0001`.
- `T01` is in progress: the rules of engagement are drafted and awaiting
personal operator approval.
- No live probe traffic is authorized yet.
- `T02` through `T07` remain gated by `T01`.
## Relationships
- Owner and security canon: `net-kingdom`.
- Finding intake, severity and disclosure: `risk-nexus`.
- Permanent publication: `policy-nexus`.
- Initial proposed target owners: `tenant-engine`, `audit-core` and
`flex-auth`.
## Getting oriented
1. Read [`INTENT.md`](INTENT.md) for the durable purpose and ownership model.
2. Read [the rules of engagement](docs/rules-of-engagement.md) before any probe
design or execution.
3. Read [`WHITEHAT-WP-0001`](workplans/WHITEHAT-WP-0001-cross-tenant-evidence.md)
for active tasks and sequencing.

18
WORK-RECORDS.md Normal file
View file

@ -0,0 +1,18 @@
# Work Records — whitehat-security
> Generated by `statehub fix-consistency` (CUST-WP-0061-T04, work-record
> stage 3). Do not edit by hand — edit the source file/block listed for
> each record and re-run fix-consistency to refresh this index. Archived
> workplans are omitted; closed decisions/intakes/engagements stay listed
> so recently-resolved work is still visible. [auto]
| Kind | ID | Status | Lane | Source |
| --- | --- | --- | --- | --- |
| workplan | WHITEHAT-WP-0001 | active | — | workplans/WHITEHAT-WP-0001-cross-tenant-evidence.md |
| task | WHITEHAT-WP-0001-T01 | progress | — | workplans/WHITEHAT-WP-0001-cross-tenant-evidence.md |
| task | WHITEHAT-WP-0001-T02 | wait | — | workplans/WHITEHAT-WP-0001-cross-tenant-evidence.md |
| task | WHITEHAT-WP-0001-T03 | wait | — | workplans/WHITEHAT-WP-0001-cross-tenant-evidence.md |
| task | WHITEHAT-WP-0001-T04 | wait | — | workplans/WHITEHAT-WP-0001-cross-tenant-evidence.md |
| task | WHITEHAT-WP-0001-T05 | wait | — | workplans/WHITEHAT-WP-0001-cross-tenant-evidence.md |
| task | WHITEHAT-WP-0001-T06 | wait | — | workplans/WHITEHAT-WP-0001-cross-tenant-evidence.md |
| task | WHITEHAT-WP-0001-T07 | wait | — | workplans/WHITEHAT-WP-0001-cross-tenant-evidence.md |

145
docs/rules-of-engagement.md Normal file
View file

@ -0,0 +1,145 @@
# Rules of engagement for tenancy evidence
Status: **pending personal operator approval**
Version: 0.1
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. Approval
Personal operator approval is still required. Record approver, date and scope
in this section or an immutable linked decision before changing the status to
accepted. Until then, only documentation and non-networked test-fixture design
may proceed; no target packets are authorized by this draft.

View file

@ -0,0 +1,249 @@
---
id: WHITEHAT-WP-0001
type: workplan
title: "Produce the adversarial evidence the Tenancy Posture ladders require"
domain: infotech
repo: whitehat-security
status: active
owner: net-kingdom
topic_slug: whitehat-security
created: "2026-08-17"
updated: "2026-08-21"
---
# WHITEHAT-WP-0001 — cross-tenant evidence
## Goal
Produce, on a schedule, the adversarial evidence artifacts that NetKingdom's
*Tenancy Posture* standard requires and no repo can honestly produce about
itself — starting with the one the framework calls its highest-severity gap.
Done means: a service claiming `E2` has been attacked as an adversary holding
its runtime credential, the attempt is recorded with a date and an attacker
model, and a failure routes to `risk-nexus` rather than to a log nobody reads.
## The forcing case
*Tenancy Posture* open question 3 has been unowned since the framework was
drafted. What it calls a tenant-boundary failure the security industry calls
**Broken Object Level Authorization** — OWASP API1, top of the API Security Top
10 since that list launched, and the most commonly exploited API vulnerability
in published assessments.
The estate has no coverage for it. `rapp-postgres` runs fifteen adversarial
probes and every one targets the *consumer* boundary — service versus service.
None targets the tenant boundary *inside* a consumer, which is where the
framework says the residual risk actually lives.
## Rules of engagement — T01, and nothing else starts first
An automated facility that probes systems without written scope is
indistinguishable from the threat it models. This is the gating task and it is
not paperwork.
- **Target authorization**, the control that matters most now the facility is
scoped to any surface we choose rather than only our own. No target without a
recorded authorization from its responsible party. Our estate in build mode
has standing authorization only as a prerequisite: every live run still
needs the dated engagement record and target-owner acknowledgement defined in
the rules of engagement. Production needs its own authorization; anything we
do not own needs written per-engagement authorization recorded here before a
packet is sent. A commercial relationship, public reachability, and "they
would obviously be fine with it" are each explicitly not authorization.
- **Scope.** Which systems, which namespaces, which credentials — and a hard
stop at the engagement boundary. A probe that discovers an adjacent system
reports what it saw and does not follow it.
- **Prohibited actions**, stated as hard rules rather than intentions:
no destructive operations against data the estate did not create for the
test; no exfiltration of real tenant data even as proof of a finding —
a count and a schema shape are proof enough; no denial-of-service against a
shared substrate outside a declared window, because the connection ceiling
means a saturation probe is an outage for every co-resident.
- **Credentials.** The facility holds leased credentials like any workload,
through the sanctioned OpenBao lane. It gets no standing privilege, and
notably **no `BYPASSRLS` and no superuser** — an attacker would not have them
and a probe holding them proves nothing.
- **Attribution.** Every probe connection is identifiable as a probe in
`pg_stat_activity` and in logs, so an operator investigating an anomaly can
tell us from a real adversary in seconds.
- **Abort.** How a run is stopped, by whom, and what state it leaves behind.
**Output:** `docs/rules-of-engagement.md`, reviewed by the operator personally.
This is exactly the class of thing `risk-nexus`'s escalation duty exists for.
## Tasks
### T01 — Rules of engagement
As above. Gates everything.
```task
id: WHITEHAT-WP-0001-T01
status: progress
priority: high
```
Drafted in `docs/rules-of-engagement.md` on 2026-08-18 with authorization
classes, per-run records, initial target envelope, hard prohibitions,
credential/attribution rules, rate defaults, abort/cleanup and evidence
schema. It authorizes no live traffic until the operator personally approves
§10. T01 remains progress and continues to gate every later task.
### T02 — The attacker model per axis
```task
id: WHITEHAT-WP-0001-T02
status: wait
priority: high
```
What the adversary is assumed to hold, so a probe is judged against a threat
rather than against taste. Drawn from *Tenancy Posture* §4.3, which already
distinguishes them:
| Axis | Adversary holds | Probe answers |
|---|---|---|
| E1/E2 | A legitimate runtime credential and the ability to make ordinary requests as tenant A | Can it reach tenant B's rows? |
| E3 | The above, plus SQL execution on the connection | Can it re-`SET` the tenant GUC and read across? |
| E4 | A leaked per-tenant credential | Can it address another tenant's substrate at all? |
| P1/P2 | A co-resident consumer behaving badly within its own allowance | What degradation do neighbours experience? |
| R | A copy of a backup taken before an erasure | Is the erased data still readable? |
**Output:** `docs/attacker-model.md`. Note that the E3 row exists because the
framework corrected itself: E3 stops accident, not compromise, and a probe that
only tested accident would report a strength E3 does not have.
### T03 — Differential cross-tenant harness (the E2 artifact)
```task
id: WHITEHAT-WP-0001-T03
status: wait
priority: high
```
The core technique: run the same request as two tenants and compare.
- Provision two disposable tenants against a target service.
- Exercise its surface as tenant A; attempt every object identifier observed
from tenant B's context.
- Assert: B receives a denial or an empty result. **A well-formed 200
containing A's data is the finding**, and the harness must be built to notice
that rather than to notice errors — both of this estate's real regressions
produced ordinary-looking responses, a 403 and a 404, and nothing alerted.
- Capture evidence as a count and a schema shape, never as tenant data (T01).
**Acceptance:** run against `tenant-engine` and `audit-core`, both of which
currently claim `E2`. The artifact is the run record, not a green tick.
### T04 — Prove the probes fail
```task
id: WHITEHAT-WP-0001-T04
status: wait
priority: high
```
A probe that has only ever passed is not evidence.
Build known-bad fixtures — a service with a deliberately missing tenant
predicate — and confirm each probe fails against them. `rapp-postgres` verified
its drift check this way, by re-pinning to a bad digest and confirming exit 1;
the same discipline applies here and is not optional.
**Acceptance:** every probe in T03 demonstrated failing before any of them is
trusted passing.
### T05 — RLS conformance under attack (the E3 artifact)
```task
id: WHITEHAT-WP-0001-T05
status: wait
priority: medium
```
`rapp-postgres` ADR-0003 supplies an `rls_conformance` view and a template, and
states plainly that the platform's guarantee is **detection, not prevention**
a table created by a later migration ships without a policy until something
notices. This repo is that something.
- Query the conformance view on a cadence; any row is a finding.
- Attack what the view cannot see: a session that sets no GUC must read
nothing; a session with another tenant's value must see nothing; an insert
attributed to another tenant must be refused.
- Attempt the documented bypasses: a `SECURITY DEFINER` function owned by the
table owner, and a role holding `BYPASSRLS`.
**Cadence is the deliverable here, not a detail.** For a detection-based
control the interval between runs *is* the exposure window, and ADR-0003 leaves
the number to this repo. Set it, and state the resulting window in the record.
### T06 — Noisy-neighbour characterisation (the P1/P2 artifact)
```task
id: WHITEHAT-WP-0001-T06
status: wait
priority: medium
```
The framework had to reword this artifact once already: its first draft
required proof that a saturating consumer "does not breach" another's
allowance, which shared infrastructure cannot provide.
What is achievable and therefore what this produces: a recorded baseline of
per-consumer resource usage; a run in which one consumer saturates its declared
allowance; evidence that the governance controls **bind**; and the degradation
co-residents experience, **measured and written down** rather than asserted
acceptable.
Runs inside a declared window per T01 — on a single-node rail with a six-
consumer connection ceiling, a saturation probe is an outage if run carelessly.
### T07 — Reporting into risk-nexus
```task
id: WHITEHAT-WP-0001-T07
status: wait
priority: medium
```
Findings leave this repo in one direction. A run produces: what was attempted,
under which attacker model, when, against which posture claim, and the outcome.
It carries no severity — that is `risk-nexus`'s.
A **passing** run is also reported. "The attacks we thought of did not work" is
the honest claim, and recording it dated is what lets anyone see how stale the
assurance has become.
## Sequencing
T01 gates all. T02 shapes T03/T05/T06. T04 gates trusting any of them. T07 can
follow T03.
## Risks
**The facility becomes the threat.** Mitigated by T01, and by holding no
standing privilege.
**Probes weaken silently.** A probe that starts passing after a change to
itself rather than to the system is a finding, not a fix. Probe changes are
reviewed as security changes.
**Green is mistaken for safe.** Every report states that a pass means the
attacks attempted did not work, not that the boundary holds.
**It drifts into fixing things.** The boundary in INTENT is load-bearing:
findings route out, work does not come in.
## Open questions
1. **Owner: NetKingdom** — settled 2026-08-17. Offensive security is security
work. The residual tension (NetKingdom owning both the Tenancy Posture
framework and the facility that tests conformance to it) is mitigated by
findings routing out to `risk-nexus` under separate ownership, and is
recorded in INTENT rather than argued away.
2. **Where probes run from.** In-cluster gives realistic network position;
outside gives independence from the substrate under test. Probably both,
eventually; pick one to start.
3. **Does a service get told it is being probed?** Announced runs are easier to
operate; unannounced ones test the alerting too. Build mode probably
announced, production probably not — which is itself a T01 decision.