Skip to documentation
OrbitMeshDocs
Browse documentation
Docs/Engineering Specs

ENGINEERING SPECS

Control Plane Deployment Specification

This document defines the production deployment contract for api.orbitmesh.dev.
View source

1. Goal

This document defines the production deployment contract for api.orbitmesh.dev.

The Control Plane is a Go Kratos service and should run as a containerized backend service. It should not be deployed to Cloudflare Workers.

2. Deployment Shape

Production:

console.orbitmesh.dev    Cloudflare Pages Tenant Console
platform.orbitmesh.dev   Cloudflare Pages Platform Console
install.orbitmesh.dev    Cloudflare Workers installer entrypoint
downloads.orbitmesh.dev  object storage or CDN artifact prefix
api.orbitmesh.dev        containerized Go Kratos Control Plane

Supported Control Plane runtime targets:

  • Cloud Run.
  • Fly.io.
  • Railway.
  • Render.
  • VPS with Docker Compose or systemd.

The first production deployment may use any container platform that provides HTTPS ingress, environment variables, logs, and restart management.

3. Container Image

Production Control Plane images are built and published by:

.github/workflows/release-control-plane.yml

The workflow follows the same mkctr pattern as other OrbitMesh services:

builder: orbitmesh/mkctr:1.24.7-alpine
base:    orbitmesh/alpine-base:3.22
image:   ghcr.io/orbitmesh-official/orbitmesh-api

The repository still keeps a Dockerfile for local, compatibility, and manual builds:

services/control-plane/Dockerfile

The image contains:

  • orbitmesh-api
  • default config directory at /etc/orbitmesh/control-plane

Default process:

/app/orbitmesh-api -conf /etc/orbitmesh/control-plane

Exposed ports:

8080 HTTP
9000 gRPC

Production public ingress should expose only HTTP port 8080 unless gRPC is intentionally enabled.

4. Required Dependencies

Required:

  • PostgreSQL by default, or MySQL 8.

Recommended:

  • Redis.

The SQL database is the source of truth. Redis is used for short-lived runtime state such as nonce, rate limit, cache, and distributed coordination. If Redis is unavailable, the deployment platform must make the limitation explicit before production traffic is enabled.

5. Environment Variables

Required production variables:

ORBITMESH_DATABASE_DRIVER=pgx
ORBITMESH_DATABASE_URL
ORBITMESH_REDIS_ADDR
ORBITMESH_PUBLIC_URL=https://api.orbitmesh.dev
ORBITMESH_JWT_SECRET
ORBITMESH_HTTP_ADDR=0.0.0.0:8080
ORBITMESH_GRPC_ADDR=0.0.0.0:9000
ORBITMESH_LOG_LEVEL=info
ORBITMESH_INSTALL_ENDPOINT_URL=https://install.orbitmesh.dev
ORBITMESH_EDGE_RUNTIME_DOWNLOAD_PREFIX=https://downloads.orbitmesh.dev/edge-runtime/latest
ORBITMESH_DEV_SEED_ENABLED=false

Optional production variables:

ORBITMESH_ACCESS_TOKEN_TTL=86400s
ORBITMESH_REDIS_PASSWORD
ORBITMESH_REDIS_URL
ORBITMESH_DEPLOYMENT_TOKEN_TTL=1800s
ORBITMESH_RUNTIME_HEARTBEAT_TIMEOUT=120s
ORBITMESH_RUNTIME_NONCE_TTL=300s
ORBITMESH_DOWNLOADS_DIR=/var/lib/orbitmesh/downloads

Production rules:

  • ORBITMESH_JWT_SECRET must be generated and stored as a platform secret.
  • ORBITMESH_DATABASE_DRIVER supports pgx, postgres, postgresql, and mysql; production defaults should use pgx unless MySQL 8 is intentionally selected.
  • ORBITMESH_DATABASE_URL must use TLS when the database is not on a private network.
  • MySQL DSNs must include parseTime=true; use charset=utf8mb4 and UTC time handling unless the deployment has a stricter standard.
  • Redis can be configured with ORBITMESH_REDIS_ADDR and ORBITMESH_REDIS_PASSWORD, or with a full ORBITMESH_REDIS_URL. If ORBITMESH_REDIS_URL is set, it takes precedence; ORBITMESH_REDIS_PASSWORD overrides the password portion of the URL when non-empty.
  • ORBITMESH_PUBLIC_URL must be the externally reachable API origin.
  • ORBITMESH_DEV_SEED_ENABLED must stay false for public production.
  • ORBITMESH_DOWNLOADS_DIR is only a local or development fallback. Production downloads should use downloads.orbitmesh.dev.

Certificate production variables, required when system certificate automation is enabled:

ORBITMESH_CERTIFICATE_SYSTEM_ENABLED=true
ORBITMESH_CERTIFICATE_SYSTEM_ENDPOINT_DOMAIN_SUFFIX=traffic.edge.orbitmesh.dev
ORBITMESH_CERTIFICATE_SYSTEM_CHALLENGE_TYPE=dns-01
ORBITMESH_CERTIFICATE_SYSTEM_DNS_PROVIDER=cloudflare
ORBITMESH_CERTIFICATE_SYSTEM_KEY_MODE=node_local_csr
ORBITMESH_CERTIFICATE_SYSTEM_RENEW_BEFORE=2592000s
ORBITMESH_CERTIFICATE_SYSTEM_RECONCILE_INTERVAL=300s
ORBITMESH_CERTIFICATE_SYSTEM_RECONCILE_BATCH_SIZE=50
ORBITMESH_ACME_DIRECTORY_URL=https://acme-v02.api.letsencrypt.org/directory
ORBITMESH_ACME_EMAIL=ops@orbitmesh.dev
ORBITMESH_ACME_ACCOUNT_KEY_REF
ORBITMESH_CLOUDFLARE_ZONE_ID
ORBITMESH_CLOUDFLARE_API_TOKEN

Certificate production checklist:

  • ORBITMESH_ACME_DIRECTORY_URL must point to the Let's Encrypt production directory before public traffic is enabled. The default config uses the staging directory.
  • ORBITMESH_ACME_EMAIL must be a monitored operations mailbox.
  • ORBITMESH_ACME_ACCOUNT_KEY_REF must point to a durable file path or file:// mounted secret path. env://VAR is supported for temporary environments. Do not store the ACME account key in the database or repository.
  • ORBITMESH_CLOUDFLARE_API_TOKEN must be stored as a platform secret and scoped to the delegated endpoint zone with only the DNS permissions required to create and remove ACME TXT records.
  • ORBITMESH_CLOUDFLARE_ZONE_ID must be the Cloudflare zone that owns ORBITMESH_CERTIFICATE_SYSTEM_ENDPOINT_DOMAIN_SUFFIX.
  • ORBITMESH_CERTIFICATE_SYSTEM_CHALLENGE_TYPE must remain dns-01; other challenge types are rejected by the current certificate usecase.
  • ORBITMESH_CERTIFICATE_SYSTEM_KEY_MODE must remain node_local_csr; endpoint private keys are generated and kept on the Edge Runtime host.
  • Edge Runtime hosts must have durable, permission-restricted state storage for /var/lib/orbitmesh/edge-runtime/certificates.
  • Certificate readiness must be verified before endpoints are included in subscription output: domain active, certificate issued, not_after beyond the renewal window, and certificate material present on the target Node.
  • The current Control Plane certificate worker creates ACME order records, waits for Node CSR submission, presents Cloudflare DNS-01 challenges, finalizes issuance, stores certificate material, and updates endpoint readiness. DNS challenge cleanup, renewal scheduling, and tenant custom-domain certificate automation remain follow-up items before public production enablement.

6. Database Migration

Ent owns target schema creation. Breaking model data migrations are explicit SQL and are not implemented as application fallback logic.

Rules:

  • CI must not connect to the production database directly.
  • do not run development seed in production.
  • cmd/migrate may remain available for local or manual operator use, but it is not the normal Kubernetes deployment path.
  • data migrations and corrections must be implemented as explicit SQL or one-off operator commands.

7. Health Checks

HTTP liveness:

GET /healthz

HTTP readiness:

GET /readyz

Expected behavior:

  • /healthz returns process liveness.
  • /readyz verifies database readiness.
  • the platform load balancer should use /readyz for traffic readiness.

8. Cloudflare DNS

api.orbitmesh.dev should point to the selected container platform origin.

Rules:

  • enable HTTPS.
  • keep CORS allowed for https://console.orbitmesh.dev and https://platform.orbitmesh.dev.
  • do not proxy gRPC through Cloudflare unless gRPC is explicitly exposed and tested.
  • keep install.orbitmesh.dev and downloads.orbitmesh.dev independent from the API origin.

9. Console Integration

Tenant Console Cloudflare Pages production environment:

NEXT_PUBLIC_ORBITMESH_API_URL=https://api.orbitmesh.dev

Platform Console Cloudflare Pages production environment:

NEXT_PUBLIC_ORBITMESH_API_URL=https://api.orbitmesh.dev

The Control Plane CORS policy must allow:

https://console.orbitmesh.dev
https://platform.orbitmesh.dev

Local development origins may remain enabled:

http://localhost:3000
http://127.0.0.1:3000

10. Release Checklist

Before making api.orbitmesh.dev public:

  1. Build and publish the Control Plane image with .github/workflows/release-control-plane.yml.
  2. Provision PostgreSQL or MySQL 8.
  3. Provision Redis or document the MVP limitation.
  4. Configure all required environment variables.
  5. Start orbitmesh-api; Ent schema creation runs during startup.
  6. Verify GET /healthz.
  7. Verify GET /readyz.
  8. Verify Console can call POST /api/v1/auth/login.
  9. Generate a deployment token from Console.
  10. Run the install command against install.orbitmesh.dev.
  11. Verify the Edge Runtime registers and becomes online.

11. Release Status Notes

Current verified production Control Plane:

version: 0.1.79
commit: 12027d2
verified_by: GET /healthz from the production pod

Release note:

  • api/v0.1.78 exists as a tag and its release workflow completed, but it did not become the verified production runtime version.
  • api/v0.1.79 is the rollback release that kept the MVP runtime usage principal format as om_sub_<subscription_id> and is the first verified production version after 0.1.77.
  • Runtime usage principal keys are internal accounting identifiers and are distinct from public subscription URL tokens, even though both currently use the om_sub_ namespace.

When recording release history, distinguish between:

  • tag pushed.
  • image built.
  • deployment triggered.
  • production pod verified by /healthz.

Only the last state means the version is considered released to production.

12. Deferred Production Hardening

These are required after MVP validation and before serious production usage:

  • Prometheus metrics endpoint and dashboard.
  • structured log shipping.
  • audit event export.
  • rate limiting backed by Redis.
  • managed secret rotation.
  • database backup and restore drill.
  • zero-downtime migration policy.
  • API container image publishing pipeline.
OrbitMesh DocumentationContent follows the repository's main branch.