All checks were successful
CI / Lint, typecheck, test (pull_request) Successful in 4m42s
CI / Build container images (pull_request) Successful in 1m11s
CI / Auth e2e pack (pull_request) Successful in 7m47s
CI / Import/export fidelity gate (pull_request) Successful in 55s
CD / Build and push images (push) Successful in 18s
CD / Deploy to Test (push) Successful in 14s
CD / Smoke tests against Test (push) Successful in 1m16s
CD / Promote to Int (push) Successful in 11s
CI / Lint, typecheck, test (push) Successful in 4m50s
CI / Build container images (push) Has been skipped
CI / Auth e2e pack (push) Successful in 7m38s
CI / Import/export fidelity gate (push) Successful in 56s
Add docs/vs-nfd/: the analysis brief, the as-is assessment (42 findings, all verified against the code), the prioritized action plan rev. 2 with issue references written back to every checkbox, the two-stage issue/ADR brief, and the full reviewed draft used to create the forge state. Add eight proposed ADRs 0019-0026 covering the VS-NfD architecture decisions: no security base functions (par. 52 VSA anchor), HKDF token key separation, external authentication, page classification, read-access audit trail (variant A), reproducible offline deployment, plugin trust model, and backup target restriction. Forge state created alongside this commit: 11 labels, milestones M24-M31, issues #188-#236 (docs-only change, no code touched). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0168Ph5uBmHm8X28CSVpbpnJ
64 lines
3.1 KiB
Markdown
64 lines
3.1 KiB
Markdown
# ADR 0024: Reproducible offline deployment
|
|
|
|
- Status: proposed
|
|
- Date: 2026-07-29
|
|
|
|
## Context
|
|
|
|
A VS zone has no internet egress. "Should work offline" is the answer that
|
|
loses a first meeting; "tested, here is the procedure" is the one that
|
|
wins it — which is why the plan pulled this out of the roadmap into
|
|
Phase 1.
|
|
|
|
The current state is favourable but unverified. There is no telemetry, no
|
|
update check, no CDN; fonts are self-hosted (ADR 0016); CSP is
|
|
`default-src 'self'`; search is Postgres rather than an external engine;
|
|
the drawio plugin is vendored rather than loaded from a remote editor. What
|
|
is missing is evidence, plus two real gaps: images are referenced by tag
|
|
(including the floating `gotenberg/gotenberg:8`), and there is no
|
|
documented mirror or update path.
|
|
|
|
## Decision
|
|
|
|
1. **All third-party images are pinned by digest** (`name:tag@sha256:…`).
|
|
The tag stays for human readability; the digest decides what runs. A CI
|
|
check rejects any un-digested third-party reference.
|
|
2. **The image list is generated, not hand-maintained**, so a mirror
|
|
procedure cannot silently miss a service.
|
|
3. **An internal registry is the supported source.** Compose takes the
|
|
registry prefix from configuration; no site edits image references.
|
|
4. **Reproducibility without network is a stated choice between two
|
|
paths**: an offline pnpm store enabling `install` + `build` with
|
|
networking disabled, **or** prebuilt images only with no customer-side
|
|
build. Either is acceptable; leaving it unstated is not, because it
|
|
determines whether the customer can patch locally.
|
|
5. **The airgap claim is proven by a documented run** in a network-isolated
|
|
environment, covering every function including the export sidecars, and
|
|
listing every outbound connection attempt observed. This run is the
|
|
artefact, and it also answers the plan's open question about what breaks
|
|
offline.
|
|
6. **The offline update path is part of the decision, not an afterthought**:
|
|
bundle, verify by digest, back up, apply, verify, roll back — with the
|
|
irreversibility of migrations stated explicitly.
|
|
|
|
## Consequences
|
|
|
|
- Digest pinning creates recurring maintenance: security updates now
|
|
require an explicit, reviewable change. That visibility is the point.
|
|
- Digest pinning must precede the mirror and update work, so it sits in the
|
|
`hardening & supply chain` milestone rather than this one.
|
|
- The isolated test run will surface findings; each becomes its own issue
|
|
referenced from #220 rather than expanding that issue's scope.
|
|
- Outbound SMTP is the one connection an authority may or may not permit;
|
|
the deployment must be functional without it, and the consequences of
|
|
disabling it (no notifications, no verification mail — which interacts
|
|
with `auth.local.enabled = false`) are documented.
|
|
- CD does not sync stage composes, so digest changes need an explicit
|
|
rollout step on the stage hosts.
|
|
|
|
## Implementing issues
|
|
|
|
#203 (digest pinning), #218 (registry mirror), #219 (network-free build),
|
|
#220 (isolated test run), #221 (offline update path), #236 (pinned Node
|
|
version — added from the Ist-Aufnahme, I-26).
|