---
id: platform/private-network
title: Private network
description: Connect services and datastores using their internal addresses, with workspace and environment isolation.
keywords: [bex, private network, private service, internal hostname, no ingress]
last_updated: 2026-09-23
---

Use private networking when one application needs to reach another service
without exposing that connection to the public internet. A private service
runs a network listener but has no public ingress. Web services can also have
internal addresses for service-to-service traffic.

## Which workloads have an address?

| Resource | Incoming private connection |
| --- | --- |
| Web or private service | Connect to the returned internal address and configured service port. |
| PostgreSQL or Key Value | Use the datastore's returned internal connection details. |
| Worker or cron job | No service endpoint; the process can initiate outbound connections. |
| Static site | No application process to receive private-network calls. Browser JavaScript runs on the reader's device. |

Bex's private-network scope follows workspace and environment network policies.
A resolvable hostname does not grant access across those boundaries. Do not
infer reachability from Render's region rules: the Bex instance's cluster and
isolation configuration determine the route.

## Deploy an internal API

In a [`render.yaml` Blueprint](./app-resource.md), use `type: pserv`:

```yaml
services:
  - name: internal-api
    type: pserv
    runtime: docker
    repo: https://github.com/your-org/internal-api
    branch: main
    autoDeployTrigger: off
```

Replace the repository with yours. The server should listen on `0.0.0.0:$PORT`;
Bex's default port is 3000. The addressable service exposes the configured port,
not every port declared by the image. Configure an appropriate
[health check](./health-checks.md) for an HTTP service.

## Connect a caller

Copy **Service Address** from the private service in the dashboard. API clients
can read Bex's `serviceDetails.internalAddress` field from the service response.
It is a scheme-less address such as `internal-api-ab12:3000`; add the protocol
expected by your client.

For example, from a process inside an allowed peer service:

```bash
# Set this to the actual internal address returned for your service.
INTERNAL_ADDRESS="internal-api-ab12:3000"
curl "http://$INTERNAL_ADDRESS/healthz"
```

This address is not a public URL you can open from your laptop. Do not construct
it from the display name or assume the namespace is `default`. Bex uses stable
service identities that can differ from the name you entered in a Blueprint.

For services declared together, let the Blueprint resolve the address:

```yaml
services:
  - name: frontend
    type: web
    runtime: docker
    repo: https://github.com/your-org/frontend
    envVars:
      - key: INTERNAL_API_ADDRESS
        fromService:
          name: internal-api
          type: pserv
          property: hostport
  - name: internal-api
    type: pserv
    runtime: docker
    repo: https://github.com/your-org/internal-api
```

Your frontend server reads `INTERNAL_API_ADDRESS` and supplies the protocol
when connecting. This is server-side configuration; a browser cannot reach the
cluster's private hostname. Use [PostgreSQL](./postgres.md) or
[Key Value](./key-value.md) connection references for datastores rather than
assembling credentials or Kubernetes names by hand.

## Troubleshoot connectivity

- **Name does not resolve:** verify the returned address and that the caller
  runs inside the expected Bex network. A laptop or browser has different DNS.
- **Connection refused:** inspect the target's listener host, port, ready
  instances, and logs.
- **Connection times out:** inspect workspace/environment isolation and target
  readiness. DNS resolution alone does not prove that network policy allows traffic.
- **Authentication fails:** verify application or datastore credentials. A
  private network does not replace authentication.

Public TLS provisioning does not encrypt every internal application connection.
Use the protocol and TLS settings required by the target, particularly for
managed datastores. See [Secrets](./secrets.md) for credentials and
[Logging](./logging.md) for application diagnostics.
