docs: surface inherit: directive on home + federal pages
All checks were successful
Deploy content to live site / deploy (push) Successful in 2s

index.html: extend the access-control bullet to mention the
inherit:false directive as the "complete reset" knob for vendor and
regulated subtrees.

federal.html: note in the strict-Rego bullet that inherit:false is
intentionally refused under strict cascade mode (NIST AC-6 invariant)
so federal-track operators understand the directive is a commercial-
mode tool, not part of the federal posture.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
ZDDC 2026-05-07 11:11:01 -05:00
parent e7678e3c4d
commit 349026b90e
2 changed files with 2 additions and 2 deletions

View file

@ -58,7 +58,7 @@
<li><strong>Verb-based least privilege (NIST AC-6).</strong> Every access decision evaluates one of five explicit verbs — <code class="inline">r</code> read, <code class="inline">w</code> overwrite, <code class="inline">c</code> create, <code class="inline">d</code> delete, <code class="inline">a</code> admin / edit ACL. A grant of <code class="inline">rc</code> means "this principal can read existing files and create new ones, but cannot modify or delete what's already there" — exactly the permission shape an immutable archive needs. Empty grants (<code class="inline">""</code>) are explicit denies that beat any other grant at the same level.</li> <li><strong>Verb-based least privilege (NIST AC-6).</strong> Every access decision evaluates one of five explicit verbs — <code class="inline">r</code> read, <code class="inline">w</code> overwrite, <code class="inline">c</code> create, <code class="inline">d</code> delete, <code class="inline">a</code> admin / edit ACL. A grant of <code class="inline">rc</code> means "this principal can read existing files and create new ones, but cannot modify or delete what's already there" — exactly the permission shape an immutable archive needs. Empty grants (<code class="inline">""</code>) are explicit denies that beat any other grant at the same level.</li>
<li><strong>Write-once-read-many archive folders (NIST AU-9, MP-5).</strong> Files placed under <code class="inline">archive/&lt;party&gt;/issued/</code> or <code class="inline">archive/&lt;party&gt;/received/</code> are protected by a server-enforced verb mask: ancestor grants are reduced to read-only when crossing the WORM boundary, regardless of what an upstream <code class="inline">.zddc</code> says. A separate <code class="inline">.zddc</code> placed at the WORM folder itself can grant <code class="inline">rc</code> to specific principals (the doc-controller dropping a fresh transmittal) — that survives the mask. Root admins bypass the mask only as the deliberate escape hatch for mis-filed documents, with bypasses visible in the audit log.</li> <li><strong>Write-once-read-many archive folders (NIST AU-9, MP-5).</strong> Files placed under <code class="inline">archive/&lt;party&gt;/issued/</code> or <code class="inline">archive/&lt;party&gt;/received/</code> are protected by a server-enforced verb mask: ancestor grants are reduced to read-only when crossing the WORM boundary, regardless of what an upstream <code class="inline">.zddc</code> says. A separate <code class="inline">.zddc</code> placed at the WORM folder itself can grant <code class="inline">rc</code> to specific principals (the doc-controller dropping a fresh transmittal) — that survives the mask. Root admins bypass the mask only as the deliberate escape hatch for mis-filed documents, with bypasses visible in the audit log.</li>
<li><strong>Pluggable policy engine.</strong> Access decisions can be delegated to an external <a href="https://www.openpolicyagent.org/" rel="noopener">Open Policy Agent</a> server with the customer's own audited Rego rules. The server POSTs request user, path, action, and the full <code class="inline">.zddc</code> cascade chain to <code class="inline">/v1/data/zddc/access/allow</code>; the customer's OPA returns allow/deny. Default in-process engine and OPA-delegated engine speak the same wire format, so customers swap by setting one environment variable. Failures fail closed by default; <code class="inline">ZDDC_OPA_FAIL_OPEN=1</code> flips it for the rare case where availability outranks confidentiality.</li> <li><strong>Pluggable policy engine.</strong> Access decisions can be delegated to an external <a href="https://www.openpolicyagent.org/" rel="noopener">Open Policy Agent</a> server with the customer's own audited Rego rules. The server POSTs request user, path, action, and the full <code class="inline">.zddc</code> cascade chain to <code class="inline">/v1/data/zddc/access/allow</code>; the customer's OPA returns allow/deny. Default in-process engine and OPA-delegated engine speak the same wire format, so customers swap by setting one environment variable. Failures fail closed by default; <code class="inline">ZDDC_OPA_FAIL_OPEN=1</code> flips it for the rare case where availability outranks confidentiality.</li>
<li><strong>Strict-least-privilege policy variant available out of the box.</strong> A parity-tested federal-mode Rego that enforces NIST AC-6 (parent denies are absolute; no leaf-level override) ships embedded in the binary. <code>zddc-server --print-rego=federal</code> emits it for use with the customer's OPA.</li> <li><strong>Strict-least-privilege policy variant available out of the box.</strong> A parity-tested federal-mode Rego that enforces NIST AC-6 (parent denies are absolute; no leaf-level override) ships embedded in the binary. <code>zddc-server --print-rego=federal</code> emits it for use with the customer's OPA. The <code class="inline">inherit: false</code> "ancestor reset" directive available in commercial deployments is intentionally <em>refused</em> under strict cascade mode — a leaf cannot widen access an ancestor refused. Operators who need fence-style semantics in a federal-track tree must restructure the cascade so the permissive ancestor rule never appears.</li>
<li><strong>Cascade tracer for reviewers (NIST AC-3 reviewability).</strong> Admins can hit <code class="inline">/.profile/effective-policy?path=&lt;url&gt;</code> on a running server to see the resolved ACL chain at any path — every directory's grants, the role evaluation, and the final verb-set returned for the requesting user. A security reviewer can confirm "yes, this person has exactly these rights at this path" without reading the source. Helpful during accreditation and for incident response.</li> <li><strong>Cascade tracer for reviewers (NIST AC-3 reviewability).</strong> Admins can hit <code class="inline">/.profile/effective-policy?path=&lt;url&gt;</code> on a running server to see the resolved ACL chain at any path — every directory's grants, the role evaluation, and the final verb-set returned for the requesting user. A security reviewer can confirm "yes, this person has exactly these rights at this path" without reading the source. Helpful during accreditation and for incident response.</li>
<li><strong>Structured audit logging.</strong> Every request is logged with the authenticated email, method, path, status, response size, and duration. Logs are JSON-line, ready for fluentd / Vector / SIEM pipelines.</li> <li><strong>Structured audit logging.</strong> Every request is logged with the authenticated email, method, path, status, response size, and duration. Logs are JSON-line, ready for fluentd / Vector / SIEM pipelines.</li>
<li><strong>Documented vulnerability-disclosure process.</strong> A <a href="https://codeberg.org/VARASYS/ZDDC/src/branch/main/SECURITY.md">SECURITY.md</a> covering supported versions, reporting channel, response timeline, embargo workflow, and CVE assignment.</li> <li><strong>Documented vulnerability-disclosure process.</strong> A <a href="https://codeberg.org/VARASYS/ZDDC/src/branch/main/SECURITY.md">SECURITY.md</a> covering supported versions, reporting channel, response timeline, embargo workflow, and CVE assignment.</li>

View file

@ -177,7 +177,7 @@
<ul class="feature-list"> <ul class="feature-list">
<li><strong>Lazy folder creation, case-fold matching.</strong> Drop a <code class="inline">.zddc</code> file into an empty directory and the canonical project layout (<code class="inline">working/</code>, <code class="inline">staging/</code>, <code class="inline">archive/&lt;party&gt;/{mdl,incoming,received,issued}/</code>) materialises on the first write into each path — never on bare reads. Folder names are matched case-insensitively, so an existing <code class="inline">Working/</code> is reused rather than shadowed by a new <code class="inline">working/</code> sibling. Each authenticated viewer sees a virtual <code class="inline">working/&lt;your-email&gt;/</code> entry; first write makes it real.</li> <li><strong>Lazy folder creation, case-fold matching.</strong> Drop a <code class="inline">.zddc</code> file into an empty directory and the canonical project layout (<code class="inline">working/</code>, <code class="inline">staging/</code>, <code class="inline">archive/&lt;party&gt;/{mdl,incoming,received,issued}/</code>) materialises on the first write into each path — never on bare reads. Folder names are matched case-insensitively, so an existing <code class="inline">Working/</code> is reused rather than shadowed by a new <code class="inline">working/</code> sibling. Each authenticated viewer sees a virtual <code class="inline">working/&lt;your-email&gt;/</code> entry; first write makes it real.</li>
<li><strong>Virtual <code class="inline">.archive</code> URL space.</strong> <code class="inline">GET /Project/.archive/123-XYZ.html</code> resolves to the canonical revision file at request time. Computed from filenames; no cache, no separate index file.</li> <li><strong>Virtual <code class="inline">.archive</code> URL space.</strong> <code class="inline">GET /Project/.archive/123-XYZ.html</code> resolves to the canonical revision file at request time. Computed from filenames; no cache, no separate index file.</li>
<li><strong>Access control via <code class="inline">.zddc</code> files.</strong> Behind a reverse proxy that authenticates users and sets an <code class="inline">X-Auth-Request-Email</code> request header, <code class="inline">zddc-server</code> consults YAML <code class="inline">.zddc</code> files at every directory along the path. The cascade walks root→leaf; the closest match wins. Five verbs (<code class="inline">r</code> read, <code class="inline">w</code> overwrite, <code class="inline">c</code> create, <code class="inline">d</code> delete, <code class="inline">a</code> admin / edit ACL) gate every operation. An empty grant (e.g. <code class="inline">"*@vendor.com": ""</code>) is an explicit deny. Common shapes (paired open/closed projects, third-party-restricted vendor folders) are documented with worked examples in the <a href="https://codeberg.org/VARASYS/ZDDC/src/branch/main/zddc/README.md#access-control-the-zddc-cascade">access-control reference</a>. No database, no admin UI.</li> <li><strong>Access control via <code class="inline">.zddc</code> files.</strong> Behind a reverse proxy that authenticates users and sets an <code class="inline">X-Auth-Request-Email</code> request header, <code class="inline">zddc-server</code> consults YAML <code class="inline">.zddc</code> files at every directory along the path. The cascade walks root→leaf; the closest match wins. Five verbs (<code class="inline">r</code> read, <code class="inline">w</code> overwrite, <code class="inline">c</code> create, <code class="inline">d</code> delete, <code class="inline">a</code> admin / edit ACL) gate every operation. An empty grant (e.g. <code class="inline">"*@vendor.com": ""</code>) is an explicit deny. A subtree that wants to start fresh — vendor folder, regulated workspace — can declare <code class="inline">inherit: false</code> to fence off ancestor grants and roles, then list the principals it does want. Common shapes (paired open/closed projects, third-party-restricted vendor folders) are documented with worked examples in the <a href="https://codeberg.org/VARASYS/ZDDC/src/branch/main/zddc/README.md#access-control-the-zddc-cascade">access-control reference</a>. No database, no admin UI.</li>
<li><strong>Roles for human-readable grants.</strong> A <code class="inline">.zddc</code> may declare named roles whose members are email patterns; permissions then reference the role name instead of pasting the same wildcard everywhere: <li><strong>Roles for human-readable grants.</strong> A <code class="inline">.zddc</code> may declare named roles whose members are email patterns; permissions then reference the role name instead of pasting the same wildcard everywhere:
<pre style="margin: 0.4rem 0;"><code>roles: <pre style="margin: 0.4rem 0;"><code>roles:
qc-reviewers: qc-reviewers: