Independent security review prep (QuantZK billing / receipt trust layer)
Audience: Halborn, NCC Group, Trail of Bits, or equivalent cryptography / application-security reviewers.
Goal: Raise the credibility ceiling from “we tested our protocol” to “an independent team reviewed these trust assumptions and attack surfaces.”
Stance: Prefer a review that finds issues you can fix over a magical zero-finding report.
Scope recommendation (narrow, billable wedge)
In scope:
- api-billing-v2 issuance & verify (
POST /api/vdi/billing/attest, async accept,POST /api/vdi/billing/verify) - Portable QZR-1 receipt offline verification path (
@quantzk/vdi-billing/client,@quantzk/sdk,@quantzk/verify) - Replay uniqueness
(tenant_id, billing_window_id, event_id)crash-safe reserve/commit - Async prove pipeline Postgres SoT, BullMQ as work queue only, leases + sweeper recovery
- Meter trust anchors, commitment binding (Phase-1 / Phase-2), revocation feed semantics
- Transparency log inclusion proofs (honesty assumptions of the log operator)
Out of scope (unless separately contracted):
- Full ZKCaptcha widget / age-verification product surface
- Broad “VDI for all machine decisions” roadmap
- Infrastructure hardening of Railway/Netlify accounts
- Social engineering / physical security
Explicit trust assumptions (ask reviewers to attack these)
| Assumption | Failure mode if false |
|---|---|
| Ed25519 meter keys are controlled by the claimed meter operator | Forged usage events with valid envelopes |
VDI_SIGNING_KEY is not exfiltrated | Issuer can mint arbitrary attestations |
| Groth16 verifying keys match published ceremony / manifest hashes | Soundness / binding break |
| Postgres is integrity-trusted for replay reserve | Double charge under partition if DB lied |
| Redis is not SoT | Queue loss must not drop accepted jobs (recovery story) |
| Revocation feed availability for Strict profiles | Stale “accepted” vs “currently good” confusion |
| Offline verify without revocation ≠ governance clearance | Reviewers should confirm messaging |
Attack surfaces to prioritize
- Fingerprint / charge malleability: can billed micros diverge from committed fingerprint while verify still passes?
- Replay races: concurrent accepts, crash between reserve and job insert, mid-prove worker SIGKILL.
- Async confusion: temporary receipt vs final attestation; webhook replay; lease steal; sweeper double-enqueue.
- Profile downgrade: Standard vs Strict; missing revocation still “VALID” offline.
- Commitment binding bypass: Phase-1 vs Phase-2; digest not constrained by public signals.
- Meter kid / PEM mixups: wrong trust JSON; signature over non-canonical event.
- Receipt portability: truncated
.qzk, field drop, algorithm confusion in browser vs Node verifier. - Transparency: inclusion proof for wrong entry; log operator equivocation (document limitation).
Evidence pack (attach to engagement)
| Item | Location |
|---|---|
| Pilot + trust chain | protocol/docs/api-billing-pilot.md |
| Async architecture + recovery | protocol/docs/api-billing-async.md |
| Live Railway smoke | protocol/docs/api-billing-async-live-smoke-evidence.md |
| Chaos evidence | protocol/docs/api-billing-async-chaos-evidence.md |
| Attack matrix | protocol/docs/billing-v2-attack-matrix.md |
| Formal audit methodology | protocol/docs/formal-security-audit.md |
| Binding model | protocol/docs/vdi-cryptographic-binding-model.md |
| QZR-1 draft | protocol/docs/qzr-1.md |
| §4.4 freeze evidence (pinned registry + vectors) | protocol/docs/qzr-1-section-4-4-freeze.md |
| Charge Authority v1 freeze (pins + reproduce) | protocol/docs/charge-authority-v1-freeze.md |
| Charge Authority v1 reviewer map | protocol/docs/charge-authority-v1-reviewer-map.md |
| Charge authority claims | protocol/docs/charge-authority.md |
| Adversarial / pilot CI | verifier-api npm run test:billing-pilot, test:billing-adversarial, test:billing-async-recovery |
| Committed-value + Claim 1 suites | protocol npm run test:committed-values, npm run test:sdk |
| Circuit artifacts + MPC transcript | verifier-api/circuits/apiBillingV2/ |
Suggested review questions (paste into SoW)
- Under the stated trust model, can an adversarial meter operator or compromised API signing key be distinguished by verifiers?
- Does async acceptance preserve “at most one final charge identity” per event key across worker and Redis failure?
- Are offline and online verify paths equivalent for Standard profile on a complete QZR-1 receipt?
- What is the precise security difference between historical validity and Strict+revocation “currently accepted”?
- Which claims in public docs over-reach the cryptography?
Deliverables we want from the firm
- Written report with severity-rated findings
- Explicit residual risks / trust assumptions
- Confirmation or negation of double-charge and binding claims
- Optional: short public attestation letter suitable for design partners
Internal readiness checklist
- [ ] Freeze a git SHA + artifact hashes for the engagement
- [ ] Provide staging API + attest secret + sample
.qzkcorpus (valid + tampered) - [ ] Point reviewers at revocation URL and transparency head
- [ ] Assign a single technical contact for finding triage
- [ ] Budget engineering time to fix findings before marketing the review
Positioning after the review
Preferred public sentence:
An independent security team reviewed QuantZK’s billing receipt trust assumptions and attack surfaces; findings were remediated and residual risks are documented.
Avoid:
Certified secure / unbreakable / zero-knowledge means no trust assumptions.
