← Security

CheckTrail security overview

For broker-dealer vendor due diligence. Last updated 2026-09-25.

CheckTrail is run by a one-person company. This document says what is in place, what is being built, and what is not done. We do not claim any certification we don't hold.

Item Status
SOC 2 Type I or Type II report Not obtained. Readiness work under way; see soc2-readiness.md.
Independent penetration test Not done. Planned before the first paid firm goes live, then yearly.
Legal review of recordkeeping (SEC 17a-4, FINRA 4511) Pending. Questions listed in ../recordkeeping.md.
Cyber insurance Not in place. To be quoted.
Signed DPAs with every subprocessor Not yet reviewed/recorded. See subprocessors.md.

1. What CheckTrail is

A web app (installable on phones) that broker-dealer staff use to photograph and log client checks, record where each check was forwarded, get principal review, flag exceptions, and export the blotter for exams. It does not move money or deposit checks.

2. Architecture in one paragraph

A Next.js application runs as serverless functions on Netlify. Structured data is in Neon Postgres (US). Check images and exam packages are in AWS S3 (us-east-1 or us-east-2), locked write-once with Object Lock in compliance mode and encrypted with a customer-managed AWS KMS key. Check reading uses AWS Textract. Email alerts go through Resend, billing through Stripe, and errors to Sentry. Diagram: data-flow-diagram.md. Full detail: ../data-flow.md.

3. Data we hold

  • Staff: name, work email, role, branch, password hash, encrypted 2FA secret, sign-in history.
  • Checks: payer name/address, client name, check number, date, amount, payee, bank name, last 4 digits of routing and account numbers only, product type, notes, images of the check.
  • Clients: name, registration, and the client's account number encrypted (AES-256-GCM) with the last 4 shown.
  • Audit log of every view, change, export and sign-in, with IP address and browser.

We do not hold Social Security numbers, dates of birth, full bank routing/account numbers from the check, card numbers or bank login details.

4. Encryption

Where How
Browser ↔ app HTTPS only (TLS certificates managed by Netlify). HSTS and other security headers: being added (section 8).
App ↔ Postgres TLS required by Neon.
App ↔ AWS HTTPS; the S3 bucket policy rejects non-TLS and TLS older than 1.2.
App ↔ Resend / Stripe / Sentry HTTPS APIs.
Images and exports at rest S3 SSE-KMS with a customer-managed key, rotated yearly. The bucket rejects uploads that don't use that key.
Database at rest Neon storage encryption.
Sensitive fields AES-256-GCM in the app (client account numbers, 2FA secrets, SSO client secrets). In production the key is itself encrypted by AWS KMS and only decrypted in memory.
Passwords, recovery codes argon2id hashes (19 MiB memory, 2 passes). Never stored in readable form.
Session and link tokens Random 256-bit tokens; only SHA-256 hashes stored.

5. Sign-in and sessions

  • Passwords: at least 12 characters; obvious ones and ones containing the email name are refused.
  • Two-factor authentication is required for every password sign-in (authenticator app, TOTP). 8 one-time recovery codes, stored hashed.
  • Lockout: 5 failed attempts (password or 2FA) lock the account for 15 minutes. Per-IP limit of 30 sign-in attempts per 15 minutes and 10 2FA attempts per user per 15 minutes, enforced in Postgres so it holds across servers. Unknown emails take as long to reject as known ones.
  • Sessions: stored server-side; cookie is HttpOnly, Secure, SameSite=Lax. 30-minute idle timeout, 12-hour maximum. Sign-out, deactivation and admin action revoke sessions immediately. A page to list and end your own sessions is being added.
  • SSO (being built): OIDC and SAML per firm; a firm can require SSO for everyone. MFA is then enforced by the firm's identity provider.
  • Every sign-in, failure, lockout, 2FA enrollment and password change is in the audit log.

6. Access control inside the app

  • Four roles (rep, principal, home office compliance, firm admin) with server-side checks on every action. Reps see their branch; principals their assigned branches; compliance all branches; firm admins no check data unless also compliance.
  • Every query is scoped by firm. Automated tests (tenancy.db.test.ts) prove a user of one firm cannot read, list, edit, review, confirm, export or administer another firm's data, even holding every role.
  • Examiners get a read-only, single-package link that expires in 30 days or less and is audited.
  • Details: access-control-policy.md.

7. Record integrity

  • Nothing is overwritten: edits create new versions with who, when and why.
  • Record tables are insert-only, enforced by database triggers and a restricted database role.
  • The audit log is hash-chained per firm so changes are detectable.
  • Images and exports are locked in S3 compliance mode for the firm's retention period (default 6 years); nobody, including CheckTrail and AWS root, can delete them early.
  • Details and limits: ../recordkeeping.md.

8. Application security

  • Input validation with typed schemas (zod) on every action.
  • File uploads: 15 MB cap; file type decided from the file's first bytes, not its name; photos re-encoded to JPEG with all metadata (including GPS) removed; only images, PDFs and CSV accepted.
  • CSV exports neutralise spreadsheet formulas.
  • Stripe webhooks verified by signature and processed once.
  • The scheduled job endpoint requires a secret.
  • Being built: security headers (HSTS, frame denial, no-sniff, referrer policy) and a nonce-based Content Security Policy; Sentry with a scrubber that removes request bodies, cookies and any run of 6+ digits.
  • Application logs contain no check data or request bodies.

9. Infrastructure and operations

  • AWS resources defined in Terraform (infra/terraform/), least-privilege IAM for the app (no delete rights at all).
  • Production access: the founder only, MFA on every console. See access-control-policy.md.
  • Backups: Neon point-in-time restore; S3 versioning and Object Lock. Restore procedure written; not yet tested in production. See business-continuity.md.
  • Vulnerability management: vulnerability-management.md. CI with npm audit and Dependabot: planned, not configured.
  • Incident response: incident-response-plan.md.

10. Data location

All customer data is stored in the United States: AWS us-east-1 or us-east-2, Neon US region. Subprocessor locations: subprocessors.md.

11. Contact

Security questions and vulnerability reports: security@ (to be set up; until then the founder's email).