Implements macOS v0: verae-print stamp + install-macos PDF menu items.
Saves {name}.pdf, {name}-verae-timestamp-{RECEIPTID}.pdf, and .verae.json.
Channels: verae (api.veraetime.net JWT) and zapier (zap.verae.ai xVerae- + attachPdf).
8.2 KiB
PrintToVeraeTimeStamp — Design Spec
Date: 2026-10-03 Owner: George Lambert / Verae Status: Draft
1. Goal
Provide a "Verae Timestamp" printer on macOS, Linux, and Windows. Printing to it:
- Captures the exact print output as a PDF.
- Computes SHA-256 of the whole PDF and of each page.
- Submits the digest(s) to the Verae Timestamping service (digest only).
- Receives the receipt (JSON, and certificate PDF if the API provides one).
- Lets the user Save, Print, or Both: the original PDF, the receipt, and optionally a combined "PDF + certificate page" or a PDF with the receipt embedded without altering the original bytes.
2. Non-goals
- Sending document content to Verae (never).
- Proving the source document (Word/Pages/etc.) — the proof is over the printed PDF bytes.
- Acting as a general PDF editor.
3. Key design facts
- The proof is over exact bytes. Printing the same document twice produces different PDFs (timestamps, IDs, fonts). Therefore the captured PDF must always be saved alongside the receipt; that file is the verifiable artifact.
- Embedding without breaking the hash. If the receipt is embedded, it is appended as a PDF incremental update (attachment + annotation/certificate page). The original byte range is unchanged, so
sha256(first N bytes)still matches. The receipt recordsN. - Per-page hashes. Each page is extracted as a single-page PDF (deterministic extraction via the same library/version) and hashed; the list is included in a canonical manifest whose SHA-256 is also stamped. This allows proving individual pages.
4. Verae Timestamp API (dual channel)
4.1 Verae Time (default — non-Zapier)
| Call | Purpose |
|---|---|
POST {base}/api/timestamp body {"data":<hex>,"digest":<hex>,"hashAlg":"SHA256","restamp":false} |
Stamp a digest. 200 with certificate or existing = done; otherwise returns a job id |
GET {base}/api/status/{jobId} |
Poll until completed |
GET {base}/api/hash/{digest} |
Look up existing stamp |
POST {base}/api/verify |
Verify |
- Default base:
https://api.veraetime.net - Auth:
Authorization: Bearer <token>from~/.verae/auth.properties(keysaccess_token/auth_token/id_token) - Certificate PDF: render locally from receipt when the API does not return a PDF body
4.2 Zapier / edge channel
| Call | Purpose |
|---|---|
POST https://zap.verae.ai/v1/timestamp body {sha256, attachPdf:true, wait:true, documentName} |
Stamp + optional registration PDF |
- Auth:
x-api-key: xVerae-…(or Bearer) from Keychain /~/.verae/xverae-token/ envXVERAE_TOKEN - Certificate PDF: decode
pdfBase64from the JSON response (or raw PDF whenAccept: application/pdf)
5. Architecture
┌──────────── OS print system ────────────┐
App ──▶ Print │ macOS/Linux: CUPS queue "Verae Timestamp" │
│ backend: verae (runs as lp, sandboxed) │──▶ spool dir (per job: job.pdf + job.json)
│ Windows: virtual printer → PDF port │
└──────────────────────────────────────────┘
│
▼
verae-print-helper (per-user, tray/menu-bar)
- watch spool, pick up job
- sha256 (doc + pages + manifest)
- stamp via API (queue offline → retry)
- dialog: Save / Print / Both / Cancel
- write: <name>.pdf, <name>.verae.json,
optional <name>.stamped.pdf
- optional: forward to real printer (+ cert page)
5.1 macOS
- v0 (fast path): PDF Services entry — "Timestamp with Verae" in the Print dialog's PDF menu. Installed to
~/Library/PDF Services/as an app/script that receives the PDF path. No CUPS driver needed.- Default channel: Verae Time (
api.veraetime.net+ MCP JWT from~/.verae/auth.properties). - Optional second menu item Timestamp with Verae (Zapier) or
--channel=zapier:zap.verae.ai+xVerae-token +attachPdf: true. - Saves to
~/Documents/Verae Timestamps/by default (override with--out-dir/ preference).
- Default channel: Verae Time (
- v1: CUPS queue with custom backend
/usr/libexec/cups/backend/verae+ PPD (or IPP Everywhere). The backend is sandboxed and cannot show UI, so it writes to/Library/Application Support/Verae/spool/<user>/and exits; the menu-bar helper (LaunchAgent) picks it up. - Signed + notarized
.pkg.
5.2 Linux
- CUPS queue
Verae-Timestamp, backend/usr/lib/cups/backend/verae, PDF input via the standard filter chain (pdftopdf). Spool to/var/spool/verae/<user>/; user helper runs as systemd user service (+ tray icon via StatusNotifier, or desktop notification with actions). Headless mode: auto-save to~/Documents/Verae Timestamps/with no dialog. - Packages:
.deb,.rpm; optional Flatpak for the helper only.
5.3 Windows
Options, in order of preference:
- Microsoft Print to PDF driver + custom port monitor writing to the spool folder (port monitor DLL, installed by MSI). Proven and simple.
- Local IPP printer service (helper exposes IPP Everywhere on 127.0.0.1); Windows 10/11 IPP class driver sends PDF or PWG raster. Same code as macOS/Linux option below.
- Print Support App (UWP/MSIX) for the modern print path — later, if enterprise deployment needs it.
Helper is a tray app; MSI signed with Authenticode.
5.4 Optional unified path
A single local IPP Everywhere printer service (e.g. built on PAPPL or a Go IPP server) advertised via DNS-SD on loopback. macOS and Linux discover it driverlessly; Windows adds it with the IPP class driver. Reduces per-OS driver code; evaluate in the spike.
6. Outputs
For a print job whose document name is Contract (extension stripped for the stem):
| File | Content |
|---|---|
Contract.pdf |
Exact captured bytes (the proven artifact) |
Contract-verae-timestamp-{RECEIPTID}.pdf |
Verae registration / certificate PDF only |
Contract.verae.json |
Receipt sidecar: doc sha256, receipt id, channel, API host, time, helper version, original byte length |
RECEIPTID is the Verae receipt / certificate CID, sanitized for filenames (safe charset). Long CIDs are kept in full when under filesystem limits.
macOS v0 naming is fixed to the table above (approved 2026-10-03). Later optional embed/combined outputs may still use .stamped.pdf but are out of scope for v0.
Certificate PDF source by channel:
- Zapier channel:
pdfBase64fromPOST https://zap.verae.ai/v1/timestampwithattachPdf: true. - Verae Time / default: stamp via
api.veraetime.net; use API/MCP registration PDF when available, otherwise render a local certificate page from the receipt JSON (document name, SHA-256, time UTC + local, receipt id, verify URL).
7. Settings
- Default action: ask / save / print / both.
- Save folder; filename pattern.
- Forward printer (real printer) for "Print" and "Both".
- Embed receipt (on/off); add certificate page when printing (on/off).
- Per-page hashing (on/off).
- Verae base URL + login (reuse
~/.verae/auth.json; login via browser flow). - Offline queue: if API unreachable, save locally, mark "pending", stamp later, update receipt.
8. Security & privacy
- Digest only over TLS; never the document.
- Spool dirs per user, mode 0700; jobs deleted after handling.
- Backend never runs network code (keeps the root/lp component tiny); all network in the user helper.
- Code signing on all platforms; installer verifies helper signature.
- Token stored in OS keychain where available (Keychain, libsecret, Credential Manager), falling back to
~/.verae/auth.json.
9. Verification
verae-print verify Contract.pdf [Contract.verae.json] recomputes digests (and for .stamped.pdf, the original byte range) and checks them against the Verae API (/api/hash/{digest} or /api/verify).
10. Open questions
- Certificate PDF endpoint/format in the Verae API.
- Batch stamping (doc + pages + manifest in one call) vs stamping only the manifest digest.
- Licensing and distribution channel (direct download vs App Store/Microsoft Store).