Relay
Relay is a network proxy that encrypts and decrypts sensitive data in transit between a client and a destination server. It works with your own APIs and third-party services, and requires minimal changes to your existing code.
How Relay works
You can use Relay in a few ways:
- Outbound from your server: you hold encrypted data (such as card details) and forward it to a third-party API. Relay decrypts the data as the request passes through it, so your infrastructure never handles sensitive data directly.
- Inbound to your server: data arrives from an external source and needs to be encrypted before it reaches your server. Relay encrypts the fields you specify on the way in.
- Outbound from your server to your frontend (specifically for revealing card details in a browser): encrypted card details are decrypted on the way out so they can be displayed to customers through the Reveal component.
Relay is most commonly used for outbound decryption. Here's what that looks like for collecting and sharing card data for a payment.
- Your customer enters their card details into our Card component. The data is encrypted within the iframe before it's returned to your application.
- Your backend receives and stores the encrypted card information. Because the data is encrypted, it's safe to store on your side.
- Using the encrypted data, you send an API request through Relay to your payment processor.
- Relay detects the encrypted card fields and decrypts them in transit.
- The payment processor receives the card data in plaintext, completes the payment, and the response is piped back to you through Relay.
Evervault doesn't do anything with the response from your payment processor. If needed, you can configure Relay to encrypt any sensitive values before the response is forwarded to your server.
Getting started
This example focuses on creating a relay and how you can send encrypted data through it. See the Card Collection page for an end-to-end guide that covers collecting, encrypting, and forwarding card data.
Encrypt and decrypt actions are tied to app keys. If you encrypt data with Relay in a sandbox app, you can't decrypt that data with Relay from a production app (or the other way around). Data can only be encrypted and decrypted using the same app key.
Create a relay
Open the Relays section in the dashboard and click Create Relay. Provide the base URL (example.com) for the API you want to proxy requests to and create the relay.
Evervault provisions a domain for your relay after creating it. This is the domain you'll send requests to when you want to proxy API calls to downstream partners. You can find the domain in the dashboard (it looks this: [DESTINATION_URL].relay.evervault.app).
Configure a route
Routes define what to do with requests that match a given URL path, and you can have multiple routes for each relay. You configure the data type and fields (JSON, form data, etc.) to operate on, as well as what to do with that data. To create a route, click + Add Route in the dashboard and then set the path (e.g., /charge), actions, etc.
You configure relays to encrypt or decrypt data with route actions. These actions can be applied to requests (data being sent to the destination) or the response (data being returned to you). The combination you configure depends on your use case.
- Decrypt on request: your backend holds encrypted data and forwards it to a third-party API. Relay decrypts the fields in transit.
- Decrypt on response: used with the Reveal component to display card details to your customers.
- Encrypt on request: Encrypt data that you collect before storing it (outside of card data which you should use our card collection for)
- Encrypt on response: encrypt data returned by a third party, such as a card issuer returning PANs, before it reaches your server.
Sending a request
Pass your relay's domain into your requests to proxy them to the target endpoint.
As an example, when you collect a card number with Evervault, it's encrypted on the frontend before being sent to your backend. So a card number like 4242 4242 4242 4242 is turned into something like this.
You store this value instead of the plaintext card number. When you want to charge the card, you send the request through relay with the encrypted string. Relay decrypts it in transit, and your downstream partner receives the plaintext card number.
Path matching
Route actions will only be applied to requests that match the request path. Paths can be configured to match a specific path or multiple paths with a wildcard.
| Example | Description |
|---|---|
/ | Matches requests to the root path |
/checkout | Matches requests to /checkout |
/patients/*/reports | Allows for dynamic URL segments such as IDs. Matches requests such as /patients/1/reports, /patients/2/reports, etc. |
/** | Matches all requests |
Selecting fields
Route actions are only applied to data that matches the list of selected fields defined on an action. Field selection can be configured on a per-content type basis.
JSON
Use JSONPath to select fields according to their path in the JSON object. JSON values must only contain encrypted strings (e.g., { "ssn": "ev:...1a2bc$" }). If the value contains other data like raw text (e.g.,{ "ssn": "User SSN: ev:...1a2bc$" }), decryption fails.
JSON payloads are supported for requests where the content-type subtype is JSON. The subtype is the part of the content-type header after the /. For example, a content-type of application/json+charset=utf8 has a subtype of JSON.
JSON selector examples
| Example | Description |
|---|---|
$.name | Matches the name field |
$.address.* | Matches all fields inside of the address object |
$.patients.*.name | Select the name field in all patients objects |
$.patients[?(@.country == 'IE')].name | Selects the |
$..* | Selects all fields inside the JSON object |
Form data
Form data is only supported for requests with a content-type of application/x-www-form-urlencoded or multipart/form-data. Form fields are matched directly by name. If a matched value contains multiple pieces of encrypted text, each one is decrypted individually. Global wildcards are supported for form data but not nested ones (e.g., * is valid but something like name.*.last isn't).
Form data selector examples
| Example | Description |
|---|---|
card[cvc] | Matches the card[cvc] field |
card[number] | Matches the card[number] field |
* | Matches all fields |
Files
Relay supports encrypting and decrypting files in multipart and form-data requests. Encrypted files are forwarded with an unchanged filename, but the bytes in the file are fully encrypted. There is a per-request limit of 25 MB for encryption and decryption.
File selector examples
| Example | Description |
|---|---|
passport-scan | Matches files named passport-scan |
* | Matches all files |
Headers
Headers can be selected by name and aren't case sensitive. If the matched header value contains multiple pieces of encrypted text, each one is decrypted individually.
Header selector examples
| Example | Description |
|---|---|
Authorization | Matches the header named Authorization |
* | Matches all headers |
XML
To work with XML data, configure your relay for JSON and select the fields to encrypt or decrypt using standard JSONPath. To encrypt attributes, use advanced JSONPath selectors.
XML selector examples
| Example | Description |
|---|---|
$.company.revenue | Matches the revenue element |
$.company.departments.*.employees.employee.salary | Wildcard selector that matches the salary field for every employee across all departments |
$.company.departments.department.*['@name'] | Matches the department name attribute |
Authentication
API key authentication adds an additional layer of security to your relay. When enabled, requests through Relay require a valid Evervault API key in the X-Evervault-Api-Key header and your app's ID in the X-Evervault-App-Id header.
Enable authentication for relays that decrypt data
Evervault strongly recommends enabling API key authentication for any relay configured to decrypt data. If your relay is pointed at your own API (which already has its own authentication), it may not be strictly necessary. When using Relay with a third-party API, API key authentication ensures that only your application can trigger decryption.
You can enable authentication for your relay in the Evervault Dashboard by navigating to the Authentication settings page.
Authorize access to decrypted data
Some flows deliver decrypted data directly to a client (e.g., the Card Reveal iframe fetching plaintext card data). In these cases, your backend endpoint is the only place where access control is enforced. Evervault has no context for which of your customers can access a given record, so authenticate the request and verify that the caller is authorized before the response is returned.
Limitations
The following limitations apply to all requests sent through Relay. If your application requires higher limits, contact support@evervault.com to discuss your requirements.
| Description | Limit |
|---|---|
| Max payload size | 5mb |
| Max file size | 25mb |
| Max chunked size (transfer-encoding: chunked) | 700kb |
| Connection Timeout | 120s |
Alerts
Alerts allow you to see errors in Slack or be sent to any webhook URL of your choice. You can create an alert for your relay inside of the Evervault Dashboard by navigating to Relay → Alerts → Add Alert. When you configure a custom webhook to receive alerts, the following fields will be in the response.
Payload
- The unique identifier for your relay.
- The unique identifier for your team.
- Message explaining what went wrong.
Message about where the error has occurred.
A link to view the failed transaction in the Evervault dashboard.
- The time the error occurred.
The relay error code.
- The HTTP status code of the response.
- 4XX, 5XX, or ERR.
- Your relay domain.
Error handling
Errors originating from within Relay can be distinguished by the X-Evervault-Error-Code header. The responses will have a content type of application/problem+json and a payload of the following structure:
Error Codes
This error indicates you are sending a request to a relay (e.g., my-api-com.relay.evervault.app) which doesn't exist. Ensure you have entered the Relay subdomain correctly. Also, ensure you have configured your relay correctly by following our Relay documentation.
The target took too long to respond. The error can have many causes ranging from network issues to malformed client requests. Ensure the target domain URL is correct, wait a few moments and try again. If the error persists, reach out to the owner of the target domain through any support channels they have in place.
This error occurs when Relay is configured to perform response encryption and receives an unsupported content type as a response from the endpoint. Currently, Relay can only encrypt JSON, XML and multipart/form-data structured data.
There was an issue authenticating with the provided API key. Ensure that you are using the correct API key.
The Content-Length header is either not present or isn't a number.
This error indicates that an invalid hostname was provided while communicating with Relay in forward proxy mode. Ensure you have entered the downstream hostname correctly, and that it can be resolved when requesting it directly.
The API key provided does not have sufficient grants to perform the actions requested. Please review the grants given to your API Key.
This request exceeds the request size limit in Relay. The current per-request limit is 25 MB for encryption/decryption of multipart data, and 5 MB for all other content types.
The content type header received by Relay was malformed, preventing the body from being processed.
There was an issue with Relay itself. Try again in a few moments.
A ciphertext's data policy prevented it from being decrypted. Ensure your data policy's configuration is correct.
This error indicates that Relay received a CONNECT request with no hostname while operating in forward proxy mode. Ensure you have entered the downstream hostname correctly, and that it can be resolved when requesting it directly.
There was an issue finding a relay for the provided domain. Make sure you are using the correct domain. If your domain is correct but you are still seeing this issue, ensure you have Relay configured correctly.
There was encrypted data where it wasn't expected. This can mean a number of things:
- An inbound request header value contained Evervault encrypted data.
- An inbound request payload had Evervault encrypted data as the value of one of the fields, which was not going to be encrypted.
- The target URI for the inbound request had Evervault encrypted data as part of the path.
Relay experienced an unexpected networking error while communicating with the downstream service. Please confirm that the downstream service is accessible when not routing through Relay, and ensure that any allowlist requirements have been met.
Relay received a request using the CONNECT method which is only supported in forward proxy mode.
The server is unable (or refuses) to process the request sent by the client, due to an issue that is perceived by the server to be a client problem.
A relay with authentication enabled was requested without valid credentials.
Custom domains
Each relay is provisioned with its own unique relay.evervault.app domain. You can also configure additional custom domains for your relay in the Evervault Dashboard by navigating to Relay → Settings → Domains.
To add a custom domain, add a CNAME record to your DNS provider that points to custom-dns.relay.evervault.app. You also need to add an ownership validation TXT record on the _ev-custom-domain subdomain of your custom domain.
DNS propagation can take anywhere from a few minutes to 24 hours depending on your DNS provider and the TTL settings on your domain. If your custom domain isn't resolving after adding the records, check that both the CNAME and TXT records have been added correctly and allow more time for propagation.
Alternative configurations
These configurations are possible with Evervault, but not generally recommended. They're only used in specific situations where the default options aren't adequate.
mTLS
mTLS (mutual TLS) lets Relay authenticate with the target server using a client certificate, adding an additional layer of transport security between Relay and the downstream service. This is typically only required by organizations with strict security policies that mandate mutual authentication at the network layer — most integrations don't need it.
mTLS must be enabled by Evervault. Contact support@evervault.com to request it for your relay.
Forward proxy mode
The integration described above is sufficient for most use cases, but there are some scenarios where you might need to use Relay in forward proxy mode (e.g., you can't change the hostname used by a third party library). Forward proxy mode requires installing the Relay certificate chain, and configuring the relevant traffic to route using Evervault Relay acting as an HTTP CONNECT proxy.
To integrate with Relay in forward-proxy mode, you need to:
- Trust the Relay cert chain on your server. The cert can be obtained from ca.evervault.com.
- Identify the best approach for establishing an HTTP tunnel in your preferred language.
- For example, in Node.js this is likely using an Agent (which can be created using the Evervault Node.js SDK), or in JVM-based languages this is through the VM's
http.proxyHostconfiguration options.
- For example, in Node.js this is likely using an Agent (which can be created using the Evervault Node.js SDK), or in JVM-based languages this is through the VM's
- Supply your proxy authentication credentials to Relay using basic auth. This can be done during either the initial
CONNECTrequest or the subsequent proxied request using theProxy-Authorizationheader. The value should be basic auth credentials, with your app ID as the username and your API key as the password.- Relay only proxies requests to hosts that have been explicitly created in your app and can't be treated as a generic forward proxy.
You can test Relay as a forward proxy using curl:
Using fixed regions
Using fixed regions isn't generally recommended and Evervault doesn't guarantee reliability or provide an SLA when using a fixed region.
Evervault operates an active-active infrastructure across multiple regions and availability zones. If you need to, you can specify specific regions (either us or eu) to use with Relay, but this doesn't come with an SLA from Evervault's side. To do this, add us or eu to your relay URL when making a call. For example, if your base URL is your-prod-app-12345.relay.evervault.app, change it to your-prod-app-12345.us.relay.evervault.app to send requests to the US region.