ShieldFive internal security review
This directory contains the internal security review of ShieldFive's design and implementation, conducted in 2026-05 ahead of public launch. Each task is a focused 2-4 hour session producing a written finding document.
What this folder is
This is the public, on-disk record of ShieldFive's internal
security review of the @shieldfive/crypto cryptography library.
The review is complete; the executive
summary is published on the
/security page, and this folder
is what that summary points at for evidence. Every claim on
/security resolves to a row in triage.md and a
section in one of the task documents.
The review is intended as the baseline an external audit engagement
would start from rather than something the firm has to discover.
HANDOFF.md is written for that audience explicitly.
Reading order
For a reader landing here cold:
- This README — orientation, methodology, task table.
HANDOFF.md— entry point for an external auditor; also useful for any technical reader who wants the "what's in flight, what to trust vs verify" view.- Individual task documents in numerical order —
task-01-wire-format-spec-review.mdthroughtask-06-upload-proof-system.md. Each is self-contained; skim the Summary section first and read the full document only for surfaces you care about. triage.md— the canonical state-of-everything table. One row per finding, with severity, status, recommended fix, and PR link. The page on/securitycites counts from this file at publication time.
How to file a finding
If you walk the task documents and the triage rows and find something the review missed, the bug bounty program is the canonical reporting channel. Reports are paid; ShieldFive operates the program directly without a third-party platform.
The triage convention mirrored from this file is: one row per finding, with severity (Critical / High / Medium / Low / Informational), status (Open / In progress / Fixed / Accepted / Document), affected component, recommended fix, and the PR or migration that lands the fix once it lands. If a report adds to the triage table, it follows that shape.
Status
| Task | Title | Status | Doc | Findings |
|---|---|---|---|---|
| 1 | Wire format spec review (v0 + v1) | Complete | task-01 | 13 (0 critical/high, 3 medium, 6 low, 4 informational) |
| 2 | Key derivation review | Complete | task-02 | 8 (0 critical/high, 2 medium, 4 low, 2 informational) |
| 3 | Threat model review against current implementation | Complete | task-03 | 7 (0 critical/high, 3 medium, 3 low, 1 informational) |
| 4 | AEAD usage audit | Complete | task-04 | 6 (0 critical/high, 1 medium, 3 low, 2 informational) |
| 5 | Streaming worker invariants review | Complete | task-05 | 7 (0 critical/high, 0 medium, 5 low, 2 informational) |
| 6 | Upload proof system review | Complete | task-06 | 10 (0 critical/high, 0 medium, 2 low, 8 informational) |
The server-side and web-application tasks of the review (share password and share-link handling, service-role boundary, RLS, database constraints and triggers, RPC function authorization, and the consolidated web-application surfaces) are kept in the private web repository and are not part of this published set.
Triage status for individual findings lives in triage.md.
Methodology
Each task produces task-NN-{slug}.md following an established template:
- Summary — one paragraph: did the area hold up, what's the highest-impact finding.
- Findings — one entry per drift, numbered
N.M. Each entry has Severity, Affects, Component, Description (with file:line citations), Reproduction or evidence, Recommendation. - What I checked but did not find issues with — mandatory. This is the audit trail that distinguishes a review from a checklist; without it the document cannot tell a future reader whether an unmentioned area was covered-and-clean or simply skipped.
- Out of scope (deferred to other tasks) — explicit handoffs.
- References — exact file paths and (where available) commit SHAs pinning the state reviewed.
Severity calibration
Used consistently across every task in this review:
- Critical — an attacker can recover plaintext, recover keys, or impersonate a user. Production fix required before any other work.
- High — an attacker can deny service to a user, exfiltrate metadata they shouldn't see, or bypass an access control that's not crypto- level. Fix required within days.
- Medium — a defense-in-depth layer is weaker than documented. Spec drift that could lead to a future bug. Fix on next planned work in the area.
- Low — documentation drift, dead code, hardening opportunity. Fix when convenient.
- Informational — observation without an action item. The "what I checked" section is implicit informational findings.
Tasks
The published crypto-library review covers six tasks, each producing a finding document at task-NN-{slug}.md.
-
Wire format spec review (v0 + v1) —
crypto/spec/format-v0.md,crypto/spec/format-v1.md, and the corresponding implementations. Spec-vs-implementation alignment audit. -
Key derivation review —
crypto/spec/key-derivation.md. Argon2id parameters, HKDF info-string domain separation, ML-KEM-1024 keypair derivation, master secret derivation, recovery key handling, no key reuse across contexts. -
Threat model review against current implementation —
crypto/spec/threat-model.md. For each protected-against threat, identify the mechanism. For each excluded threat, verify it's still excluded under v1. -
AEAD usage audit — Across both v0 and v1: nonce reuse prevention, AAD non-emptiness, tag-check-before-plaintext, wrong-key fail-fast.
-
Streaming worker invariants review —
utils/sfCryptoWorkerImpl.ts. Single-frame-in-flight invariant under all paths (encrypt/decrypt × v0/v1 × happy/error). Content key zeroing. -
Upload proof system review —
utils/uploadProof.ts,utils/uploadProofClient.ts. v0/v1 proof shapes, three-way cross-check, proof key uniqueness, timing-safe MAC, version confusion.