keyserver: cache remote users' device and cross-signing keys
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Test (windows-latest) (push) Canceled after 0s
CI / Storage tests on PostgreSQL (push) Canceled after 0s
CI / Complement (federation off) (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
CI / Smoke test the binary (push) Canceled after 0s
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Test (windows-latest) (push) Canceled after 0s
CI / Storage tests on PostgreSQL (push) Canceled after 0s
CI / Complement (federation off) (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
CI / Smoke test the binary (push) Canceled after 0s
POST /keys/query for a remote user who shares a room with a local user is
now answered from a cache, fetched whole with GET /user/devices/{userId}
on a miss. Incoming m.device_list_update EDUs are applied when their
prev_id matches the cached stream_id; anything else marks the copy stale
and it is fetched again in the background, and a stale copy is never
served. m.signing_key_update replaces the cached cross-signing keys. A
user's copy is dropped once no local user shares a room with them, by a
keyserver listener on the roomserver's emit stage.
Migration 0009 adds keyserver_remote_users, keyserver_remote_device_keys
and keyserver_remote_cross_signing_keys for sqlite and postgres.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
fc49f56339
commit
74f7bc8805
19 files changed
+1769
-92
No files matched your search
@@ -0,0 +1,48 @@
|
||||
-- The cache of other servers' users' keys.
|
||||
--
|
||||
-- A local client about to send an encrypted message asks for the keys of
|
||||
-- everyone in the room, and asks again whenever a sync says their device
|
||||
-- list moved. Answering that for a remote user by asking their server
|
||||
-- every time puts a federation round trip in front of every message, and
|
||||
-- turns a busy room into a steady stream of identical queries. So the
|
||||
-- keys of remote users who share a room with somebody here are kept, and
|
||||
-- kept current by the m.device_list_update and m.signing_key_update EDUs
|
||||
-- their server sends whenever they change.
|
||||
--
|
||||
-- These are tables of their own rather than rows in the local key tables.
|
||||
-- A local user's keys are the source of truth, and every write to them
|
||||
-- moves the device list stream and goes out over federation; a cached
|
||||
-- copy of somebody else's is neither, and keeping them apart means no
|
||||
-- code path that announces a local change can ever announce a copy.
|
||||
|
||||
-- One row per cached user: the marker that the user's device list is held
|
||||
-- here at all, and the position in their server's device list stream the
|
||||
-- copy is at. An update names the position before it (prev_id), and is
|
||||
-- applied only when that is the position held; anything else means an
|
||||
-- update was missed, and the copy is marked stale until it is fetched
|
||||
-- again whole.
|
||||
CREATE TABLE IF NOT EXISTS keyserver_remote_users (
|
||||
user_id TEXT NOT NULL PRIMARY KEY,
|
||||
stream_id BIGINT NOT NULL,
|
||||
stale BOOLEAN NOT NULL DEFAULT 0
|
||||
);
|
||||
|
||||
-- The identity keys of a cached user's devices, as their server sent
|
||||
-- them, and the display name it gave each.
|
||||
CREATE TABLE IF NOT EXISTS keyserver_remote_device_keys (
|
||||
user_id TEXT NOT NULL,
|
||||
device_id TEXT NOT NULL,
|
||||
display_name TEXT NOT NULL DEFAULT '',
|
||||
key_json TEXT NOT NULL,
|
||||
PRIMARY KEY (user_id, device_id)
|
||||
);
|
||||
|
||||
-- A cached user's master and self-signing keys. The user-signing key is
|
||||
-- never sent over federation, so there is no row for one.
|
||||
CREATE TABLE IF NOT EXISTS keyserver_remote_cross_signing_keys (
|
||||
user_id TEXT NOT NULL,
|
||||
-- master or self_signing.
|
||||
purpose TEXT NOT NULL,
|
||||
key_json TEXT NOT NULL,
|
||||
PRIMARY KEY (user_id, purpose)
|
||||
);
|
||||
Reference in new issue
Block a user