Pouch vaults
A pouch-vault is a small daemon you run on a box you control — home server, NAS, Raspberry Pi, Mac mini, even your laptop. It connects to your pouch over a single outbound HTTPS link and mirrors every drop to a local SQLite archive as it happens. No public URL, no port forwarding, no firewall hole — works anywhere outbound HTTPS works.
The vault is open source (pointegrity/pouch-vault), a few thousand lines of Go, statically linked, no CGO. Pre-built binaries ship for Linux (amd64 / arm64), macOS (Intel / Apple Silicon) and Windows; a Docker image too.
How it fits (default: pull mode)
[pouch SaaS] ◀──── outbound HTTPS SSE stream ──── [your vault] ──▶ drops.db
◀──── outbound HTTPS heartbeat ─────
every 30 s: "I have N drops"
Both arrows go outward from your vault box. Pouch never tries to reach in. That's the property that makes this trivial to deploy on a laptop, behind CGNAT, on a corporate network, or anywhere else inbound connections aren't possible.
Drops arrive over a long-lived Server-Sent Events stream the vault holds open. Each event is HMAC-signed with the secret you minted at provisioning — wire format and verification semantics are the same as the webhook contract. Drops fired while the vault was offline are queued by pouch and replayed automatically when the vault reconnects.
1. Mint your vault (admin shell)
Today, vaults are admin-provisioned. From a shell on the pouch server:
pouch vault create --owner <your-user-id> --name <a-name-you-pick>
Output is shown once. Save these three values — you'll paste them into the vault's config:
POUCH_URL https://pouch.pointegrity.com
POUCH_VAULT_KEY pk_... # auth, long-lived
POUCH_HMAC_SECRET ... # delivery signature
2. Install
Pre-built binaries from the latest GitHub release:
# Apple Silicon
curl -fL -o pouch-vault https://github.com/pointegrity/pouch-vault/releases/latest/download/pouch-vault-darwin-arm64
chmod +x pouch-vault
sudo mv pouch-vault /usr/local/bin/
# Intel: replace darwin-arm64 with darwin-amd64.
curl -fL -o pouch-vault https://github.com/pointegrity/pouch-vault/releases/latest/download/pouch-vault-linux-amd64
chmod +x pouch-vault
sudo install -m 755 pouch-vault /usr/local/bin/
# arm64 (Pi, Graviton, ARM cloud): replace amd64 with arm64.
docker run -d --name pouch-vault \
-p 7780:7780 \
-v pouch-vault-data:/data \
-e POUCH_URL=https://pouch.pointegrity.com \
-e POUCH_VAULT_KEY=pk_... \
-e POUCH_HMAC_SECRET=... \
-e POUCH_PUBLIC_URL=https://vault.example/hook \
ghcr.io/pointegrity/pouch-vault:latest
3. Run it
The vault is a foreground process that handles SIGTERM and logs to stderr. Pick whichever supervisor matches your OS:
Foreground (any OS)
POUCH_URL=https://pouch.pointegrity.com \
POUCH_VAULT_KEY=pk_... \
POUCH_HMAC_SECRET=... \
POUCH_PUBLIC_URL=https://vault.example/hook \
VAULT_DB=./drops.db \
pouch-vault
systemd (Linux servers, NAS, Pi)
Example unit at
examples/pouch-vault.service.
One EnvironmentFile= + systemctl enable --now
and you're set.
launchd (always-on Mac)
Example plist at
examples/com.pointegrity.pouch-vault.plist.
Drop in ~/Library/LaunchAgents/ +
launchctl load.
4. Verify it works
Drop something into your pouch (CLI, SPA, ingress key — whatever). Within a few seconds:
sqlite3 /var/lib/pouch-vault/drops.db \
"SELECT received_at, drop_id, label
FROM drops
ORDER BY received_at DESC LIMIT 5"
You should see the drop you just made. Pair with litestream if you want the vault's database continuously replicated to S3 / B2 for offsite backup at minute-level RPO.
Producer mode (watch paths)
A vault isn't only a mirror — it can also originate drops by
watching local folders. Point a path at a stream with
direction: "watch" and the vault computes a sha256
per file, debounces edits, and uploads new or changed files as
drops on the named stream.
VAULT_PATHS='[{"path":"~/scrape-out","stream":"scrape","direction":"watch"}]'
Companion CLI subcommands: pouch-vault sync
(one-shot reconcile), pouch-vault history,
pouch-vault get <id>. See the
project README
for the full VAULT_PATHS schema and per-direction
behavior.
Advanced: push mode
If you actually want pouch to POST to a publicly-reachable URL
you operate (a server with a static IP and a real domain, a
cloudflared tunnel terminating at your laptop, an nginx in
front of a NAS) you can use push mode. Set
POUCH_PUBLIC_URL in your config to the URL pouch
should POST to, and the vault exposes /hook
instead of opening an outbound stream.
Push and pull are per-vault. Same binary, same
provisioning flow — the vault switches based on whether
POUCH_PUBLIC_URL is set. You can run multiple
vaults and have some pull, some push, depending on what each
box looks like.
| tunnel pattern (push mode) | good for |
|---|---|
| cloudflared tunnel | NAT-friendly, free tier covers personal use |
| tailscale funnel | if Tailscale is already in your stack |
| nginx + Let's Encrypt | full control on a server you operate |
Most users should use the default pull mode. Push mode exists for a small set of advanced operators with pre-existing public infrastructure. Either works equally well from the SaaS side; the bytes go through HMAC + HTTPS regardless.
FAQ
Does the vault see my drop bodies in plaintext?
Yes — today, drop bodies are plaintext on the wire. The HMAC protects integrity (nobody can forge a delivery), not confidentiality. Sealed drops (end-to-end encryption) are a separate roadmap item; when they ship, vaults will store opaque ciphertext alongside the metadata.
What happens if my vault is offline when a drop arrives?
In the default pull mode, nothing is lost. Drops fired while the vault was disconnected are queued by pouch and replayed automatically over the SSE stream when the vault reconnects — no manual action, no re-deliver step.
In push mode, pouch retries the HTTP POST with geometric backoff at 30 s / 2 m / 8 m, four attempts total. After that the delivery is marked failed in pouch's outbox and sits there for manual re-delivery.
Can I run multiple vaults?
Yes. Each gets its own pouch vault create, its
own key, its own database. Run one on your home server and
one on a VPS for redundancy — pouch will deliver to both. The
replication-status panel will show both side-by-side.