If you're an engineer, secret-sharing usually shows up in three places: onboarding, vendor hand-off, and incident response. Here's a developer's-eye view of when to reach for a one-time link, when to skip it, and how to script it without leaking the secret into your shell history along the way. To try the mechanism first, the free one-time secret link generator needs no account.
When should a developer use a one-time link?
When a human is on at least one end of the hand-off and the value should not persist anywhere afterwards. The usual cases:
- Onboarding a new engineer with their first set of credentials.
- Sharing a temporary admin password during an incident.
- Delivering a vendor or contractor token that should not live in your vault.
- Rotating a credential where the old value should die promptly.
- Sending a customer the [API key](/glossary#api-key "Glossary: api key") you provisioned for them.
When not to use a one-time link
- Machine-to-machine secrets. CI environment variables (GitHub Actions secrets, for example), Kubernetes Secrets, and Vault dynamic credentials are the right primitive there. A link is for the human hand-off into those systems.
- Long-lived team credentials. Those belong in a password manager.
- Public configuration. Don't dress up non-secret config as a secret. Use a regular link.
The dividing line: if both ends of the transfer are machines, use your platform's secret store. If at least one end is a human, a one-time link is usually the cleanest primitive.
| Situation | Right primitive |
|---|---|
| New engineer's first credentials | One-time secret link |
| CI pipeline needs a deploy token at runtime | CI secret store / env vars |
| Pod needs a database password | K8s secret / external secrets operator |
| Team login used daily by five people | Password manager (shared vault) |
| Customer needs their provisioned API key | One-time secret link |
| Secret needed inside a git repo | Never — reference a secret store; add scanning to CI |
Scripting it
LinkPilot has a REST API (available on paid plans). Issuing a secret from a script looks like this:
LP_KEY=lp_live_...
URL=$(curl -sS https://api.uselinkpilot.com/v1/secrets \
-H "Authorization: Bearer $LP_KEY" \
-H "Content-Type: application/json" \
-d '{
"payload": "'"$NEW_DB_PASSWORD"'",
"expires_in": 3600,
"burn_after_read": true,
"passphrase": "'"$ONBOARDING_PASSPHRASE"'"
}' | jq -r '.url')
echo "Secret link: $URL"
Pipe that URL into whatever delivery channel you already use — Slack DM, email, your onboarding tool's webhook.
Keeping the payload out of the process list
The snippet above has a classic flaw: interpolating the payload into
-d puts it on curl's command line, where any local user can read
it via ps while the request runs. Build the JSON with
jq and feed it over stdin with
curl's -d @- instead:
set -euo pipefail
jq -n --arg payload "$NEW_DB_PASSWORD" \
--arg pass "$ONBOARDING_PASSPHRASE" \
'{payload: $payload, expires_in: 3600,
burn_after_read: true, passphrase: $pass}' |
curl -sS https://api.uselinkpilot.com/v1/secrets \
-H "Authorization: Bearer $LP_KEY" \
-H "Content-Type: application/json" \
-d @- | jq -r '.url'
Three habits worth making reflexive:
- Values arrive via environment variables or a secrets manager CLI — never typed into an interactive shell where they land in history.
- The script prints the link, never the payload.
set -euo pipefailso a failed API call can't silently hand an empty URL to the next step.
Onboarding template
A pattern that works well for new engineers on day one:
- Onboarding script provisions accounts and pulls one-time credentials.
- Script creates a secret link per credential with a 4-hour expiry and a shared passphrase.
- Script sends an email with all the links and a Slack DM with the passphrase.
- Engineer opens each link, copies the credential into their password manager.
- Anything unread by end-of-day gets revoked and reissued at their pace.
Why these parameters: the 4-hour expiry covers a normal first morning without leaving credentials live overnight; the passphrase travels by a second channel so a forwarded or misdelivered email is harmless; burn-after-read means the engineer's mailbox ends the day containing only dead URLs.
Tell the new hire explicitly: "each link works once — save the value into your password manager before closing the tab." The most common onboarding failure is a recipient who reads the secret, closes the tab, and assumes they can come back later.
A rotation runbook
Rotating a shared database password with a contractor or teammate on the receiving end:
- Generate the new password and apply it in the source system (database, cloud console, wherever it's canonical).
- Update your own consumers first — CI vault, K8s secret, app config — so nothing breaks while the human hand-off happens.
- Create a one-time link for the new value: burn after read, 1-hour expiry, passphrase.
- Deliver link and passphrase through different channels.
- Verify the view event in the audit timeline. No view before expiry? Revoke and reissue — never re-send the same link.
- Confirm the old credential is disabled at the source.
Each rotation gets its own link. Links are independent by design — that's a feature for delivery and a non-feature for governance, so the rotation schedule lives in your manager or runbook, not in the link tool.
Incident response
During an incident you often need to rotate a credential and distribute the new one to a few responders fast. Don't paste it in the incident channel — that channel is being recorded for the postmortem, and the secret will end up in the export, the retro doc, and every retention system downstream of them.
- Rotate the credential in the source system.
- Issue a secret link with a 30-minute expiry.
- Drop the link in the channel; send the passphrase by DM.
- After the incident, confirm the link is burned or revoked.
The postmortem then contains a dead URL instead of a live admin password — and the audit trail gives the timeline reviewer an exact "credential re-issued at 14:32, read at 14:33" record for free.
One unfurl-related note: chat clients fetch pasted URLs to render
previews. A well-designed secret link survives this because the
preview fetch is a GET and the reveal is an explicit POST — see
link scanners and one-time secrets
for the full mechanics. If you're evaluating a tool, test this
before an incident, not during one.
What does the audit trail tell you?
Whether a secret was read, when, and roughly from where, and whether anyone tried a wrong passphrase. Every LinkPilot secret carries an event timeline: created, viewed, failed_passphrase, burned, expired, revoked. Views are recorded with a timestamp, coarse geolocation when available, the user agent, and a hashed IP (SHA-256 with a daily-rotating salt — the raw IP is never stored). In practice that gives you three answers scripts and runbooks can rely on:
- Delivery confirmation — a viewed event means the hand-off happened.
- Anomaly detection — a failed_passphrase burst or a view you don't recognize is your cue to rotate immediately.
- A clean record for reviews — "delivered once, read once, burned" is a sentence auditors like.
Limits: what links don't solve
- They're not a vault. Nothing about a one-time link manages ongoing access, rotation schedules, or who-has-what inventories.
- The link is the key. LinkPilot encrypts text payloads in your browser and never receives the key, but that key travels in the URL fragment — so anyone who obtains the full link can read the secret, and a lost link means the secret is unrecoverable. Attached files are encrypted the same way, though their names and sizes are not. Short expiry plus burn-after-read still matters. Update, 29 September 2026: this bullet previously read "they're not end-to-end encrypted", which was accurate until that date. Details on the security architecture page.
- They don't fix secret sprawl in code. Keys hardcoded in repos need scanning and rotation, not a better delivery mechanism.
- They can't protect the far end. Once a human has read the value, treat it as living wherever they put it.
Try it free, no signup
One-Time Secret Link Generator
Share a password or note through a link that opens once.
Related reading
- How to share API keys securely
- Expiring links: why short windows matter
- LinkPilot Security Architecture
References
- GitHub Docs, Using secrets in GitHub Actions.
- Kubernetes, Secrets.
- jq, Manual.
- curl, Manual page,
-d, --data.