Security model

What happens to a secret you send through ShareShield

We encrypt every secret on our servers with its own key, store only its ciphertext, and delete that when it has been read, burned or has expired. ShareShield is not end-to-end encrypted: our servers hold the keys needed to decrypt a secret while it exists. This page explains what that means, what we do to limit it, and when you should use a different tool.

The short version

  • Encryption

    Each secret is encrypted with AES-256-GCM under its own random 256-bit key, and that key is encrypted with a key-encryption key held by the application.

  • Not end-to-end

    Encryption happens on our servers, not in your browser. While a secret exists, ShareShield’s systems can decrypt it.

  • Deletion

    The ciphertext is deleted with the last permitted view, on burn, after five wrong passcodes, or at expiry. Files too.

  • Metadata stays

    After a secret is deleted we keep a record that it existed: who sent it, when, to whom, and how it ended. Not its contents.

  • Logging

    We never log secret contents. IP addresses in audit and access logs are cleared after 90 days.

  • Accounts

    TOTP two-factor authentication, organisation-wide 2FA requirements, and OIDC single sign-on with Microsoft Entra ID.

How a secret is encrypted

One key per secret, wrapped by a key we rotate

Envelope encryption: the secret is sealed with a data key of its own, and the data key is sealed with a key-encryption key that never touches the database.

Envelope encryption of one ShareShield secretLayer 1: the plaintext secret is encrypted with AES-256-GCM under a data key (DEK) of 32 random bytes, with a random 12-byte IV and additional authenticated data made of the secret id and the key id. The result is the ciphertext, its IV and a 16-byte authentication tag. Layer 2: the DEK itself is encrypted with AES-256-GCM under the key-encryption key k2, taken from a keyring held in the application's environment and never stored in the database, with the same secret id and key id as authenticated data. The result is the wrapped DEK. The plain DEK is then wiped from memory. One database row stores the ciphertext, IV, auth tag, wrapped DEK and key id. The row is deleted with the last view, on burn, after five wrong passcodes or at expiry.1 The secret2 Its data keyPLAINTEXTTq7!mR2#vK9pLxa password, note or fileAES-256-GCMkey DEKiv 12 random bytesaad secret id | key idSEALEDciphertext+ iv, 16-byte auth tagDATA KEY (DEK)32 random bytesnew for every secretWiped from memory onceboth layers are sealed.DEK as the keyAES-256-GCMkey KEK k2iv 12 random bytesaad secret id | key idKEYRING · ENVIRONMENTk1 kept until its secrets expirek2 active, wraps new secretsWRAPPED DEKiv ‖ tag ‖ key60 bytesSTORED, ONE ROWciphertextivauthTagBoth layers are boundto this row by the aad.wrappedDekkeyId k2ROW DELETEDlast view · burn5 wrong passcodes · expiryEnvelope encryption of one ShareShield secretThe plaintext secret is encrypted with AES-256-GCM under a fresh 32-byte data key (DEK), with the secret id and key id as authenticated data, giving the ciphertext, IV and auth tag. The DEK is encrypted with AES-256-GCM under key-encryption key k2 from the keyring in the application's environment, with the same authenticated data, giving the wrapped DEK. One row stores the ciphertext, IV, auth tag, wrapped DEK and key id, and is deleted with the last view, on burn, after five wrong passcodes or at expiry.1 The secret2 Its data keyPLAINTEXTTq7!mR2#vK9pLxDATA KEY (DEK)32 random byteswiped after sealingAES-256-GCMkey DEKaad secret id | key idrandom 12-byte ivAES-256-GCMkey KEK k2aad secret id | key idKEK from the keyringSEALEDciphertext+ iv, 16-byte auth tagWRAPPED DEKiv ‖ tag ‖ key60 bytesSTORED, ONE ROWciphertextivauthTagwrappedDekkeyId k2Both layers are bound to this row by the aad.ROW DELETEDwith the last view, on burn,after 5 wrong passcodes, or at expiry
What happens when you create a secret. The keyring lives in the application’s environment; the database holds only the sealed row.

When you create a secret, the application generates a fresh random 256-bit data key for it. The secret is encrypted with that key using AES-256-GCM, which also produces an authentication tag, so any change to the stored ciphertext is detected when it is decrypted.

The data key is then encrypted (“wrapped”) with a key-encryption key, also using AES-256-GCM, and the plain data key is wiped from memory. What we store is the ciphertext, the wrapped data key and the id of the key-encryption key that wrapped it. Key-encryption keys are supplied to the application when it starts and are not stored in the database, so a copy of the database alone is not enough to decrypt anything.

Each layer is bound to the secret it belongs to. The secret’s record id and the key id are included as additional authenticated data, so ciphertext or a wrapped key copied onto a different record fails to decrypt rather than revealing anything.

Key rotation

The key-encryption key can be rotated without touching existing secrets. To rotate, we add a new key to the keyring and make it the one that wraps new secrets. The old key is kept only until every secret it wrapped has expired, at most 90 days on any plan, and is then removed.

Files

File secrets use exactly the same encryption. A file’s ciphertext is kept, encrypted, in private Azure blob storage under a random name that has no link to the secret or the file name. The keys and the file’s metadata are held separately, with a SHA-256 hash of the stored ciphertext that is checked before every download. Downloads always pass through the application, so view limits, passcodes and burns apply to files as they do to text.

Read the API overview

Gone means the ciphertext is deleted, not hidden

A secret’s encrypted contents are deleted in any of these cases. Each one removes the stored ciphertext, and for files the stored file as well.

When a secret’s encrypted contents are deleted
WhenWhat happens
The last permitted view is usedTaking the view and deleting the ciphertext happen in one database transaction.
The sender burns itDeleted immediately, from the dashboard or the API.
An organisation owner or admin burns itThe same, for any member’s secret.
A recipient uses the burn linkDestroyed without being opened.
Five wrong passcodes are enteredDestroyed, and the sender is emailed.
It expiresIt can’t be opened from the moment it expires; a scheduled job then deletes the ciphertext.
The sender deletes their accountAll their secrets are burned and their contents deleted at once.

For a file kept in blob storage, the stored file is deleted straight after the database change, and a sweep that runs on a schedule removes anything a failed delete left behind.

What ShareShield can see, stated plainly

Because encryption happens on our servers, ShareShield’s systems decrypt a secret when someone with the link opens it. That also means someone with access to the production systems and the key-encryption keys could, in principle, decrypt a secret that has not been deleted yet. We don’t read secrets, the contents never appear in our logs, and nothing in the product shows contents to anyone but the person opening the link. We would rather you knew this than assumed otherwise.

Once a secret is deleted, its link can never open it again, and nothing in the product can bring it back. Encrypted copies can remain in the database backups described under deletion until those backups age out.

What ShareShield holds about a secret while it exists and after it is gone
WhatWhile the secret existsAfter it is gone
The contents, text or fileEncrypted. Decrypted on our servers when the link is opened.Deleted
A file’s name, type and sizeStored beside the encrypted contentsDeleted
The wrapped data key and its key idStored beside the encrypted contentsDeleted
A passcode, if you set oneA bcrypt hash, never the passcode itselfThe bcrypt hash stays on the record
Who created it, when, its expiry and view limitKeptKept
Who it was emailed to, delivery status, when each recipient opened itKeptKept
The private name you gave itKept, not encryptedKept, not encrypted
How it ended: viewed, burned, expired or locked outNot yetKept
For requests: your note and the address you sent it toKept, not encryptedKept, not encrypted

A secret’s name and a request’s note are stored as you typed them, not encrypted, so they shouldn’t contain anything sensitive. The app says so next to the request note field.

We log the event, never the secret

Every secret has an access log: each attempt to open it, whether it worked, the IP address and the browser’s user agent. Organisations also get an audit log of secrets, requests, members, API keys, policies, billing, sign-ins, 2FA and SSO. The audit log stores IPv6 addresses shortened to their /64 network.

IP addresses and user agents in both logs are cleared after 90 days. The rest of each record stays, so an organisation keeps its history.

Our application logs never contain secret contents. Secret ids and request tokens in URLs are replaced with placeholders before a line is written, so the logs can’t be used to open a link. For rate limiting we store a hash of the IP address, not the address.

See the audit log feature

Controls that protect the link, the account and the organisation

The link

  • Links carry a 10-character random id (about 50 bits). An IP address that tries 20 links that don’t exist within an hour is blocked from looking up links until the hour ends.
  • Opening a secret is a deliberate action, not a page load, so link previews in chat apps and email scanners don’t use up a view. Through the API, revealing is POST-only for the same reason.
  • Secret and request pages are sent with Cache-Control: no-store and Referrer-Policy: no-referrer, so browsers don’t cache them or pass the link on to other sites.
  • Passcodes are hashed with bcrypt. A secret is destroyed after five wrong passcodes, and parallel guesses can’t get round the limit.
  • Recipients-only secrets ask unverified viewers for a 6-digit code sent to their email. Codes last 10 minutes and allow five attempts.

Accounts

  • Two-factor authentication with any TOTP app, with backup codes. Organisations can require it for every member.
  • Single sign-on with your own OpenID Connect provider, starting with Microsoft Entra ID. Domains are verified by DNS TXT record, and SSO can be enforced for everyone on them, with owners keeping a break-glass sign-in.

The organisation

  • Four roles: owner, admin, member, viewer. Viewers can’t create secrets, requests or API keys.
  • Enforced policies cap expiry and views, require passcodes or sign-in, turn files and requests off, and restrict which email domains secrets can be sent to.
  • API keys are tied to one organisation, limited to the scopes you choose, can expire, and stop working when their owner leaves. We store only a hash of each key. Keys can never manage users, billing, SSO or other keys.

See team controls

Where your data is held

Database
A managed database in Microsoft Azure.
Files
Encrypted in private Azure blob storage, as described under Files above.
Email
Notifications, recipient emails and requests are sent through Microsoft 365.
Payments
Card payments are taken by Stripe on Stripe’s own checkout page. We never see or store card numbers.
This website
www.shareshield.net is a static site served by Cloudflare. It sets no tracking cookies and runs no analytics scripts.

When to use something else

We would rather lose a sign-up than have you rely on ShareShield for a job it isn’t built for.

You need the provider to be unable to read your secret.
ShareShield encrypts on our servers. If your threat model includes the service itself, use a tool that encrypts in your browser before anything is sent, such as the sharing features in 1Password or Bitwarden Send, or encrypt the file yourself with a tool like age and share the passphrase separately.
The credential is used every day by several people.
A one-time link is for handing something over. A password that a team keeps using belongs in a shared vault in a password manager, where access can be granted and removed.
An application or pipeline needs the secret at run time.
Use a secrets manager such as Azure Key Vault, AWS Secrets Manager or HashiCorp Vault. ShareShield is for getting a secret to a person, not for serving it to a program.
The file is larger than 25 MB.
That is the largest file any plan accepts.
Your contract requires a certified supplier.
If you need a supplier with a SOC 2 report or an ISO/IEC 27001 certificate, email us before you rely on ShareShield, so we can tell you exactly what we can evidence.

Read: how to send a password securely

Reporting a security problem

Email with “Security” in the subject line. Include what you found, the steps to reproduce it, and what you think the impact is. Please don’t access other people’s data, run denial-of-service tests or use automated scanners against the production service, and give us a reasonable chance to fix the problem before you publish it.

Never include a real secret or someone else’s data in your report. If we need a sample from you, we’ll send you a ShareShield request link.

Email a security report

Check it against your own requirements

Send yourself a secret, open it, and try opening it again. Then look at the team controls and decide whether they fit how you work.