Skip to content

Admin guideSecurity

What this install tells an assessor

The NIST SP 800-171r3 control document and audit report — what each covers and who can read them.

View as Markdown

Admin → Compliance produces two documents against NIST SP 800-171 Revision 3, from one registry compiled into the binary.

Control document Audit report
Describes the build — what Toft does per requirement the install — what this machine is set to now
Reads nothing settings, providers, credentials, sources, apps
Stale when you upgrade you change anything
Download PDF, toft-800-171r3-controls-<version>.pdf JSON export, compliance-<install>-<date>.json

Both render the same registry, so they cannot disagree about what the controls are. The PDF is generated in the binary, so it works without outbound HTTPS, and every page footer names the build.

Each of the 97 requirements is one of:

platform Toft does this
shared Toft does part; you do the rest
inherited Your infrastructure does it
customer Entirely yours

At least twenty stay customer or inherited — a test holds that floor. There is no score: nineteen requirements have nothing to do with Toft, so an average would mean nothing.

Where SP 800-171 asks you to define a value, the report reads your live setting:

Parameter Setting
Account inactivity period dormant_lock_days
Session termination period session_idle_minutes
Malware response dependency_block_malware

Parameters the install does not hold are shown as unbound and counted.

All 39 evidence items always produce a row:

ok Read; here is the value
absent The install does not offer that capability — not a finding
refused An access boundary stopped the read
error It should have worked and did not

A bare install produces no error rows.

The report is computed per request and never stored. The JSON export names the install, the date and the collector, and carries a digest recomputable from the file alone (it covers its own timestamp). File it wherever you keep evidence.

The digest is the SHA-256 of the report member in RFC 8785 canonical JSON, and the file says so in sha256_rule. Any RFC 8785 library recomputes it. So does Python’s standard library, since these documents use plain keys and whole numbers:

Terminal window
python3 -c 'import json,sys,hashlib; d=json.load(open(sys.argv[1])); b=json.dumps(d["report"],sort_keys=True,separators=(",",":"),ensure_ascii=False); print(hashlib.sha256(b.encode()).hexdigest()==d["sha256"])' export.json

It prints True for an unaltered file.

Each app also has an Audit tab, read by its editors. It shows the app’s own evidence: grants, with who gave each one and when; deploys and who started them; packages and an SBOM per release; reach; credential age; logs; viewers; and deletion. Each section is checked exactly as the page it mirrors would be. An editor who is not an administrator sees the app’s change history as Refused, with the reason, and never sees more than they could elsewhere. A personal API key can read it; deploy keys cannot.

API
The reading the tab shows GET /api/v1/apps/{id}/audit-file
The export, with its digest GET /api/v1/apps/{id}/audit-file/export
One release’s SBOM GET /api/v1/apps/{id}/deployments/{deploymentID}/sbom

Only the export carries a digest, a sha256 beside the report member under the same rule as this report’s, and the command above checks it too. The reading is the live page and has none.

It lists access. Reviewing that access is the organization’s job, not Toft’s.

Administrators in a browser only. All five routes return 404 to non-administrators and refuse every API key class, deploy keys included. Scan targets is the deliberate contrast: a deploy key can read addresses, not posture.

Not license-gated — a lapsed install can still read its own posture.

Out of scope: other frameworks, POA&M, remediation tracking, per-app compliance, scheduled generation, attestation.