LanternDOCS

Deployment

Lantern splits into a control plane (scheduling, routing, dashboard) and a data plane (microVMs, execution, secrets). The data plane runs in your cloud — agent data never leaves your VPC.

In plain termsTwo halves: the control plane is the brain (dashboards, scheduling, budgets — it decides what should run), and the data plane is the muscle (where agent code actually executes, with your API keys and your data). The point of the split: you can keep the muscle inside your own cloud account, so prompts, credentials, and customer data never leave your infrastructure — while the brain is run for you as a service. Pick the mix that fits: fully managed, hybrid, or everything self-hosted.

Architecture — the CP/DP split

🏮 Lantern production runtime for AI agents · control plane orchestrates, YOUR cloud executes Go Rust your VPC WHERE AGENTS MEET PEOPLE Channels — your users' actual apps WhatsApp · iMessage · Slack · Discord · Telegram · Voice (Twilio / LiveKit) · Webchat /widget.js · Email Builders SDKs (TS · Python · Go) · lantern CLI (onboard / agents dev) · Dashboard · A2A peers surface-gateway RUST:8444 inbound webhooks · signature verification · normalization gateway RUST:8443 TLS JWT / API-key auth (hlx_live_) · rate limiting · end-to-end streaming CONTROL PLANE — ORCHESTRATION, NEVER USER CODE control-plane GO:8080 REST · :50051 gRPC agents · runs · sessions · budgets (402) · forecasts · evals · experiments · marketplace MCP registry · A2A cards · receipts · memory + people graph · auth/RBAC · RLS multi-tenancy workflow-engine GO :50052 durable steps · event-sourced journal model-router RUST :50053 · model: "auto" capability routing · 4 strategies scheduler GO tz-aware cron · loop-agent cadences memory GO people graph · distillates · pgvector notifier GO webhooks · email · Slack · push billing GO usage metering · budget rollups System of record Postgres (tenant-fenced rows) · Redis (live events) · S3 (bundles + snapshots) OUTBOUND-ONLY · TOKEN-AUTHENTICATED metadata only — prompts and data never leave your VPC DATA PLANE — YOUR CLOUD (EKS · GKE · AKS · LAPTOP) runtime-scheduler GO:50055 HA leader election · 5-factor placement: warm-pool · region · fair-share · cost · health per-tenant quota + spawn rate limits (402/429) runtime-manager RUST:50054 fail-closed isolation gate — never a bare pod: runc → gVisor → Kata → Firecracker · Wasm snapshot / restore · warm pools · per-node microVM workload · harness RUST PID 1 in-guest tool runner (shell_exec · http_fetch) deny-default egress allowlist · SO_PEERCRED secrets session-scoped VM reuse · step events → journal The invariants: no user code in the control plane · durable steps · tenant-fenced rows · isolation fails closed
The full system: channels → gateways → control plane → your data plane. The control plane never runs user code.
Your cloud runs the code. Ours never sees it. the control plane orchestrates by metadata — prompts, data, and code stay in your VPC CONTROL PLANE — MANAGED SAAS 1 · Authenticate JWT / API key (hlx_live_) · RBAC tenant_id stamped on every row, span, and gRPC call · RLS policies 2 · Budget + quota forecast → hard-fail limits → 402 per-tenant VM quota + spawn rate limits (402/429) 3 · Mint identity Ed25519 per-instance identity at spawn · short-TTL secret refs — values resolve only at execution 4 · Dispatch gRPC to the data plane, service- token authenticated · W3C trace context rides the whole way down also here: workflow engine · model router · memory · evals · marketplace · notifier Postgres · Redis · S3 — stores metadata, costs, and journals, never your data THE TRUST BOUNDARY — TOKEN-AUTHENTICATED, METADATA ONLY ↓ specs, identity, trace context · ↑ heartbeats, step events, audit — mTLS hardening planned DATA PLANE — YOUR VPC (EKS · GKE · AKS · A LAPTOP) runtime-scheduler GO:50055 HA leader election · 5-factor placement: warm-pool · region · fair-share · cost · health picks the node, hands the spec to that node's manager runtime-manager RUST:50054 fail-closed isolation gate — never a bare pod: runc → gVisor → Kata → Firecracker · Wasm snapshot / restore · warm pools · hardened K8s Jobs workload VM + harness RUST, PID 1 deny-default egress allowlist proxy (:3128) kernel-attested secret vends (SO_PEERCRED) in-guest tool runner · session-scoped VM reuse reports bound to the VM's OWN run — forgery → 403 your LLM keys, your prompts, your customer data, your code — all of it executes and stays here WHAT COMES BACK UP step events → journal → run waterfall + traces → a signed receipt anyone can verify
What crosses the boundary: specs, identity, and trace context go down; heartbeats, step events, and audit come back. Token-authenticated (mTLS hardening planned) — prompts and data never leave your VPC.

Deployment options

Fully managed (Lantern Cloud)

Both planes hosted by Lantern. No infrastructure to manage. Sign up at lantern.run, create agents from the dashboard, everything runs on Lantern infrastructure.

Best for: getting started and workloads without strict data residency requirements.

Hybrid (recommended for production)

Control plane hosted by Lantern; data plane in your cloud. Agent data stays in your VPC.

  1. Deploy the data plane Helm chart into your cluster (see below).
  2. Register via POST /v1/data-planes or Settings → Data Planes. This mints a one-time 32-byte bootstrap token — store it immediately.
  3. The data plane dials out to :50051 (gRPC), sends the bootstrap token via Register RPC, and receives a short-lived session JWT (1 h TTL, auto-rotated via RefreshToken).
  4. The data plane opens a persistent RunStream bidi RPC. The control plane pushes run assignments; the agent reports status and completion back. Only run metadata crosses the boundary.

Tunnel RPCs

Defined in packages/proto/lantern/v1/dataplane.proto, served on the control plane's :50051 listener.

RPCDirectionPurpose
Registeragent → CPExchange bootstrap token for session JWT
Heartbeatagent → CPLiveness (every 30 s); learns drain orders
ReportMetricsagent → CPCPU / memory / active-run pressure (every 60 s)
RefreshTokenagent → CPRotate session JWT before 1 h expiry
RunStream (bidi)agent ↔ CPCP pushes assignments; agent reports accepted / completed
Per-tenant cap: up to LANTERN_DP_MAX_STREAMS_PER_TENANT concurrent RunStream connections (default 10). Excess connections return gRPC RESOURCE_EXHAUSTED.

Fully self-hosted

Both planes in your infrastructure. Full control, full responsibility.

Operational overhead: you manage Postgres, Redis, and Kubernetes. Ensure your team has the capacity before choosing this path.

Helm

# Data plane only (hybrid mode — control plane at your self-hosted URL)
helm install lantern-data-plane ./charts/data-plane \
  --namespace lantern --create-namespace \
  --set controlPlane.endpoint=http://your-control-plane:8080 \
  --set controlPlane.token=$LANTERN_DATA_PLANE_TOKEN \
  --set firecracker.enabled=true

# Full self-hosted stack
helm install lantern ./charts/lantern \
  --namespace lantern --create-namespace \
  --values values.yaml
# values.yaml
controlPlane:
  replicas: 3
  database:
    host: your-postgres-host
    name: lantern
    user: lantern
    passwordSecret: lantern-db-credentials
  redis:
    host: your-redis-host

dataPlane:
  firecracker:
    enabled: true
    snapshotBucket: s3://your-bucket/snapshots
  resources:
    limits:
      cpu: "4"
      memory: "8Gi"

ingress:
  enabled: true
  host: lantern.yourcompany.com
  tls:
    enabled: true

Terraform

Terraform modules for EKS, GKE, and AKS are generated by lantern infra install — they are not yet published to the Terraform Registry. Run the CLI command to generate the config, review the output, then terraform apply.

lantern infra install   # generates terraform/ in the current directory
cd terraform
terraform init
terraform plan
terraform apply

Namespace isolation

Each tenant gets its own Kubernetes namespace: lantern-t-<tenant_id>. Provides network isolation, per-tenant resource quotas, and separate service accounts and secrets.

Monitoring

Every service emits OTel traces tagged with tenant_id, run_id, step_id, and agent_version. Compatible with Grafana + Tempo, Datadog, New Relic, Jaeger, and any OTel backend. Production alert rules, Grafana dashboards, and runbooks live in infra/monitoring/ and docs/runbooks/. See Observability for details.

Database migrations

The control plane manages its Postgres schema via golang-migrate. Migrations are embedded SQL shipped inside the binary.

  • Fresh databases — migration 0001 creates the full schema on first boot.
  • Existing databases0001 is fully IF NOT EXISTS; running it records version 1 in schema_migrations with no DDL changes.
  • New changes — sequential pairs (0002_*.up.sql / 0002_*.down.sql). Down migrations required after the baseline.
Only the control plane runs migrations. Other services read and write tables but never apply schema changes.