steekem steekem
single-use, end-to-end encrypted

How steekem works

You open one of the tools — text, Wi-Fi, password, or credit card — and pick what to share. Steekem hands you a 6-character code and a link. The other person opens that link, and your two browsers find each other through a tiny signaling worker — the only server steekem runs. From there the browsers negotiate a direct WebRTC connection and the bytes flow straight between them, encrypted by the same DTLS layer your browser uses for video calls. There is no upload. Nothing you share ever lands on a server we control.

Why peer-to-peer

Most "send a file" or "share a password" tools work by asking you to upload to a server, then issuing a link other people can use to download. The server holds your data — for minutes, hours, sometimes longer. That server can be subpoenaed, breached, or operated by someone whose privacy promises don't survive a change of CEO. Even when the file is encrypted at rest, the operator usually holds the key.

Peer-to-peer skips that step. The two browsers exchange a handful of small messages, just enough to find each other through routers and firewalls, then connect directly. Bytes flow from one device to the other. We don't have a copy. The room code and a few packets of routing metadata are everything we ever see, and only for the seconds the connection is being set up.

What happens when you share something

The full flow looks like this:

  1. You pick something to share. Each tool has its own page tuned to the type of thing — a text snippet, Wi-Fi credentials, a login, a credit card.
  2. Steekem generates a room code. Six characters from a non-confusable alphabet (abcdefghjkmnpqrstuvwxyz23456789 — no i/l/o/0/1). About 887 million combinations. The code is generated entirely in your browser using crypto.getRandomValues; we never see it server-side until your browser opens a WebSocket to that room.
  3. You share the link. The link is /r#abc123 — the room code lives in the URL fragment, which browsers do not send to servers. Even our signaling worker, which receives the WebSocket connection on /room/abc123, only sees the path, not anything you'd consider sensitive.
  4. The other person opens the link. Their browser connects to the same room on the signaling worker. The worker's job at this point is exactly: "tell each of you that the other has arrived."
  5. The browsers negotiate. This is the WebRTC part. They exchange Session Description Protocol (SDP) offers and ICE candidates — essentially "here's a list of network addresses I can be reached at; pick one" — and run a DTLS handshake to set up encryption keys.
  6. They open a DataChannel. WebRTC's equivalent of a TCP connection, but encrypted end-to-end and tunneled through whatever NAT/firewall traversal trick worked. Once it's open, the two browsers can send arbitrary bytes to each other directly.
  7. The transfer happens. What this looks like depends on the tool — see below.
  8. It ends. The channel closes. The signaling worker drops the room. Nothing persists.

The signaling layer

The only server steekem runs is a small Cloudflare Worker paired with a Durable Object per active room. A Durable Object is a tiny isolated process Cloudflare runs at a single point — one per room ID. Two browsers using the same room land in the same instance.

What it does:

What it doesn't do:

Single-use snippets: text, Wi-Fi, password, card

Each tool packages your inputs into a single data-offer message and sends it over the DataChannel. The data is small and inline, so it doesn't need chunking:

{ "type": "data-offer", "data": {
    "kind": "wifi",
    "ssid": "...",
    "password": "...",
    "security": "WPA",
    "hidden": false
} }

The receiver renders it appropriately — a scannable Wi-Fi QR code, a labeled credentials card, a card-shaped credit-card preview — and immediately auto-acks data-viewed back to the sender. The sender flips the session to "delivered," writes a localStorage marker so anyone who later opens the same /r#code link sees "this share has already been used," and closes the connection.

The receiver-side card has three security guards:

For passwords specifically, there's also a "Save to password manager" button that calls the Credential Management API, triggering the browser's native save-credential prompt. Browser extensions (1Password, Bitwarden) intercept that prompt and let you save into your real vault with the right URL. Available where the API is supported (Chromium-based browsers); silently hidden where it's not.

End-to-end encryption

Every byte that flows over a steekem DataChannel is encrypted by DTLS — the same protocol your browser uses for the audio and video in a video call. The handshake happens between your two browsers, mediated by the signaling worker, but the worker never sees the negotiated keys. The keys are unique to each connection and discarded when the channel closes.

We have no way to decrypt anything you send. The keys never reach us. That's a property of the protocol, not a policy we could change.

What we don't see, log, or store

One thing does live somewhere: in your own browser. The sender keeps a localStorage marker (steekem-room-<code>) so a refreshed tab can still show what you sent and confirm it went through. It never leaves your machine, and it ages out after seven days.

What's still rough

About · How it works · Terms