Bluesky recently introduced a new form of verification. It’s a social version of the familiar notion of a blue check, in a way that is architecturally aligned with Bluesky and its underlying protocol ATProto. This allows notable accounts and accounts that are related to trusted organizations to be verified as authentic.

In order to support that, the Bluesky app has a list of a few trusted verifiers - the Bluesky team itself, NY times, Wired and The Athletic. Each of these organizations can attest that another user is authentic. They do so by adding records on their own Personal Data Server (PDS), which stores all the records related to their activity in Bluesky and potentially a wider ATProto ecosystem, the Atmosphere. Steve Klabnik has a good post that describes how it fits within the protocol design considerations. This form of attestation is simple and decentralized in spirit - while the official Bluesky has this initial list of trusted verifiers, other views of the same social Bluesky records can ignore these or trust other verifiers.

In this short post, I’d liked to explore potential ways this mechanism can be extended to more forms of verification, and especially those that are automated and verifiable - verifications that contain non-interactive cryptographic evidence rather than just attestations.

Recap on current verification

As Steve describes in his post, verification is done by the attester adding a record of the following form to their PDS:

{
  "$type": "app.bsky.graph.verification",
  "handle": "steveklabnik.com",
  "subject": "did:plc:3danwc67lo7obz2fmdg6jxcr",
  "createdAt": "2025-04-21T10:49:07.620Z",
  "displayName": "Steve Klabnik"
}

The record of type app.bsky.graph.verification describes the verified identity, including some other details like when they were verified, what’s their handle and their name.

Design goals

A couple of very simple ones:

  1. The new form of verification should be easy to, at least partially, integrate into apps that support the existing form
  2. Apps that would like to perform full verification have all the cryptographic evidence necessary to do so in a way that is compatible with ATProto

Non-interactive verification using ZK Email

As a concrete example, let’s look at ZK Email. It’s an open source project that uses zero knowledge proofs about the content of emails. This is possible since modern email infrastructure uses DKIM (DomainKeys Identified Mail), where sent emails contains signatures on the headers and body.

This allows us to create some fun examples of verified sets of users:

  1. Prove that Kobi sent you an email
  2. Prove that your were a speaker in a conference
  3. Prove that you have a valid Instagram accounts

The above all contain links of examples from the ZK Email Registry of how you can use regex on the email contents to achieve these properties. The nice thing about this method is that you don’t have to expose the entire email. Because the proofs are zero-knowledge, you can just prove that the email satisfies the desired property without revealing the rest of it, containing potentially sensitive data. Note that the examples above require you to associate your email with your Bluesky identity somehow.

First method - new schema

A design that ignores the first requirement is just adding new records. We could think of something of the following form: