4.1 KiB
CertPack
Generates a NIST 800-53 control document (a System Security Plan section with a remediation plan) from automated verification checks, with the evidence for each check attached. It is used in Hitt Hosting products.
What it does and why
An accreditation package that lists results without the scan output behind them is a set of claims. CertPack attaches the evidence to each check and labels any check without evidence as a claim. It does not drop the check or leave the cell blank, because a blank cell reads as "nothing to report" and a missing check is worse than a weak one.
You pass a control (document number, title, control family, the gap, the fix)
and a list of checks, each with a status and optional evidence in the
@extant2000/evidence-record format. renderControlDoc() returns HTML and
markdown built from one list of seven sections, so the two never drift apart:
- Document information
- Purpose and scope, including the gap and the deployments in scope
- Current implementation status: a table of checks with their evidence, a summary line, and a count of checks with no attached evidence
- Remediation plan with a target completion time (30 days by default)
- Evidence: the full citation for every check, or a statement that the result is a claim and not a verified finding
- References (NIST SP 800-53 Rev. 5, SP 800-53A and the FedRAMP SSP template by default)
- Approval and sign-off table
The rules that keep the document from claiming more than it knows:
- A status other than
pass,failorwarnis counted as unrecognised and shown in the summary, never folded into another status or dropped. - A control with no checks says that an unassessed control is not an implemented control, instead of printing "0 failing".
- Missing fields print "Not specified", never
undefinedornull. - The date is a parameter, not read from the clock, so the same input always produces byte-identical output. A document that changes when regenerated is not reproducible evidence.
Every value interpolated into the HTML goes through escapeHtml(), including
titles, table cells and evidence, with no "trusted field" exception. The
markdown output decodes entities because markdown is not an HTML context; if
you inject that markdown into a page as HTML, escape it there.
toReport() and formatControl() give the same assessment as an
evidence-record report, so a control's status can be rolled up without
parsing HTML. pass passes, fail and warn fail, and an unrecognised
status is not assessed.
Usage
import { renderControlDoc, formatControl, type ControlDocInput } from '@extant2000/cert-pack'
import { evidence } from '@extant2000/evidence-record'
const input: ControlDocInput = {
docNumber: 'SSP-AC-01',
title: 'Access Control',
family: 'AC',
familyName: 'Access Control',
gap: 'Tenant isolation is not documented',
fix: 'Document the row-level security policy',
date: '2026-09-28',
systemName: 'Example App',
checks: [
{ check: 'Row-level security on every tenant table', status: 'pass',
evidence: [evidence.command('psql -c "select relname, relrowsecurity from pg_class ..."', 0, '42 of 42 tables')] },
{ check: 'Least privilege enforced', status: 'pass' },
{ check: 'MFA for admins', status: 'skipped' },
],
}
const { html, markdown, sections } = renderControlDoc(input)
console.log(formatControl(input))
In the generated document, section 3 ends with "2 passing, 0 failing, 0
warnings, 1 unrecognised out of 3 checks" and "2 of 3 check(s) carry no
attached evidence". The two checks without evidence show NOT ATTACHED.
formatControl() prints:
✗ HIGH MFA for admins [NOT ASSESSED]
Status "skipped" is not recognised. An unrecognised status is not a passing one.
◦ info Row-level security on every tenant table [MET]
◦ info Least privilege enforced [MET]
controlDocSections(), renderDocument(), table(), stripTags(),
escapeHtml() and tally() are exported for building other documents.
Install
npm install @extant2000/cert-pack
License
MIT. See LICENSE.