Blog / Security

  • signal
  • sealed-sender
  • metadata
  • privacy
  • traffic-analysis
  • encryption

Metadata Privacy in Signal: What Sealed Sender Actually Hides

In April 2021, the US Attorney's Office in the Central District of California sent Signal a grand jury subpoena asking for a small pile of things about half a dozen accounts: registration information, correspondence, contact lists, IP logs, the name behind each account. Signal's public reply amounted to two Unix timestamps per account: when it was created, and when it last connected to the server. That was, genuinely, all there was to hand over.

That response is a decent way into what "sealed sender" does and does not achieve, because it is easy to read Signal's minimal data retention as a single magic feature. It is actually two separate things stacked on top of each other: a protocol-level mechanism that stops the server learning who sent a given message, and an operational policy of not logging what it could still infer. Conflating the two leads to wrong assumptions about what is and is not protected.

The problem sealed sender solves

Signal Protocol encrypts message content end to end, so the server never sees plaintext. That was true well before sealed sender existed. What was still visible, in the older design, was the envelope: to authenticate a client and apply per-account rate limiting, the server needed to know who was sending a message as well as who it was going to. Even with content locked away, "Alice sent Bob something at 03:14, then again at 03:17" is exactly the kind of record that builds a contact graph, and it is often more useful to an investigator than the content would have been anyway.

Sealed sender, which Signal shipped as a technology preview in October 2018, removes the "from" field from that envelope.

How it actually works

Two pieces do the work. First, a client periodically fetches a short-lived sender certificate from Signal's server: a signed statement containing the sender's phone number (or, on newer accounts, their account identifier), their public identity key, and an expiry time. The certificate proves "this is a legitimate Signal account" without the server needing to be told whose account it is at send time.

Second, instead of authenticating the send request against an account login, the client derives a 96-bit delivery token from the recipient's profile key and attaches it to the message. Because Signal contacts already exchange profile keys as part of normal use, this reuses infrastructure that already exists rather than adding a new credential for the server to manage. The server checks the token, confirms it maps to a real destination, and queues the message. It never asked, and is never told, who the sender is.

The payload the server actually handles is layered: the Signal Protocol ciphertext and the sender certificate are packaged together, and that package is encrypted again with keys negotiated for delivery, so the outer layer the server touches carries no sender-identifying information at all. Only the recipient's device, on decrypting the inner layer, learns who sent it.

By default this only works between people who already trust each other enough to have exchanged profile keys, which in practice means contacts. Signal also offers an unrestricted mode that accepts sealed sender messages from strangers, at the cost of taking on more of the abuse-mitigation problem that per-sender authentication used to solve for free.

What the server still knows

None of this touches the recipient side. To deliver anything, the server has to know which account and which device it is delivering to; that half of the envelope was never sealed, and could not be, short of some much more elaborate scheme like private information retrieval over the entire message queue, which nobody runs at the volume Signal operates at. So an operator, or anyone who compels the operator, still learns that an account exists, its creation date, and roughly when it is active, because "is this account online right now" is inherent to running a push messaging service at all.

IP address is a separate matter again. Sealed sender is about the content of the delivery request, not the TCP connection carrying it. Signal's server sees the connecting IP address the same way any server does, which is why Signal also ships a proxy and censorship-circumvention option, and why anyone treating IP-level correlation as part of their threat model routes Signal traffic through Tor as well. Sealed sender was never advertised as network anonymity, only as message anonymity, and it is worth keeping those two claims apart.

Group messages add a further wrinkle. A message still has to reach every member's device, so the server has to know the membership list to fan a message out, sealed sender or not. Signal's separate zero-knowledge groups mechanism tries to keep group membership itself hidden from the server, using zero-knowledge proofs rather than a plaintext member list, but that is a genuinely different piece of cryptography solving a different problem, not an extension of sealed sender.

Why the subpoena response actually checks out

Given all that, the Central District of California response makes more sense as an engineering fact than a policy promise. Signal was not refusing to produce message logs, contact lists or correspondence out of principle; by its own account it does not retain what it could technically observe about delivery, and it cannot see who sent what in the first place. The subpoena asked for categories of data (correspondence, the name associated with each account, who talked to whom) that sealed sender means the server never learns, and for other categories (contact lists, group membership) that Signal states it discards rather than logs. Account creation date and last-connection timestamp are what is left over, because the server has to know an account exists and has to serve pushes to online devices. There is no clever way to encrypt that fact away.

There is an asymmetry worth noticing, though. All of this is about data that would already exist by the time a subpoena arrives. A subpoena compels production of records; it cannot retroactively create logging that was never turned on. A prospective order, of the kind used for real-time interception rather than historical records, is a different legal instrument, and it could in principle compel a provider to start capturing something going forward, within whatever the underlying architecture still allows it to see. Sealed sender narrows that surface considerably too, since sender identity is cryptographically absent rather than merely unlogged, but recipient and timing metadata sit in a different category: they are visible to the operator in real time by necessity, which is exactly the kind of thing a well-drafted prospective order could target even where nothing was ever stored historically.

The traffic analysis floor

None of this defeats an adversary who can watch the network rather than ask the operator nicely. If someone can see Alice's device open a connection to Signal's servers at 14:03:02 and Bob's device receive a push notification a fraction of a second later, sealed sender has not hidden much: the correlation sits right there in connection timing, independent of what the envelope contains. This is the standard limit of basically every low-latency messaging system, encrypted or not, and it is why people who need to defend against a network-level observer reach for mix networks, timing obfuscation or simply accept higher latency, none of which Signal is built around. Sealed sender was designed to answer "what can the operator infer from the messages it handles", not "what can a passive network observer infer from watching connections", and it is a genuinely good answer to the first question. It was never trying to answer the second.