Skip to main content
Version: 5.x

MTE Relay questions and answers

The questions below are the ones customers ask most often about MTE Relay v5, grouped by topic. Every answer links to the page that holds the detail. Each question has its own link. Hover a heading and use its anchor link to get the address of that one question.

Product basics​

What is MTE Relay?​

MTE Relay applies MicroToken Exchange (MTE) protection to HTTP(S) traffic without an application rewrite. An MTE Relay client library, or a second Relay, encrypts each request before it leaves; the Relay in front of your API decrypts it, forwards plain HTTP to the upstream, and encrypts the response for the trip back. Your API sees ordinary HTTP. MTE Relay ships as two packages built on the same core: MTE Relay Server for client to server traffic and MTE API Relay for server to server traffic. The introduction describes the MTE technology behind both.

What is the difference between MTE Relay Server and MTE API Relay?​

MTE Relay Server (MRS) protects traffic from web and mobile applications. The client side is an SDK inside the application, and the Relay runs in front of the backend. MTE API Relay (MAR) protects traffic between two services with a chain of two Relays: an outbound Relay next to the calling service takes ordinary HTTP and encrypts it, and an inbound Relay in front of the destination API decrypts it. Neither service changes beyond the address it calls. Both packages run the same Relay program with the same settings. They differ in the MTE library build each image links. An MRS pairs only with the client SDKs, and a MAR pairs only with another MAR. See MRS and MAR images.

Does MTE Relay replace TLS?​

No. Run both. TLS protects the connection between two hops. MTE protects the application data itself, from the SDK to the Relay, so a CDN, load balancer or WAF that terminates TLS in the middle sees only ciphertext in the body and in the encrypted metadata. The Relay listens on plain HTTP and expects a TLS terminator in front of it. The client token, the pairing exchange and the frame envelopes travel in the clear inside the HTTP exchange, which is why every hop belongs inside TLS. See WAF, CDN, and proxy notes.

What traffic can MTE Relay protect?​

HTTP and HTTPS request and response exchanges: REST and JSON APIs, form posts, file uploads and downloads, and streamed responses such as server sent events. Every HTTP method works, and the path, query, headers and body travel encrypted, apart from the few values listed under Which parts of a request are encrypted. WebSocket traffic is the job of SocketX, a separate product built on the same frame format, and a TCP gateway for raw connections such as SSH or database protocols is built on that frame too, with its availability announced separately. gRPC, which needs HTTP/2 streams and trailers end to end, is outside what the HTTP Relay carries. The engineering guide describes the three transports.

Do I need to change my backend?​

No. The Relay forwards each decrypted request to the upstream named in DOMAIN_MAP as ordinary HTTP, with the original method, path, query, headers and body, plus the standard X-Forwarded-Host, X-Forwarded-Proto and X-Forwarded-For headers. Cookies, authorization headers and status codes pass through. The backend facing choices are optional: pass_through_routes for paths that should skip encryption, preserve_host when the API needs the client's hostname, and per domain headers the Relay adds on the way in. See DOMAIN_MAP.

Do I need to change my client applications?​

For MTE Relay Server, one small change per application: swap fetch for mteFetch in a web app, add one provider in Angular, or route requests through the SDK on iOS, Android and Flutter. The SDK handles authentication, pairing, encryption, keepalive and recovery. MTE API Relay needs no SDK. The calling service points its HTTP client at the outbound Relay instead of the remote API, and the Relay chain does the rest. See the client libraries under MTE Relay Server and outbound domains.

Security​

What encryption does MTE Relay use?​

MicroToken Exchange. MTE protects your data in transit with values from NIST SP 800-90A deterministic random bit generators, so the same message looks different every time, and only the paired endpoint can recover the original. Two encode types exist: standard MTE, which replaces your data with random tokens that are not derived from it, and MKE (Managed Key Encryption), the default, which encrypts with a cipher keyed from those generators and is the efficient form for bodies of any size. Each pair is established with a CRYSTALS Kyber key exchange, 1024 by default. See the introduction and What is new in v5.

How is MTE Relay quantum resistant?​

The key exchange that establishes each pair is CRYSTALS Kyber, a lattice based key encapsulation designed to resist attack by a quantum computer, at the 1024 parameter set by default. 512 and 768 are available through KYBER_STRENGTH, but the browser engine always uses 1024, so keep the default on any Relay that serves browsers; v4 used 512. The keys and tokens MTE uses come from random bit generators seeded through that exchange. Both ends check the Kyber strength and the library profile before pairing, so a mismatch fails at setup with a clear message. See Kyber strength and the v5 brief.

Is MTE Relay FIPS validated or NIST approved?​

MTE's random bit generators are the NIST SP 800-90A CTR DRBG and Hash DRBG algorithms, and pairing uses the CRYSTALS Kyber key encapsulation. For questions about formal validation, compliance statements and the exact algorithm set in your build, contact Eclypses Support.

Which parts of a request are encrypted?​

The method, path, query string, headers and body of every request, and the status, headers and body of every response, travel inside encrypted frames. A few values ride in the clear by design: a one byte method code for the nine standard methods and the response status, both of which the receiver checks against the encrypted copy; the browser's cookies and the origin's Set-Cookie, because a browser applies Set-Cookie only from a real HTTP response (forward_browser_cookies, on by default); headers you list in the SDK's unencryptedHeaders; and anything on a pass through route. The Relay's own X-MTE-Relay-* headers carry routing and error information, never application data. See What is new in v5.

Is data verified before it reaches my application?​

Yes. Every request, response and nonempty data frame is one complete MTE or MKE operation, and neither end releases a byte of plaintext until the frame is verified. A corrupted or forged frame produces no plaintext. Corrupt request data never reaches your API, and corrupt response data never reaches the client. The encrypted method, frame version and frame flags must also match their plaintext copies, or the Relay refuses the request with 483 header_mismatch and logs a security event, and the client refuses a response whose status disagrees with its encrypted copy. The v4 streaming path released decrypted chunks before its final integrity check; v5 does not. See Why v5.

How does MTE Relay handle replayed requests?​

Each frame advances the MTE state of its pair, so a request captured and sent again does not decode. The Relay answers 479 replay_rejected, keeps the pair usable, and logs a security event. The same property means a proxy or load balancer must never retry an encrypted request on its own; the SDKs send a failed request again by themselves only where nothing ran at the origin. See Errors and recovery.

Does the Relay store or log my data?​

No request or response data is written to disk. Pair state lives in memory, or in Redis when replicas share it, and the control plane stores configuration, not traffic. The audit event for each encrypted request records hashes and sizes, never plaintext, and a secret that appears in a log line shows three characters followed by asterisks. At LOG_LEVEL=debug the operational log carries decoded request paths, so keep production at info. Codec state saved in Redis is not encrypted at rest, so restrict who can reach the store. See Event schema.

How are clients authenticated, and does this replace my application's authentication?​

Every client holds a signed token: a client id, an issue time and an HMAC SHA256 under the domain's client_id_secret. The token rides in every request, its signature is checked on the data path, and its age (24 hours by default) is checked at pairing and keepalive. Pairing itself is a Kyber exchange, and the auth, pair and keepalive endpoints are rate limited. This proves that a request came from a paired client; it does not identify your users. Your own authentication, whether Authorization headers, cookies or session tokens, travels inside the encrypted frames to the origin unchanged. See Pairing, tokens, and abuse limits.

Does MTE Relay protect against denial of service, or replace a WAF?​

It is neither a WAF nor a DDoS shield, and it runs behind yours. What it has: rate limits on the auth, pairing and keepalive endpoints (600 auth and 600 pairing calls per minute per source, 60 pairing and 120 keepalive calls per minute per client), a configurable request body cap, hard bounds on frames and metadata that are checked before any memory is allocated, and a token check that needs no store lookup. The data path is never rate limited. A WAF in front of the Relay still filters by source address, rate and Host, but every encrypted request reaches it as POST / with a ciphertext body, so exclude the encrypted route from body rules and allow application/octet-stream. See Rate limits and CORS and WAF.

How is the container image hardened?​

The runtime image is Google's distroless cc-debian12 base with the Relay binary and its runtime libraries, and no shell, package manager or OS utilities. The binary is compiled in a separate build stage, so build tooling and source never ship. The container runs as the unprivileged nonroot user, declares only ports 8080 and 9091, and runs on OpenShift under the default restricted-v2 constraint without changes. No secrets are baked in beyond the development license. See Security.

Are the images scanned for vulnerabilities?​

Yes, before release, and scan reports for the current tag are available from Eclypses Support on request. Because you pull the image into your own registry, you can also produce your own evidence with Amazon ECR enhanced scanning, Microsoft Defender for Containers, Oracle's vulnerability scanning service, or a scanner such as Trivy or Grype. See Vulnerability scanning.

How quickly are security fixes released?​

Critical vulnerabilities are addressed in a patched image within 30 days of confirmed disclosure, and lower severities in a subsequent release. Patches ship out of band rather than on a calendar. Applying one means pulling the new tag and redeploying; within v5, releases are additive and need no client changes. See Maintenance.

Which secrets do I manage, and where do they live?​

The MTE license (COMPANY_NAME and LICENSE_KEY), one client_id_secret per DOMAIN_MAP host, REDIS_URL when it carries a password, and, with the control plane, CONTROL_PLANE_TOKEN, ADMIN_PW and ADMIN_JWT_SECRET. A standalone Relay reads them from its environment, so your orchestrator's secret store supplies them. A managed fleet enters the license, the client secrets and REDIS_URL once in the control plane, which keeps them on its own volume and shows the values workers run as fingerprints. CONTROL_PLANE_TOKEN and ADMIN_PW stay in the environment, and ADMIN_JWT_SECRET only seeds the session signing secret, which the control plane then keeps on its volume. The control plane API carries these secrets, so keep it on an internal network behind TLS. See Environment variables and Control plane security.

Latency and overhead​

How much latency does MTE Relay add?​

About one millisecond per request at light load for the full round trip through two Relays, encrypting and decrypting in both directions, against a fraction of a millisecond straight to the origin. The cost is a small, roughly fixed amount per request, not a multiplier on network distance. In a June 2026 test across the public internet, with one Relay on a residential connection and the other on AWS in us-east-1, the Relay pair added a median of 2.07 ms to a 56 ms round trip, about 3.7 percent. That run was v4; v5 has not been measured across a WAN yet. With two Relay replicas sharing Redis, v5 answers 39% faster than v4 at light load, 1.13 ms against 1.86 ms. See MTE Relay performance.

How much bandwidth does the encryption add?​

Little on large bodies, and a flat amount on small ones: below 1 KiB the Relay adds about 1,880 bytes per round trip. Ciphertext travels as raw bytes in the body, never as Base64 text in a URL or header. With MKE, the default, each frame costs a 12 byte envelope plus the fixed overhead of one MKE operation, and the first frame of a request adds 64 bytes of fixed fields, the token and pair id among them. Standard MTE encodes each plaintext byte as 8 bytes, which is why MKE is the default. On the loopback bench a 1 GiB download carried 0.028 percent of wire overhead, a 1 KiB request round trip moved 4,261 bytes, and on a 1 MiB body the 64 KiB default frames cost 7,445 more bytes per round trip than 1 MiB frames, 0.36 percent. Pairing is the one larger exchange, about 15 KB for authentication, discovery and the Kyber exchange together, and it happens when a client starts, not per request. See Measurements.

What does the first request cost?​

The first request from a client to a Relay origin authenticates, reads the discovery document and pairs, which includes the Kyber exchange, about 10 ms and 15 KB on the loopback bench, once when a client starts. The browser SDK waits for one pair and fills the rest of its pool in the background, and keepalive calls, every 10 minutes by default, keep pairs alive while a client is idle, so a returning client does not pair again; a pair with neither traffic nor keepalive expires after 120 minutes. Outbound Relays in a MAR chain hold a warm pool of pairs for the same reason. See Keepalive and timeouts.

Does Kyber 1024 slow anything down?​

Not on the data path. The key exchange runs only at pairing, and a 4 CPU Relay measured the same throughput with Kyber 1024 as with 512: 9,190 against 9,152 requests per second. The stronger parameter set is paid at pairing, which happens once per pair, not per request. See Kyber strength.

Will my users notice anything?​

Not in normal use. The added latency is about a millisecond, the first request on a page pays one pairing, and the SDK keeps pairs alive while the page stays open and pings as soon as a hidden tab becomes visible again. Requests look different in the browser's network tab, as POST / with Content-Type: application/octet-stream in place of the original method and path. When something fails, the SDK raises a typed error with a code, a reason and a recommended action, and the request id in it matches the Relay's log line. See the JavaScript client.

Does it support streaming and large files?​

Yes. Bodies move as frames of at most MAX_FRAME_BYTES, 64 KiB by default, so memory follows the frame size rather than the body size: a 1 GiB upload ran through a Relay at 277 MiB/s with a 44 MiB peak RSS on the loopback bench. The exception is an outbound Relay in an MTE API Relay chain, which buffers each request body before framing it, so set MAX_REQUEST_BODY_MIB there. The Relay sends the response status and headers as soon as the origin answers, before the first body byte, so server sent events and other streamed responses start at once, and a streamed response may stay quiet for up to IDLE_TIMEOUT_SECONDS (90 by default) between frames. The request body cap is unlimited by default, and the mobile SDKs stream file uploads and downloads with progress callbacks. See Streaming.

Capacity and sizing​

How many requests per second can one Relay handle?​

Measured on 5.0.0 with 10 KB JSON requests and a pair of Relays in one cluster: about 2,760 requests per second at 1 CPU, 5,200 at 2 CPU, 9,150 at 4 CPU and 13,570 at 8 CPU, where the test rig itself was the limit. A 4 CPU / 4 GB Relay pair moves about 790 million encrypted requests a day, and across the 131 million requests of the run not one failed. Throughput is 37% higher than v4 on the same 2 CPU Relay. See MTE Relay performance.

How much CPU and memory does a Relay need?​

CPU is the limiter and memory is small. At 10 KB payloads a Relay stayed under 160 MiB on every shape measured (86 to 152 MiB), with 42 to 91 MiB at 2 KB and 250 to 411 MiB at 100 KB. Memory tracks payload size, not load, and did not grow under overload. v4 needed about 2 GB per Relay at 10 KB, so v5 uses about 90% less. Size by CPU; the 1 to 8 GB memory limits used in the runs left ample headroom. See Resource footprint.

What happens when a Relay is overloaded?​

Requests queue. Throughput holds flat at the Relay's ceiling, latency rises in proportion to the excess demand, and nothing fails: at eight times saturating demand 99 percent of requests still completed in under 34 ms, at sixteen times the error count stayed at zero, and a separate run at 1,000 connections held 8,337 requests per second without an error. Overload shows up as queueing delay, not as error storms, so alert on latency. See Measured throughput and latency.

Does payload size change capacity?​

Yes, but less than you might expect. The measured cost per request is about 141 µs of Relay pair capacity plus 4.8 µs per KB, so at 10 KB three quarters of the cost is independent of the payload. Plan capacity by request rate for small payload APIs, and note that moving the same data in larger requests costs less than in many small ones: 10 KB requests cost about four times less capacity per byte than 2 KB requests. To estimate the ceiling for any payload size, take 1 ÷ (141 µs + 4.8 µs × KB) and scale by the CPU curve. See Payload size sensitivity.

How do I size a deployment?​

Take your peak sustained request rate, adjust it for payload size, and pick the smallest tier whose recommended load covers it, running at or below 60 percent of measured saturation so p99 latency stays low. The tiers at 10 KB: Small, one 2 CPU Relay with no shared state, up to 3,100 requests per second; Medium, two 2 CPU Relays with one Redis, up to 4,900 and highly available; Large, two 4 CPU Relays with one Redis, up to 7,800; Enterprise, independent cells of the Large tier that scale linearly. Confirm a size beyond the measured range with a one hour certification sweep before relying on it. See Deployment tiers.

Deployment and runtimes​

How is MTE Relay delivered?​

As container images: one for MTE Relay Server and one for MTE API Relay, built for linux/amd64, distroless, and tagged per release. Customers pull them from Eclypses' private registry with credentials Eclypses issues and copy them into their own registry (Amazon ECR, Azure Container Registry, OCIR, Artifact Registry, the OpenShift internal registry, or any private registry), which is also the recommended production setup because registry authorization tokens expire. The web SDK is an npm package; the mobile SDKs come from Maven Central for Android, Swift Package Manager or CocoaPods for iOS, and GitHub for the Flutter plugin. See On premises deployment.

Where can I run it?​

Anywhere that runs a linux/amd64 container. The documentation has guides for Docker, Docker Compose, Kubernetes, OpenShift and Docker Swarm on premises; Amazon ECS and EKS; Azure Kubernetes Service; Google Kubernetes Engine; and Oracle Cloud Container Instances and OKE. Podman, K3s and other runtimes run the same image. The control plane runs on the same runtimes and knows the restart commands for Kubernetes, OpenShift, Swarm, Compose, ECS and systemd. See the deployment cards under MTE Relay Server and MTE API Relay.

What does a deployment depend on?​

A single Relay on the on premises image depends on nothing but its upstream. Pair state stays in memory, and DOMAIN_MAP is the only required setting. Two or more replicas that serve the same clients need a Redis instance for shared pair state and the same client_id_secret on every replica. Production also needs a TLS terminator in front of the Relay, because the Relay serves plain HTTP. The control plane is optional. See Running more than one replica.

Can it run in an air gapped network?​

Yes, with the on premises image. The Relay makes no calls to Eclypses at runtime. The license is checked locally from COMPANY_NAME and LICENSE_KEY, and the on premises images carry no marketplace metering. Its only network dependencies are the upstream, Redis when you share state, and the control plane when you run one. The exception is an image built for the AWS Marketplace, which registers with AWS Marketplace metering at startup and stops when it cannot, so an air gapped network runs the on premises image. Mirror the image into a registry inside the network and deploy from there. See Pull the Docker image.

Does it support HTTP/2 and HTTP/3?​

Clients can use HTTP/2 or HTTP/3 to your TLS terminator. The Relay itself serves HTTP/1.1 on its plain listener, so the terminator speaks HTTP/1.1 to the Relay, which load balancers and ingress controllers do by default. Toward an https:// upstream the Relay negotiates HTTP/2 when the origin offers it. See HTTP mapping.

Where should the Relay sit in my network?​

Inside your protected network, directly in front of the API it protects, behind the load balancer or ingress that terminates TLS. For MTE API Relay, run each Relay next to the service it fronts, the outbound Relay beside the caller and the inbound Relay beside the API, so the plaintext hops never leave the host or the cluster network. Keep the probe port and the control plane off public networks; they are for the orchestrator and the operators. See Load balancers and proxies.

Which ports does it use?​

Two by default: 8080 for traffic (LISTEN_PORT) and 9091 for the liveness and readiness probes (PROBE_PORT, which 0 disables). A control plane instance listens on its own LISTEN_PORT, 8081 in the documented examples, and the Go profiler port 6060 opens only while ENABLE_PPROF is on. Outbound, the Relay reaches its upstream, Redis and the control plane at the addresses you configure. See Environment variables.

How is it configured?​

Through environment variables, with DOMAIN_MAP as the one required setting: a JSON map from each hostname clients call to its upstream and per host options. Every other setting has a documented default and validation rule. A boolean, integer or level name that fails to parse logs a warning and uses the default, while a value that would make the Relay unsafe, such as an invalid DOMAIN_MAP or port, stops it at startup with the reason. With the control plane, a setting resolves in the order control plane override, then environment variable, then default, and six settings apply live without a restart. See Environment variables and DOMAIN_MAP.

What is the control plane, and do I need it?​

It is optional. The control plane is the same image started with MODE=control: a web admin panel and JSON API where you enter the license and hosts once, and every worker that polls it picks the configuration up. It adds a setup wizard, live edits to DOMAIN_MAP and five other settings, a fleet view of every worker and what it is running, a 50 version history with diff and rollback, scoped service tokens for automation, and an audit line in its log for every write. Workers keep serving their last applied configuration if the control plane goes away. A single Relay or a small fleet configured from environment variables works without it. See Control plane.

Can one Relay serve several APIs or hostnames?​

Yes. DOMAIN_MAP keys can be hostnames, host:port, *.example.com wildcards or a catch all *, and each entry carries its own upstream, client secret, CORS policy, pass through routes, headers and timers. The Relay picks the entry from the request's Host header, most specific first, so one fleet can front many services or many tenants. See DOMAIN_MAP keys.

Does it work behind my load balancer, CDN or WAF?​

Yes, with a few rules for the device in front: allow application/octet-stream request bodies, do not buffer or transform responses, do not retry encrypted requests, keep the X-MTE-Relay-Error response header, and give routes that stream an idle timeout above IDLE_TIMEOUT_SECONDS, 90 by default. Where one idle timeout also covers idle connections, as on an AWS Application Load Balancer, a value above 60 seconds trades occasional 502 answers for longer quiet streams, because the Relay closes an idle connection after 60 seconds. Relay errors use statuses 470 to 490, a block that CDNs pass through unchanged where they would replace a 5xx or 403 body with their own page, and that service mesh outlier detection does not count against the pod. Behind a proxy, set TRUSTED_PROXIES so each client gets its own rate limit budget, and hash on X-MTE-Relay-Route when you want each client pinned to one replica. See WAF, CDN, and proxy notes.

How do health checks work?​

A probe listener on port 9091 answers GET /healthz for liveness and GET /readyz for readiness, and readiness turns 503 while a worker waits for configuration or drains at shutdown. For a load balancer or a security scanner that can only reach the traffic port, HEALTH_CHECK_PATH mounts a health answer at a path you choose, for any Host and outside every rate limit, and GET /api/mte-echo answers as it did in v4. The image is distroless, so a Docker Compose or ECS health check command cannot run inside the container; check from outside. See Health checks and scanners.

How do I run it highly available?​

Run two or more replicas behind a load balancer with the same client_id_secret on every replica and REDIS_URL pointing at one Redis without cluster mode, so any replica can serve any client and a replica can be replaced without breaking sessions. Only the inbound side needs shared state; outbound Relays keep their pairs in process, so a highly available chain runs one Redis where v4 needed two. Add replicas for availability and size each one for throughput, because one 4 CPU Relay moved more than two 2 CPU Relays sharing Redis. Sticky routing on X-MTE-Relay-Route with LOCAL_STATE_CACHE saves a Redis round trip per state read. See Running more than one replica.

What happens if Redis or the control plane goes down?​

Redis is a hard dependency, so run it with the availability the fleet needs. While it is unreachable, requests that need pair state fail with retryable errors (503 state_store_unavailable at pairing and keepalive, 470 pair_not_found on the data path) until it returns, and clients pair again afterwards; there is nothing to restore, because pair state is short lived. While the control plane is down, workers keep serving their last applied configuration and catch up on their next poll, and a worker that cannot validate a new document keeps the old one. See How the control plane works and Errors and recovery.

How do restarts and upgrades affect users?​

A Relay drains on SIGTERM: readiness turns 503, the listener stops accepting, requests in flight finish within DRAIN_SECONDS (30 by default), and only then does the process exit. The listener closes as soon as readiness turns 503, so a load balancer that has not yet seen the 503 can still send a new request to a stopping Relay; keep more than one replica for a rolling update, and give the orchestrator a termination grace period above the drain budget. Without Redis, a restart loses pair state and clients pair again on their next request. The browser SDK does that itself after a 475 invalid_client_id, though the request that found the Relay restarted is surfaced to your code as a repaired error, and your code decides whether to send it again. With Redis, sessions survive. An upgrade within v5 is a redeploy with the new tag, with no client change. See Fault recovery.

Client platforms​

Which client platforms are supported?​

Web applications through mte-relay-browser-public-client, a fetch replacement, and mte-relay-angular, an HttpClient transport for Angular 17 through 22; iOS through a Swift package; Android through a Maven library that works with Volley and OkHttp; and Flutter through a plugin for iOS and Android. Each needs its frame version 2 release, and any frame version 2 client works with any v5 Relay. MTE API Relay needs no client library. See Version compatibility.

How does the browser integration work?​

Install the npm package and replace fetch with mteFetch for calls to the Relay origin. The package bundles the MTE WebAssembly engine and the license and initializes itself on import, so there is no setup call. On the first request to a Relay origin it authenticates, reads the Relay's discovery document, checks that the Relay speaks frame version 2 with a matching library profile and Kyber strength, and pairs. After that it encrypts each request, decrypts each response, keeps a small pool of pairs, sends keepalives and recovers from Relay errors. Angular gets the same engine through one provider, and existing interceptors keep seeing plaintext. See the JavaScript client and the Angular client.

Will browsers send a CORS preflight for every request?​

For cross origin calls, yes, because application/octet-stream is not a CORS safelisted content type. The Relay answers preflights itself with 204 from the domain's CORS settings, and cors_max_age_seconds lets browsers cache the answer so most requests skip the preflight. When you customize cors_allowed_headers, keep Content-Type and X-MTE-Relay-Route in the list. See CORS for browser clients.

Do cookies, sessions and my existing authentication keep working?​

Yes. Authorization headers and every other application header travel inside the encrypted frame and reach your API unchanged. Browser cookies ride the plain HTTP request, and the origin's Set-Cookie moves to the plain HTTP response, the only response a browser applies Set-Cookie from, so cookie sessions work, subject to the browser's third party cookie rules when the Relay host is on a different site from the application. The cookie must be valid for the Relay host, because the Relay does not rewrite Domain or Path. The browser SDK sends credentials by default, and the Relay allows them unless a domain turns cors_allow_credentials off. See Cookies.

What happens when a request fails?​

The SDK throws a typed error carrying the Relay code, a reason token, the registered recovery action, the Relay's message and the request id. It repairs or replaces pairs on its own as the action says, sends a request again by itself only in the two cases where nothing ran at the origin, and otherwise leaves the retry decision to your code, which knows whether the request was idempotent. An answer that is not a valid frame, such as a CDN error page or a WAF block, is a transport error and never application data. On an outbound domain the calling service receives errors as JSON bodies with the same code and reason. See Errors and recovery.

How do mobile apps move to a new Relay version?​

Within v5, servers and clients need not move together, because any frame version 2 client works with any v5 Relay release, so an app on an older v5 SDK keeps working after a Relay upgrade. The v4 to v5 move is different, because the wire protocols differ. A mobile app keeps using the SDK it shipped with until users update, so run the old and new Relay versions side by side on different hostnames, ship the app build that points at the new one, and retire the old Relay when its traffic stops. See the cutover plan.

Operations​

How do I monitor MTE Relay?​

Through its structured JSON logs. Every request produces a performance event, and each encrypted request that reaches the origin adds its decrypt, validate, proxy and encrypt timings; security events cover token failures, replays and header mismatches; an audit record holds hashes only; and error events report faults. The events of one request share a correlation id that is also the X-MTE-Relay-Request-Id the client sees and the Relay sends upstream. No vendor agent runs inside the Relay. Your log shipper forwards the container output, and this site provides a Datadog pipeline, dashboard and monitors, a New Relic dashboard and alert policy, and Grafana dashboards for CloudWatch Logs Insights and Loki. See Monitoring and integrations.

What do the 470 to 490 status codes mean?​

They are Relay faults, each with a reason token and a registered client action: a missing or failed pair (470 to 474), a bad token (475), a malformed frame, an oversized frame or body, or bad metadata (477, 481, 482), an unsupported protocol version (478), a replay (479), a Host with no DOMAIN_MAP entry (480), a bound envelope mismatch (483), outbound capacity (485), rate limiting (488) and validation failures (490). The Relay keeps 500, 502 and 503 for true server, upstream and state store faults. The code travels twice, in an ERROR frame body and in the X-MTE-Relay-Error header, so it survives a proxy that replaces the body. A relayed response always travels as HTTP 200; the origin's real status is inside the frame. See Errors and recovery.

How much does the Relay log, and can I reduce it?​

Per request performance events dominate the volume, and the Relay emits them for every request. Filter or sample those in your log shipper or log platform when cost matters, and keep security, error and audit events unsampled. Echo hits are logged at debug, and probe and health check path hits are not logged, so a load balancer check does not fill the log. LOG_LEVEL=warn still carries medium, high and critical security events. See Log volume.

Versions and support​

Can v4 clients talk to a v5 Relay?​

No. v5 uses a new binary wire protocol, frame version 2, and there is no dual stack mode. A v5 Relay serves only v5 clients, and a v4 Relay serves only v4 clients. A v4 client that reaches a v5 Relay gets 478 frame_version_unsupported on its first call and never gets a session, and the Relay logs the minimum SDK versions at warn level. Servers and clients therefore upgrade together, per application, and the documented cutover plan runs v4 and v5 side by side on different hostnames until every application has moved. See Upgrading from v4.

Do clients and servers have to upgrade together within v5?​

No. Within a major version, releases are additive and backwards compatible, and any frame version 2 client works with any v5 Relay release. Upgrading a server is a redeploy with the new tag and no client change, and a feature added in a later minor is marked in the documentation with a Since badge naming the minimum server version. See Version compatibility.

How often are releases, and how long is a version supported?​

Images are published as needed, when features, dependency updates or fixes warrant a release, with security patches out of band. Breaking changes arrive only with a new major version, which gets its own documentation set. MTE Relay v4 is supported until October 1, 2027, its images stay available at least until then, and its documentation stays online. See the v4 support policy.

How is MTE Relay licensed?​

MTE Relay is a commercially licensed and commercially supported product. A license is a company name and key, set on every Relay through COMPANY_NAME and LICENSE_KEY. The images ship with a development license so that an evaluation runs out of the box, and production deployments set their own. On the AWS Marketplace images the subscription is the license, so both stay unset. The public web client package bundles its license, and the Angular client takes the license in its provider. Contact Eclypses for terms.

Is there a trial build?​

There is no v5 trial build yet. The MTE Relay Server trial build runs v4, and v4 components cannot pair with v5. For a v5 evaluation, the release images run with their built in development license, so the server side of an evaluation needs only access to the images. See the trial build page and contact Eclypses.

How do I get support?​

Licensed and subscribed customers contact Eclypses Support at customer_support@eclypses.com, Monday to Friday, 8:00 AM to 5:00 PM MST, excluding holidays, for escalations, scan reports and hardening documentation. Include the X-MTE-Relay-Request-Id of a failing request where you have one; it ties the client error to the Relay and origin logs. See Support.