Signal · Schema

Signal Protocol Entities

Schema defining the core cryptographic entities used in the Signal Protocol, including identity keys, pre-key bundles, signed pre-keys, Kyber post-quantum pre-keys, and session state. These entities form the foundation of the key exchange and message encryption mechanisms used by Signal clients and server.

EncryptionMessagingSecurityCryptographyOpen-SourcePrivacy
View JSON Schema on GitHub

JSON Schema

signal-protocol-entities-schema.json Raw ↑
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://signal.org/schemas/signal/protocol-entities.json",
  "title": "Signal Protocol Entities",
  "description": "Schema defining the core cryptographic entities used in the Signal Protocol, including identity keys, pre-key bundles, signed pre-keys, Kyber post-quantum pre-keys, and session state. These entities form the foundation of the key exchange and message encryption mechanisms used by Signal clients and server.",
  "type": "object",
  "$defs": {
    "IdentityKey": {
      "type": "object",
      "title": "Identity Key",
      "description": "A long-term Curve25519 identity key pair used to identify an account. Each account has an ACI (Account Identity) key and a PNI (Phone Number Identity) key.",
      "required": ["publicKey"],
      "properties": {
        "publicKey": {
          "type": "string",
          "description": "The Base64-encoded Curve25519 public identity key (32 bytes).",
          "pattern": "^[A-Za-z0-9+/=]+$"
        }
      }
    },
    "PreKey": {
      "type": "object",
      "title": "One-Time Pre-Key",
      "description": "An ephemeral Curve25519 key pair uploaded to the server for use in the X3DH or PQXDH key agreement. Each pre-key is used at most once.",
      "required": ["keyId", "publicKey"],
      "properties": {
        "keyId": {
          "type": "integer",
          "format": "int64",
          "description": "The unique identifier for this pre-key.",
          "minimum": 0
        },
        "publicKey": {
          "type": "string",
          "description": "The Base64-encoded Curve25519 public key (32 bytes).",
          "pattern": "^[A-Za-z0-9+/=]+$"
        }
      }
    },
    "SignedPreKey": {
      "type": "object",
      "title": "Signed Pre-Key",
      "description": "A medium-term Curve25519 key pair signed by the identity key. Rotated periodically and used as a fallback when one-time pre-keys are exhausted.",
      "required": ["keyId", "publicKey", "signature"],
      "properties": {
        "keyId": {
          "type": "integer",
          "format": "int64",
          "description": "The unique identifier for this signed pre-key.",
          "minimum": 0
        },
        "publicKey": {
          "type": "string",
          "description": "The Base64-encoded Curve25519 public key (32 bytes).",
          "pattern": "^[A-Za-z0-9+/=]+$"
        },
        "signature": {
          "type": "string",
          "description": "The Base64-encoded XEdDSA signature over the public key, created with the identity private key (64 bytes).",
          "pattern": "^[A-Za-z0-9+/=]+$"
        }
      }
    },
    "KyberPreKey": {
      "type": "object",
      "title": "Kyber Post-Quantum Pre-Key",
      "description": "A post-quantum key encapsulation mechanism (KEM) key pair using CRYSTALS-Kyber, uploaded to the server for the PQXDH key agreement protocol. Provides quantum resistance for forward secrecy.",
      "required": ["keyId", "publicKey", "signature"],
      "properties": {
        "keyId": {
          "type": "integer",
          "format": "int64",
          "description": "The unique identifier for this Kyber pre-key.",
          "minimum": 0
        },
        "publicKey": {
          "type": "string",
          "description": "The Base64-encoded Kyber-1024 public key.",
          "pattern": "^[A-Za-z0-9+/=]+$"
        },
        "signature": {
          "type": "string",
          "description": "The Base64-encoded signature over the Kyber public key, created with the identity private key.",
          "pattern": "^[A-Za-z0-9+/=]+$"
        }
      }
    },
    "PreKeyBundle": {
      "type": "object",
      "title": "Pre-Key Bundle",
      "description": "A complete pre-key bundle retrieved from the server for establishing a new Signal Protocol session. Contains identity key, signed pre-key, optional one-time pre-key, and optional Kyber pre-key.",
      "required": ["identityKey", "signedPreKey", "registrationId"],
      "properties": {
        "identityKey": {
          "type": "string",
          "description": "The Base64-encoded identity public key of the account."
        },
        "registrationId": {
          "type": "integer",
          "description": "The registration ID of the target device.",
          "minimum": 0,
          "maximum": 16383
        },
        "deviceId": {
          "type": "integer",
          "format": "int64",
          "description": "The device identifier. Primary device is always 1.",
          "minimum": 1
        },
        "preKey": {
          "$ref": "#/$defs/PreKey",
          "description": "An optional one-time EC pre-key."
        },
        "signedPreKey": {
          "$ref": "#/$defs/SignedPreKey",
          "description": "The current signed pre-key."
        },
        "pqPreKey": {
          "$ref": "#/$defs/KyberPreKey",
          "description": "An optional one-time Kyber post-quantum pre-key for PQXDH."
        }
      }
    },
    "MessageEnvelope": {
      "type": "object",
      "title": "Message Envelope",
      "description": "A Signal Protocol message envelope containing encrypted content and routing metadata.",
      "required": ["type", "timestamp", "content"],
      "properties": {
        "type": {
          "type": "integer",
          "description": "The envelope type: 1 (ciphertext), 3 (prekey), 6 (plaintext content), 7 (unidentified sender).",
          "enum": [1, 3, 6, 7]
        },
        "sourceUuid": {
          "type": "string",
          "format": "uuid",
          "description": "The sender's ACI UUID. Absent in sealed sender messages."
        },
        "sourceDevice": {
          "type": "integer",
          "description": "The sender's device ID. Absent in sealed sender messages.",
          "minimum": 1
        },
        "destinationUuid": {
          "type": "string",
          "format": "uuid",
          "description": "The recipient's ACI UUID."
        },
        "timestamp": {
          "type": "integer",
          "format": "int64",
          "description": "The client-side send timestamp in milliseconds since epoch."
        },
        "serverTimestamp": {
          "type": "integer",
          "format": "int64",
          "description": "The server-side receive timestamp in milliseconds since epoch."
        },
        "content": {
          "type": "string",
          "description": "The Base64-encoded encrypted message payload."
        },
        "serverGuid": {
          "type": "string",
          "format": "uuid",
          "description": "A server-assigned GUID for this delivery instance."
        },
        "urgent": {
          "type": "boolean",
          "description": "Whether this message should be treated as urgent for push delivery."
        },
        "story": {
          "type": "boolean",
          "description": "Whether this envelope contains a story message."
        }
      }
    },
    "Account": {
      "type": "object",
      "title": "Signal Account",
      "description": "A Signal user account identified by a phone number and one or more UUIDs.",
      "required": ["uuid", "number"],
      "properties": {
        "uuid": {
          "type": "string",
          "format": "uuid",
          "description": "The ACI (Account Identity) UUID, the primary stable identifier."
        },
        "number": {
          "type": "string",
          "description": "The E164-formatted phone number associated with the account.",
          "pattern": "^\\+[1-9]\\d{1,14}$"
        },
        "pni": {
          "type": "string",
          "format": "uuid",
          "description": "The PNI (Phone Number Identity) UUID, which changes when the phone number changes."
        },
        "usernameHash": {
          "type": "string",
          "description": "The Base64url-encoded SHA-256 hash of the username, if set."
        },
        "identityKey": {
          "type": "string",
          "description": "The Base64-encoded ACI identity public key."
        },
        "pniIdentityKey": {
          "type": "string",
          "description": "The Base64-encoded PNI identity public key."
        },
        "devices": {
          "type": "array",
          "description": "The list of devices linked to this account.",
          "items": {
            "$ref": "#/$defs/Device"
          }
        }
      }
    },
    "Device": {
      "type": "object",
      "title": "Device",
      "description": "A device linked to a Signal account. Each account has a primary device (ID 1) and may have additional linked devices.",
      "required": ["id"],
      "properties": {
        "id": {
          "type": "integer",
          "format": "int64",
          "description": "The device identifier. The primary device is always 1.",
          "minimum": 1
        },
        "name": {
          "type": "string",
          "description": "The encrypted device name, Base64-encoded."
        },
        "registrationId": {
          "type": "integer",
          "description": "The Signal Protocol registration ID for this device.",
          "minimum": 0,
          "maximum": 16383
        },
        "lastSeen": {
          "type": "integer",
          "format": "int64",
          "description": "Unix timestamp in milliseconds when the device last connected."
        },
        "created": {
          "type": "integer",
          "format": "int64",
          "description": "Unix timestamp in milliseconds when the device was linked."
        },
        "fetchesMessages": {
          "type": "boolean",
          "description": "Whether this device uses WebSocket to fetch messages (true) or relies on push notifications (false)."
        },
        "apnId": {
          "type": "string",
          "description": "The Apple Push Notification Service token for iOS devices."
        },
        "gcmId": {
          "type": "string",
          "description": "The Firebase Cloud Messaging registration token for Android devices."
        }
      }
    },
    "SealedSenderCertificate": {
      "type": "object",
      "title": "Sealed Sender Certificate",
      "description": "A delivery certificate issued by the server for sealed sender message delivery. Sealed sender hides the sender identity from the server during message transmission.",
      "required": ["certificate"],
      "properties": {
        "certificate": {
          "type": "string",
          "description": "The Base64-encoded signed certificate containing the sender's UUID, device ID, identity key, and expiration."
        },
        "expiration": {
          "type": "integer",
          "format": "int64",
          "description": "The certificate expiration timestamp in milliseconds since epoch."
        }
      }
    },
    "GroupV2": {
      "type": "object",
      "title": "Signal Group (V2)",
      "description": "A Signal group using the V2 groups protocol with server-side state. Groups use zero-knowledge group credentials to maintain member privacy.",
      "properties": {
        "masterKey": {
          "type": "string",
          "description": "The Base64-encoded 32-byte group master key.",
          "minLength": 1
        },
        "groupId": {
          "type": "string",
          "description": "The Base64-encoded group identifier derived from the master key."
        },
        "title": {
          "type": "string",
          "description": "The encrypted group title."
        },
        "avatar": {
          "type": "string",
          "description": "The CDN path to the encrypted group avatar."
        },
        "revision": {
          "type": "integer",
          "description": "The current group state revision number.",
          "minimum": 0
        },
        "members": {
          "type": "array",
          "description": "The list of group members with their roles.",
          "items": {
            "$ref": "#/$defs/GroupMember"
          }
        },
        "accessControl": {
          "type": "object",
          "description": "Access control settings for group modifications.",
          "properties": {
            "attributes": {
              "type": "string",
              "description": "Who can modify group attributes.",
              "enum": ["UNKNOWN", "ANY", "MEMBER", "ADMINISTRATOR", "UNSATISFIABLE"]
            },
            "members": {
              "type": "string",
              "description": "Who can modify the member list.",
              "enum": ["UNKNOWN", "ANY", "MEMBER", "ADMINISTRATOR", "UNSATISFIABLE"]
            },
            "addFromInviteLink": {
              "type": "string",
              "description": "Who can join via invite link.",
              "enum": ["UNKNOWN", "ANY", "MEMBER", "ADMINISTRATOR", "UNSATISFIABLE"]
            }
          }
        }
      }
    },
    "GroupMember": {
      "type": "object",
      "title": "Group Member",
      "description": "A member of a Signal V2 group.",
      "properties": {
        "uuid": {
          "type": "string",
          "format": "uuid",
          "description": "The member's ACI UUID."
        },
        "role": {
          "type": "string",
          "description": "The member's role in the group.",
          "enum": ["UNKNOWN", "DEFAULT", "ADMINISTRATOR"]
        },
        "joinedAtRevision": {
          "type": "integer",
          "description": "The group revision at which this member joined.",
          "minimum": 0
        }
      }
    }
  }
}