Bring-your-own Cloudflare Worker + R2 backend for syncing a Voltius vault.
The Worker stores opaque ciphertext and minimal sync metadata (device ids, labels, timestamps, KDF salt).
Vault encryption stays in the Voltius client. This Worker never sees your passphrase or plaintext hosts/keys.
Tracking: VoltiusApp/voltius#267 (marketplace-only; core PR #268 closed)
Install the Cloudflare Sync marketplace plugin, open Settings → Cloudflare Sync, and use the Deploy Worker section:
- Paste your Cloudflare Account ID and an API token (see permissions below).
- Optionally change Worker name / R2 bucket (defaults:
voltius-cloudflare-sync/voltius-vault-sync). - Click Generate sync token, then Deploy Worker.
- The plugin creates the R2 bucket if needed, uploads this Worker bundle, sets
SYNC_TOKEN, fills the Worker URL, and toasts success. - Add a separate encryption passphrase → Create vault or Link existing.
The plugin fetches the published worker.mjs release asset from this repo (no Wrangler required on your machine).
After the button finishes:
- Open the new Worker in the Cloudflare dashboard → Settings → Variables and Secrets.
- Add secret
SYNC_TOKEN= a long random string (password manager is fine). - Copy the Worker URL (e.g.
https://voltius-cloudflare-sync.<account>.workers.dev). - In Voltius → Cloudflare Sync plugin → paste URL + token + a separate encryption passphrase → Create vault or Link existing.
Requires Node 20+ and a Cloudflare account (npx wrangler login once).
git clone https://github.com/mrchatam/voltius-cloudflare-sync-worker.git
cd voltius-cloudflare-sync-worker
npm install
npx wrangler login
npm run setup:buckets # creates R2 buckets (ignore "already exists")
npm run deploy
npm run secret:token # prompts for SYNC_TOKENOr the all-in-one:
npm run deploy:easyThen paste the printed Worker URL into the Voltius plugin settings.
cp .dev.vars.example .dev.vars # set SYNC_TOKEN=
npm install
npm run dev # http://127.0.0.1:8787Create a Cloudflare API token with at least:
| Permission | Level | Why |
|---|---|---|
| Account → Workers Scripts | Edit | Upload / update the Worker script |
| Account → Workers R2 Storage | Edit | Create the R2 bucket + bind VAULT_BUCKET |
| Account → Account Settings | Read | Resolve your *.workers.dev subdomain |
Account resources: include the account you will deploy into.
Do not use a Global API Key. The Voltius plugin keeps the token in memory only (not persisted).
| Field | Value |
|---|---|
| Worker URL | Your *.workers.dev (or custom domain) — no trailing slash needed |
| Sync token | Same value as Worker secret SYNC_TOKEN |
| Encryption passphrase | Different from the token — used only on-device for vault crypto |
Use Create vault on the first device, Link existing on the next ones.
| Method | Path | Auth | Notes |
|---|---|---|---|
| GET | /health |
no | Liveness |
| OPTIONS | * |
no | CORS preflight |
| GET/PUT | /v1/manifest |
Bearer | { schema:1, salt, devices[] } — GET sends ETag; PUT honors If-Match (412 on mismatch) |
| GET/PUT/DELETE | /v1/devices/:id |
Bearer | PUT { content, label, pushedAt } — If-Match is the manifest ETag (RMW); 412 on mismatch. GET still returns device etag. |
R2 keys: manifest.json, devices/{id}.b64
Quick check:
curl -sS "$WORKER_URL/health"
curl -sS -H "Authorization: Bearer $SYNC_TOKEN" "$WORKER_URL/v1/manifest"Used by the Voltius plugin (and CI) to produce dist/worker.mjs:
npm install
npm run build:artifact # wrangler deploy --dry-run --outdir=dist → dist/worker.mjsRelease assets attach worker.mjs for in-app deploy
(…/releases/latest/download/worker.mjs).
npm install
npm test
npm run typecheckMIT — clean-room example; not a copy of the Voltius AGPL sync server.
See SECURITY.md for the threat model and operational checklist. There is no Worker HTML UI for key management — that stays in the Voltius client.