External audit handoff
This document is the entry point for an external security audit
engagement against @shieldfive/crypto, the open-source
cryptography library. It is written for an auditor or audit firm
walking into the codebase cold and trying to figure out where to
start.
The published crypto-library review produced six task documents and a triage table of their findings. The framing this document gives is: what was looked at, how deep, what to re-verify, what to trust as a starting baseline, and what is in flight at handoff.
Scope of the internal review
What was reviewed
@shieldfive/crypto library (separate GitHub repository
shieldfive/crypto):
- v0 and v1 wire formats —
spec/format-v0.md,spec/format-v1.md, and the corresponding parsers (src/format/,src/suites/*-v1/). - Key derivation tree —
spec/key-derivation.md. Argon2id presets, HKDF-SHA-256 info-string domain separation, ML-KEM-1024 keypair derivation from a 64-byte master secret split into(d, z), master-secret-to-recovery-key derivation. - Threat model —
spec/threat-model.md. For each protected-against threat, the mechanism. For each excluded threat, verification it remains excluded under v1. - AEAD usage discipline — nonce reuse prevention, AAD non-emptiness, tag-check-before-plaintext, wrong-key fail-fast across v0 and v1 suites.
Client-side crypto integration (ShieldFive web repository):
- Streaming worker invariants in
utils/sfCryptoWorkerImpl.ts— single-frame-in-flight under every path (encrypt/decrypt × v0/v1 × happy/error). Content key zeroing on completion and on abort. - Upload proof system —
utils/uploadProof.ts,utils/uploadProofClient.ts. v0/v1 proof shapes, three-way cross-check (client/server/B2), proof-key uniqueness, timing-safe MAC comparison, version confusion.
What was not reviewed
These surfaces are outside the published crypto-library review and are expected to be in scope for an external engagement, or are explicitly deferred to a follow-up engagement:
- Cipher suite
0x04(aes-gcm-v2) — the review covered the three suites in force at the time (0x01AES-256-GCM,0x02XChaCha20-Poly1305,0x03ML-KEM-1024 hybrid); suite0x04was added to@shieldfive/cryptoin1.0.0-alpha.11after this review completed and is not covered here. It is opt-in via a dedicated subpath import only — the production default remains Suite0x03— and it is queued for the same audit-firm-depth review the other suites received. - Server-side and web-application surfaces — share-password and share-link handling, the service-role boundary, RLS policies, database constraints and triggers, RPC function authorization, and the consolidated web-application surfaces were reviewed separately and are kept in the private web repository; they are not part of this published handoff.
- Mobile application — the
mobile/repo is in active development but has not been brought under the internal review. Per the plan, mobile follows the web application stabilization. - Infrastructure layer — Vercel deployment configuration, edge-network behavior, Vercel build environment, secrets storage at the platform layer.
- B2 bucket policy — Backblaze B2 bucket configuration, cross-account replication boundaries, direct-upload URL scope.
- Backup and disaster recovery procedure —
docs/ops/backups.md,docs/ops/disaster-recovery.mdexist; their security properties under restore have not been validated. - CSP / XSS under live computation —
docs/security/csp-checklist.mdis a checklist of policies enforced at the response layer. Live XSS surface coverage is external work. - Third-party services beyond their public APIs — Stripe, Supabase, Backblaze B2, Resend. The integration surfaces are reviewed; the services themselves are trust-the-vendor.
Method
Each task document follows a fixed template:
- Summary — one paragraph: did the area hold up, highest-impact finding.
- Findings — one entry per drift, numbered
N.M. Each entry carries 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, a future reader cannot tell whether an unmentioned area was covered-and-clean or simply skipped.
- Out of scope (deferred to other tasks) — explicit handoffs to other task documents or to external audit.
- References — file paths and (where available) commit SHAs pinning the state reviewed.
Findings are numbered TASK.M (e.g. 2.3 is the third finding
in Task 2) and tracked in triage.md as one row
per finding.
Severity legend
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, or 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" sections are implicit informational findings.
Known limits
The depth is uneven by design.
- Tasks 1–6 were reviewed at audit-firm depth. Each task is a focused 2–4 hour session on one surface, with full enumeration of the surface, file-and-line citations for every finding, and an explicit "what I checked and did not find issues with" section. The reading audience for these documents is an auditor who wants to skim what was looked at and where the attention concentrated.
- The review is static-inspection-heavy. The wire-format parsers, key-derivation tree, and AEAD discipline were inspected at the code level rather than exercised under live adversarial pressure or fuzzing. An external engagement is expected to do the live-probe and differential-testing work.
- The review covers library state at the time it was written. The per-document references section pins the commit SHA reviewed; the library moves, so re-pin before relying on a citation.
What to verify vs trust
For an external engagement under time pressure, these are suggested allocations:
Verify independently — load-bearing invariants
- Crypto invariants in
@shieldfive/crypto: - Streaming worker invariants — single-frame-in-flight and
content-key zeroing in
task-05. - Upload proof cross-check — the three-way client/server/B2
proof verification in
task-06.
Trust as a starting baseline — start from, don't redo
- Scope enumeration. The list of files, routes, RPCs, and tables in each task document is the result of a deliberate enumeration pass. Re-enumerating before starting work would duplicate effort; the right move is to read the enumeration and flag anything that looks missing.
- Finding catalogue structure.
triage.mdis the state-of-everything table. An external engagement can append to it under the existing severity/status convention rather than building a parallel catalogue. - "What was checked and clean" sections. Each task document's "what I checked but did not find issues with" section is the internal review's positive claim about each surface. Treat those as the internal review's positive findings — they are claims that an external engagement can re-verify but should not need to re-derive from scratch.
Re-verify with fresh eyes — if calendar allows
- Differential and fuzz testing of the parsers — the v0/v1 decode paths and the suite dispatch were reviewed by inspection; an external engagement is the right place to drive them under malformed-input fuzzing and cross-implementation differential testing.
- ML-KEM-1024 derivation against the reference — the
deterministic
(d, z)seed split and keypair derivation were checked against the spec by reading; re-deriving against a reference implementation is worth the fresh eyes.
Suggested first 1–2 days
A pragmatic time allocation for an auditor under time pressure:
- Read this HANDOFF (~2 hrs). End with a written list of questions or surfaces you want more on. The internal review does not pretend to be exhaustive; the list of questions is the honest input to the engagement scope.
- Read Tasks 1, 2, 3 (~3 hrs) — wire format, key derivation, threat model. These are the crypto core, written at audit-firm depth, and the foundation everything else sits on.
- Read Tasks 4, 5, 6 (~2 hrs) — AEAD usage discipline, streaming worker invariants, upload proof system. The client-side integration the wire format relies on.
- Walk the triage table (~1 hr). Spot the rows marked Open and read the recommended fix; spot the rows marked Fixed and verify the linked PR landed.
- Form first impressions and request what isn't in the docs. Specific questions about a surface, missing reproducibility information for a finding, additional context on a deferral — the internal review team will produce on demand.
What is in flight at handoff
This section is updated as state changes. As of the publication
of Step 12 of the plan
(final-plan.md):
- Open crypto findings. The two Open findings in the published
set — the flat-envelope key hierarchy (2.2) and the Argon2id
preset on high-entropy metadata-key inputs (2.3) — are spec /
implementation hardening items tracked in
triage.mdwith recommended fixes; neither is a launch blocker. - Phase 3 (Suite 0x03 default) — design phase, not started.
Per Step 13 of the plan. ML-KEM-1024 + XChaCha20-Poly1305 is
the production-default cipher suite for Phase 3. The Phase 3
prerequisites in
@shieldfive/crypto(crypto#1 through crypto#4) are closed; the application-side rollout shape follows the Phase 2 five-stage pattern. - External audit deferral. The audit will be commissioned when product revenue funds it. The internal review is the work that establishes the baseline; the external engagement is expected to extend that baseline rather than replace it.
If you are landing on this document because the external audit
engagement is starting, the maintainer to contact is the team
behind the bug bounty program at [email protected]. The
/security page is the
public-facing companion to this document.