From 773e8db18cb3f901663f2b924746a8dc458f593c Mon Sep 17 00:00:00 2001 From: ZDDC Date: Tue, 19 May 2026 12:45:23 -0500 Subject: [PATCH] =?UTF-8?q?docs(reference):=20section=2010=20=E2=80=94=20z?= =?UTF-8?q?ddc-server=20bootstrap=20config?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A fresh deployment grants no access to anyone until the operator populates the root /.zddc (admins) and per-project //.zddc (role members). Without them the server runs but every request returns 403 — the embedded defaults intentionally ship with empty role members so deployments must opt-in to authorize anyone. The new section walks operators through: - Step 1: root /.zddc with `admins:` only. - Step 2: per-project .zddc populating `document_controller` and `project_team` role members. - Schema essentials (admins/acl/roles/title, permission bits, principal forms). - The `acl: { allow: [...] }` footgun — silently dropped because ACLRules only reads `permissions:`. - The startup warning to watch for and `zddc-server show-defaults` as the full schema reference. Renumbered "Tools" from 10 to 11 and updated the sidebar TOC to match. Mirrors the new sections added to the main repo's README.md and AGENTS.md. Co-Authored-By: Claude Opus 4.7 (1M context) --- reference.html | 137 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 134 insertions(+), 3 deletions(-) diff --git a/reference.html b/reference.html index 6d228a8..e02c9f1 100644 --- a/reference.html +++ b/reference.html @@ -80,7 +80,8 @@ - + + @@ -1101,9 +1102,139 @@ project/ - + +
+

10. zddc-server bootstrap

+ +
+

A fresh zddc-server deployment grants no access to anyone until two config files are populated. Without them the server runs but every request returns 403. The embedded defaults ship with empty role members, so deployments must opt-in to authorize anyone — there is no default "anything goes" mode (except --insecure, which is explicitly for deliberately-public archives).

+
+ +

Two files, both named .zddc. YAML format. Hand-edited.

+ +

Step 1 — root /.zddc

+ +

At <ZDDC_ROOT>/.zddc, name at least one admin:

+ +
admins: + - cwitt@burnsmcd.com +
+ +

admins: is honored only at the root file. Admins behave as normal users by default and elevate per-request via the zddc-elevate=1 cookie (the header toggle visible in every tool) or implicitly when authenticating with a bearer token. This sudo-style model means an admin can't accidentally clobber files in their everyday browsing — elevation is opt-in.

+ +

Without this file the server refuses to start (the served tree would be publicly accessible to anonymous callers); pass --insecure to acknowledge a deliberately-public deployment.

+ +

Step 2 — per-project <project>/.zddc

+ +

In each project, populate the document_controller and project_team role members:

+ +
title: "Project Phoenix" +roles: + document_controller: + members: + - dc1@burnsmcd.com + project_team: + members: + - alice@burnsmcd.com + - '*@acme.com' # external counterparty (glob) +
+ +

That's it. The embedded cascade does the rest:

+ +
    +
  • project_team gets read across the project
  • +
  • document_controller gets read+write project-wide, plus create authority on archive/, WORM filing rights on received/ and issued/, and subtree-admin of working/, staging/, and reviewing/
  • +
+ +

Add a new project team member with one line; revoke by removing the line. No need to restate the cascade's grants — they're already in the embedded defaults that ship with zddc-server.

+ +

Schema essentials

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KeyWhereShape
admins:Root onlyList of emails. Sudo-style; gates on zddc-elevate=1.
acl:Anywhere; cascades{ permissions: { <principal>: <bits> }, inherit: <bool>? }
roles:Anywhere; members union across the cascade{ <name>: { members: [...], reset: <bool>? } }
title:Per-project onlyString; surfaces on the landing-page picker.
+ +

Permission bits — any subset of:

+ +
    +
  • r read
  • +
  • w write (overwrite existing files)
  • +
  • c create (new files, new directories)
  • +
  • d delete
  • +
  • a admin (subtree-admin at this level and below)
  • +
+ +

An empty bits string ('') is an explicit deny.

+ +

Principals — three forms:

+ +
    +
  • Email address — must contain @, e.g. alice@burnsmcd.com
  • +
  • Email glob — wildcard on the local part, e.g. '*@acme.com' (quote it in YAML so the leading * doesn't confuse the parser)
  • +
  • Role name — anything without an @, e.g. document_controller. The role's members are looked up via roles: at any cascade level.
  • +
+ +

Common footgun

+ +
+

This is silently dropped:

+
acl: + allow: + - '*@burnsmcd.com' +
+

The YAML parses cleanly but ACLRules only reads permissions:. The allow: block is discarded during unmarshal and you end up with zero grants. Correct form:

+
acl: + permissions: + '*@burnsmcd.com': r +
+
+ +

Verifying the bootstrap

+ +

zddc-server prints a startup warning when the root .zddc grants nobody anything — watch for it on first boot:

+ +
level=WARN msg="root .zddc grants nobody anything (no admins, +no acl.permissions, no role members). ZDDC will refuse every +request until you populate it..."
+ +

To dump the full annotated schema (every cascade key with documentation):

+ +
zddc-server show-defaults
+ +

That prints the embedded defaults.zddc.yaml with comments explaining every option (worm:, auto_own:, drop_target:, apps:, convert:, on_plan_review:, records:, available_tools:, default_tool:, dir_tool:, and more). Pipe it to a file and use it as the starting point for any deeper customization.

+
+ +
-

10. Tools

+

11. Tools

Two single-file HTML applications — each is complete and self-contained. Save them locally and they work forever, without internet, without updates, without a subscription. Together they cover the full ZDDC workflow: archive for searching and exporting the formal record; browse for navigating, editing, and managing the project tree.