What is new in MTE Relay v5
MTE Relay v5 is a new major version with a new wire protocol. v5 servers and v5 clients work together; v4 clients cannot connect to a v5 relay. Plan the move with Upgrading from v4.
Performance against v4
On the same hardware, v5 moves up to 37% more requests per second than v4, uses about 90% less memory per relay, and answers with up to 39% lower latency. High availability needs 1 Redis instead of 2. Every chart is in the v5 executive brief.
Release components
| Component | Current v5 release |
|---|---|
| MTE Relay Server (MRS) image | 5.0.5 |
| MTE API Relay (MAR) image | 5.0.5 |
mte-relay-browser engine | 5.0.0 |
mte-relay-browser-public-client | 5.0.0 |
| Angular client | 5.0.0 |
| Java / Android client | 5.3.0 |
| Swift / iOS client | 5.3.0 |
| Flutter client (SPM) | 5.3.0 |
| Flutter client (CocoaPods) | 5.3.0 |
| Blazor client | 5.0.0 |
| Python Requests client | 5.0.0 |
| Python Locust client | 5.0.0 |
Protocol
- Frame version 2. Every request and response travels as binary frames,
each with a 12 byte header. A request is one REQUEST frame followed by DATA
frames, and a response is one RESPONSE frame followed by DATA frames. An
encrypted request is a single
POST /withContent-Type: application/octet-stream. - Verified before released. Each DATA frame is one MTE or MKE operation, and neither end releases a byte of plaintext until its frame is verified.
- One encrypted metadata object per request. Method, path, query, and
headers are encoded together. Response headers are encoded the same way, and
the response status is repeated inside them. While
forward_browser_cookiesis on, the default, the origin'sSet-Cookiemoves to the plain HTTP response. - Bounded frames. Bodies move as frames of at most
MAX_FRAME_BYTES(64 KiB by default). - Headers first. The relay sends the response status and headers as soon as the origin answers, before the first body byte, so streamed responses such as server sent events start at once.
Security
- Kyber 1024 by default, with 512 and 768 available through
KYBER_STRENGTH. v4 used 512. - Bound envelope. The encrypted method, frame version, and frame flags must
match the plaintext envelope, or the relay answers
483 header_mismatch. A mismatch in the metadata or in any DATA frame is also logged as a security event. The client applies the same check to the response status. - Replay detection. A replayed request is refused with
479 replay_rejectedand logged as a security event. - Rate limits on auth, pairing, and keepalive, answered
488 rate_limitedwithRetry-After. - Signed client tokens with a maximum age, checked at pair and keepalive.
- Library profile check. Discovery publishes the MTE library profile, and a client refuses to pair with a relay whose library settings differ.
Operations
- New error model. Relay errors use 470 to 490 with a reason token and an
X-MTE-Relay-Errorheader, and 500, 502, and 503 stay for true faults. See Errors and recovery. - Discovery. The auth answer lists the relay's limits, timers, features, and per domain settings. See Discovery.
- Keepalive.
POST /api/mte-keepaliverefreshes every pair of a client in one call. See Keepalive and timeouts. - Control plane. An optional admin panel and API, from the same image with
MODE=control: a setup wizard, live settings, fleet status, history, and rollback. See Control plane. - Probes. Workers answer
GET /healthzandGET /readyzon a separate port, 9091 by default, withGETandHEAD./healthzanswers200{"status":"ok","phase":"<phase>"}for as long as the process runs./readyzanswers200{"status":"ready","phase":"ready"}while the relay takes traffic, or503with the phase and a reason otherwise. - Health check path.
HEALTH_CHECK_PATH, off by default, mounts a200{"status":"ready"}answer on the relay port at a path you pick, for anyHostand outside every rate limit, for a load balancer or a security scanner that cannot reach the probe port. It applies live from the control plane. See CORS and WAF. - Echo takes
HEAD.GET /api/mte-echoandHEAD /api/mte-echoanswer outside every rate limit, and the message stays a JSON string as in v4. MTE Relay and SocketX now share the same health, readiness, and echo behavior, the same discovery check order, codes, and 600 per minute budget, and the same origin rules: case insensitive, andhttps://*.example.comrequires the scheme to match. See Discovery. - Request ids.
X-MTE-Relay-Request-Idis set on every response and sent upstream, so one id ties client, relay, and origin logs together. - Sticky routing. Every framed request, pairing call, and keepalive carries
X-MTE-Relay-Route, so a load balancer can hash clients to replicas, andLOCAL_STATE_CACHEcan then serve pair state from memory.
Configuration
DOMAIN_MAPonly. The v4 single upstream variables are removed. Domain keys can be hostnames,host:port, bracketed IPv6 literals,*.suffixwildcards, or*. Keys and the requestHostcompare case insensitively, overlapping wildcards resolve from the most specific, and a relay that generates a missingclient_id_secretwarns at startup naming the hosts. SocketX uses the same member names and the same matcher. See DOMAIN_MAP.- One vocabulary with SocketX.
LISTEN_HOSTandLISTEN_PORTname the listener (PORTstays as an alias,HOSTNAMEis retired because it never bound anything),MAX_PAIR_BYTESreplacesMAX_PAIR_MIB(kept as an alias),DRAIN_SECONDSis the honored shutdown budget,LOG_LEVELacceptswarning, and every environment value that does not parse logs a warning naming the variable and the default in use. Log lines carrytimeas RFC 3339 with milliseconds and acallerfield in both products, and a logged secret shows three characters then asterisks. See Environment variables. - More per domain settings: CORS credentials, headers, and preflight
handling,
preserve_host,trust_forwarded_headers,forward_browser_cookies,forward_plain_headers, per domain timers, and response coalescing. - Outbound domains. MTE API Relay chains use
outbound: trueentries in place of v4's outbound token andx-mte-upstreamheader. - New limits:
MAX_REQUEST_BODY_MIB,MAX_CONTROL_BODY_MIB, and the frame, metadata, and pair bounds. See Limits and scaling. - New pool settings:
DEFAULT_POOL_SIZEandMAX_POOL_SIZE_LIMITfor the server codec pools, andCLIENT_INITIAL_PAIRS,CLIENT_MIN_PAIRS,CLIENT_MAX_PAIRS,CLIENT_REFILL_THRESHOLD, andCLIENT_PAIR_ACQUIRE_WAIT_MSfor outbound domains.
Every setting is listed on Environment variables.
Clients
- Browser. The
mte-relay-browserengine 5.0.0 speaks frame version 2. The public client packagemte-relay-browser-public-client5.0.0 bundles it, withconfigureMteRelayfor startup options. See the JavaScript client. - Angular.
mte-relay-angularplugs the same engine into Angular'sHttpClient. See the Angular client. - Mobile. v5 iOS and Android clients speak frame version 2. See each platform page.