> ## Documentation Index
> Fetch the complete documentation index at: https://docs.revyl.com/llms.txt
> Use this file to discover all available pages before exploring further.

# AWS PrivateLink Overview

> Connect Revyl builds and devices to services in your AWS VPC without exposing them to the internet

<Info>
  **AWS PrivateLink is available on Enterprise plans.** Contact your Revyl
  account team or [support@revyl.ai](mailto:support@revyl.ai) to enable it for
  your organization before you start.
</Info>

Some builds and tests need things that live inside your network: a private
package registry, an internal artifact store, a staging API, a feature-flag
service. AWS PrivateLink lets Revyl reach those services privately, over the
AWS backbone, without a VPN, VPC peering, or any public ingress on your side.

<img src="https://mintcdn.com/cognisim/fF6HqkVdQl5Brusv/images/diagrams/privatelink/architecture.png?fit=max&auto=format&n=fF6HqkVdQl5Brusv&q=85&s=4556b08378596fbd25c0b6bace8898d3" alt="How Revyl reaches your private service over AWS PrivateLink" width="2800" height="1320" data-path="images/diagrams/privatelink/architecture.png" />

## When to use it

<CardGroup cols={2}>
  <Card title="Private build dependencies" icon="box">
    Remote builds pull packages from Artifactory, Nexus,
    CodeArtifact, or an internal Git mirror that only resolves inside your VPC.
  </Card>

  <Card title="Private test backends" icon="server">
    The app under test talks to a staging or pre-production API that is not
    reachable from the internet.
  </Card>

  <Card title="No public allowlisting" icon="shield">
    Your security policy does not allow opening services to third-party IP
    ranges, even with an [IP allowlist](/guides/allowlist-ip-addresses).
  </Card>

  <Card title="Overlapping address space" icon="network-wired">
    PrivateLink does not route between VPCs, so overlapping CIDR ranges on
    either side are not a problem.
  </Card>
</CardGroup>

If your service is already reachable from the internet and protected by
authentication, an [IP allowlist](/guides/allowlist-ip-addresses) is the
simpler option.

## How it works

You are the **service provider** and Revyl is the **service consumer**, in
AWS PrivateLink terms.

1. You put the service behind an **internal Network Load Balancer (NLB)** and
   publish it as a **VPC endpoint service**.
2. You allow Revyl's AWS account to connect to that endpoint service, and
   nothing else.
3. Revyl creates an **interface VPC endpoint** for your service in Revyl's
   AWS account. You approve the connection request.
4. Revyl's egress gateway routes traffic for your hostnames from your Revyl
   workloads to that endpoint.

Connections are one way. Revyl can open connections to the listeners on your
NLB; nothing in your VPC is reachable beyond those listeners, and nothing in
Revyl's network becomes reachable from yours.

```mermaid theme={null}
sequenceDiagram
    autonumber
    participant W as Revyl runner or device
    participant G as Revyl egress gateway
    participant E as Interface endpoint (Revyl VPC)
    participant N as Your NLB
    participant S as Your service
    W->>G: CONNECT artifactory.internal.example.com:443
    G->>G: Map your hostname to the endpoint
    G->>E: Open TCP connection to endpoint private IP
    E->>N: AWS PrivateLink
    N->>S: Forward to healthy target
    W-->>S: TLS handshake, end to end (Revyl does not terminate TLS)
    S-->>W: Encrypted response
```

## Security model

<AccordionGroup>
  <Accordion title="What can Revyl reach in my network?" icon="lock">
    Only the listeners you configure on the NLB behind your endpoint service.
    PrivateLink does not create a route into your VPC. Security groups,
    network ACLs, and route tables on the rest of your VPC are not involved.
  </Accordion>

  <Accordion title="Is traffic encrypted?" icon="key">
    Traffic between Revyl's device hosts and Revyl's AWS gateway travels over
    an authenticated proxy tunnel, and the PrivateLink leg stays on the AWS
    network. Revyl does not terminate your TLS: when your service serves TLS,
    the session is encrypted end to end between the client on the Revyl
    runner or device and your service. Serve TLS on every service you expose.
  </Accordion>

  <Accordion title="Can I see and revoke the connection?" icon="eye">
    Yes. The connection appears under your endpoint service's **Endpoint
    connections** tab with Revyl's account ID (`992382537093`) and endpoint ID. Reject the
    accepted connection at any time to cut access immediately. Removing
    Revyl's principal only blocks new endpoint connections; an endpoint you
    already accepted keeps working until you reject it. See [Offboarding](/guides/privatelink/troubleshooting#offboarding).
  </Accordion>

  <Accordion title="Who pays for what?" icon="receipt">
    AWS bills the service provider for the NLB and the consumer for the
    interface endpoint. Your NLB runs in your account; the interface endpoint
    runs in Revyl's account.
  </Accordion>
</AccordionGroup>

## Regions and Availability Zones

Revyl's PrivateLink consumer runs in **`us-west-2`**.

* **Same region (recommended).** Host your endpoint service in `us-west-2`.
* **Another region.** AWS supports cross-region PrivateLink. Add `us-west-2`
  to your endpoint service's **supported Regions** and tell Revyl the
  service's home region. Expect inter-region data transfer charges and some
  added latency. Cross-region endpoints need no zone alignment, so keep your
  NLB in at least two zones of its own region and skip the `usw2-az2`
  requirements below.

Revyl's interface endpoint runs in one Availability Zone: **`usw2-az2`**.

Availability Zone **names** such as `us-west-2a` map to different physical
zones in each AWS account, so match on the **AZ ID**, not the name. For a
service in `us-west-2`, your NLB must have a subnet in `usw2-az2`; Revyl cannot
create its endpoint otherwise. Keep subnets in your other zones too, for your
own clients.

<Tip>
  Find the AZ ID of each of your subnets in the VPC console's **Subnets** view,
  or run `aws ec2 describe-availability-zones --region us-west-2 --query "AvailabilityZones[].[ZoneName,ZoneId]"`.
</Tip>

## Cross-zone load balancing

For a service in `us-west-2`, every Revyl connection enters your NLB through
its `usw2-az2` node. AWS wires
an interface endpoint to the load balancer node in the same zone, so this
entry point does not move.

<img src="https://mintcdn.com/cognisim/fF6HqkVdQl5Brusv/images/diagrams/privatelink/cross-zone.png?fit=max&auto=format&n=fF6HqkVdQl5Brusv&q=85&s=f077cf4a6b8e6b64288c88fb72384e99" alt="Cross-zone load balancing off vs on" width="3040" height="1360" data-path="images/diagrams/privatelink/cross-zone.png" />

**With cross-zone load balancing off** (the NLB default), each NLB node sends
traffic only to targets in its own zone. For Revyl that means:

* **Only your `usw2-az2` targets serve Revyl.** All Revyl load lands on them,
  however many healthy targets you run in other zones.
* **No healthy targets in `usw2-az2` means a blackhole.** Revyl's connections
  time out while the service looks healthy to your other clients.
* **DNS failover does not help.** When a zone has no healthy targets, the NLB
  removes that zone's IP from its own DNS name. Revyl's endpoint never resolves
  that name, so its traffic keeps arriving at the `usw2-az2` node. The NLB only
  fails open to all zones once every zone is unhealthy.

**With cross-zone load balancing on**, the `usw2-az2` node spreads Revyl's
connections across healthy targets in every enabled zone. A zone that empties
during a deploy or scale-in no longer takes Revyl down with it. AWS bills
regional data transfer for traffic that crosses zones.

<Note>
  Turn cross-zone load balancing on for the NLB or target group that serves
  Revyl. If you need it off, keep enough healthy capacity in `usw2-az2` to carry
  all of Revyl's traffic on its own.
</Note>

### Fronting an Application Load Balancer

You can register an existing ALB as the NLB's target (an `alb` target group).
It works, but there is a second load balancer in the path, and its zone
behaviour stacks on top of the NLB's.

* **The ALB must be enabled in `usw2-az2`.** AWS recommends keeping cross-zone
  load balancing off on an NLB that fronts an ALB, and you cannot change the
  attributes of an `alb` target group. So the `usw2-az2` NLB node forwards only
  to the ALB's `usw2-az2` node. If the ALB has no node there, the result is the
  same blackhole as above.
* **ALB target groups with cross-zone off turn imbalance into errors.** Each
  ALB node then uses only its own zone's targets. Every Revyl request hits your
  `usw2-az2` targets: a few targets there run hot and slow, and an empty or
  fully unhealthy `usw2-az2` returns `503` for every Revyl request.
* **ALB cross-zone on (the default) trades errors for latency.** Requests are
  balanced across all zones, but many cross a zone boundary after already
  passing through two load balancers.
* **Results depend on where traffic enters.** Your other clients arrive
  through every zone, while Revyl arrives through one. A zone imbalance
  among your targets can show up as slow responses or `503`s for Revyl alone,
  while your dashboards look healthy.
* **The NLB balances connections, not requests.** It picks a path once per
  TCP connection. Long-lived keep-alive or HTTP/2 connections stay on that path
  until they close, so adding targets or fixing a zone does not move traffic
  that is already flowing. Idle connections close after the NLB's TCP idle
  timeout (350 seconds by default), and pooled clients see them as resets.

If you register service targets on the NLB directly, the whole ALB layer and
its zone behaviour drop out of the path. Do this whenever you don't need the
ALB's layer 7 routing.

## What is supported

| | Supported |
| - | - |
| Protocols | Any TCP protocol: HTTPS, HTTP, gRPC, SSH (Git), database wire protocols |
| Services per endpoint service | Multiple, one NLB listener per port |
| Endpoint services per organization | Multiple; each gets its own interface endpoint |
| Revyl workloads | All Revyl services: remote builds, cloud device sessions, tests, and Atlas |
| UDP | Not supported |

## Next steps

<CardGroup cols={2}>
  <Card title="Set up PrivateLink" icon="list-check" href="/guides/privatelink/setup">
    Step-by-step: NLB, endpoint service, and the details to send Revyl.
  </Card>

  <Card title="Verify and troubleshoot" icon="stethoscope" href="/guides/privatelink/troubleshooting">
    Confirm traffic flows, fix common problems, and offboard cleanly.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.