Networking and endpoints
A public endpoint gives a Worker or Container in a deployment a hostname that users and other systems can reach, declared with .publicEndpoint(). A deployment needs no inbound access for anything else: releases and commands arrive through cloud APIs or an outbound connection.
In the running example, an api Worker hands out signed upload URLs, so the customer's browser uploads documents straight into their bucket:
const api = new alien.Worker("api")
.code({ type: "source", src: "./api", toolchain: { type: "typescript" } })
.publicEndpoint("api")
.readinessProbe({ method: "GET", path: "/health" })
.link(documents)
.permissions("api")
.build()Public endpoints
The Worker serves HTTP by default-exporting an app, for example with Hono:
import { storage } from "@alienplatform/sdk"
import { Hono } from "hono"
const documents = storage("documents")
const app = new Hono()
app.get("/health", c => c.json({ ok: true }))
app.post("/uploads", async c => {
const { name } = await c.req.json<{ name: string }>()
const upload = await documents.signedUrl({ method: "PUT", path: `inbox/${name}`, expiresIn: 900 })
return c.json(upload)
})
export default appAuthenticate these requests yourself, for example with a short-lived token your backend issues and the deployment verifies. See Connect your backend.
Containers name a port and a protocol, "http" or "tcp":
const viewer = new alien.Container("viewer")
.code({ type: "image", image: "ghcr.io/acme/viewer:1.8.0" })
.cpu(1)
.memory("2Gi")
.publicEndpoint("viewer", 8080, { protocol: "http", hostLabel: "docs", wildcardSubdomains: true })
.permissions("viewer")
.build()Each deployment gets its own domain, and each endpoint is a host on it: api.<deployment-domain> by default.
- Endpoint names are lowercase DNS labels (letters, digits, and hyphens).
hostLabelchanges the label."@"serves the apex.wildcardSubdomainsalso routes*.docs.<deployment-domain>. It can't be combined with the apex.
Host labels must be unique across the stack. On AWS, Google Cloud, Azure, and Machines, alien build refuses two HTTP endpoints, on any Workers, Containers, or Daemons, that get the same label. Creating the release fails with PUBLIC_ENDPOINT_HOST_LABEL_CONFLICT; rename one endpoint or give it a different hostLabel.
Alien issues a TLS certificate per deployment, because every deployment runs in a different account. It imports the certificate into the customer's account (ACM on AWS, Certificate Manager on GCP, Key Vault on Azure), and renews and re-imports it before it expires.
A TCP endpoint goes through a network load balancer and doesn't terminate TLS, so your workload owns its protocol and encryption. Clients connect to the endpoint's hostname on the declared port.
During rollouts and deletes, a replica leaves the load balancer before it stops, and its open connections drain within the workload's stopGracePeriod.
Find an endpoint's URL
Your backend reads resolved URLs from Alien rather than building them. GET /v1/deployments/{id}/info returns each resource's endpoints under resources.<resource-id>.publicEndpoints.<name>. See Deployment status.
| Field | Value |
|---|---|
url | Base URL of the endpoint |
host | Hostname only |
wildcardHost | *.<host>, when wildcardSubdomains is on |
loadBalancerEndpoint | DNS target for a custom domain's record |
Custom domains
A customer can serve an endpoint on their own domain with their own certificate. Alien never sees the private key. Set it per deployment in the stack settings, keyed by resource id:
{
"domains": {
"customDomains": {
"api": {
"domain": "docs.customer-1.example",
"certificate": { "aws": { "certificateArn": "arn:aws:acm:us-east-1:..." } }
}
}
}
}| Platform | Certificate reference |
|---|---|
| AWS | aws.certificateArn: an ACM certificate ARN |
| Google Cloud | gcp.certificateName: a Certificate Manager certificate name |
| Azure | azure.keyVaultCertificateId: a Key Vault certificate ID |
| Kubernetes | kubernetes.tlsSecretRef: an existing TLS Secret |
With the CLI, put the same settings in the deploy config and run alien deploy --config deploy.toml:
name = "production"
platform = "aws"
[domains.customDomains.api]
domain = "docs.customer-1.example"
[domains.customDomains.api.certificate.aws]
certificateArn = "arn:aws:acm:us-east-1:123456789012:certificate/..."On AWS the ACM certificate must be issued, cover the hostname, and be in the deployment's account and region. Domains are set at initial setup, the one-time step the customer's admin runs: resuming initial setup with different domain settings fails instead of changing the deployment.
Alien attaches the certificate to the load balancer but creates no DNS record. The customer points the domain at the endpoint's loadBalancerEndpoint.
In CloudFormation, set the DomainName and CertificateArn parameters instead. When the stack has more than one public HTTP resource, DomainResource picks the one that gets the hostname.
Traffic in a deployment
Every path in or out of a deployment, and where you declare it:
| Traffic | How it flows | Declared in |
|---|---|---|
| Alien manages the deployment | Cloud APIs (push) or outbound HTTPS from the Operator, Alien's agent in the environment (pull) | Nothing to declare. See Push, pull, and air-gapped |
| Your backend sends commands or reads and writes resources | Commands or remote bindings, through Alien | .commandsEnabled(true), { remoteAccess: true } |
| The deployment calls your backend | Outbound HTTPS to a URL you pass as an input | An input such as ACME_API_URL |
| Users or other systems reach the deployment | A public endpoint | .publicEndpoint() |
| One workload calls another | Private address inside the stack | .link() |
Private traffic inside the stack
Workloads reach each other without public endpoints. Link the target and read its private URL with the container() binding; see Using resources. The plan refuses some links, such as a Worker linking a Container on Google Cloud; see Platform checks.
Keep endpoints inside the customer's network
For Containers on AWS, the customer's admin can choose private endpoint access at initial setup: --endpoint-access private, or the CloudFormation EndpointAccess parameter. Endpoints then use internal load balancers, reachable only from the VPC and networks routed to it.
The choice applies to every endpoint in the deployment and can't change later; changing it takes a new deployment. Worker and Daemon endpoints, and other platforms, don't support it: initial setup fails its preflight check if a stack with Worker or Daemon endpoints asks for private.
- Pick an existing network, the VPC where the calling apps run. Internal load balancers go in its private subnets, or in the public subnets of a default VPC. Connected networks need their own peering or VPN routes.
- Routing is the only access control. Alien adds no source filtering inside routable networks.
- Hostnames still resolve in public DNS, to private IP addresses. The hostname and certificate stay the same, but an internet client can't connect. A private DNS name alone doesn't make an internet-facing endpoint private.
Private DNS
The deployment's generated domain, and any domain you delegate to Alien, is hosted in public DNS and gets certificates through a public DNS challenge. Those hostnames always resolve publicly, so a private-only domain such as corp.internal, or a Route 53 private hosted zone, can't be used for them.
To keep the hostname private too, use a custom domain. On AWS Containers, Alien never looks up or connects to a custom domain, so the customer can create its record in internal DNS or a private hosted zone.
The ACM certificate must cover the hostname and be in the deployment's AWS account and region, and clients must trust its issuer.
Network choices at initial setup
The VPC or VNet is chosen at initial setup, not in alien.ts, because it depends on each customer's account:
| Mode | Flag | Use it for |
|---|---|---|
| Auto (default) | --network auto | Creates a network only when the stack needs one, such as for Containers |
| Provider default | --network use-default | Development and tests |
| New isolated network | --network create | Production: private subnets and a NAT gateway |
| Existing network | --network byo | The customer's own VPC or VNet, with subnet flags per cloud |
use-defaulton Azure creates a VNet, because Azure has no default network.createmakes an isolated VPC with private subnets and a managed NAT gateway; VMs get private IPs only. Without--network-cidr, Alien picks a /16 that doesn't overlap the account's existing VPCs (on AWS, from100.64.0.0/10first).--availability-zonesdefaults to 2.byois available on AWS, Google Cloud, and Azure. Alien validates and stores the references but creates no network infrastructure: the customer owns routing, egress, and subnet layout. The private subnets need outbound internet access, such as a NAT gateway.
The same choices appear in the deployment portal, the setup page Alien hosts for the admin, and as setup template parameters. Details per cloud are in AWS, Google Cloud, and Azure, and every flag is in the CLI reference.
Next
- Local development: run the stack on your machine
- Connect your backend: send a browser straight to a deployment, with a token from your backend
- Network reference