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
2.8 KiB
ADR 0025: Plugin trust model
- Status: proposed
- Date: 2026-07-29
Context
Dorfteich has a plugin architecture with a sandbox (ADR 0008): plugins declare a manifest, run isolated, and hold declared permissions. In a VS zone the question this attracts is blunt — can code execute inside the protected area, and who vouches for it?
Two facts shape the answer. First, the manifest has no integrity or identity field: nothing binds a bundle to what was reviewed. Second, real code signing needs a signing identity, and without a legal entity behind the project there is none to be had — a self-generated key that we also distribute proves nothing.
There is also an asymmetry in cost: a hard off-switch is ~2 AT and closes the risk completely for a deployment that does not need plugins; a trust model is 8–10 AT and only manages the risk.
Decision
- Short term: hard, verifiable off-switch.
plugins.enabled = falsemakes every plugin surface answer 404 — manifests, assets, the frame route, install/uninstall, and the per-pond toggles — following the established pattern ofapi.enabledandmcp.enabled. Off is part of the VS-NfD reference configuration. - Documents stay readable with plugins off. An existing plugin block
renders its declared
fallback, never an error. Disabling a feature must not damage content. - Medium term: hash pinning, not code signing. A SHA-256 over the
bundle in the manifest, an allowlist of id + pinned hash in
instance_settings, verification on install and on every load, failing closed. A version bump requires an explicit re-pin. - Signing is deliberately rejected for now, with its reason on the record: no signing identity is available. Should a legal entity exist later, signing becomes an amendment to this ADR, not a new discovery.
- The sandbox remains the containment mechanism. Hash pinning answers "is this the reviewed code", not "what may it do". Both are needed and neither substitutes for the other.
- Network allowlisting for plugins stays unscheduled, consistent with the existing project decision; in the VS-NfD profile plugins are off, so it is not the binding constraint.
Consequences
- The offer stage can answer the code-execution question with a switch and a test, without waiting for #232.
- Vendored third-party plugin code (drawio 30.3.6 under
packages/plugins/drawio/vendor/) is part of our supply chain and appears in the SBOM (#202). It loads no external editor URL — verified — and CSP would block it if it tried. - Hash pinning makes plugin updates a deliberate act, which is the intended friction.
- The plugin ecosystem stays small by construction. Accepted.
Implementing issues
#200 (hard off-switch), #232 (allowlist + hash pinning).