Files
shopdb-flask/docs/adr
cproudlock 91143d94fb
Some checks failed
CI / backend (push) Failing after 8s
CI / naming (push) Successful in 2s
CI / frontend (push) Successful in 9s
CI / migrations-mysql (push) Failing after 7s
ADR-016: credential delivery to the fleet
Controller and share credentials are currently edited as cleartext into a
script on the SFLD share, one value for the whole fleet, re-applied by
GE-Enforce every cycle. Rotating means editing that file and hoping - nothing
reports which bays picked the new value up - and sites need per-bay variation,
which a manifest scope cannot express because scopes are per PC TYPE. A scope
per bay is a spreadsheet, not a model.

ShopDB therefore owns the definitions and the targeting, and a PC receives a
decided answer rather than rules to evaluate. Targeting uses the axes
GE-Enforce already filters on plus those the asset model knows: hostname
(including -like globs), machine, model, controller OS, PC type with alias
expansion, GE-Enforce profile, and a selector over the stored DNC projection -
"every machine whose DataHost is that share" is answerable from data already
held, and it also answers which machines need a credential at all.

Overlapping matches are guaranteed rather than exceptional, so precedence is
explicit: an integer priority, then scope specificity, then rule id for
stability. The resolver must be able to explain which rule won and why, or
nobody will trust it. It reuses plugins/geenforce/filters.py; there are already
two implementations of this matching logic kept honest by a parity harness, and
a third would drift silently.

Targeting stays separate from detection, mirroring PCTypes versus
DetectionMethod: who gets a credential is a server question, whether it is
already applied is a local one, and conflating them rewrites the secret every
cycle instead of healing drift.

Stored Fernet-encrypted with the key OUTSIDE the database, write-only through
the API and masked on read, fetched with a dedicated credentials.fetch scope so
a leaked collector key does not yield controller passwords, and every fetch
audited.

PROPOSED, not accepted: it makes ShopDB a credential store, and the key becomes
a single point of loss - restore the database without it and every credential
is unrecoverable, which docs/BACKUP-RESTORE.md must state in the same change
that implements this. Registry-only provisioning is recommended as a first step
regardless, since it removes the cleartext from the share immediately and the
client helper is identical either way.
2026-08-11 10:54:42 -04:00
..

Architecture Decision Records

Each ADR captures a single architectural decision: the context, the decision itself, the consequences, and the alternatives considered. ADRs are immutable once accepted. Superseded ADRs stay in this folder with a pointer to the newer ADR.

Status definitions

  • PROPOSED: drafted, awaiting decision
  • ACCEPTED: decision is in effect
  • SUPERSEDED: replaced by a later ADR (link forward)
  • DEPRECATED: no longer in effect, no replacement

Index

ADR Title Status
001 Asset model is the platform contract ACCEPTED
002 Plugin contract versioning (semver) ACCEPTED
003 Plugin distribution model ACCEPTED
004 Deployment topology (per-site instances) ACCEPTED
005 Equipment vs measuringtools plugin scope ACCEPTED
006 Plugin collector contract pattern ACCEPTED
007 Product versioning and releases ACCEPTED
008 Plugin migration ownership (per-plugin chains) ACCEPTED
009 Frontend plugin route gating ACCEPTED
010 Frontend plugin hook contract ACCEPTED
011 Machines rename + modeltypes retyping ACCEPTED
012 GE-Enforce manifest ownership in shopdb ACCEPTED
013 Plugin catalog, curated shelf, and lean per-site builds PROPOSED
014 Schema-lean per-site builds (retire cross-plugin FKs, prune not-installed plugin tables) ACCEPTED
015 Where a site's own data is allowed to live (setting, site directory, or seed) ACCEPTED
016 Credential delivery to the fleet (ShopDB-resolved targeting, encrypted at rest) PROPOSED

Authoring

When proposing a new decision, copy the most recent ADR as a template, increment the number, and update this index. Do not edit accepted ADRs in place; supersede them with a new one.