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
62 lines
2.8 KiB
Markdown
62 lines
2.8 KiB
Markdown
# 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
|
||
|
||
1. **Short term: hard, verifiable off-switch.** `plugins.enabled = false`
|
||
makes every plugin surface answer 404 — manifests, assets, the frame
|
||
route, install/uninstall, and the per-pond toggles — following the
|
||
established pattern of `api.enabled` and `mcp.enabled`. Off is part of
|
||
the VS-NfD reference configuration.
|
||
2. **Documents stay readable with plugins off.** An existing plugin block
|
||
renders its declared `fallback`, never an error. Disabling a feature must
|
||
not damage content.
|
||
3. **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.
|
||
4. **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.
|
||
5. **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.
|
||
6. **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).
|