Rename all project references from quicproquo/qpq to quicprochat/qpc across documentation, Docker configuration, CI workflows, packaging scripts, operational configs, and build tooling. - Docker: crate paths, binary names, user/group, data dirs, env vars - CI: workflow crate references, binary names, artifact names - Docs: all markdown files under docs/, SDK READMEs, book.toml - Packaging: OpenWrt Makefile, init script, UCI config (file renames) - Scripts: justfile, dev-shell, screenshot, cross-compile, ai_team - Operations: Prometheus config, alert rules, Grafana dashboard - Config: .env.example (QPQ_* → QPC_*), CODEOWNERS paths - Top-level: README, CONTRIBUTING, ROADMAP, CLAUDE.md
7.0 KiB
Auth Schema
Proto file: proto/qpc/v1/auth.proto
Package: qpc.v1
Method IDs: 100-103
The auth proto defines the OPAQUE asymmetric password-authenticated key exchange (PAKE) messages used for user registration and login. OPAQUE never transmits the password to the server; the server learns only a random value derived from the password.
Registration is a two-round-trip flow (start + finish). Login is a two-round-trip flow (start + finish). On successful login, the server returns a session_token used to authenticate subsequent RPCs.
See Authentication Service Internals for the server-side implementation and the full flow diagram.
Full proto listing
syntax = "proto3";
package qpc.v1;
// OPAQUE registration + login (4 methods).
// Method IDs: 100-103.
message OpaqueRegisterStartRequest {
string username = 1;
bytes request = 2;
}
message OpaqueRegisterStartResponse {
bytes response = 1;
}
message OpaqueRegisterFinishRequest {
string username = 1;
bytes upload = 2;
bytes identity_key = 3;
}
message OpaqueRegisterFinishResponse {
bool success = 1;
}
message OpaqueLoginStartRequest {
string username = 1;
bytes request = 2;
}
message OpaqueLoginStartResponse {
bytes response = 1;
}
message OpaqueLoginFinishRequest {
string username = 1;
bytes finalization = 2;
bytes identity_key = 3;
}
message OpaqueLoginFinishResponse {
bytes session_token = 1;
}
Registration flow (IDs 100-101)
User registration takes two round trips. The request and response fields carry opaque OPAQUE protocol blobs; their internal structure is defined by the opaque-ke crate.
OpaqueRegisterStart (ID 100)
Client Server
| |
| OpaqueRegisterStartRequest |
| username: "alice" |
| request: <OPAQUE blob> |
| -----------------------------> |
| |
| OpaqueRegisterStartResponse |
| response: <OPAQUE blob> |
| <----------------------------- |
Request fields:
| Field | Type | Description |
|---|---|---|
username |
string |
The username being registered. Must be unique on the server. |
request |
bytes |
OPAQUE RegistrationRequest blob generated by the client using the opaque-ke crate. |
Response fields:
| Field | Type | Description |
|---|---|---|
response |
bytes |
OPAQUE RegistrationResponse blob generated by the server. Client feeds this into the finish step. |
OpaqueRegisterFinish (ID 101)
Client Server
| |
| OpaqueRegisterFinishRequest |
| username: "alice" |
| upload: <OPAQUE record> |
| identity_key: <32 bytes> |
| -----------------------------> |
| |
| OpaqueRegisterFinishResponse |
| success: true |
| <----------------------------- |
Request fields:
| Field | Type | Description |
|---|---|---|
username |
string |
Must match the username from the start request. |
upload |
bytes |
OPAQUE RegistrationUpload blob. The server stores this as the user's OPAQUE record; it contains the password-derived key material without revealing the password. |
identity_key |
bytes |
The user's Ed25519 identity public key (32 bytes). Stored alongside the OPAQUE record and used as the user's long-term identifier for key packages and delivery queues. |
Response fields:
| Field | Type | Description |
|---|---|---|
success |
bool |
true if the registration record was stored successfully. false if the username is already taken or another error occurred. |
Login flow (IDs 102-103)
User login also takes two round trips. On success, the server issues a session_token that the client attaches to subsequent authenticated RPCs.
OpaqueLoginStart (ID 102)
Client Server
| |
| OpaqueLoginStartRequest |
| username: "alice" |
| request: <OPAQUE blob> |
| -----------------------------> |
| |
| OpaqueLoginStartResponse |
| response: <OPAQUE blob> |
| <----------------------------- |
Request fields:
| Field | Type | Description |
|---|---|---|
username |
string |
The username logging in. |
request |
bytes |
OPAQUE CredentialRequest blob generated by the client. |
Response fields:
| Field | Type | Description |
|---|---|---|
response |
bytes |
OPAQUE CredentialResponse blob. Contains the server's masked public key and envelope for the client to derive its export key. |
OpaqueLoginFinish (ID 103)
Client Server
| |
| OpaqueLoginFinishRequest |
| username: "alice" |
| finalization: <OPAQUE blob> |
| identity_key: <32 bytes> |
| -----------------------------> |
| |
| OpaqueLoginFinishResponse |
| session_token: <32 bytes> |
| <----------------------------- |
Request fields:
| Field | Type | Description |
|---|---|---|
username |
string |
Must match the username from the start request. |
finalization |
bytes |
OPAQUE CredentialFinalization blob containing the client's proof of knowledge of the password. The server verifies this against its stored OPAQUE record. |
identity_key |
bytes |
The user's Ed25519 identity public key (32 bytes). The server verifies this matches the key registered during OpaqueRegisterFinish. |
Response fields:
| Field | Type | Description |
|---|---|---|
session_token |
bytes |
Opaque bearer token (32 bytes). Included in subsequent RPC requests to authenticate the session. The server associates this token with the user's identity and device. |
If login fails (wrong password, unknown username, or identity key mismatch), the server returns an error status in the response frame; the session_token field is empty.
Session token usage
After a successful OpaqueLoginFinish, the client uses the session_token as a bearer credential for all authenticated RPC methods. The token is passed at the QUIC connection level (not per-frame); the server validates it on connection establishment and maintains the association for the lifetime of the connection.
The Auth message in common.proto carries the token for federation and internal use:
message Auth {
bytes access_token = 1;
bytes device_id = 2;
}
Further reading
- Wire Format Overview -- frame format and transport parameters
- Method ID Reference -- all 44 method IDs
- Authentication Service Internals -- server-side OPAQUE flow and session management
- RPC Reference -- all proto definitions