Answers zone-engine ZONE-WP-0001-T01.
Decision 5.6 — enforcement stance is a sibling standard, not an axis. The six
ladders are monotone and the whole current/target/guard machinery depends on it;
enforcement stance is not (ADR-0006 is the finding that the top rung is wrong for
the SSH lane). And this framework is descriptive: an accurately declared exempt
would be conformant and exempt. Membership is declared, stance belongs to the
control owner. Zone membership rides tenancy.yaml under a reserved zones: key so
the estate keeps one declaration surface; the schema permits it, unconstrained.
Decisions 8.4.1/8.4.2 — 'substrate location is not evidence' stated once instead
of three repo-local slogans, and the reef/P/V gap recorded as this document's
defect rather than zone-engine's scope. NK-WP-0027 takes it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
T02 done. Deployed user-engine digest c501aeb2 reads the projected flex-auth
token per decision (verified in the running container); flex-auth-user-engine
138aa347 serves with caller-auth enforce. Probes: valid 200
decision:d9aef25f08e17b84, missing token 401, wrong-system 403.
Closes manifest drift: runtime.yaml pinned e3b5f65b, the digest T01 warned
against, while the cluster ran c501aeb2. Re-applying it would have rolled the
portal back to an image that cannot authenticate to a PDP now in enforce.
kubectl diff is now empty.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
audit-core, railiance-platform and flex-auth all reviewed. Every posture I
guessed was too generous, on every repo that has now self-reported.
Two of my statements about other repos were wrong as fact in canon. flex-auth
does not call tenant-engine synchronously on the authorization path - the
adapter is built and has no non-test caller, which is also why they cannot
reach I3. And I justified A4 partly as ending the copying of action strings
between repos; AuthZEN standardises the envelope and deliberately not the
action vocabulary, so that argument is withdrawn and the interoperability one
kept.
Section 13.1 was found broken independently by audit-core and flex-auth: it
required an evidence artifact for every claim while defining none below I2, A2,
E1, P1, R2 - so section 5's own worked example of a conformant absorbed repo
could not satisfy it on any axis. At or below the no-control rung a declaration
now needs a stated reason, not an artifact.
The weakest-surface rule from draft-6 was insufficient alone. A bare minimum
destroys signal, since E3-write with E1-read declares identically to E1/E1.
Declare per path, quote the minimum. Two services found this shape in
themselves within a day, so it is the common case rather than a corner.
n/a is now an admissible level. P0 presupposes a database and R0 presupposes
retained data; a stateless service is neither, and without n/a a missing rung
forces the fabrication section 6 prohibits - which is what draft-1 was rejected
for.
The A ladder had no seat for a decision point. flex-auth cannot occupy A3,
since delegating to flex-auth is not something flex-auth can do. A PDP now
declares two numbers: its own inbound level and the maximum it enables. They
read A0 enables A3, which is more alarming than A3, which is the point.
The ladders described consumers and not providers. railiance-platform showed
apps-pg at I0 A0 E0 where the zeros are structural, and OpenBao at E0 where the
mechanism in place is E4 machinery aimed at a consumer boundary - literally
correct and inverting the real security position. A provider now declares what
it makes reachable.
Crypto-shredding needed a condition it did not have. audit-core showed that a
hash over a low-entropy canonical record is a confirmation oracle, so
destroying the key does not make content unrecoverable while the commitment
survives - and that shreddability is not retrofittable onto a chain committing
to cleartext. R4 by key destruction now requires that no retained commitment
reveal the erased content.
Section 9 named database credentials only; audit-core pointed out the argument
applies with more force to the credential carrying the tenant claim. Extended.
Section 17 led with the connection ceiling when memory binds first and fails
worse. Corrected against rapp-postgres ADR-0004.
Also: a low level may be permanent by design and the guard must not nag it, and
the A4 evidence artifact now requires recording decision differences, since
substitution proves interface portability rather than equivalence.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
tenant-engine assessed itself against the ladders and came back with
corrections. All five are adopted, because the ratification test says that if a
repo cannot express itself the ladders are wrong - and it could not, in three
places.
I2 conflated authority with verification. Its text named tenant-engine as the
source of existence, which made the level describing canonical identity
unclaimable by the service that provides it. An axis is assessed on a service's
own inbound surface, never on its authority over the concept. tenant-engine is
the source of tenant records and is at I1, because the acting identity arrives
in the request body rather than in a verified token.
A level now reports the weakest surface. tenant-engine has PDP-authorized
mutations and three unauthorized read routes - including the one flex-auth
calls for aal2-class decisions - and reported A2 rather than A3. Publishing the
stronger surface would be accurate about that surface and misleading about the
service. A per-surface vector was considered and rejected as premature.
The E ladder assumed all data is tenant-keyed. A registry whose rows ARE the
tenants has no predicate to scope a policy by, and enforcing one would break
the service rather than secure it. Mixed-shape services now declare an E level
plus a named registry exception; an unnamed exception is an overclaim. Without
this they overclaim or sit at E2 forever, which is what tenant-engine was
facing.
Retention and erasure are two dimensions and one level cannot carry both.
tenant-engine is R1 on backup and R0 on erasure - its lifecycle contract
deliberately defines no hard-delete, so a tenant record cannot be deleted ever,
by design, while carrying display_name and contact_email. Declared R1/R0 now.
And the compounding - personal data, no erasure path, a backup window set by
the longest-retaining co-resident - is the substrate owner's to surface,
because each part looks locally reasonable alone.
My own error, corrected: I listed tenant-engine as a live P1 occupant in both
the ladder and the E/P matrix. They are on SQLite. P1 is TEN-WP-0009's target
and the provisioning is my own unapplied intake. Asserting a placement that a
workplan exists to create is exactly the kind of claim this document forbids.
Worth recording: they found an unfiltered cross-tenant read in their own event
accessor while assessing against the ladder, before publishing anything.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
An earlier revision of this section asserted the adversarial facility was
deliberately not NetKingdom's, on independence grounds. Overruled, and the
counter-argument is better: offensive security is security work.
The facility is also framed more broadly than this document assumed - it is
pointed at infrastructure we choose, our own estate among them, and testing
conformance to this framework is one use of a general capability rather than
its purpose.
The tension I raised is left in the text rather than deleted, because it is
real: NetKingdom now owns both this framework and the facility that tests
conformance to it. The mitigation is that findings leave for risk-nexus under
separate ownership instead of being closed in place, and the trigger to
revisit is conformance findings starting to close quietly.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Question 12 asked whether to add a quality-of-service dimension. No - because
we could not enforce it. Community PostgreSQL has no resource governor, so a
declared priority would be an unenforced claim in a declaration, which is what
retiring tenantIsolation was about. An axis implies graduation and enforcement
and this has neither.
Co-residents are equal, and a consumer whose latency cannot survive an
unprioritised neighbour escalates to P2. Service class is still declared, as a
category not a level: it informs placement, acts as a trigger, and gives
"acceptable degradation" in the noisy-neighbour artifact something to be
acceptable relative to - what batch tolerates is an outage for latency-critical.
Class mixture must be visible, because an unenforceable risk nobody can see is
worse than one that is stated. rapp-postgres now reports it and the live
instance already flags latency-critical beside batch.
Gateway-level prioritisation in a connection proxy is recorded as the known
escalation short of P2 - real, and infrastructure we do not run.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
whitehat-security takes the adversarial evidence artifacts - the framework's
highest-severity gap, unowned since it was drafted. audit-core and tenant-engine
were right to decline it as fleet-scope work; the answer was a home of its own
rather than a volunteer.
Recorded here with the part that bears on this document: the facility is
deliberately not owned by NetKingdom, which owns this framework. Verifying
conformance to a standard while reporting to the standard's owner is
self-grading one level up.
Two consequences land back on the framework. Cadence becomes a security
parameter rather than a schedule, since for a detection-based control the
interval between runs is the exposure window. And a passing suite is proof that
the attacks attempted did not work, not proof of isolation - recording a green
run as "E2 verified" would be exactly the overclaim section 6 prohibits.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>