security/SikkerLink Security

SikkerLink Security

Learn how SikkerLink encrypts one-time secret links in your browser and removes them after the first successful reveal.

Updated 2 days ago

SikkerLink lets you send a secret through a link that can be opened once and then destroys itself. Encryption and decryption happen in the browser, so the SikkerLink server stores an encrypted blob without receiving the plaintext or the key required to read it.

Treat the complete SikkerLink URL as sensitive when the passphrase is included in it. Anyone who receives the full link can use its single reveal.


Open SikkerLink and enter the secret you want to share.

Choose how long the link should remain available, from one hour to one day.

Create the link. Your browser generates the passphrase, derives the encryption key, and encrypts the secret before uploading anything.

Send the link to the intended recipient. You can include the passphrase in the URL or share it separately.

The recipient opens the link. After the passphrase is accepted, the encrypted blob is released once and deleted from the server.

The recipient’s browser decrypts and displays the secret locally.

After the first successful reveal, refreshing or reopening the link cannot retrieve the secret again.


#Browser-side encryption

All cryptographic work happens locally in the sender’s browser before the encrypted data is uploaded.

  • Generated passphrase. The browser creates a random passphrase with 256 bits of entropy using the platform’s cryptographically secure random-number generator.

  • Per-link key derivation. PBKDF2 derives the encryption key from the passphrase using SHA-256, 250,000 iterations, and a random salt unique to the link.

  • Authenticated encryption. The secret is encrypted with AES-256-GCM using a random 96-bit initialization value. The GCM authentication tag causes modified or corrupted ciphertext to fail decryption.

  • Opaque upload. Only the salt, initialization value, and ciphertext leave the browser. They are packed together and encoded with base64url for transport.

The passphrase never reaches the server. When included in the link, it appears after the URL’s # as a fragment. Browsers do not include URL fragments in HTTP requests. You can also share the passphrase through a separate channel and have the recipient enter it manually.


#What the server stores

Each active link has only three server-side records:

  • the opaque encrypted blob containing the salt, initialization value, and AES-256-GCM ciphertext

  • a SHA-256 hash of the passphrase used as the one-time access gate

  • the expiry timestamp

The server does not receive or store the plaintext secret, passphrase, derived AES key, or any other material that can decrypt the blob. Decryption exists only in the recipient’s browser.

Why the access hash cannot decrypt the secret

Before releasing the encrypted blob, the recipient’s browser sends SHA-256(passphrase). The server compares it in constant time with the access hash stored when the link was created.

The access hash is separate from the AES key. The encryption key is derived through PBKDF2 with the link’s random salt and 250,000 iterations. Possession of the stored access hash does not provide the key needed to decrypt the blob.

An incorrect passphrase leaves the link untouched so the intended recipient can try again.


#One successful reveal

A correct reveal deletes the link in the same locked database transaction that releases the encrypted blob. The database serializes competing requests with a row lock, so two simultaneous reveal attempts cannot both succeed.

  • The first valid request locks the link, deletes the stored record, and receives the encrypted blob.

  • A competing request finds that the record is no longer available.

  • The successful recipient’s browser decrypts the blob locally.

  • Reloading the page cannot retrieve the ciphertext again.

A link that never existed, has expired, or was already opened produces the same unavailable response. The response does not reveal which of those states applies.


#Expiry

The sender chooses a lifetime between one hour and one day. Expiry is checked inside the same locked read used for a reveal. If the link is expired, the request removes it instead of returning the blob.

A background cleaner also removes expired records on a short interval. A link’s lifetime cannot be extended; create a new link if the secret needs to be shared again.

Choose the shortest lifetime that still gives the recipient enough time to open the link.


#Accounts and retained data

Creating and opening a SikkerLink require no account or sign-in. SikkerLink does not attach a sender identity or recipient identity to a link. It retains only the encrypted blob, access hash, and expiry needed to perform the one-time handoff.

Reveal pages are marked as noindex and excluded from search-engine crawling.


#Abuse and transport protections

  • Rate limits. Link creation and reveal requests are limited by source IP because both operations are available without an account.

  • Bounded storage. The encrypted blob has a maximum size, and request bodies are limited before application processing begins.

  • TLS. SikkerLink is served only over TLS 1.2 or newer.

  • Strict transport security. HSTS instructs browsers to continue using HTTPS.

  • Content Security Policy. A restrictive browser policy limits where the page can load content from and which network destinations it can contact.

Shared hosting and infrastructure protections are described in the Security Overview.


#Data boundaries

Stored by SikkerLink

Kept in the browser or with the users

Opaque blob: salt, initialization value, and AES-256-GCM ciphertext

The plaintext secret

SHA-256 hash of the passphrase for the one-time access gate

The passphrase

Expiry timestamp

The AES encryption key derived through PBKDF2


SikkerLink is designed for a one-time handoff between people. Its browser can hold the encryption key while the server stores only unreadable ciphertext. This makes the sharing flow zero-knowledge.

The SikkerKey vault serves ongoing machine, CLI, SDK, and integration access. For an authorized vault read, SikkerKey decrypts the secret in memory and returns it to the authenticated workload. Vault secrets are protected through envelope encryption, isolated root-key infrastructure, signed machine authentication, and layered authorization.

Use SikkerLink when a person needs to send one secret to another person once. Use the SikkerKey vault when applications, machines, teams, or automation need managed and auditable access over time.


#Your responsibilities

  • Protect the passphrase. If it is part of the URL, protect the entire link as you would the secret itself. When shared separately, the recipient needs both the link and the passphrase.

  • Choose an appropriate lifetime. Use the shortest practical expiry window.

  • Verify the recipient and channel. Send the link only through a channel you trust and confirm that it reached the intended person.

  • Protect the revealed value. After the browser decrypts the secret, the recipient controls the plaintext. Keep it out of screenshots, logs, chat history, and other unintended storage.

  • Create a new link when necessary. A consumed, expired, or lost link cannot be recovered or extended because SikkerLink does not hold the passphrase or decryption key.

A lost passphrase cannot be reset or recovered. This is a direct consequence of the server never receiving the key needed to decrypt the secret.