For developers
Share API keys and .env files with a link that works once
The production database password shouldn’t live in a Slack DM, and the .env for staging shouldn’t be an email attachment. Paste it into ShareShield, or create it from a script, and send a link that opens once and then deletes the secret.
curl -sS -X POST https://app.shareshield.net/api/v2/secrets \
-H "x-api-key: $SHARESHIELD_API_KEY" \
-H "content-type: application/json" \
-d '{"content": "staging DB: app / Rk7#mQ2vL9",
"expiryHours": 4, "maxViews": 1}'{
"id": "k7mq-2vx-r9t",
"url": "https://app.shareshield.net/secret/k7mq-2vx-r9t",
"burnUrl": "https://app.shareshield.net/secret/k7mq-2vx-r9t/burn?token=…",
"expiresAt": "2026-10-03T13:41:00.000Z",
"maxViews": 1
}01Four times this week you needed it
The handovers that don’t belong in a chat thread
A teammate needs the staging database password
A password pasted into a DM isn’t only in the DM. Depending on your workspace’s plan and settings, it can turn up in a workspace export or a compliance archive. It’s in both people’s search results for as long as the message exists, and on every laptop and phone where either of you is signed in. In a channel, add every member and every app installed there.
Paste the connection string into ShareShield instead, leave it at one view, set the expiry to an hour, and drop the link in the DM. When they open it, the secret is deleted, and the link left in the chat history leads nowhere.
Link previews don’t use up the view. Opening a secret takes a deliberate click in the browser, and through the API it is POST-only, so an unfurler or a scanner fetching the URL never reveals anything.
The timer sets how long the link stays valid, and how many times it can be opened. After that the secret is permanently deleted.
Email the link straight to the people who need it, and optionally make sure only they can open it.
A contractor needs the .env file
Upload the file as a file secret and send it to the contractor’s address, locked to them. It is encrypted like any other secret and downloaded once as an attachment. It never renders in a browser tab.
File secrets need an active paid plan: up to 1 MB on Standard, 10 MB on Professional and 25 MB on Enterprise. A typical .env file is a few kilobytes.
Your pipeline creates a credential a person needs
A provisioning job creates a database user, or rotates a third-party key, and someone has to be told the new value. Have the job create a ShareShield secret and email it to that person, locked to their address.
Print only the delivery report in the job log, never the link: the link is a credential too.
- name: Send the staging database password to the on-call engineer
env:
SHARESHIELD_URL: https://app.shareshield.net
# a key with only secrets:create
SHARESHIELD_API_KEY: ${{ secrets.SHARESHIELD_API_KEY }}
DB_PASSWORD: ${{ secrets.STAGING_DB_PASSWORD }}
run: |
jq -n --arg content "$DB_PASSWORD" '{
content: $content, expiryHours: 4, maxViews: 1,
recipients: ["[email protected]"], recipientsOnly: true
}' \
| curl -sS --fail-with-body -X POST "$SHARESHIELD_URL/api/v2/secrets" \
-H "x-api-key: $SHARESHIELD_API_KEY" \
-H "content-type: application/json" \
--data @- \
| jq '{expiresAt, recipients}'Need a password, key or other secret from a colleague or client? Send them a request: they get a one-time link to a form, and their answer comes back to you as a secret link.
The request link expires after
1 day3 days7 daysYou need a key from someone else
Send a secret request. The other person, who doesn’t need an account, pastes the key into a one-time form, and it arrives in your ShareShield account. Scripts can send requests too, with a key that has the requests:create scope.
02What ShareShield is not
Not a secrets manager, and not trying to be
If an application needs a secret at run time, keep it in Azure Key Vault, AWS Secrets Manager, HashiCorp Vault or your CI provider’s encrypted variables. ShareShield’s job is the moment a secret passes between people: the first handover to a new teammate, the one-off key from a vendor, the credential a pipeline has to tell a human about.
03API v2
A key that can do one thing, in one organisation
API v2 is a REST API with an OpenAPI 3.1 description, so you can generate a client or read the reference in the app.
New API Key
Scopes
secrets:createCreate self-destructing secrets and files in the organization.secrets:readReveal (and so consume a view of) a secret by its id.secrets:burnDestroy secrets the key owner created.secrets:listList metadata of the key owner's secrets (never their content).requests:createAsk someone to send you a secret.requests:readList the key owner's secret requests.
It creates text and file secrets, checks and burns them, and sends and lists secret requests, under the same plan limits and organisation policies as the web app. A request outside the policy gets a 403; outside the plan, a 402.
Keys are bound to one organisation and carry only the scopes you tick:
secrets:createsecrets:readsecrets:burnsecrets:listrequests:createrequests:read
- A key can never do more than its owner’s role allows.
- It can be set to expire, and stops working if its owner leaves the organisation.
- Keys can’t manage users, settings, billing, SSO or other keys, so a leaked CI key can’t mint another one.
- We store only a hash of each key. You see it once, when it is created.
Read the integration guide API reference OpenAPI 3.1 description
04Which feature does what
The parts you’ll use
| You need to | Use |
|---|---|
| Send a password or connection string once | A one-view link with a short expiry |
Send an .env, key file or certificate | A file secret (Standard and above) |
| Make sure only one person can open it | Email recipient, recipients only |
| Get a key from a vendor or client | A secret request |
| Do any of that from CI or a script | API v2 with a scoped key |
| Stop a misdirected link before it’s opened | Burn it, or use the burn link |
05Further reading
Guides for developers
Send the next key you were about to paste into Slack
No account needed for a one-off link. For the API, create a free account and a key with exactly the scopes your script needs.
