First public release
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
# 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:
|
||||
|
||||
1. Document information
|
||||
2. Purpose and scope, including the gap and the deployments in scope
|
||||
3. Current implementation status: a table of checks with their evidence, a
|
||||
summary line, and a count of checks with no attached evidence
|
||||
4. Remediation plan with a target completion time (30 days by default)
|
||||
5. Evidence: the full citation for every check, or a statement that the
|
||||
result is a claim and not a verified finding
|
||||
6. References (NIST SP 800-53 Rev. 5, SP 800-53A and the FedRAMP SSP template
|
||||
by default)
|
||||
7. Approval and sign-off table
|
||||
|
||||
The rules that keep the document from claiming more than it knows:
|
||||
|
||||
- A status other than `pass`, `fail` or `warn` is 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 `undefined` or `null`.
|
||||
- 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
|
||||
|
||||
```ts
|
||||
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](LICENSE).
|
||||
Reference in New Issue
Block a user