dorfteich/docs/architecture/adr/0025-plugin-trust-model.md
Claude Opus 5 fd07f716f6
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
docs: VS-NfD readiness planning (ist-aufnahme, plan, ADRs 0019-0026, issue drafts)
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
2026-07-30 01:48:05 +02:00

2.8 KiB
Raw Blame History

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 810 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).