security/
A short, honest security page. We're a young company; we don't have a SOC 2 yet and we don't have a paid bug bounty yet. Here is what we actually do today, and what's on the roadmap.
#Where data lives
Delvry runs as a Cloudflare Worker. Persistent data lives in Cloudflare D1 (SQLite-on-the-edge) and Cloudflare KV, primary in the iad-1 region (US-East). Cloudflare encrypts data at rest. We don't run our own servers, and there is no second cloud in the picture.
#Encryption
Every endpoint is HTTPS-only. TLS is terminated at Cloudflare's edge with modern ciphers. Data at rest is encrypted by Cloudflare's storage layer. Internal Worker-to-D1 and Worker-to-KV traffic stays within Cloudflare's network.
#API key handling
API keys are minted server-side and shown to you exactly once at creation. We store only a hash — no plaintext, no encrypted-but-recoverable copy. If you lose a key, you rotate it; we cannot recover it. Keys carry a short prefix (delvry_sk_…) for log identifiability and follow a fixed-length format so log scanners can detect leaks.
Every authenticated request runs through a constant-time hash compare. Rate limits are applied per account and per IP.
#Webhook signatures
Outbound webhooks are signed with Svix-style HMAC-SHA256. Each delivery carries an svix-id, svix-timestamp, and svix-signature header. Verify the signature before trusting the payload — sample code is in the docs. Replays older than five minutes should be rejected by your verifier.
Inbound webhooks (Resend delivery events) are verified with the same scheme before we mutate any state.
#Authentication model
- API: bearer token in the
Authorizationheader. One key per row in theapi_keystable; revocation is instant. - Dashboard: short-lived session cookies, signed with a per-deployment session secret. Passwords are hashed with PBKDF2-SHA256 (100,000 iterations, per-user random salt) — that's the iteration cap on the Cloudflare Workers runtime. We'd prefer Argon2id and will move to it once the runtime supports it; until then, every authenticated request runs through a constant-time hash compare.
- Recipient links: short-lived JWTs signed with the deployment's JWT secret. Tokens are scoped to a single survey/thread and a single recipient. They expire automatically.
#Tenant isolation
Every read and write is scoped by account_id. Cross-account access is impossible by construction — there is no "admin override" path. We have integration tests that specifically try to read another account's data and expect a 404; they run on every change.
#Responsible disclosure
If you find a security issue, email security@delvry.ai. Please don't open a public GitHub issue. We'll acknowledge within two business days, keep you updated as we work on a fix, and credit you in the changelog if you want credit.
We don't run a paid bug bounty yet, but we will say thank you publicly and send you swag. Critical reports may earn an ad-hoc reward at our discretion.
#Audits and certifications
None yet. SOC 2 Type I is on the roadmap once we have enterprise customers who need it. We don't claim certifications we don't hold. If you have a vendor security questionnaire, send it over and we'll fill it in honestly.
#Contact
Security questions or disclosures: security@delvry.ai. Everything else: hello@delvry.ai.