E2e Key Exchange Blueprint

Manages cryptographic key material for end-to-end encrypted messaging. Handles device key publication, one-time pre-key upload/claiming, and cross-server key queries.

   
Feature e2e-key-exchange
Category Auth
Version 1.0.0
Tags e2e, encryption, key-exchange, olm, megolm, devices, security
YAML Source View on GitHub
JSON API e2e-key-exchange.json

Actors

ID Name Type Description
sender_device Sending Device human Device establishing an encrypted session with recipients
recipient_device Recipient Device human Device whose keys are being queried to set up encryption
homeserver Homeserver system Key distribution server; stores and serves keys without decrypting content
remote_server Remote Server external Foreign server hosting recipient devices

Fields

Name Type Required Label Description
device_id token Yes Identifier of the device the keys belong to  
user_id text Yes Account the device belongs to  
identity_keys json Yes Long-lived public keys for the device (curve25519 and ed25519)  
one_time_keys json No Single-use pre-keys uploaded in bulk to bootstrap Olm sessions  
fallback_keys json No Fallback pre-keys used when no one-time keys remain  
claimed_keys json No One-time keys retrieved by another device to initiate encryption  
failures json No Map of server domains to error descriptions for failed queries  

Rules

  • key_management: The server stores device keys and one-time keys but never stores private key material, One-time keys are consumed exactly once; after claiming they are removed from the pool, When one-time keys are exhausted, fallback keys are used and marked for replacement, Devices that are deleted have their associated keys removed from the store
  • querying: Device key queries must be separated by domain: local devices from database, remote via federation, Remote device key results are cached to reduce federation load; stale cache entries refreshed on demand, Servers that are unreachable during a query are recorded in the failures response, Servers previously marked as down are not contacted until their backoff window expires

Outcomes

Device_keys_uploaded (Priority: 1)

Given:

  • device is authenticated
  • uploaded keys include valid signatures from the device

Then:

  • create_record target: key_store — Device identity keys stored and indexed for querying
  • emit_event event: keys.device_keys_uploaded

Result: Device keys are discoverable by other users in shared rooms

One_time_keys_uploaded (Priority: 2)

Given:

  • device is authenticated
  • uploaded one-time keys have valid signatures

Then:

  • create_record target: key_pool — One-time keys added to the available pool for this device
  • emit_event event: keys.one_time_keys_uploaded

Result: Other devices can claim these keys to establish Olm sessions

One_time_key_claimed (Priority: 3)

Given:

  • requester specifies one or more target devices
  • target device has at least one unclaimed one-time key

Then:

  • delete_record target: key_pool — Claimed one-time key removed from pool; cannot be reused
  • emit_event event: keys.one_time_key_claimed

Result: Requester can use the claimed key to establish an encrypted Olm session

Fallback_key_used (Priority: 4)

Given:

  • target device has no unclaimed one-time keys
  • a fallback key is available

Then:

  • emit_event event: keys.fallback_key_used

Result: Encryption session established using fallback key; device should upload new one-time keys

Keys_queried_local (Priority: 5)

Given:

  • queried users are all on the local server

Then:

  • emit_event event: keys.query_completed

Result: Device keys returned from local database with cross-signing bundles

Keys_queried_federated (Priority: 6)

Given:

  • queried users include users on remote servers
  • remote servers are reachable

Then:

  • create_record target: key_cache — Remote device keys cached locally
  • emit_event event: keys.query_completed

Result: Keys for remote users returned; unreachable servers listed in failures

Key_query_partial_failure (Priority: 7)

Given:

  • one or more remote servers are unreachable or in backoff

Then:

  • set_field target: failures — Unreachable servers recorded in failures map
  • emit_event event: keys.query_partial_failure

Result: Available keys returned; caller can retry for failed servers later

No_keys_available (Priority: 8) — Error: KEY_EXCHANGE_NO_KEYS

Given:

  • target device has no one-time keys and no fallback key

Result: No key returned for that device; encryption session cannot be established

Errors

Code Status Message Retry
KEY_EXCHANGE_NO_KEYS 404 No one-time keys available for this device No
KEY_EXCHANGE_QUERY_FAILED 503 Key query could not be completed for one or more servers No

Events

Event Description Payload
keys.device_keys_uploaded A device’s long-lived identity keys were published user_id, device_id
keys.one_time_keys_uploaded A batch of one-time pre-keys was added to a device’s pool user_id, device_id, key_count
keys.one_time_key_claimed A one-time key was consumed to bootstrap an Olm session claimer_id, target_device_id
keys.fallback_key_used A fallback key was used because no one-time keys remained target_device_id
keys.query_completed A device key query was resolved (fully or partially) querying_device_id, user_count, failures
keys.query_partial_failure Key query completed but one or more servers were unreachable failed_servers
Feature Relationship Reason
cross-signing-verification recommended Cross-signing keys are bundled in key query responses alongside device keys
device-management required Device keys are invalidated when the device is deleted
key-backup-recovery recommended Session keys established during key exchange are backed up for recovery
server-federation recommended Remote device keys are fetched via federation queries

AGI Readiness

Goals

Reliable E2e Key Exchange

Manages cryptographic key material for end-to-end encrypted messaging. Handles device key publication, one-time pre-key upload/claiming, and cross-server key queries.

Success Metrics:

Metric Target Measurement
unauthorized_access_rate 0% Failed authorization attempts that succeed
response_time_p95 < 500ms 95th percentile response time

Constraints:

  • security (non-negotiable): Follow OWASP security recommendations
  • security (non-negotiable): Sensitive fields must be encrypted at rest and never logged in plaintext

Autonomy

Level: supervised

Human Checkpoints:

  • before modifying sensitive data fields

Escalation Triggers:

  • error_rate > 5
  • consecutive_failures > 3

Verification

Invariants:

  • sensitive fields are never logged in plaintext
  • all data access is authenticated and authorized
  • error messages never expose internal system details

Tradeoffs

Prefer Over Reason
security performance authentication must prioritize preventing unauthorized access

Coordination

Protocol: orchestrated

Consumes:

Capability From Fallback
device_management device-management fail

Safety

Action Permission Cooldown Max Auto
device_keys_uploaded autonomous - -
one_time_keys_uploaded autonomous - -
one_time_key_claimed autonomous - -
fallback_key_used autonomous - -
keys_queried_local autonomous - -
keys_queried_federated autonomous - -
key_query_partial_failure autonomous - -
no_keys_available autonomous - -
Extensions (framework-specific hints) ```yaml source: repo: https://github.com/element-hq/synapse project: Synapse Matrix homeserver tech_stack: Python / Twisted async files_traced: 8 entry_points: - synapse/handlers/e2e_keys.py - synapse/storage/databases/main/end_to_end_keys.py ```