Skip to main content

Certificate-Based Security

info

This section contains an advanced discussion of Ditto's underlying certificate, identity, and encryption implementation. Most readers can skip this section. However, if you are deploying an enterprise on-premises deployment of Ditto, you may be required to reference the following material.

All communications are consistently protected by modern and robust encryption for all of Ditto's communication methods. Cryptographically-signed business rules ensure users can only sync data that they are permitted to access. The app developer is in complete control of the keys, certificates, and rules.

The Ditto Big Peer provisions a signed x509 certificate. This certificate may then be presented to other Ditto peers to mutually establish trust and create encrypted communications channels.

The following details information about the certificates used to encrypt the communication channels.

CapabilityType
EncryptionTLS 1.3
AuthenticationEC keypairs with signed certificates
Trust infrastructureX.509 with a developer-controlled certificate authority
Access RulesQuery patterns on Document _id's describing read and or write access

Identities

An identity is a bundle of the device and app-specific information:

  • Site ID - A number unique to this device.
  • App Name - A name identifying the application. This avoids different Ditto-enabled apps trying to sync with each other. These are unique identifiers, for example, 5322afcd-5a70-43a3-bc2d-85d98ccf5ac0
  • Access Rules - Define which documents this device is allowed to read or write during sync.
  • Private Key - A secret for authenticating as this identity.
  • Identity Certificate - A certificate verifying the particulars of this device, signed by the CA.
  • CA Certificate - Used to verify certificates presented by other devices with the same app.
ProductionDevelopment
Site IDAllocated by central authorityDefaults to a random number; can be customized
App IDSet by central authorityFor example, "5322afcd-5a70-43a3-bc2d-85d98ccf5ac0"
Access RulesSet by central authorityAll devices may read/write all documents
Private KeyEither generated on device or distributed by central authorityHard-coded and shared by all devices
Identity CertificateUnique and signed by a central authority; contains this device's public keyHard-coded and shared by all devices
CA CertificateShared by all users of the same appHard-coded and shared by all devices

Certificates

Ditto identities and public keys are distributed in the standard X.509 certificate format. They do not directly contain potentially sensitive data such as access rules, but these can be defined by the app's authentication webhook with the OnlineWithAuthentication identity, or by the developer through the Manual identity.

When you are ready to use production identities, feel free to contact us through the Ditto Portal and we will help you set up the right CA tooling for your use case - or provide specifications so you can build your own.

Discovering peers

Devices need to have the same AppID to discover other peers on the network, as well as matching certificates to connect over TLS 1.3. Peer-to-peer connections use mTLS (client certificates) with TLS 1.3. Connections to the Big Peer use a TLS-secured WebSocket connection, with authentication by JWT. Once the certificates match, then the embedded authorization information inside each certificate is used to authorize any incoming requests by that peer. This ensures that those access control rules are enforced.

Synchronizing with the Big Peer

info

The description below covers internal details of the Big Peer implementation. Ditto’s authentication module handles this implementation for you under the hood as part of the OnlineWithAuthentication and OnlinePlayground identities.

Overview

Online Authentication can be used when a Ditto application is hosted on a Big Peer. The Big Peer hosts an HTTPS identity service, which handles login requests. In Online Authentication mode, a Small Peer must log in with credentials before it can communicate with any peers. The login flow populates the Small Peer with valid authentication material that identifies the user and defines their level of access. Once the Small Peer receives this data after a successful login, the transports which depend on it will start automatically.

Step 1: Complete a Peer Key Challenge

The peer’s public key will be included in the certificates returned by the identity service. The identity service needs proof that the authenticating Small Peer actually holds the corresponding private key.

  1. Small Peer downloads a challenge token from /_ditto/auth/cert - this is a time-limited JWT which the client treats as opaque data.
  2. Small Peer uses their Peer Key to sign it.

Step 2: Log in with Credentials

When a client attempts to authenticate, it will make an HTTPS request to the identity service containing the following payload:

Once the identity service has a response from the auth webhook, it will build and sign a JWT. In addition to the information we would expect to find in a JWT (issuer, issued at, expiry, etc), we also include an encoded representation of the Ditto Identity. The Ditto Identity is built from the information provided by the app's authentication webhook response.

Step 3: Upgrade to an X.509 Certificate

Once a peer has a JWT, it will want to use this to get a device certificate.  The peer will now make an HTTPS certificate request to the identity service. The “request certificate” endpoint requires a valid JWT.  The contents of the new certificate is closely tied to the JWT.  The certificate expiration time is the same as the JWT, and the ditto identity embedded in the certificate is pulled from the JWT.  The identity service generates a private key for the device.  It uses this private key to generate a CSR on behalf of the client and then the identity service’s CA keys to sign it.

Once this information is prepared, the identity service is ready to respond to the request. The response will include the client's generated certificate and private key, a list of CA certificates the client should trust, and a DateTime for expiration. The client will persist the JWT, device private key, device certificate, and CA certificates on disk and only update them when they get near expiration.

When two peers authenticate with each other, they can use either the JWT or the device certificate via MTLS. The decision depends on the client's capabilities and connection type.

Rationale

Why does X.509 return both a key and a certificate instead of locally generating a key and sending a CSR?

It would be possible to use a standard CSR flow. It was chosen to issue keys directly for a few reasons.

  • There is no security benefit as our certificate request is in a secured tunnel, and the identity service is presumed to be completely trustworthy.
  • Validating and signing CSRs is more complex than simply creating one with the correct format and fields.
  • This is a convenient workflow if using Hashicorp Vault or similar to manage your PKI and issue certificates on demand.

Why is X.509 a separate request?

The idea is that JWTs could be quite short-lived but the X.509 certs could be long-lived to permit long periods of working offline, so the Small Peer could call them to refresh at different intervals. Different expiry periods between JWT and X.509 isn’t implemented yet.

Additionally, browser peers have no use for X.509 certificates so they don’t request them.

Of course, the Small Peer could have a single request that lets you request some combination of identities at once. There is no reason this couldn’t be added in the future to reduce latency.

New and Improved Docs

Ditto has a new documentation site at https://docs.ditto.live. This legacy site is preserved for historical reference, but its content is not guaranteed to be up to date or accurate.