1 · What is live vs. pilot-gated
| Capability | Status | Unlock |
| Journal (hash-chained, offline sync, mobile capture, ID scan) | LIVE | — |
| Cases, encrypted evidence, legal hold, payments, analytics, org/firm admin | LIVE | — |
| Commission verification (document tier) + e-seal with SPECIMEN gating | LIVE | State-portal automated checks activate per state as adapters are confirmed |
| Digital sealing of PDFs (PAdES X.509 signature + certificate page + seal) | LIVE | Each notary enrolls a certificate — test cert for pilot, AATL CA cert for production; notary needs their state e-notary registration to use it for real acts |
| In-person electronic notarization sessions (consent → identity → ceremony → sealed) | LIVE | — |
| Remote video sessions — ceremony, recording custody, session sealing | PILOT | LiveKit configured (§5) for live video; sessions are marked pilot until identity proofing is active |
| Appointment booking (public page, slots, ICS calendar files, auto-cases) | LIVE | — |
| Location assurance (GPS + IP region + timezone, notary gate on remote ceremonies) | LIVE | IP-intelligence vendor (IPQualityScore/MaxMind-class) recommended for production VPN/proxy detection — adapter seam in api/core/location.py; state boundary check is bounding-box (coarse) by design |
| Statutory remote identity proofing (credential analysis + KBA) | VENDOR REQUIRED | Contract with an identity vendor (IDology/Persona class); provider adapter seam is built. Their compliance review takes weeks — start the conversation now. |
The honest line for testers: every remote-video session is labeled "pilot" on the signer's screen and in the session record, and states plainly that statutory identity proofing is not active. No pilot session should be represented as a remote notarization of record. In-person acts — paper or digitally sealed — are real.
2 · Deployment runbook
# On the server (Ubuntu, Python 3.11+)
unzip sealbook-full-build.zip && cd sealbook/app
python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt
cp .env.example .env # then edit — see §3
python -m api.seed_states # 51-state rules (required)
python -m api.gen_state_pages
python -m api.seed # demo data — SKIP in production
uvicorn api.main:app --host 0.0.0.0 --port 8070
# or: docker compose -f deploy/docker-compose.yml up -d
# or: systemd unit at deploy/sealbook.service (/opt/sealbook)
Put it behind the Cloudflare tunnel (or the provided Caddyfile) with HTTPS — camera and video APIs require a secure origin. URL map: landing /, app /app/, handbook /handbook.html, this manual /ops-manual.html, ID-scan test /test-id.html, state pages /notary-journal/, signer pages /sign/* and /ron/*.
Mobile app: cd mobile && npm install && npx expo start, open in Expo Go, point the Server field at your deployment. Store builds via eas build.
3 · Configuration reference (.env)
| Variable | Purpose |
SECRET_KEY | JWT + key-wrapping root. Generate long and random; rotating it invalidates sessions. Back it up — losing it means losing encrypted files. |
DATABASE_URL | Postgres in production (postgresql+psycopg2://…); SQLite by default for pilots. |
STORAGE_DIR | Encrypted file store. Back this up with the database. |
STRIPE_SECRET_KEY / STRIPE_WEBHOOK_SECRET | Stripe payments, subscriptions, billing portal, and webhooks. Blank = mock/disabled billing (fine for pilot). |
STRIPE_PRICE_SOLO_MONTHLY / STRIPE_PRICE_SOLO_YEARLY / STRIPE_PRICE_PRO_MONTHLY / STRIPE_PRICE_COUNTER_MONTHLY / STRIPE_PRICE_FIRM_MONTHLY | Stripe recurring Price IDs used by public checkout and in-app plan changes. |
PLATFORM_ADMIN_EMAILS | Comma-separated owner emails that can see the SealBook Billing tab. |
TSA_URL | RFC 3161 timestamp authority for signed PDFs, e.g. http://timestamp.digicert.com. Blank = no timestamp (pilot OK; set for production sealing). |
LIVEKIT_URL / LIVEKIT_API_KEY / LIVEKIT_API_SECRET | Video layer (§5). Blank = remote sessions run without in-app video (all record steps still function). |
MILEAGE_RATE_CENTS / PLATFORM_FEE_PCT | Business math defaults. |
4 · Enabling digital sealing
- Verify the commission. Settings → E-notary → upload the commission certificate. The evidence (document hash, entered data, timestamp) is logged and retained — this satisfies the seal-vendor proof-of-commission duty. Until verified, the e-seal renders with a SPECIMEN watermark and PDF sealing is refused. Every seal render is logged in
seal_issuances.
- Enroll a signing certificate. Settings → E-notary → upload the PKCS#12 (.p12/.pfx) and its passphrase. The file is stored encrypted; the passphrase is verified and discarded — it is required again at every signing and is never stored.
- Pilot: a self-signed test certificate is fine (the test suite shows how one is generated). Adobe will show "unknown trust" — expected.
- Production: an AATL-listed CA certificate (IdenTrust-class, ~$50–100/yr, identity-proofed issuance) so Acrobat shows the green trusted checkmark; plus the notary's electronic-notary registration with the commissioning office for their state.
- Seal a document. Case → file list →
digital seal on any PDF → signer name, act type, passphrase. SealBook appends the statutory certificate page with the verified e-seal, signs the whole PDF (PAdES), stores it as new evidence, and returns the SHA-256.
- Bind to the journal. Create the journal entry for the act with that hash in its file hashes. The sealed PDF and the journal entry now cross-verify — the evidence package re-checks both.
Tested in CI: a signed PDF validates as intact and trusted; flipping one byte breaks validation; the hash binds into the chain. That's the tamper-evidence claim, proven on every build.
5 · Enabling the video layer
SealBook uses LiveKit (open source) for live audio-video. One-time setup on the server (or any $40 VPS):
> docker run -d --name livekit -p 7880:7880 -p 7881:7881 \
-p 50000-50200:50000-50200/udp \
-e LIVEKIT_KEYS="APIkey: APIsecret" livekit/livekit-server \
--bind 0.0.0.0
# then in SealBook .env:
LIVEKIT_URL=wss://livekit.yourdomain.com
LIVEKIT_API_KEY=APIkey
LIVEKIT_API_SECRET=APIsecret
With those set, remote sessions get live rooms automatically: the signer's session page connects in-browser (no install), and the notary token is returned by GET /api/ron/sessions/{id}. Recordings: run LiveKit egress (composite MP4) and upload the file to POST /api/ron/sessions/{id}/recording — it is encrypted into the case, hashed, and required before a remote session can complete. Put LiveKit behind TLS (Caddy/Cloudflare) — browsers require wss://.
Bandwidth math: a 30-minute composite recording ≈ 200–400 MB. Size STORAGE_DIR accordingly and include it in backups.
6 · The VisaDC pilot script
Goal: VisaDC staff exercise every flow in one sitting (~30 minutes) and report friction. Have them use the User Handbook as the reference; this is the test sequence:
- Sign in with the demo account (or a fresh account with their real commission data). Confirm the state-rule panel in Settings shows their jurisdiction correctly.
- ID scan test — open
/test-id.html on a phone, photograph the back of a driver's license, confirm the parsed fields and that only last-4 appears.
- Record an act on mobile — full 5-step capture including barcode autofill and on-screen signature. Then airplane mode, record another, and watch it sync on reconnect.
- Case + evidence — create a case, upload a PDF, run the evidence package, confirm "all intact."
- Verification + e-seal — view the SPECIMEN seal, verify by document, watch the watermark drop.
- Digital seal — enroll the provided test certificate, seal the uploaded PDF, open it in Adobe Acrobat and inspect the signature panel; then edit the PDF in any tool and reopen — watch validation break.
- Journal binding — create the entry with the sealed hash; run the evidence package again and confirm cross-verification.
- In-person electronic session — create a session, run the signer's consent/identity steps on a second device, seal, complete.
- Remote pilot session — same flow in remote mode; observe the pilot banner and (if LiveKit is configured) the live video connection; upload any MP4 as the recording; confirm completion is refused until the recording exists.
- Booking — set up the Schedule tab, open the public booking page on another device, book a slot, download the .ics, confirm the auto-created case, cancel via the manage link and watch the slot free up.
- Location gate — create a remote session and try to start the ceremony before the location check (blocked), run the check from the session drawer, observe the verdict and that a failed verdict blocks ceremony start.
- Firm admin — open the Admin tab, invite a second tester, have them record a firm-scoped act, view it in receipts, then offboard them and confirm the receipt survives.
Pilot ground rules for VisaDC: test documents only — no real client documents until production hosting, the LLC, and (for remote acts) identity-proofing vendors are in place. Remote sessions are labeled pilot and are not notarizations of record. In-person digital seals made with a test certificate are demonstrations; real sealing requires the notary's AATL certificate and e-notary registration.
7 · Security model & operator duties
- Tamper evidence: journal entries are SHA-256 hash-chained (client- and server-verified); signed PDFs are PAdES-sealed; recordings and files are hash-bound to entries; the audit log is itself hash-chained.
- Encryption: every stored file (evidence, certificates, recordings, verification documents) is Fernet-encrypted under per-notary keys wrapped by
SECRET_KEY. Database + storage directory are both required to read anything.
- PII minimization: no ID images, no full ID numbers, ever — enforced in code, including per-state prohibitions (TX/MT strip last-4 automatically). The ID-decode tool processes in memory and discards.
- Key custody: signing-certificate passphrases are never stored; certificates are encrypted at rest; the private key is only in memory during a signing operation.
- Access: role checks on every org endpoint (admins see receipts, never journals); tenant isolation on every notary endpoint; one-use expiring tokens for signer-facing pages; every evidence access audited.
- Operator duties: protect
.env (600 permissions), keep the host patched, use HTTPS only, restrict server SSH, and review the audit log for anomalies. Production must run on hardened cloud hosting — not a home network — before real client data.
8 · Backups, retention & incident response
- Back up together, nightly: the database,
STORAGE_DIR, and .env (encrypted, offsite). Files without the key, or the key without files, are useless — that's a feature; keep both safe.
- Retention: per-file
retained_until follows the commission state's rule (5–10 years). Files bound to sealed entries or under legal hold cannot be deleted by anyone, including operators, through the app.
- Lost/stolen device: the notary signs in elsewhere and rotates their password; journals live server-side. States with notification duties (e.g., journal lost/stolen notices) — the notary files with their commissioning office.
- Suspected tamper: run journal verify + evidence packages; the break point is pinpointed by design. Preserve the audit log; it is the investigation.
9 · Production go-live checklist
- ☐ Cloud VPS (hardened), HTTPS, firewall; move off pilot hardware
- ☐ Postgres with nightly encrypted backups;
SECRET_KEY escrowed safely
- ☐ LLC formed before legal-industry customers; terms of service + privacy policy reviewed
- ☐ Stripe live keys, recurring Price IDs, billing portal, and webhook secret set
- ☐ Stripe webhook points to
/api/payments/webhook and listens for checkout, subscription, invoice, and payment-link events
- ☐ TSA_URL set; each production notary: AATL certificate + state e-notary registration
- ☐ Identity-proofing vendor contracted before any remote notarization of record
- ☐ Biometric counsel review before marketing thumbprint capture
- ☐ State-rules research pass completed for every state you market compliance in. Run
python api/tools/state_rule_reviewer.py --fetch inside the API container, replace second-party citations with official primary sources, and only market states whose packet row is official-source-backed.
- ☐ SMTP live credentials configured and password reset tested end-to-end from
/app/
- ☐ Evidence-mode act test completed: create Pro case, attach case from New Entry, capture/upload multiple files, seal entry, verify hashes in Evidence package
- ☐ Rate limiting / WAF at the edge (Cloudflare) for public endpoints