Skip to main content

Overview

When using the Server Connection with Custom Authentication identity, Ditto issues X.509 certificates and JWTs (referred to collectively as “certificates” in this document) to authenticated peers. Once a certificate is granted, a peer can continue syncing data across the mesh until the certificate expires. Revocations allow you to invalidate these certificates when a user or device should no longer have access. Rather than revoking individual certificates by ID, you define a filter expression using DQL that matches against identity fields. This allows you to revoke access for a single user, a group of users, or any set of identities matching specific criteria. Revocations are managed centrally via the Big Peer’s HTTP API and are automatically propagated to all connected peers — including Small Peers that communicate only via peer-to-peer connections (Bluetooth, LAN, etc.). In the diagram above, “check peer connections” means both existing connections and any future connection attempts are evaluated against the revocation.

When to use revocations

Common scenarios where revocation is necessary:
  • Deprovisioning a user — An employee leaves the organization and their device should no longer sync data.
  • Compromised device — A device is lost or stolen and should be immediately excluded from the mesh.
  • Bulk access removal — Revoke all users matching certain criteria, such as a specific role or store location.
Revocations only apply to peers whose certificates were issued before the revocation was created. Peers who re-authenticate after a revocation will receive new certificates that are not affected by existing revocations.

Revocation filters

Revocations use DQL filter expressions that are evaluated against a peer’s identity context. The identity context is derived from two fields set in your authentication webhook response:

Filter examples

Revoke a single user:
Revoke all users at a specific store:
Revoke a user at a specific store:
Only the userID and identityServiceMetadata fields are allowed in revocation filters. Filters referencing other fields will be rejected by the API.

Create a revocation

To revoke access, send a POST request with a DQL filter expression and a reason.
Reject the matching identities in your authentication webhook before you create the revocation. Peers may refresh their tokens automatically and a revocation only applies to certificates issued before it was created. If your webhook still returns authenticate: true for that identity, the peer re-authenticates, receives a fresh certificate that the revocation does not match, and regains access.
To use the HTTP API, you need an API key with appropriate permissions. See HTTP API Authentication for details.
Request:
The endpoint expects a JSON payload that looks like:
Both fields are required, and each must be non-empty and at most 16384 characters. Example request:
Response:
  • _id: A UUIDv7 that encodes the creation time, enabling chronological ordering.
  • transactionId: A monotonically increasing identifier for the write operation, consistent with the transactionId returned by other HTTP Data API endpoints.

List revocations

Retrieve the current list of revocations for auditing. The endpoint supports cursor-based pagination. The response includes a hasMore field indicating whether additional pages are available, and a cursor field to fetch the next page. Request:
All three query parameters are optional. Example request:
Response:
Paginate through results When hasMore is true, pass the returned cursor value to fetch the next page, with an optional limit:
Response:
When hasMore is false, the cursor field is omitted from the response since there are no further pages to retrieve.

Search revocations

You can search for revocations by filter text using the filter_contains query parameter. This performs a case-sensitive substring match against the filter field of each revocation. This parameter can be combined with cursor and limit for paginated searches.

Error responses

How revocation propagation works

When you create a revocation through the HTTP API:
  1. The Big Peer stores the revocation and signs it with its private key before propagating it.
  2. The signed revocation is propagated to connected Small Peers.
  3. Each Small Peer verifies the signature to confirm the revocation originates from a trusted Big Peer, then stores it locally.
  4. Small Peers propagate revocations to other Small Peers they connect with. Each receiving peer verifies the signature before storing, ensuring every hop in the mesh is authenticated.

Revocation checking

Revocations are enforced at two points:
  • New connections: When a peer attempts to connect, it is evaluated against all active revocation filters. If any filter matches, the connection is rejected.
  • Existing connections: When a new revocation is added, it is immediately evaluated against all currently connected peers. Any matching connections are terminated.
This dual-check approach ensures that revoked peers are disconnected promptly, not just prevented from establishing new connections.

Mesh-wide propagation

Revocations are not limited to the Big Peer → Small Peer path. Small Peers also propagate revocations to each other during peer-to-peer sync. This means:
  • A Small Peer that received a revocation from the Big Peer will share it with other Small Peers it connects to.
  • Peers that are not directly connected to the Big Peer can receive revocations through the mesh, as long as they have authenticated with the Big Peer earlier.
Revocation propagation depends on peers syncing with the Big Peer or with another peer that already has the revocation. Fully offline peers will not receive revocation updates until they reconnect to the mesh.

Signature verification

Each revocation entry is individually signed by the Big Peer. Small Peers verify the signature against their trusted CA keys before storing the revocation. This prevents forged revocations — a compromised Small Peer cannot fabricate revocation entries that other peers would accept. If signature verification fails, the revocation entry is skipped.

Revocations collections

Revocations are stored in collections that you can query read-only via DQL. The Big Peer holds the authoritative list, while each Small Peer holds a signed copy of the revocations it has received.

Big Peer

The Big Peer maintains the authoritative list of revocations in the __revocations collection. This is where entries created through the HTTP API are stored, including the human-readable filter, reason, and created_at values.
Manage revocations on the Big Peer only through the HTTP API. Do not write to the __revocations collection directly.

Small Peer

Small Peers store the revocations they have received in a local __revocation_cache collection. You can query this collection to inspect which revocations a peer currently holds — useful for debugging and auditing on-device state.
Each document is individually signed by the Big Peer. Its contents include the signed revocation payload, the signature, the signing key, and metadata such as the creation time.
Treat __revocation_cache as read-only. Do not insert, update, or delete documents in this collection. Because each entry is verified against its signature, a modified entry is treated as invalid.

Considerations