Skip to content

feat(reports): Framework Attestation kind + CSV evidence face (B1)#641

Merged
remyluslosius merged 1 commit into
mainfrom
feat/reports-b1a-attestation
Jun 22, 2026
Merged

feat(reports): Framework Attestation kind + CSV evidence face (B1)#641
remyluslosius merged 1 commit into
mainfrom
feat/reports-b1a-attestation

Conversation

@remyluslosius

Copy link
Copy Markdown
Contributor

Reports Phase B1 (backend) — the auditor/GRC bulk evidence path. Adds the attestation report kind + the CSV face.

The key design refinement

Instead of storing the ~50k-row result set in the snapshot (the §10.5 blob path), the attestation snapshot freezes just the host → latest-completed-scan_id mapping (small). Because scan_results are immutable, that's point-in-time without copying bulk rows — so the snapshot stays inline JSONB, no blob store needed, sidestepping the one-way-door storage decision. The CSV face reconstructs the rows from those frozen scans on demand.

What

  • New attestation kind (migration 0043 extends the kind CHECK). POST /reports:generate takes kind=attestation; unknown kind → 400 reports.invalid_kind.
  • Snapshot = AttestationContent {framework, hosts_total, hosts_attested, attested:[{host_id, scan_id, scanned_at}]}.
  • CSV face (?format=csv): one row per (host, rule) from the frozen scans' scan_results — hostname, ip, os, rule_id, status, severity, framework_refs, evidence_sha256, scanned_at — applying the framework lens. csvSafe-guarded (CWE-1236), row-capped with a trailing disclosure row, cached in report_faces.
  • Faces are now kind-scoped: pdf executive-only, csv attestation-only, json canonical for both (kind-aware re-marshal preserves signing verifiability). Signing applies to attestation identically.

SDD

api-reports v1.7.0 — C-03 (multi-kind), C-10 (kind-scoped faces), C-13 (attestation), AC-19 (signed attestation + CSV + framework lens + face/kind validity + ErrInvalidKind).

Validation

gofmt/vet/build clean; go mod tidy no-op; specter check 111; api-reports 19/19 (100%); report suite + full server suite (407s) green; schema.d.ts regenerated.

Follow-up B1b: frontend kind selector + kind-aware download (CSV for attestation).

Reports Phase B1 backend (docs/engineering/reports_design.md §12). Adds
the auditor/GRC bulk-evidence kind. Frontend (kind selector + CSV
download) follows as B1b.

- A new 'attestation' report kind (migration 0043 extends the kind
  CHECK). POST /reports:generate takes kind=attestation; an unknown kind
  is 400 reports.invalid_kind.
- The attestation snapshot FREEZES which completed scan attests each
  in-scope active host (the latest as of generation) - AttestationContent
  {framework, hosts_total, hosts_attested, attested:[{host_id, scan_id,
  scanned_at}]}. It does NOT copy the bulk rows: scan_results are
  immutable, so the snapshot is point-in-time while staying small (inline
  JSONB, no blob store needed - sidesteps the §10.5 storage decision).
- CSV face (GET /reports/{id}/export?format=csv): reconstructs one row per
  (host, rule) from those frozen scans' scan_results - hostname, ip, os,
  rule_id, status, severity, framework_refs, evidence_sha256, scanned_at -
  applying the framework lens. csvSafe-guarded (CWE-1236), row-capped with
  a trailing disclosure row, cached in report_faces.
- Faces are now kind-scoped: pdf executive-only, csv attestation-only,
  json canonical for both (kind-aware re-marshal preserves the signing
  verifiability). Signing applies to attestation the same way.

SDD: api-reports v1.7.0 (C-03 multi-kind, C-10 kind-scoped faces, C-13
attestation, AC-19). gofmt/vet/build clean; go mod tidy no-op; specter
111 (api-reports 19/19, 100%); report suite + full server suite (407s)
green; frontend schema.d.ts regenerated.
@remyluslosius remyluslosius merged commit e632f5e into main Jun 22, 2026
13 checks passed
@remyluslosius remyluslosius deleted the feat/reports-b1a-attestation branch June 22, 2026 02:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant