What's already in place
These controls ship in every release today. No federal-specific build required to use them.
- Hardened TLS posture. The TLS 1.2 cipher suite list, curve preferences, and HSTS header are pinned to the federal TLS guidance (NIST SP 800-52 Rev. 2). Only AEAD ciphers; only forward-secret key exchanges; only modern curves. Weak suites cannot be negotiated even if a client offers them.
- Role-based access control (NIST AC-2 / AC-3). A
.zddcfile declares named roles whose members are email patterns; permissions reference role names rather than pasting the same wildcards across every directory. Role definitions cascade and child files shadow ancestors for that subtree, so federation between an organisation-wide role definition and a project-specific override is built in. Maps cleanly to AC-3(7) "role-based" enforcement and AC-2 account-management workflows. - Verb-based least privilege (NIST AC-6). Every access decision evaluates one of five explicit verbs —
rread,woverwrite,ccreate,ddelete,aadmin / edit ACL. A grant ofrcmeans "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 ("") are explicit denies that beat any other grant at the same level. - Write-once-read-many archive folders (NIST AU-9, MP-5). Files placed under
archive/<party>/issued/orarchive/<party>/received/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.zddcsays. A separate.zddcplaced at the WORM folder itself can grantrcto 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. - Pluggable policy engine. Access decisions can be delegated to an external Open Policy Agent server with the customer's own audited Rego rules. The server POSTs request user, path, action, and the full
.zddccascade chain to/v1/data/zddc/access/allow; 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;ZDDC_OPA_FAIL_OPEN=1flips it for the rare case where availability outranks confidentiality. - Strict-least-privilege policy variant available out of the box. A parity-tested federal-mode Rego that enforces NIST AC-6 (parent denies are absolute; no leaf-level override) ships embedded in the binary.
zddc-server --print-rego=federalemits it for use with the customer's OPA. - Cascade tracer for reviewers (NIST AC-3 reviewability). Admins can hit
/.profile/effective-policy?path=<url>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. - Structured audit logging. 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.
- Documented vulnerability-disclosure process. A SECURITY.md covering supported versions, reporting channel, response timeline, embargo workflow, and CVE assignment.
- Cascading access control with explicit trust boundaries. The
.zddcACL model has documented invariants — root-only admin escalation gate, subtree-author authority limited to their subtree, default-deny when any.zddcexists. The access-control reference includes a five-minute verify-it recipe a security reviewer can run on their own deployment.
Supported deployment shape
Federal-track deployments run zddc-server on loopback only, fronted by a TLS-terminating proxy. The proxy handles authentication (PIV/CAC via the customer's IdP), terminates TLS using a FIPS-validated module, and forwards plaintext to zddc-server over the local interface. zddc-server stays small, lean, and focused on file-tree access decisions; the proxy is where federal-mandated cryptographic boundaries live.
PIV/CAC user
│
▼
┌──────────────────────┐ (FIPS-validated TLS termination,
│ oauth2-proxy / │ OCSP stapling, MFA, session mgmt)
│ nginx-FIPS / │
│ stunnel-FIPS │
└──────────────────────┘
│ loopback (HTTP, mTLS or signed JWT)
▼
┌──────────────────────┐ (Per-directory ACL via .zddc;
│ zddc-server │ OPA-delegated for AC-6 strict;
│ on 127.0.0.1:8080 │ structured access log to stdout)
└──────────────────────┘
│
▼
/srv/zddc (RHEL/UBI volume, encrypted at rest by the platform)
The base image for the federal track is RHEL UBI 9 or equivalent (Rocky 9, Ubuntu Pro 22.04+) with the OS-level FIPS mode enforced kernel-side. Encryption at rest is delegated to the deployment platform (cloud KMS, LUKS, dm-crypt). Audit logs ship from the proxy and zddc-server's stdout to the customer's SIEM via the orchestrator's normal log pipeline.
This isn't a new architecture — it's the standard "small focused service behind a hardened proxy" shape that DoD reference designs already prefer. zddc-server's job is to be the small focused service.
What you'd add for full ATO
None of these are forever-open questions; each is a roadmap-able piece of work that an integrator builds when a customer engages on accreditation. Engineering detail for each item lives in the federal-readiness gap analysis.
| What | Plain-language summary |
|---|---|
| FIPS-validated cryptography | A separate zddc-server-fips binary built with Microsoft's FIPS-aware Go toolchain on a RHEL/UBI base. The validated cryptography belongs to the OS-level OpenSSL FIPS module; this binary uses it. See the two-track build plan below. |
| Authenticated proxy↔server channel | Today the proxy and zddc-server trust each other via network isolation. For federal, the recommended path is a signed forwarding token (JWT) — proxy signs each request with its private key, zddc-server verifies with the published public key. mTLS available as an alternative when the customer already operates a private CA. |
| Identity-provider role sync | Role-based grants are already in the .zddc model — see the "Role-based access control" row above. What an integrator adds for federal is a sync layer that populates a role's members: list from the customer's identity provider (Active Directory groups, Okta, EntraID) on a schedule, so role membership tracks the IdP rather than being maintained by hand. The cascade format already accepts role members; this is the wiring that keeps them in sync. |
| Policy export for change control | The cascade tracer (/.profile/effective-policy) already returns a resolved policy for any single path. What's missing is a batch export — a command that walks the entire served tree and emits every directory's resolved access policy in JSON / Markdown / CSV. The change-control workflow checks the export into a Git repo; every .zddc change produces a diff that reviewers approve before deploy. NIST CM-3. |
| Code-signed tool fetches | When a .zddc file pins a tool to a URL, zddc-server today fetches and caches it with no integrity check. The federal answer is code signing: the release pipeline signs every published artifact once with a long-lived key; zddc-server verifies signatures before caching. The operator trusts a published public key once and never deals with hashes — no per-artifact tracking burden. |
The two-track build plan
Federal evaluators sometimes ask a perfectly reasonable question: "Does the standard zddc-server binary use FIPS-validated cryptography?" The answer is no, and that's by design.
FIPS validation is a property of the cryptographic module — typically the OS-level OpenSSL FIPS package shipped by Red Hat or Canonical, certified by NIST and tracked by certificate number. Building with the Microsoft FIPS-aware Go toolchain is what lets a Go program use that validated module instead of Go's stdlib crypto. But it requires linking against the host's OpenSSL, which:
- Eliminates the "single static binary" property of the standard build (validated OpenSSL must be present at runtime)
- Ties the deployment to a RHEL/UBI-class OS (validated OpenSSL packages exist there; not on macOS or Windows)
- Gains nothing for the ~95% of customers who don't need a FIPS certificate to procure the system
So when a federal customer engages, an integrator builds a parallel zddc-server-fips binary using the FIPS toolchain and ships it alongside the standard one. linux-amd64 only, RHEL/UBI base, validated OpenSSL on the host. Federal customers download the FIPS variant; everyone else downloads the lean pure-Go binary. The application code is identical between tracks — only the toolchain and the host OS configuration differ.
This way every customer gets the deployment shape that fits their environment without paying for ones that don't.
Engineering reference
For implementors picking up federal-track work, the in-repo references include effort estimates, design trade-offs, library choices, and pointers to the existing code that each piece would build on.
- Federal-readiness gap analysis — every NIST control we know is incomplete, with the planned remediation. Per-item subsections cover FIPS, authenticated proxy↔server, policy export, and code-signed app fetches with implementation depth.
- ARCHITECTURE.md § Server security model — commercial-vs-federal trust models side-by-side. Cooperating layers (auth, policy decider, ACL cascade, tool-rooted view, audit log) and what each one's actual job is.
- Access-control reference — cascade rules, anti-patterns, worked deployment layouts (third-party-vendor folders, paired open/closed projects), and a five-minute verify-it-works recipe. Useful for the security-review reading too.
- codeberg.org/VARASYS/ZDDC — source code, issue tracker, contribution docs.