MTE API Relay
Introduction
MTE API Relay is an end-to-end encryption system that protects HTTP traffic between server applications. It acts as a proxy server that encodes and decodes payloads using Eclypses MTE software, an encryption library combining quantum-resistant algorithms with proprietary, patented techniques to secure data.
Below is an architecture where a server application communicates through an MTE API Relay container, which then transmits proxied traffic to another API Relay that decodes and delivers the request to its upstream API service:

View MTE API Relay on the Azure Marketplace
MTE API Relay instances are only compatible with each other. Neither an MTE Relay Server nor an MTE Client SDK can communicate with an MTE API Relay. MTE API Relays are strictly for server-to-server communications.
Prerequisites
Technical Requirements
- Two services that use HTTP to communicate with each other.
Skills and Knowledge
- Familiarity with AKS and/or Kubernetes.
- General familiarity with Azure Services.
- Experience with the Azure CLI.
Deployment Options
MTE API Relay is provided as a Docker image and can be deployed on Azure AKS, or manually using another container runtime.
Azure Kubernetes Service (AKS)
If kubectl is already configured for your AKS cluster:
Example Deployment File (deployment.yaml)
apiVersion: apps/v1
kind: Deployment
metadata:
name: azure-mte-api-relay-deployment
spec:
replicas: 1
selector:
matchLabels:
app: azure-mte-api-relay
template:
metadata:
labels:
app: azure-mte-api-relay
spec:
containers:
- name: azure-mte-api-relay
image: <CONTAINER_IMAGE>
ports:
- containerPort: 8080
env:
- name: CLIENT_ID_SECRET
value: <YOUR CLIENT ID SECRET HERE>
- name: UPSTREAM
value: <UPSTREAM VALUE HERE>
- name: OUTBOUND_TOKEN
value: <OUTBOUND TOKEN HERE>
- name: SECRET
value: <SERVER SECRET HERE>
---
apiVersion: v1
kind: Service
metadata:
name: azure-mte-api-relay-service
spec:
type: LoadBalancer
selector:
app: azure-mte-api-relay
ports:
- protocol: TCP
port: 80
targetPort: 8080
Commands
kubectl apply -f deployment.yaml
kubectl get all
kubectl delete -f deployment.yaml
Server Configuration
MTE API Relay is configured using environment variables.
Using a DOMAIN_MAP (Recommended)
DOMAIN_MAP is a JSON object keyed by the Host header that arrives with each request.
The value for each key is a settings object that tells the proxy how to process the request.
Settings
| Field | Type | Purpose |
|---|---|---|
| upstream | string | Full URL (http://localhost:8080, https://api.internal) |
| pass_through_routes | string[] | Paths that use standard HTTP proxy, without MTE encryption |
| outbound_token | string | Token that authorizes a request to be encoded and sent out. |
| client_id_secret | string | Legacy shared secret used by some auth layers |
Examples
- Single Proxy: Requests with Host header
mte-api.company.comare decrypted and forwarded tohttp://internal-service. The/healthroute is proxied without MTE encoding/decoding.
{
"mte-api.company.com": {
"upstream": "http://internal-service",
"client_id_secret": "8KeJmtuKweUhymNJmGHvGMrJCUtHxhQG",
"pass_through_routes": ["/health"]
}
}
- Multi-service proxy that handles:
- Incoming encoded requests for
billing.company.io, forwarding tohttp://billing-servicewith/readyand/liveroutes unencoded. - Request to
users.company.iothat include thex-mte-outbound-tokenheader will be encrypted and proxied to the url specified in thex-mte-upstreamheader. - All other requests (any Host) are proxied to
http://default-backend:8080without encoding.
{
"billing.company.io": {
"upstream": "http://billing-service",
"pass_through_routes": ["/ready", "/live"],
"client_id_secret": "8KeJmtuKweUhymNJmGHvGMrJCUtHxhQG"
},
"users.company.io": {
"outbound_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9"
},
"*": {
"upstream": "http://default-backend:8080",
"client_id_secret": "8KeJmtuKweUhymNJmGHvGMrJCUtHxhQG"
}
}
Export as one-line env var:
export DOMAIN_MAP='{ "billing.company.io": { "upstream": "http://billing-service", "pass_through_routes": ["/ready", "/live"], "client_id_secret": "8KeJmtuKweUhymNJmGHvGMrJCUtHxhQG" }, "users.company.io": { "outbound_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9" }, "*": { "upstream": "http://default-backend:8080", "client_id_secret": "8KeJmtuKweUhymNJmGHvGMrJCUtHxhQG" } }'
Host header derivation
The Host header is taken directly from the authority component of the absolute URL used in the request.
For example, https://api.example.com/users/1 the authority is api.example.com (port 443 is implicit for HTTPS), so the Host header sent by the client is exactly:
Host: api.example.com
If the URL contains an explicit port (https://api.example.com:8443/users/1) the header becomes:
Host: api.example.com:8443
DOMAIN_MAP must therefore use the exact same string—domain only, or domain:port—to match the incoming Host header. Or, use a wildcard "*" to match any host.
Host Matching
MTE API Relay performs an exact match against the Host header (case-insensitive).
If an exact match is not found, it checks for a wildcard ("*").
If no match is found, the request is rejected with 404.
Using individual Environment Variables (Legacy)
Using these environment variables will result in the MTE API Relay being configured to only handle a single domain. This method is deprecated in favor of using the DOMAIN_MAP variable. If both are provided, DOMAIN_MAP will take precedence.
Example:
UPSTREAM- Upstream API or service URL.CLIENT_ID_SECRET- Secret for signing client IDs (minimum 32 characters).PASS_THROUGH_ROUTES- Comma-separated list of routes proxied without encoding/decoding.OUTBOUND_TOKEN- Token for authenticating outbound requests.
UPSTREAM='https://api.my-company.com'
CLIENT_ID_SECRET='2DkV4DDabehO8cifDktdF9elKJL0CKrk'
PASS_THROUGH_ROUTES='/health,/version'
OUTBOUND_TOKEN='s3cr3tT0k3nV4lu3'
Additional Environment Variables
PORT- Default:8080.LOG_LEVEL- One of trace, debug, info, warning, error, panic, disabled. Default:info.HEADERS- A JSON string of additional headers to add to upstream requests.
Usage Guide
To use MTE API Relay, simply redirect your application's HTTP requests to the Outbound Relay instance and include the required x-mte-* headers. The Outbound Relay will handle encoding the request, forwarding it to the Inbound Relay, and decoding the response before returning it to your application.
Outbound Request Headers
When sending a request to the Outbound Relay, include the following headers:
x-mte-outbound-token: The outbound token configured in the Outbound Relay.x-mte-upstream: The URL of the upstream service, from the perspective of the Outbound Relay. It should be an Inbound Relay URL.
Example Request
Before using MTE API Relay, a normal HTTP request would look like this:
curl -X GET https://api.my-company.com/data
After setting up MTE API Relay, the request to the Outbound Relay would look like this:
curl -X GET https://outbound-relay.my-company.com/data \
-H "x-mte-outbound-token: __YOUR_OUTBOUND_TOKEN__" \
-H "x-mte-upstream: https://inbound-relay.my-company.com/data"
- The
x-mte-upstreamheader should point to the Inbound Relay URL, not directly to the backend service. - Only the Domain portion of the URL needs to be updated. The path of the URL can remain the same.
Testing & Health Checks
- Monitor container logs for startup messages
- Use the default or custom echo routes to test container responsiveness:
- Default:
/api/mte-echo - Custom Message:
/api/mte-echo?msg=test
- Default:
Expected response:
{
"message": "test",
"timestamp": "<timestamp>"
}
Monitoring
Azure Managed Grafana
- Create a Grafana workspace in Azure.
- Add Azure Monitor as a data source (service principal auth recommended).
- Import the provided dashboard:
Dashboard Metrics
- Requests Processed [req/sec]
- Request Time [ms]
- Outbound Proxy Time [ms]
- Upstream Proxy Time [ms]
- Average Request Encode Time [ms]
- Average Request Decode Time [ms]
- Average Response Encode Time [ms]
- Average Response Decode Time [ms]
Performance Metrics
Performance was measured with ~1 kb request/response payloads:
| Concurrency | Req/Sec Relay | Req/Sec API | Relay % | Extra Latency (Median) |
|---|---|---|---|---|
| 400 | 185 | 188 | 98.5% | +10 ms |
| 500 | 298 | 305 | 97.8% | +17 ms |
| 550 | 338 | 355 | 95.1% | +45 ms |
| 600 | 339 | 402 | 84.3% | +202 ms |
Note: At higher volumes (≥650 concurrent), scaling across multiple Relay instances is recommended.
Troubleshooting
- Invalid Configuration
- Check logs for missing/invalid environment variables.
- Relay unreachable
- Verify Network Security Groups and load balancer settings.
- Redis connection issues
- Ensure Redis is properly deployed and credentials are correct.
Security
- No sensitive data is stored in the container.
- No root privileges required.
- Should be deployed in the same VNet as the upstream service to ensure proxied traffic remains internal.
Costs
The service uses a usage-based cost per instance per hour.
Associated Azure services include:
| Azure Service | Purpose |
|---|---|
| AKS | Container orchestration |
| Azure Cache (Redis) | State/session management |
| Azure Monitor | Logging and monitoring |
| VNet | Networking isolation |
| Azure Load Balancer | Scaling across Relay containers |
| Azure Key Vault | Recommended for secrets/env vars |
Maintenance
Routine Updates
- Updated container images are distributed through the Azure Marketplace.
Fault Recovery
- Relaunch the Relay container pod; API Relays will automatically re-pair.
Service Limits
- AKS: AKS Service Quotas
- Azure Monitor: Limits
- Azure Load Balancer: Limits
Key/Variable Rotation Recommendations
- Rotate the
CLIENT_ID_SECRETandOUTBOUND_TOKENevery 90 days as per security best practices.
Supported Regions
MTE API Relay is supported in most Azure regions, except:
- Azure Gov
- UAE and Bahrain Regions
- China
Support
For assistance, contact Eclypses Support:
📧 customer_support@eclypses.com
🕒 Monday–Friday, 8:00 AM–5:00 PM MST (excluding holidays)