Skip to content
andrew.dunn.dev

Evidence Factory

Source Catalog listing

Evidence Factory is a worked demonstration I built at GitLab Public Sector and published as a group of its own, of how a continuous Authority to Operate evidence pipeline for NIST SP 800-53 controls can run without leaving GitLab. It is seven public projects under one group: a driver, a policy plane, a governed CI/CD Catalog, three consumer workloads seeded at three adoption phases, and a landing page that is the guided way in. Read it, walk it, then rebuild the pattern in your own namespace: it is not a product to install.

I built it for the community of practitioners working toward continuous ATO, converging the primitives GitLab already carries, pipeline execution policies, a governed catalog, external status checks and controls, into one worked pattern rather than a scatter of features each team assembles alone. The idea underneath is that a control’s posture can be a byproduct of the pipeline a team already runs, rather than a document assembled once at assessment time, serving both audiences from the same run: a developer wants to know whether this merge request is blocked and which control blocked it, and an assessor wants to know what the current posture is and which artifacts back it. I seeded the three consumer repos on the same report, cutover, enforce ladder egress uses for its own conformance contract.

other than satisfiedsatisfiedCHANGEmerge requesta consumer repoINJECTED BY POLICYconformance stageno repo can edit it800-53Averdict?STATUS CHECKmerge blockednames the controlCOMPLIANCE CENTERposture recordedand a public read-out
A merge request meets a conformance stage the repository cannot edit, and the 800-53A verdict either blocks the merge or records the control posture.
injects a stagethe repo cannot editthe stage includes pinned catalog releasesevery job installs the pinned driverone verdict, pushedto two placesregenerated, no account neededblocks the mergePOLICY PLANEquality-control800-53 framework as versioned JSONpipeline execution policy, no skip_ciREPORT, CUTOVER, ENFORCEthree consumersgo-cli, container, ci-componentone planted gap per phasePUBLIC READ-OUTSgitlab-profileposture-snapshot.md, every six hourscontrol-allocation.md, release-pinnedSEMVER CATALOG, PROVIDES.YMLproduction-lineconformance, vale, code-quality,catalog-guard, boe-manifestMERGE GATEstatus check and controlblocks a merge on other-than-satisfiedposture in the Compliance CenterDRIVER, PROVISIONS THE GROUPfactoryassess returns an 800-53A verdictpush-check and push-control post it
The policy plane injects the stage, the catalog components run inside it, and the factory driver turns every run into a merge gate, a control posture, and a public read-out.

Two properties make the loop hold. The evidence stage is not something a consumer opts into: a pipeline execution policy in quality-control force-injects conformance-stage.yml into every tagged project, invisible and uneditable from the consumer’s own repository, and what actually blocks the merge is a separate mechanism, a GitLab external status check. The verdict and the evidence behind it are kept apart on purpose, too: factory assess writes one mutable verdict per control, which the Compliance Center reads through an external control, while the evidence is the set of files named in each consumer’s boe.yaml and versioned by git, so asking what the posture is right now and what it was in March are different questions, answered by different systems. Each consumer also carries one deliberately planted gap against a real control ID, which is why container and ci-component run red on main by design.

It’s one continuously refreshed input to a Security Assessment Report, not an authorization package on its own.