Service Architecture
The quicproquo server exposes 44 RPC methods through a single QUIC + TLS 1.3
endpoint on port 5001. Methods are dispatched by numeric method ID using
the v2 Protobuf framing protocol. This page documents the method reference,
connection lifecycle, storage model, and authentication flow.
RPC Endpoint
A single QUIC + TLS 1.3 listener on port 5001 serves all operations.
The ALPN identifier is qpq. Each RPC call uses a dedicated QUIC
bidirectional stream; calls are concurrent and do not block each other.
RPC Method Reference
Auth (100-103)
OPAQUE password authentication (asymmetric PAKE). The password is never sent
to the server. Method IDs 100-103 implement the 4-step OPAQUE handshake.
| ID |
Method |
Description |
| 100 |
OpaqueRegisterStart |
Client initiates registration with username and OPAQUE registration_request blob. Server returns registration_response. |
| 101 |
OpaqueRegisterFinish |
Client completes registration with username, OPAQUE upload blob, and Ed25519 identity_key. Server stores the OPAQUE record. |
| 102 |
OpaqueLoginStart |
Client initiates login with username and OPAQUE login_request blob. Server returns login_response. |
| 103 |
OpaqueLoginFinish |
Client completes login with username, OPAQUE finalization blob, and identity_key. Server returns a session_token. |
The session_token is an opaque bearer token used for subsequent authenticated
RPCs. It is passed in the Protobuf request body (not as a frame-level header).
Delivery (200-205)
Store-and-forward relay. The server never inspects MLS ciphertext -- it routes
opaque byte blobs by recipient key.
| ID |
Method |
Description |
| 200 |
Enqueue |
Append an opaque payload to the recipient's FIFO queue. Wakes FetchWait waiters. |
| 201 |
Fetch |
Drain and return all queued payloads in FIFO order. |
| 202 |
FetchWait |
Same as Fetch, but long-polls if the queue is empty (up to timeout_ms). |
| 203 |
Peek |
Return queued payloads without removing them. |
| 204 |
Ack |
Acknowledge and remove specific payloads by sequence number. |
| 205 |
BatchEnqueue |
Enqueue multiple payloads in a single RPC call. |
Keys (300-304)
MLS KeyPackage distribution and hybrid PQ public key management.
| ID |
Method |
Description |
| 300 |
UploadKeyPackage |
Append a TLS-encoded MLS KeyPackage to the identity's queue. Single-use: each fetch atomically removes one. |
| 301 |
FetchKeyPackage |
Atomically pop and return the oldest KeyPackage for an identity. Returns empty if none. |
| 302 |
UploadHybridKey |
Store (or replace) the X25519+ML-KEM-768 hybrid public key for an identity. |
| 303 |
FetchHybridKey |
Return the stored hybrid public key for a single identity. |
| 304 |
FetchHybridKeys |
Return hybrid public keys for multiple identities in one call. |
Group Management (400, 410-413)
| ID |
Method |
Description |
| 400 |
CreateChannel |
Register a new channel (group) on the server. |
| 410 |
RemoveMember |
Remove a member from a group (server-side record). |
| 411 |
UpdateGroupMetadata |
Update group name, description, or settings. |
| 412 |
ListGroupMembers |
List all members of a group. |
| 413 |
RotateKeys |
Trigger a server-assisted key rotation event. |
User / Identity (500-501)
| ID |
Method |
Description |
| 500 |
ResolveUser |
Resolve a username to an Ed25519 public key. |
| 501 |
ResolveIdentity |
Resolve an identity key to user profile information. |
Key Transparency (510-520)
| ID |
Method |
Description |
| 510 |
RevokeKey |
Append a key revocation record to the transparency log. |
| 511 |
CheckRevocation |
Check whether a given key has been revoked. |
| 520 |
AuditKeyTransparency |
Fetch a transparency log audit proof for a key. |
Blob Storage (600-601)
| ID |
Method |
Description |
| 600 |
UploadBlob |
Store a binary blob (file attachment, avatar, etc.). Returns a content-addressed blob ID. |
| 601 |
DownloadBlob |
Retrieve a blob by ID. |
Device Management (700-710)
| ID |
Method |
Description |
| 700 |
RegisterDevice |
Register a new device for a user account. |
| 701 |
ListDevices |
List all registered devices for the authenticated user. |
| 702 |
RevokeDevice |
Revoke a device, invalidating its session. |
| 710 |
RegisterPushToken |
Register a push notification token (APNs / FCM) for a device. |
Recovery (750-752)
| ID |
Method |
Description |
| 750 |
StoreRecoveryBundle |
Encrypt and store an account recovery bundle server-side. |
| 751 |
FetchRecoveryBundle |
Retrieve the recovery bundle (requires OPAQUE re-authentication). |
| 752 |
DeleteRecoveryBundle |
Delete the stored recovery bundle. |
P2P and Health (800-802)
| ID |
Method |
Description |
| 800 |
PublishEndpoint |
Publish a direct P2P endpoint (iroh node address). |
| 801 |
ResolveEndpoint |
Resolve a peer's P2P endpoint by identity key. |
| 802 |
Health |
Liveness/readiness probe. Returns server uptime and status. |
Federation (900-905)
| ID |
Method |
Description |
| 900 |
RelayEnqueue |
Relay a single message to a user on another server. |
| 901 |
RelayBatchEnqueue |
Relay multiple messages in one request. |
| 902 |
ProxyFetchKeyPackage |
Fetch a KeyPackage from a remote server on behalf of a local client. |
| 903 |
ProxyFetchHybridKey |
Fetch a hybrid public key from a remote server. |
| 904 |
ProxyResolveUser |
Resolve a username on a remote server. |
| 905 |
FederationHealth |
Check health of the federation link to another server. |
Moderation (420-424)
| ID |
Method |
Description |
| 420 |
ReportMessage |
Submit a content moderation report. |
| 421 |
BanUser |
Ban a user from a channel or server-wide. |
| 422 |
UnbanUser |
Lift a ban. |
| 423 |
ListReports |
List pending moderation reports (admin only). |
| 424 |
ListBanned |
List banned users (admin only). |
Account (950)
| ID |
Method |
Description |
| 950 |
DeleteAccount |
Permanently delete the authenticated account and all associated data. |
Per-Connection Lifecycle
Each incoming QUIC connection follows this sequence:
Concurrency model
Unlike the v1 Cap'n Proto RPC (which was !Send due to Rc<RefCell<>>
internals and required LocalSet), the v2 RPC framework uses Arc-based
shared state and spawns each handler with tokio::spawn. The server can
handle many concurrent requests per connection without a LocalSet.
Status Codes
Response frames carry a status: u8 field:
| Value |
Status |
Meaning |
| 0 |
Ok |
Success |
| 1 |
BadRequest |
Malformed request or missing required field |
| 2 |
Unauthorized |
Missing or invalid session token |
| 3 |
Forbidden |
Valid token but insufficient permissions |
| 4 |
NotFound |
Requested resource does not exist |
| 5 |
RateLimited |
Request rate limit exceeded; retry after backoff |
| 8 |
DeadlineExceeded |
Request timed out on the server |
| 9 |
Unavailable |
Server temporarily unable to serve the request |
| 10 |
Internal |
Unexpected server error |
| 11 |
UnknownMethod |
The requested method_id is not registered |
Authentication Flow
OPAQUE (RFC-compliant asymmetric PAKE) prevents the password from reaching
the server in any form:
The session_token is then passed in subsequent Protobuf requests. The server
validates it on every authenticated method call.
Configuration
| Flag |
Env var |
Default |
Description |
--listen |
QPQ_LISTEN |
0.0.0.0:5001 |
QUIC listen address (host:port). |
--data-dir |
QPQ_DATA_DIR |
data |
Directory for persisted state. |
--tls-cert |
QPQ_TLS_CERT |
data/server-cert.der |
Path to TLS certificate (DER). Auto-generated if missing. |
--tls-key |
QPQ_TLS_KEY |
data/server-key.der |
Path to TLS private key (DER). Auto-generated if missing. |
Logging level is controlled by the RUST_LOG environment variable (default: info).
Further Reading