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
        }
      }
    }
  }
}