Docs

Control plane ⇄ Data plane

When customer data must stay in the customer's environment, a common design splits the product in two: a shared control plane hosted in your cloud, and a data plane that stores and processes customer data in their environment. Only the data plane runs there; the rest of your product keeps running as SaaS.

Architecture diagram. Control plane manages 2 remote environments: Data plane (customer-1 only), https, outbound; Data plane (customer-2 only), https, outbound.

The data plane connects out to the control plane. The control plane never connects in.

Metadata and customer data

The split rests on the difference between the data your product runs on and the data it exists to hold:

  • Metadata: who the customers are, their plans, seats, and settings, which version they run, and whether it's healthy. Sign-in, billing, analytics, releases, and monitoring all run on metadata.
  • Customer data: what your product exists to store and process. The rows in a database product, the documents in a docs product, the messages in a chat product.

A metadata leak is bad. A customer data leak is far worse. Only customer data needs to be isolated, so only the code that touches it needs to move.

When it fits

  • It fits when the buyer says "our content can't leave our account", and your product can separate the code that touches content from sign-in, billing, and the UI.
  • It's more than you need when the customer only wants to revoke access, keep prompts under their AI agreement, or store files in their account. Customer-managed keys, local AI models, and customer buckets meet those requirements with nothing of yours in their account.
  • It's the wrong split when the requirement is about reaching a private system. See Agent or connector.
  • It's less than they asked for when the buyer requires every component in their environment. See Whole product, and ask first which part of the requirement is about the data.

The two planes

The control plane runs in your cloud and handles everything shared across customers: sign-in, billing, analytics, the admin UI, and monitoring. It stores only metadata, and keeps using your usual SaaS services, such as your auth provider and Stripe.

The data plane runs the code that touches customer data, and stores that data: the database, the files, the credentials. Each customer gets their own, in their cloud account, on their servers, or in a dedicated account in your cloud.

Nothing outside connects into the data plane unless you declare an endpoint, and an endpoint can stay on the customer's private network. The data plane reaches your control plane over outbound HTTPS.

Like on-prem, a data plane can only be reached from the customer's side. Unlike on-prem, it stays connected to you, so you can still update and operate it.

The data plane is usually a service that owns the content or a processing pipeline:

  • A service that owns the content. Your product is an API over customer content, such as documents or records. Accounts, routing, and billing stay hosted. The routes that read and write content move to the customer, with the storage and search index they use. Move the content and what's derived from it, not everything near it: "add search" shouldn't turn into "move the database".
  • A processing pipeline. Customers upload files you parse or index. The upload target, queue, and workers run in their account. The browser uploads straight to their storage with a signed URL. Your backend sees job status and counts.

A data plane for a processing pipeline declares the storage, the queue, and the Worker that reads them:

alien.ts
import * as alien from "@alienplatform/core"

const files = new alien.Storage("files").build()
const jobs = new alien.Queue("jobs").build()

const processor = new alien.Worker("processor")
  .code({ type: "source", src: "./", toolchain: { type: "typescript" } })
  .commandsEnabled(true)
  .link(files)
  .link(jobs)
  .build()

Smallest to run, or smallest to build

The smallest data plane to run is not always the smallest to build. A data plane with no database can mean rewriting most of your backend.

If metadata and content share one service and one database, a practical first step deploys your existing backend, with its database, as the data plane. Sign-in, billing, and routing stay hosted. The data plane then shrinks one table at a time, as you separate metadata from content.

Where the data plane runs

Where a data plane runs is a separate choice from what you split. The same alien.ts and the same release deploy to each of these:

WhereGuide
Shared in your cloud, one per regionSingle-tenant in your cloud (the same stack backs shared deployments)
Dedicated to one customer, in your cloudSingle-tenant in your cloud
The customer's cloud accountAWS, Google Cloud, Azure
The customer's Kubernetes clusterKubernetes
The customer's machinesLinux servers
An air-gapped siteAir-gapped

A data plane can start in your cloud and move later. Moving a customer changes where their data lives, not the architecture. See Push, pull, and air-gapped for how releases reach each one.

In a shared data plane, scope every request, storage key, and cache entry by customer, because the cloud's permissions cover all customers in that deployment.

What this gets you

  • No open ports by default. A data plane accepts no connections from the internet unless you declare a public endpoint. An attacker can't scan for it or send it an exploit.
  • A break-in reaches one customer. Each data plane has its own data and its own credentials.
  • Less to secure. The only shared part is the control plane, which is smaller than your whole product.
  • The shared part holds only metadata. Breaking into it reveals who your customers are, not their data.

What goes where

Go through your product component by component. For each one, ask: does it need to be next to the customer's data, a private system, or special hardware? If not, it stays in the control plane.

ComponentUsually goes inWhy
Sign-in, SSO, user managementControl planeShared across customers; metadata
Billing, plans, usage meteringControl planeMetadata. Send usage counts, not content.
Web UIControl planeThe browser can call the data plane directly for content
Admin dashboards, analyticsControl planeBuilt on metadata and aggregate counts
Release and rollout logicControl plane (Alien)Alien runs this for you
Database of customer recordsData planeCustomer data
Uploaded files, documents, message bodiesData planeCustomer data
Search indexes and caches over customer dataData planeDerived from customer data, so they are customer data
Workers that read or transform customer dataData planeThey need the data in memory
Connectors to the customer's internal systemsData planeOnly reachable from inside their network
AI calls with customer content in the promptData plane, or the customer's model providerSee Local AI models

What counts as metadata is the customer's call, not yours. A security review can decide that email addresses or file names are content. Ask early, and go field by field with Classify your data.

What the control plane knows

The control plane can know that work exists, who started it, its status, and its timing. It can't know what the work says.

Keep reports from the data plane to fixed fields: status codes, counts, sizes, durations, versions. Never send free text or raw error messages, which can quote content.

Even IDs and timing say something. Moving them to your cloud reveals who uses your product, how much, and when. Say so in the security review instead of calling it "no data".

Rules that keep the split honest

  1. Content never passes through the control plane. If a request carries customer data, it goes straight to the data plane. The browser can call the data plane directly with a short-lived token from your control plane. See Browser to the deployment.
  2. Fail closed. When the data plane is down, return an error. Never fall back to processing that customer's data in your cloud.
  3. Send counts, not content. Usage, health, and status flow back to the control plane. The data itself doesn't.
  4. One base URL for users. Users shouldn't have to know which plane they're talking to. Route behind one domain or one SDK.
  5. Keep the data plane small. Every component you move is one more thing in every customer environment. Move only what has to be there.

Paths that leak

Content reaches the control plane through side paths more often than through the main API. Check each one:

PathWhat can leakFix
LogsA log line that includes a request body moves that body. Deployment logs go to the Alien manager, the server that tracks your deployments.Log IDs and categories. Redact, or turn telemetry off for the deployment.
Error messages and tracesExceptions and provider errors often quote the inputSend an error category and an ID. Keep the message in the data plane.
Command resultsA command that returns database rows moves those rowsReturn the summary your product needs
Webhooks, events, realtimePayloads copied from contentSend IDs. The consumer fetches content from the data plane.
AnalyticsEvent properties such as titles, search terms, or filenamesSend counts and fixed properties
Support toolingScreenshots, exports, and admin views of customer recordsDebug inside the environment with Remote Operator, under approved, time-boxed access

Updates and operations

The customer's admin runs initial setup once: the one-time step that creates the data plane in their account. After that comes ongoing management: alien release reaches every data plane without the admin.

You roll out, pin, and roll back per customer. See Push, pull, and air-gapped.

Your control plane calls functions in the data plane with commands, and reads or writes its resources with remote bindings. The data plane reports to your API over outbound HTTPS. See Connect your backend.

When something breaks, Remote Operator, an outbound-only container next to your code, runs approved operations inside the environment.

When your control plane is down

The data plane keeps running, and so does anything that doesn't need you:

  • Users with a token keep working. A short-lived token issued before the outage stays valid until it expires. The token's lifetime is the usual answer to "what happens when you're down".
  • Sign-in and token refresh need you. New sessions wait until the control plane is back.
  • Background work keeps running. Jobs in the data plane use the deployment's own credentials, never a user's session, so a schedule or a queue doesn't stop when your sign-in does.

Example

GitHub integration keeps the dashboard hosted and runs the credentialed agent in each customer's account.

More data planes are in the examples: an AI trace store and a vector database on the customer's bucket, and a chat app over a private Postgres.

Next

On this page