3 Commits

Author SHA1 Message Date
cproudlock
794bb4668f Add vulnerability scanning on top of the SBOM
Some checks failed
CI / naming (push) Successful in 3s
CI / frontend (push) Successful in 13s
CI / migrations-mysql (push) Successful in 41s
CI / backend (push) Has been cancelled
The SBOM was generated and installed onto every server, and nothing read it.
"Are we exposed to this advisory" was still a person going and looking, which
meant it happened when somebody remembered to.

scripts/scan_sbom.py queries OSV.dev by purl - no account, no API key, no agent,
no vulnerability database to maintain on a box that cannot reach the internet.
The SBOM is already the input OSV wants, so this is a lookup against what
shipped rather than a second scan of the tree that could disagree with it.

Three decisions worth recording:

Shipped and build-only findings are both reported, but only shipped ones can
fail a build. Two thirds of the components here are build tooling the SBOM
already marks scope 'excluded', and the highest-severity match in the whole tree
today is a CRITICAL against the test runner. A gate that fails a release over
that trains everybody to bypass it, and then it catches nothing.

Severity is taken from the advisory, never derived. Where there is only a CVSS
vector the report says UNKNOWN, which is shown and never gates. A guessed score
is worse than an honest gap because somebody would act on it.

The allowlist is a record rather than a mute button: each entry carries the
reason, the accepter, the date, and what would invalidate the reasoning. The
first entry is a worked example - a PyJWT algorithm-confusion advisory that
needs both mixed algorithm families and a raw JSON JWK as the key, and this
application configures neither.

The report ends with a per-component upgrade rollup, since that is the part
somebody acts on. A target on a different major version is labelled rather than
listed beside patch bumps as though the two cost the same.

Current state: 8 shipped components have fixes available, none of them
exploitable through a path this application opens today.
2026-08-29 17:18:58 -04:00
cproudlock
928a50c16e docs: what a site needs that no page answered
Four gaps a second site hits and cannot resolve by reading.

**Restoring on Windows** was one sentence - "the standard mysql < dump.sql" -
with no ordering. Restoring a database under running code that expects a
different schema turns a restore into a second incident, so the steps are now
ordered and each says why. It also says what `.env` costs if it is lost, which
is the part nobody discovers until they are already rebuilding: the dump does
not contain it, and without the JWT secrets every issued token dies, so every
collector and every GE-Enforce client on the fleet needs a new key.

**Rolling back** had a paragraph saying downgrades are refused and a backup is
the way back, but not the procedure. Rollback is restoring a matched pair, code
and the schema it expects, in that order - and the doc now separates it from the
case it gets confused with: a migration that failed mid-update has already been
rolled back by the installer, and fixing forward is the only move.

**Sizing, acquisition and support** were absent from the install guide entirely.
A reader could not learn how big a server to ask for, where the .exe comes from,
or where to raise a problem. The sizing is small and the reasons are stated, so
a site does not over-provision a VM for a load that is a few dozen users.

**Credentials** were described in three documents from three ends, so three
answers existed for where a key lives. One table, both ends - server and PC -
plus the two rules behind it: what a shop-floor PC holds is scoped to exactly
what it does, and a credential is delivered rather than typed, because a value
entered per machine is a value that is wrong on some machine.
2026-08-14 16:16:01 -04:00
cproudlock
1d73bd477e Document what future Windows releases look like, for operators and for builders
Some checks failed
CI / backend (push) Failing after 8s
CI / naming (push) Successful in 1s
CI / frontend (push) Successful in 8s
CI / migrations-mysql (push) Failing after 7s
Two audiences, two documents. Both were only in people's heads.

UPDATES-WINDOWS.md is for whoever runs a server: updates arrive as one
self-contained exe, an update takes two to four minutes, the site is down for
that time, .env and data and any hand-edited web.config are kept, unticking a
feature never removes it, the database is backed up and verified first, and a
downgrade is refused because migrations only go forwards. It covers both kinds
of security release, application and third-party, and explains that the
CycloneDX inventory staged on every server is what answers a published
vulnerability question. It also says plainly that the exe is not signed and the
checksum is the integrity check to rely on today.

It answers one question the existing docs did not address at all: the effect on
other sites sharing the same IIS server. The application pool is isolated and
the configuration is scoped to its own path, so other sites keep their own
handlers. What IS shared gets named rather than glossed: installing the IIS
modules and writing server-level configuration recycles application pools
across the server, which can drop requests in flight and clears in-memory
session state, though IIS is never stopped and no iisreset is issued. The two
IIS modules and the single permitted rewrite server variable are machine-wide
and stay behind on uninstall, deliberately, since another site may have come to
depend on them. The bundled database option collides on port 3306 with an
existing MySQL.

RELEASING-WINDOWS.md is for whoever builds releases: the three kinds of change
and the commands for each, why bundle-lock.json must be committed, the two
dependency traps that have each already cost a release, which generated files
must never be hand-edited, and the pre-release checks. It records the two known
gaps honestly - no code signing, and compiling still requires Windows and a
person.

UPGRADE.md and OPERATE-WINDOWS.md link to the operator document.
2026-08-04 20:54:05 -04:00