How LinkPilot Secret Links work.
A plain-language reference to how secret payloads are stored, revealed, and destroyed — and what we deliberately do not do with them.
Secret Links are private by design. LinkPilot separates secret-sharing workflows from marketing-link analytics. Secret contents are never used for analytics or profiling.
Found a vulnerability or abusive link? Report it here — reports go straight to the team.
1. Overview
LinkPilot runs two distinct link pipelines on the same platform: Smart Links for branded short URLs with click analytics, and Secret Links for one-time, expiring, passphrase-protected delivery of sensitive content. They are kept apart at the data, code-path, and product level so that secret payloads can never bleed into analytics dashboards, dataset exports, or AI features.
This page describes the Secret Links pipeline specifically: how a secret is created, how it is revealed, what happens after it is viewed, and what metadata is logged along the way.
2. How Secret Links work
- The sender creates a secret with optional passphrase, expiry window, and burn-after-views limit.
- The payload is written to a dedicated
secret_linkstable, isolated from the click-analytics tables. - LinkPilot returns a short URL (e.g.
shrd.link/s/<slug>) to share with the recipient. - When the recipient opens the link, the app calls the
secret-revealedge function. AGETreturns metadata only (status, whether a passphrase is required). APOSTwith the passphrase is what actually reveals the payload. - A successful reveal is recorded atomically and may immediately mark the secret as
burned, depending on the burn-after-views setting.
3. Encryption model
We want to be precise here, because the words "encrypted" and "zero-knowledge" are often used loosely.
- In transit: all traffic is TLS-encrypted end to end between the recipient, our edge, and our managed database.
- At rest: secret payloads are stored in a column logically separated from analytics data, on a managed Postgres instance with disk-level encryption.
- Passphrases: hashed with SHA-256 on the client before transport, then compared by hash on the server. The plaintext passphrase is never written to our database or logs.
- What we do not currently claim: end-to-end encryption with a recipient-only key. An operator with database access could read an active secret's payload, the same as with any managed-database product. The strongest defenses are short expiry windows and burn-after-read.
If end-to-end client-side encryption matters to your workflow, tell us — it is on the roadmap and we want to ship the right design rather than a misleading label.
4. What happens after a secret is viewed
- The view is recorded atomically through a database function — concurrent reveal attempts cannot leak the secret twice.
- If the view-count limit is reached, the secret's status flips to
burnedand the stored payload is overwritten with[REDACTED]. - Subsequent reveal attempts return a clear "already viewed and destroyed" response with HTTP 410.
- The audit timeline records every view, burn, and revoke event with a hashed IP — useful for incident response and credential rotation.
5. Expiration and revocation
- Every secret can carry a time-based expiry (5 minutes to 30 days) and an optional view-count cap.
- Expired secrets are flipped to
expiredon the next access and the payload is redacted in the same write. - The owner can revoke a secret manually at any time from the dashboard. Revoked secrets immediately refuse to reveal and return HTTP 410.
- Once a secret is burned, expired, or revoked, the payload cannot be recovered through the product — there is no "unrevoke" or "restore" action by design.
6. Passphrase protection
- Passphrases are optional but recommended for any secret you do not want a stray viewer to consume.
- The passphrase is SHA-256 hashed in the browser, sent over TLS, and compared by hash on the server. The raw value never reaches our database.
- We rate-limit passphrase attempts to 5 per IP per minute per secret, enforced across an in-memory limiter and a database-backed sliding window.
- Every failed attempt is written to the audit log with a hashed IP so workspace owners can see suspicious activity.
- We recommend sending the passphrase through a different channel from the link itself — for example, the link by email and the passphrase by Slack DM or SMS.
7. Link scanner and preview-bot protection
Email security scanners and chat-app link unfurlers (Slack, LinkedIn, iMessage, Outlook) routinely fetch URLs as soon as they appear. For a burn-after-read link, a naive design would mean the very first preview destroys the secret before the recipient sees it.
LinkPilot prevents that in three ways:
- Separate metadata and reveal endpoints. A
GETon the reveal endpoint only returns the status and whether a passphrase is required. A view is only recorded on an explicitPOSTreveal, which is the action a human takes after clicking the reveal button. - Passphrase gate. When a passphrase is set, no payload is returned to anyone — bot or human — without the correct hash.
- Cache-Control: no-store on every reveal response, so intermediaries do not cache secret contents.
8. What metadata is logged
For each reveal attempt we record only what is needed to give workspace owners a credible audit trail:
- Timestamp of the attempt.
- Hashed IP: SHA-256 of the client IP combined with a daily-rotating salt, truncated to 32 characters. The raw IP is never stored.
- Coarse geolocation (country and city) from the edge, when the upstream provides it.
- User-Agent string reported by the client.
- Event type: created, viewed, failed_passphrase, burned, expired, revoked.
We do not log: the secret contents, the raw passphrase, the raw IP address, cookies on the recipient (there are none), or any third-party tracking pixels.
9. Difference between Secret Links and analytics links
| Aspect | Smart Links (analytics) | Secret Links |
|---|---|---|
| Purpose | Branded short links with click tracking | One-time, expiring secure delivery |
| Storage | Links + click events | Isolated secret_links table, redacted on destroy |
| Per-click data | Hashed IP, referrer, UA, geo, UTM | Hashed IP, UA, geo, event type — no payload |
| Analytics / AI use | Yes (aggregated, hashed) | Never — fully excluded |
| Lifetime | Persistent until you delete | Burns, expires, or revokes; payload then irrecoverable |
| Bot previews | Counted as bot, filtered from analytics | GET returns metadata only — bots cannot reveal |
The two pipelines share the same brand, dashboard, and team controls — but the data flows do not cross.
10. FAQ
Is the secret end-to-end encrypted?
No. We do not claim end-to-end encryption. Secret payloads are stored separately from analytics data, protected at rest by the managed database, and irreversibly cleared the moment a secret is burned, expires, or is revoked. Passphrases are hashed with SHA-256 on the client and verified by hash on the server — the raw passphrase never reaches our database or logs.
Can LinkPilot staff read my secrets?
Operators with database access could, in principle, read an active secret's stored payload — the same as any managed-database SaaS. Once a secret is burned, expired, or revoked, the payload is overwritten and cannot be recovered. Use a short expiry plus burn-after-read for the strongest guarantees.
Does opening a link preview in Slack or email burn the secret?
No. Link unfurlers issue GET requests, which only return metadata (status, whether a passphrase is required). A view is only recorded on an explicit POST reveal — the action the human recipient takes when they click the reveal button.
What information do you log about a view?
Per view we record: timestamp, hashed IP (SHA-256 with a daily-rotating salt, truncated to 32 chars), country and city from the edge if available, and the User-Agent string. We do not log the secret contents, the raw passphrase, or the raw IP address.
Are secrets ever used to train models or for analytics?
No. Secret payloads are excluded from analytics, profiling, and any AI features. The Secret Links pipeline is separate from the Smart Links analytics pipeline.
What happens if someone tries to brute-force the passphrase?
Passphrase attempts are rate-limited to 5 per IP per minute per secret across two layers (in-memory and database). Failed attempts are written to the audit log with a hashed IP.