Security
Linktary is a certified safe-link shortener: every destination is verified to origin before the link works, and every verification is publicly auditable. This page documents how data moves through the system, what we keep, who else touches it, and what we do — and don't — protect against.
Data flow
you ──TLS 1.3──▶ linktary.com (Cloudflare Worker)
│
┌───────────────┼────────────────┐
│ │ │
create link verification click (redirect)
│ │ │
▼ ▼ ▼
dest encrypted fetches chain 1 indexed D1 read
AES-256-GCM (≤5 hops, decrypt, 302
per-link nonce 8s, 1MB cap)
│ │
▼ ▼
D1 (encrypted verdict + chain report
at rest) stored WITH the link
│
▼
public trust report
linktary.com/v/<code> (HTML + JSON)
Encryption boundaries: the destination is decrypted only inside the Worker isolate at the moment of use (creation, verification, redirect) — never written to logs, never exported in bulk. The verification pipeline receives the destination blob plus a job nonce and returns a verdict plus a chain report; no user id, no account handle, no email flows through verification. A breach of verification logs cannot map destinations back to users, because the mapping was never there.
What we store, and for how long
| Data | Kept | Deleted |
|---|---|---|
| Link records (encrypted destination, verdict, chain) | While your account exists, or until you delete the link | Soft-deleted immediately (410); purged from active queries |
| Account email | While your account exists | On account closure |
| Sessions (token hashes only) | 30 days | Expire automatically; lazily deleted on lookup |
| Magic-link tokens | 15 minutes, single-use | Consumed on use; expired tokens are inert |
| Rate-limit counters | Minutes (sliding windows) | Expire with the window |
| Abuse reports | Until reviewed and resolved | On resolution |
| Visitor IPs, user agents, referrers | Never collected | Nothing to delete |
Subprocessors
One: Cloudflare — compute (Workers), database (D1),
DNS, TLS termination. There is no analytics vendor, no third-party error
tracker, no third-party script on any page. Transactional sign-in email
goes through MailChannels (the Workers-native sender) from
noreply@linktary.com. If threat-intel feeds are ever wired in, they
will be listed here before they see a single URL.
Threat model
Protects against
- D1 theft — backups, SQL dumps, stolen database credentials. Destinations are encrypted; sessions are hashes.
- Log leakage. No plaintext destination exists in any log, because we never write one.
- Insider curiosity. No dashboard shows plaintext destinations except the owner's own links.
- Traffic analysis by outsiders. Verification is identity-separated: watching the verifier teaches you nothing about who created what.
Does not protect against: a compromised Cloudflare account. Whoever controls the Cloudflare account can read Worker secrets, including the master encryption key. This is the honest boundary of any Cloudflare-hosted system that encrypts at the application layer, and we state it here rather than in a footnote.
The path to stronger: per-customer key-encrypting keys on the enterprise tier (customer-held KEKs via envelope encryption), so a compromise of our Cloudflare account no longer decrypts your destinations. The schema already reserves the key-version column — it's a key-management upgrade, not a redesign.
Authentication
Email magic links — no passwords to phish or breach. Sessions are httpOnly + Secure + SameSite cookies; the sessions table stores token hashes, never raw tokens. Sign-in responses are identical for known and unknown emails (no account enumeration).
Coordinated disclosure
Found a vulnerability? Email hello@linktary.com with "security" in the subject, or file it at /report-abuse. We acknowledge promptly and publish what we fixed once it's fixed. Please give us a reasonable window before any public disclosure.
For the longer essay behind this page — why we resolve the zero-knowledge-vs-verification tension in the open — read The honest crypto design.