How Alien Works
Alien provides infrastructure for deploying managed software into your customer's cloud. You define your application once, Alien handles provisioning, updates, and monitoring across every customer environment.
Let's walk through how it works, step by step.
One codebase, any cloud
You'll have customers on AWS, GCP, and Azure. Do you need to build separate integrations for each one?
No. With Alien, you define the infrastructure your application needs once, in a file called alien.ts:
import * as alien from "@alienplatform/core"
const data = new alien.Storage("data").build()
const secrets = new alien.Vault("credentials").build()
const api = new alien.Function("api")
.code({ type: "source", src: "./api", toolchain: { type: "typescript" } })
.link(data)
.link(secrets)
.ingress("public")
.build()
export default new alien.Stack("my-app")
.add(api, "live")
.add(data, "frozen")
.add(secrets, "frozen")
.build()Alien translates each resource to the native service at deploy time:
┏━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━┓
┃ Function ┃ ┃ Storage ┃
┗━━━━━┯━━━━━━┛ ┗━━━━━┯━━━━━━┛
│ │
├── AWS ───▶ Lambda ├── AWS ───▶ S3
├── GCP ───▶ Cloud Run ├── GCP ───▶ Google Cloud Storage
└── Azure ─▶ Container App └── Azure ─▶ Azure Blob StorageThe same applies to queues, vaults, KV stores, and networking. See Stacks for the full reference.
Notice .add(api, "live") and .add(data, "frozen"). Each resource is either frozen or live — a tradeoff between security and control:
- 🧊 Frozen: Alien can only monitor it. Created once during setup, then Alien has no permissions to modify or delete it.
- 🔁 Live: Alien can manage it from your cloud. Push code updates, roll config changes, redeploy — without the customer's involvement.
Learn more about frozen and live resources.
Your code
Because your code runs inside the customer's network, it can reach things that aren't accessible from the outside: internal wikis, private databases, on-prem APIs.
Here's an example: an API that crawls the customer's internal Confluence and caches pages in their cloud storage. An AI agent in your cloud calls this to build a knowledge base from internal docs.
import { Hono } from "hono"
import { serve, storage } from "@alienplatform/sdk"
import { chromium } from "playwright"
const app = new Hono()
const pages = storage("pages") // S3 / Cloud Storage / Blob Storage
// Crawl a page from the customer's internal wiki.
// This URL is only reachable from inside their network.
app.post("/crawl", async (c) => {
const { url } = await c.req.json()
const browser = await chromium.launch()
const page = await browser.newPage()
await page.goto(url) // e.g. https://wiki.corp.internal/page/123
const data = {
title: await page.textContent("h1"),
body: await page.textContent("#main-content"),
}
await browser.close()
// Cache in the customer's own storage
await pages.put(`${encodeURIComponent(url)}.json`, JSON.stringify(data))
return c.json(data)
})
// Retrieve a previously crawled page
app.get("/pages/:key", async (c) => {
const raw = await pages.get(c.req.param("key"))
return c.json(JSON.parse(raw))
})
serve(app)use alien_sdk::{serve, Storage};
use axum::{Router, Json, extract::Path, routing::{get, post}};
let pages = Storage::new("pages").await?; // S3 / Cloud Storage / Blob Storage
let app = Router::new()
// Crawl a page from the customer's internal wiki.
// This URL is only reachable from inside their network.
.route("/crawl", post({
let pages = pages.clone();
move |Json(req): Json<CrawlReq>| async move {
let browser = Browser::new(LaunchOptions::default())?;
let tab = browser.new_tab()?;
tab.navigate_to(&req.url)?; // e.g. https://wiki.corp.internal/page/123
let data = WikiPage {
title: tab.find_element("h1")?.get_inner_text()?,
body: tab.find_element("#main-content")?.get_inner_text()?,
};
// Cache in the customer's own storage
let key = urlencoding::encode(&req.url);
pages.put(&format!("{key}.json"), &serde_json::to_vec(&data)?).await?;
Ok::<_, Error>(Json(data))
}
}))
// Retrieve a previously crawled page
.route("/pages/:key", get({
let pages = pages.clone();
move |Path(key): Path<String>| async move {
let raw = pages.get(&key).await?;
Ok::<_, Error>(Json(serde_json::from_slice::<WikiPage>(&raw)?))
}
}));
serve(app).await?;You can also use the native cloud SDKs directly (e.g. @aws-sdk/client-s3) if you prefer. Alien injects the credentials and connection details either way. See Accessing Resources.
Build and test locally with alien dev. Alien provides local equivalents for every resource: storage on the filesystem, vaults in an embedded store, queues in memory. Same API, no cloud credentials needed. See Local Development.
The isolated area
Now that we know what we're deploying, where does it actually go inside the customer's cloud?
Their cloud account contains their own databases, services, networking, and storage. They don't want you anywhere near that.
So your application gets its own isolated area within their account. Your resources live inside it. Everything outside is off-limits.
╔═ Customer's Cloud Account ═════════════════════════════════╗
║ ║░
║ Their databases, services, networking, storage ║░
║ ║░
║ ┌─ Isolated Area (your application) ────────────────┐ ║░
║ │ │ ║░
║ │ ┏━━━━━━━━━━┓ ┏━━━━━━━━━━┓ ┏━━━━━━━━━━┓ │ ║░
║ │ ┃ Function ┃ ┃ Storage ┃ ┃ Queue ┃ │ ║░
║ │ ┗━━━━━━━━━━┛ ┗━━━━━━━━━━┛ ┗━━━━━━━━━━┛ │ ║░
║ │ │ ║░
║ └───────────────────────────────────────────────────┘ ║░
║ ║░
╚════════════════════════════════════════════════════════════╝░
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░What does "isolated area" mean concretely? It depends on the cloud:
- Azure: a resource group
- GCP: a dedicated project
- AWS: a set of resources that share a naming prefix (e.g.
acme-*)
See Cloud Scoping for details on each provider.
Why isolation matters
Many teams skip isolation and deploy directly into the customer's existing VPCs or shared infrastructure. This is often easier from a sales perspective, and Alien does support it to a degree.
But it usually hurts reliability. The customer's environment has its own network policies, security groups, resource quotas, and configuration quirks that you don't control. When something breaks, you can't tell if it's your code or their environment.
An isolated area means you control the environment your software runs in. You define the networking, the IAM policies, the resource configuration. The customer controls the boundary. This is the setup that scales to hundreds of customers without each one becoming a unique snowflake.
Your application can also connect to the customer's existing resources (a database, an internal API, a secret store) if they choose to allow it.
Ongoing management
Now that we know what we're deploying and where it goes: how do you manage it?
With traditional self-hosting, you hand the customer a Docker image or Helm chart. They run it themselves. Your code is in their cloud, but:
- Every customer runs a different version
- You have no logs, no metrics, no visibility
- When something breaks, you schedule a call or wait days for a partial log dump
- You can't push a fix without asking them to re-deploy manually
With Alien, the customer shares access to the isolated area with your account. Think of sharing a Google Drive folder: they share a specific folder, you can manage what's inside, they can revoke access at any time.
Not every customer will agree to share cross-account access. For those cases, there's an agent-based alternative that doesn't require it.
Within the shared area, what you can do is limited:
- Can: update application code, monitor health, collect telemetry (sent outbound via OpenTelemetry)
- Cannot: create or delete infrastructure, read customer data, access anything outside the area
Alien automatically derives least-privilege permissions from your stack definition. The customer's security team only needs to review what's actually required.
The Alien Server
You run the Alien Server on your own infrastructure. It's the control plane that manages all customer deployments from one place.
alien serveSee Self-Hosting for setup.
╔═ Customer's Cloud ══════════════════╗
║ ║░
║ Their databases, services, infra ║░
║ ║░
╔═ Alien Server ══════════╗ ║ ┌─ Isolated Area ──────────────┐ ║░
║ ║ cloud APIs ║ │ │ ║░
║ Push updates ───────╬───────────────────╬─▶│ ┏━━━━━━━━━━┓ │ ║░
║ Collect telemetry ◀────╬───────────────────╬──│ ┃ Function ┃ │ ║░
║ Run commands ───────╬───────────────────╬─▶│ ┗━━━━━━━━━━┛ │ ║░
║ ║ ║ │ ┏━━━━━━━━━━┓ │ ║░
║ ║ ║ │ ┃ Storage ┃ │ ║░
╚═════════════════════════╝ ║ │ ┗━━━━━━━━━━┛ │ ║░
║ └──────────────────────────────┘ ║░
║ ║░
╚═════════════════════════════════════╝░
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░The Alien Server manages resources by calling cloud provider APIs (e.g. UpdateFunctionCode on AWS). No network connection to the customer's environment is needed.
How access works
Every cloud provider has a built-in mechanism for granting scoped access:
- Azure: managed identity
- GCP: service account impersonation
- AWS: cross-account IAM role
No passwords or keys are exchanged. The cloud provider handles the trust.
See Impersonation for details.
This is the push model. It's the default for AWS, GCP, and Azure.
The agent alternative
Some security teams won't allow cross-account access at all. They don't want any external identity in their cloud, even a scoped one.
For those environments, a lightweight agent runs inside the customer's isolated area. It connects outbound to the Alien Server, fetches releases, and deploys them locally.
╔═ Customer's Cloud ══════════════════╗
║ ║░
║ Their databases, services, infra ║░
║ ║░
╔═ Alien Server ══════════╗ HTTPS ║ ┌─ Isolated Area ──────────────┐ ║░
║ ║ (outbound) ║ │ │ ║░
║ Fetch releases ◀──────╬───────────────────╬──│─── ┏━━━━━━━━━┓ │ ║░
║ Send telemetry ◀──────╬───────────────────╬──│─── ┃ Agent ┃ │ ║░
║ Fetch commands ◀──────╬───────────────────╬──│─── ┗━━━━━━━━━┛ │ ║░
║ ║ ║ │ ┏━━━━━━━━━━┓ │ ║░
║ ║ ║ │ ┃ Function ┃ │ ║░
╚═════════════════════════╝ ║ │ ┗━━━━━━━━━━┛ │ ║░
║ │ ┏━━━━━━━━━━┓ │ ║░
No cross-account access. ║ │ ┃ Storage ┃ │ ║░
No inbound ports. ║ │ ┗━━━━━━━━━━┛ │ ║░
║ └──────────────────────────────┘ ║░
║ ║░
╚═════════════════════════════════════╝░
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░The Alien Server never touches the customer's cloud directly. The agent deploys using its own local credentials.
This is the pull model, used for on-prem or stricter security teams.
Both models give you the same capabilities. Use push when possible. See Deployment Models.
Initial setup
Before the Alien Server can manage anything, the infrastructure needs to exist. That happens once.
The customer's admin runs a setup command using their own cloud credentials:
alien-deploy up --token ax_dg_abc123... --platform awsThis creates everything inside the isolated area:
- Storage buckets, database tables, queues, networking
- The service identity that the Alien Server will use for ongoing management
- The initial deployment of your code
The admin needs elevated permissions because they're creating resources that don't exist yet.
After setup, the admin is done. The Alien Server takes over with auto-derived least-privilege permissions — it can only monitor 🧊 frozen resources, and can remotely manage 🔁 live resources (push code, roll config, redeploy).
Releases
alien releaseEvery active deployment picks up the new version:
- Push mode: the Alien Server swaps live resources immediately
- Pull mode: the agent picks it up on its next poll (~30 seconds)
One command. Every customer updated. No coordination.
After deployment
Once deployed, you have full visibility and control through the Alien Server.
Telemetry
Logs, metrics, and traces flow back from every customer environment. Debug issues without asking the customer to send you anything.
Remote commands
Invoke code inside the customer's VPC. The command travels through the Alien Server. No inbound ports, no VPN:
// Runs inside the customer's environment
command("get-user-count", async () => {
const pool = new Pool(await getCredentials())
return pool.query("SELECT count(*) FROM users")
})alien commands invoke \
--deployment acme-corp \
--command query \
--params '{}'This is how AI agents execute tool calls, data connectors run queries, and security scanners report results.
See Remote Commands.
Events
React to things happening inside the customer's environment:
onQueueMessage("tasks", async (msg) => {
// A message arrived in the customer's queue
})
onStorageEvent("uploads", async (event) => {
// A file was uploaded to the customer's bucket
})
onCronTrigger("nightly", async () => {
// Runs on schedule
})See Events & Triggers.