Skip to content

feat(reports): Signed badge + offline Verify on the report detail (A4b)#637

Merged
remyluslosius merged 1 commit into
mainfrom
feat/reports-a4b-verify
Jun 21, 2026
Merged

feat(reports): Signed badge + offline Verify on the report detail (A4b)#637
remyluslosius merged 1 commit into
mainfrom
feat/reports-a4b-verify

Conversation

@remyluslosius

Copy link
Copy Markdown
Contributor

Reports A4b (frontend) — completes signing from A4a, and finishes Phase A of the reports build-out. The report detail gains a Signed badge and an offline Verify action.

What

  • A verifyReport helper checks a signed report entirely in the browser:
    1. GET /api/v1/reports/signing-key for the public key;
    2. re-hash the canonical JSON face (export?format=json) with SHA-256 and compare to content_sha256 (content integrity);
    3. Ed25519-verify the signature via Web Crypto over the same domain-separated payload the server signs ("openwatch/report-snapshot/v1\n" + content_sha256).
  • Graceful degradation: where Web Crypto lacks Ed25519, the content hash is still verified and the result says so. An ephemeral dev key is disclosed.
  • The detail header shows a green Signed badge (key id on hover) + a Verify control, both gated on report.signature; the result (verified / failed / content-only) renders in the modal body.
  • All Web Crypto inputs are ArrayBuffers to sidestep the TS 5.7 Uint8Array<ArrayBufferLike> / BufferSource mismatch.

This mirrors A4a's offline-verification contract exactly, so the UI is a faithful client of the signing-key endpoint.

SDD

frontend-reports v1.4.0 — C-07 + AC-08 (source inspection of the verify helper + the Signed badge / Verify control). schema.d.ts regenerated for the signing fields + endpoint.

Validation

tsc / eslint / prettier clean; reports vitest 8/8; full frontend suite 327; specter frontend-reports 8/8 (100%).

This completes Phase A (A1 scope → A2 coverage → A3a snapshots → A3b PDF → A3b-2 download → A4a signing → A4b verify).

Reports A4b (frontend) - completes signing from A4a. The report detail
shows a Signed badge and an offline Verify action.

- A verifyReport helper checks a signed report entirely in the browser:
  fetch GET /api/v1/reports/signing-key, re-hash the canonical JSON face
  (export?format=json) with SHA-256 and compare to content_sha256
  (content integrity), then Ed25519-verify the signature via Web Crypto
  over the same domain-separated payload the server signs
  ("openwatch/report-snapshot/v1\n" + content_sha256). The Ed25519 step
  degrades gracefully where Web Crypto lacks it (content hash still
  verified); an ephemeral dev key is disclosed in the result.
- The detail header shows a green Signed badge (key id on hover) and a
  Verify control, both gated on report.signature; the verify result
  (verified / failed / content-only) renders in the modal body.
- All Web Crypto inputs are ArrayBuffers to avoid the TS 5.7
  Uint8Array<ArrayBufferLike> BufferSource mismatch.

SDD: frontend-reports v1.4.0 (C-07 + AC-08, source inspection).
schema.d.ts regenerated for the signing fields + endpoint. tsc/eslint/
prettier clean; reports vitest 8/8; full frontend suite 327; specter
frontend-reports 8/8 (100%). This completes Phase A of the reports
build-out.
@remyluslosius remyluslosius merged commit 9d9403d into main Jun 21, 2026
13 checks passed
@remyluslosius remyluslosius deleted the feat/reports-a4b-verify branch June 21, 2026 20:20
remyluslosius added a commit that referenced this pull request Jun 21, 2026
Reconciles the docs with the merged reports build-out.

- BACKLOG.md: the Reports entry flips Planned -> Phase A shipped (P1->P2),
  summarizing A1-A4b and the production signing-key op note; remaining
  work scoped to Phases B-D (OSCAL/CSV, async+scheduling, other kinds).
- reports_design.md: a STATUS banner on §11 records Phase A as shipped
  and the two in-flight plan adjustments (coverage shipped before the
  structural migration; A3/A4 split backend/frontend).
- SESSION_LOG.md: a Phase A handoff entry (per-PR summary, the live
  verification result, Phases B-D next, and the dev-serve / ephemeral-key
  gotchas).
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