# Reach the platform privately

> Reach the platform from a VPC with no internet route through an AWS PrivateLink interface endpoint that the AWS setup creates for you.

_How-to · Updated 2026-10-28 · Describes release 0.1.165_

Code that runs in your AWS account — the automation Lambda, a private-network agent, your own scripts — normally reaches this platform over the internet. With AWS PrivateLink it reaches it through an **interface endpoint** in your own subnets instead: the traffic never leaves the AWS network, and the subnet needs no internet gateway, NAT or proxy. The platform publishes an endpoint service; your AWS setup run creates the endpoint and a security group for it.

The path, end to end: your subnet → the interface endpoint → AWS PrivateLink → the platform's internal Network Load Balancer → the platform's load balancer. TLS still ends on the platform's own certificate, so a client verifies the same host name it would verify on the internet.

## Before you start {#before-you-start}

- Ask platform staff to allow your AWS account on the platform endpoint service, and to give you its **service name** (`com.amazonaws.vpce.<region>.vpce-svc-…`). Until they do, the endpoint service is invisible to your account and the setup stops before any change.
- Pick the VPC and one private subnet per Availability Zone. Each subnet must sit in an Availability Zone the service offers; the setup compares AWS Availability Zone IDs (such as `apse1-az1`), because zone names map to different physical zones in different accounts.
- The endpoint is in the platform's Region. Run the setup in that Region.
- You need the same AWS rights as the [AWS setup](/help/setup-aws.md) itself, plus, in that VPC: `ec2:CreateVpcEndpoint`, `ec2:ModifyVpcEndpoint` (a later run turns private DNS on), security-group creation, and `ec2:CreateTags` — the setup tags both resources, and AWS's [Service Authorization Reference](https://docs.aws.amazon.com/service-authorization/latest/reference/list_ec2.html) lists `ec2:CreateTags` with `CreateVpcEndpoint`. For private DNS, also `route53:AssociateVPCWithHostedZone` for that VPC: AWS associates a private hosted zone with it ([Manage DNS names](https://docs.aws.amazon.com/vpc/latest/privatelink/manage-dns-names.html)).

## 1. Run the AWS setup with the endpoint inputs {#run-the-setup}

In CloudShell, before you paste the setup command from [AWS setup](/help/setup-aws.md), set three variables:

```sh
export AIOPS_PRIVATELINK_SERVICE_NAME=com.amazonaws.vpce.ap-southeast-1.vpce-svc-0123456789abcdef0
export AIOPS_PRIVATELINK_VPC_ID=vpc-0123456789abcdef0
export AIOPS_PRIVATELINK_SUBNET_IDS=subnet-0123456789abcdef0,subnet-0123456789abcdef1
```

All three or none: one alone is refused before the first AWS call. The setup then reads, without changing anything, the service (is it visible to this account?), the VPC (its primary CIDR) and the subnets (in that VPC, one per zone, in the service's zones). The same reviewed CloudFormation change set that carries the connection roles now also carries two resources, and nothing else is accepted:

- a security group that allows HTTPS (TCP 443) **only from the VPC's primary CIDR** and allows no outbound traffic;
- the interface endpoint, in your subnets, with that security group.

Run the setup with the same three values every time afterwards. The setup refuses a change set that deletes or replaces anything, and the setup command the portal gives you does not carry these variables: run without them on a stack that has the endpoint, the setup stops before planning anything and prints the three `export` lines to paste. To remove the endpoint, delete it from the stack in the CloudFormation console after reviewing the change.

**You should see** a line before the final JSON: `Platform endpoint vpce-…: waits for platform staff to accept it`. The final JSON is unchanged — paste it as usual.

## 2. Wait for the acceptance {#acceptance}

The endpoint service requires acceptance: your endpoint stays *pending acceptance* until a person on the platform side checks the requesting account and accepts it. Allowing your account only lets you ask. In the VPC console the endpoint's status turns *Available* once accepted. Then run the setup again with the same three values: that run turns private DNS on (next section).

## 3. Use the platform host name {#host-name}

**Private DNS on.** The setup never creates the endpoint with private DNS on: the endpoint service requires acceptance, so the first run creates it off and says `Private DNS: off until platform staff accept the endpoint.` Once the endpoint is *Available*, run the setup again with the same three values. That run turns private DNS on — a change to the endpoint, not a new one — when the platform's private DNS name is verified and your VPC has DNS resolution and DNS hostnames turned on, and says `Platform endpoint vpce-…: accepted. Private DNS on`. Inside the VPC the platform's usual host name then resolves to the endpoint's addresses: keep the platform URL exactly as it is, with no DNS work on your side. Those answers come from the VPC's Amazon-provided resolver; a VPC whose DHCP options send queries to your own DNS servers sees them only if those servers forward to it.

**Private DNS off.** Until then — or when the name or the VPC settings are missing — the setup says why (`Private DNS: off …`) and prints the endpoint's own DNS name as `AIOPS_PLATFORM_ENDPOINT_DNS=vpce-….vpce.amazonaws.com`. A client then connects to that name but still asks for the platform host in TLS (SNI) and in the HTTP `Host` header — the certificate never names the endpoint. The workspace automation the setup installs does not read that name: it reaches the platform only once private DNS is on, so wait for the acceptance and run the setup again. A client of your own can dial the name. By hand:

```sh
curl --connect-to aiops.example.com:443:vpce-0123456789abcdef0-abcd1234.vpce-svc-0123456789abcdef0.ap-southeast-1.vpce.amazonaws.com:443 \
  https://aiops.example.com/healthz
```

**You should see** HTTP 200 from a subnet with no internet route.

## The private-network agent over the endpoint {#agent}

A [private-network agent](/help/private-access.md) in the same VPC polls the platform through the endpoint too: it only ever dials out to the platform URL over HTTPS. An agent in a peered or transit-gateway network needs two more things: the endpoint's security group must allow its CIDR (the setup allows only this VPC's primary CIDR — see [Access control](#endpoint-policy)), and, with private DNS on, its DNS queries must reach this VPC's resolver.

- **Private DNS on:** nothing changes. Install the agent with the usual platform URL; its connections resolve to the endpoint.
- **Private DNS off:** the agent has no endpoint-name setting. Map the platform host to the endpoint's addresses in the agent's own host table instead, so TLS still verifies the platform's certificate. Read the addresses with `aws ec2 describe-network-interfaces --filters Name=vpc-endpoint-id,Values=<vpce-id> --query 'NetworkInterfaces[].PrivateIpAddress'`, then add one entry per address: on Kubernetes the chart value `hostAliases` (`- ip: 10.0.1.25` / `hostnames: [aiops.example.com]`), on Docker `--add-host aiops.example.com:10.0.1.25`. AWS states that an endpoint network interface keeps its IP addresses for the lifetime of the endpoint ([PrivateLink guide, subnets and Availability Zones](https://docs.aws.amazon.com/vpc/latest/privatelink/privatelink-access-aws-services.html#aws-service-subnets-zones)); an endpoint you delete and create again has new ones.

The agent's other traffic — its model gateway, its image registry and the systems it reads — does not use this endpoint. Each of those needs its own route from the agent's network (for AWS services, their own interface endpoints).

## Cloud health over a private network {#cloud-health}

The *Check cloud health* triage step and the built-in detection's provider-health rule read AWS Health from where the platform runs — the platform itself, never a private-network agent — through your read connection's role. What each source needs when that network has no internet route (checked on 26 October 2026):

| Source | What it is | Without internet |
|---|---|---|
| AWS Health API | `health.us-east-1.amazonaws.com`, signed in `us-east-1`; needs a Business, Enterprise On-Ramp or Enterprise support plan ([AWS Health API](https://docs.aws.amazon.com/health/latest/ug/health-api.html)) | Works through an interface endpoint for AWS Health. AWS's endpoint-service catalogue offers `com.amazonaws.us-east-1.health` (and `com.amazonaws.us-east-2.health`), with private DNS names that include `health.us-east-1.amazonaws.com` and `global.health.amazonaws.com`, and from Asia Pacific (Singapore) as a cross-Region endpoint — there is no Singapore one. The PrivateLink guide's lists of [services](https://docs.aws.amazon.com/vpc/latest/privatelink/aws-services-privatelink-support.html) and [cross-Region services](https://docs.aws.amazon.com/vpc/latest/privatelink/aws-services-cross-region-privatelink-support.html) did not name AWS Health on that date, so confirm in your account before you rely on it (command below). The role's STS call needs its own endpoint too. |
| Public AWS Health Dashboard | the fallback without a support plan: `health.aws.amazon.com`, a public website, not account-specific | Does not work: it has no VPC endpoint. It needs internet egress (NAT or a proxy). |

```sh
aws ec2 describe-vpc-endpoint-services --region ap-southeast-1 --service-regions us-east-1 \
  --service-names com.amazonaws.us-east-1.health \
  --query 'ServiceDetails[0].[ServiceName,PrivateDnsNames[].PrivateDnsName]'
```

A cross-Region endpoint needs the `vpce:AllowMultiRegion` permission for whoever creates it and the Regional DNS name, not a zonal one ([cross-Region endpoints](https://docs.aws.amazon.com/vpc/latest/privatelink/aws-services-cross-region-privatelink-support.html)). When neither source answers, the step reads *not available* and its detail starts with `no answer from the AWS Health API` or `no answer from the public AWS Health Dashboard`, followed by what that read needs; the analysis goes on without it.

## Access control: no endpoint policy {#endpoint-policy}

An interface endpoint to an endpoint service that is not an AWS service takes no endpoint policy: AWS allows full access through it ([AWS PrivateLink guide, endpoint policies](https://docs.aws.amazon.com/vpc/latest/privatelink/vpc-endpoints-access.html)). So the setup sets none. Access is controlled by:

- the platform side: which accounts or roles may ask (allowed principals) and a person's acceptance of each endpoint;
- your side: the endpoint's security group, HTTPS from your VPC's primary CIDR only. Add other sources yourself if callers in a secondary CIDR or a peered network need it;
- the platform itself: every request still needs its token, exactly as over the internet.

The platform sees the connection coming from its own load balancer's private addresses, not from your client's address.

## Cost {#cost}

An estimate from the AWS price list for Asia Pacific (Singapore), read on 26 October 2026 — check your Region's price list: an interface endpoint is billed per hour in each Availability Zone it uses, USD 0.013 per AZ-hour, so about USD 19 a month for two zones, plus USD 0.01 per GB it processes. The platform side's load balancer is the platform's cost, not yours.

## Next steps {#next-steps}

- Once the endpoint is accepted, run the setup again so private DNS turns on: the workspace automation then reaches the platform URL as it is.
- [Connect a private network](/help/private-access.md) — the private-network agent can use the same endpoint.
