Commit graph

2 commits

Author SHA1 Message Date
88ef2dd921 docs(server): correct overstated WORM/config-edit comment; pin two-step demotion
The decider comment claimed standing config-edit "only ever grants VerbA, so it
can never write/delete/create WORM records." True for a single decision, but it
overstated the guarantee: a config-editor who administers a WORM zone can edit
that zone's .zddc (inherit:false drops the embedded worm:), after which ordinary
writes are no longer clamped. That two-step demotion is intended — owning a
subtree's policy includes its worm: marker, and the edit is access-logged — so
WORM is tamper-EVIDENT to its policy owner, not tamper-PROOF.

Rewrite the comment to say so (and note where to gate worm: relaxation behind
elevation if a deployment needs tamper-proof markers), and add
TestStandingConfigEdit_WormDemotionIsTwoStep pinning the boundary (direct WORM
write denied unelevated), the lever (config-edit allowed), and the consequence
(post-demotion write allowed). Surfaced by the deferred-findings triage.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 19:57:13 -05:00
bd219afeb7 feat(policy): config-edit is a standing permission, not elevation-gated
Editing a .zddc you administer no longer requires toggling admin mode.
Elevation becomes purely additive — it only adds the WORM/destructive
overrides ("things you otherwise couldn't do"), never a prerequisite for
authority you already hold.

Mechanism: a new zddc.IsConfigEditor(chain, email) reports STANDING
config-edit authority — being a subtree admin (admins: cascade) OR holding
the `a` verb — without the elevation gate. InternalDecider.Allow grants
VerbA on that basis ABOVE the WORM clamp: config is not WORM-protected
data, and VerbA only ever authorises .zddc/.zddc.zip/role mutations, never
write/delete of records (those stay clamped + elevation-gated). The full
WORM/ACL bypass (IsActiveAdmin) is unchanged — still admins: + Elevated.

This flows for free to the client: EffectiveVerbsFromChainP loops
ActionAdmin through the decider, so /.profile/access + cap.has(node,'a')
light up the .zddc form editor with no client change, and ServeZddcFile
already gates raw .zddc reads on directory read ACL (config is visible).

A standing subtree admin can thus rewrite their subtree's policy
(admins:/ACL/roles) un-elevated — bounded to their scope (authority
cascades down only, never up), logged, and unable to touch WORM data or
secrets without elevating. That's "admin of X = owns X's policy."

Tests: new TestStandingConfigEdit (decider matrix incl. WORM-transcending
config-edit + data-write still gated); updated the old "un-elevated admin
cannot edit .zddc" invariants (TruthTable, ZddcPut/DeleteMatrix,
NoSilentBypass now scoped to WORM/out-of-scope, profile PathVerbs) to the
new model. Full suite green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 17:00:54 -05:00