Cloud (SaaS / hosted) mode — showing cloud provider documentation
Enterprise cloud migration control plane

Move any cloud.
Any direction.
In control.

Monster Cloud orchestrates the complete migration lifecycle — discovery, planning, execution, data transfer, and DNS cutover — across all six major cloud providers and on-premises infrastructure.

7providers
129migration paths
108API routes
14DB migrations
174tests
On-premises migration control plane

Migrate your data centre.
No cloud required.
Fully automated.

Monster Cloud On-Prem orchestrates bare-metal and VM migrations entirely within your private infrastructure — discovery, planning, Ansible execution, data transfer, and traffic cutover — with zero cloud dependencies.

1provider (on-prem)
12migration paths
76API routes
14DB migrations
182tests
01 — Getting started

Up in four commands

Prepare environment variables, generate a signing key, start the stack, verify readiness. The default mode is preview — no cloud operations will execute until you explicitly set PROVIDER_EXECUTION_MODE=apply.

bash
# 1. Create your local env file
cp .env.example .env
perl -i -pe 's/JWT_SECRET=.*/JWT_SECRET='"$(openssl rand -hex 32)"'/' .env

# 2. Generate a stable Ed25519 signing key and paste it into .env
go run ./cmd/api --gen-key
# → ED25519_PRIVATE_KEY=<base64>

# 3. Start the API stack
docker compose up -d db redis api

# 4. Verify readiness
curl http://localhost:8080/readyz
# → {"status":"ready"}
💡
Preview mode is the safe default
Without PROVIDER_EXECUTION_MODE=apply, every provider action returns the exact CLI command it would run — nothing touches your cloud. Inspect, validate, then flip the switch.
🔑
Required env vars
DATABASE_URL JWT_SECRET ED25519_PRIVATE_KEY
All others are optional tuning knobs.
🐳
Docker Compose profiles
docker compose up -d
starts: db + redis + api

--profile temporal up
also starts the worker
📡
Health endpoints
GET /healthz — liveness
GET /readyz — readiness + DB
GET /metrics — expvar counters
GET /debug/pprof/ — Go profiles
01 — Getting started (On-Prem)

Up in four commands

On-prem mode requires Ansible ≥ 2.14 and SSH access to your target hosts. No cloud credentials needed. The same preview-first safety default applies — set PROVIDER_EXECUTION_MODE=apply only when ready.

bash
# 1. Generate a stable Ed25519 signing key
./cloudmigrator-api --gen-key
# → ED25519_PRIVATE_KEY=<base64>  — add to .env

# 2. Set required on-prem bootstrap variables
export PROVIDER=onprem
export CLOUDMIGRATOR_LICENSE_KEY=<issued-license-key>
export ADMIN_EMAIL=admin@example.com
export ADMIN_PASSWORD='change-me-long-random-password'
export DATABASE_URL=sqlite:///var/lib/cloudmigrator/cloudmigrator.db

# 3. Install without Docker or start the container stack
sudo ./install-onprem.sh
# or: docker compose up -d db redis api

# 4. Verify readiness
curl http://localhost:8080/readyz
# → {"status":"ready","provider":"onprem"}
🖥️
Ansible is the on-prem executor
All infrastructure actions are translated into ansible-playbook invocations. Monster Cloud generates the playbooks at runtime — you only need a working SSH inventory and sudo access on target hosts.
🔑
Required env vars
DATABASE_URL JWT_SECRET ED25519_PRIVATE_KEY ANSIBLE_INVENTORY
SSH key path defaults to ~/.ssh/id_ed25519.
🐳
Docker Compose profiles
docker compose up -d
starts: db + redis + api

--profile temporal up
also starts the worker
⚙️
Pre-requisites
Ansible ≥ 2.14
SSH access to all target hosts
sudo on target hosts
Python 3.8+ on targets
01b — SaaS & free tier

Accounts, tenants & plans

Sign-up flow
POST /auth/register creates a user and tenant in one call. It returns a signed JWT immediately — no email verification step.

The first 5 accounts on any deployment are automatically assigned plan=free. Subsequent registrations get plan=pending_payment. Demo credentials (demo@monstercloud.io / Demo1234!) are seeded automatically by migration 010.
JWT lifecycle
Tokens are HMAC-SHA256 signed, carry tenant_id, roles, and exp (8-hour TTL). The UI calls /auth/refresh automatically when ≤30 minutes remain. On any 401, the session is cleared and the user is redirected to signin.html. JWT_SECRET is mandatory — the server will not start without it.
02 — Core concepts

Four objects, one flow

Every migration is modelled as a chain of four objects. Understanding these unlocks the entire API.

📁
Project
The top-level container. Holds one source environment (discovered resources + dependency graph) and one or more migration plans. Multi-tenant — every project is scoped to a tenantId.
🗺️
Plan
Generated from a project's inventory. Contains an ordered list of PlannedActions (create_network, provision_database, etc.), risk scores, approval gates, and a dry-run simulation result.
⚡
Execution
A prepared-for-execution snapshot of a plan. Tracks status (ready → running → completed), action approvals, command evidence, and rollback artifacts. Immutable once completed.
📦
Evidence
Every action — infrastructure, data transfer, cutover — produces an Ed25519-signed LedgerEntry. The chain is tamper-evident; each entry hashes the previous, forming an audit log.
9action types per provider
7providers supported
129migration paths
2policy layers
0SQL injection vectors
03 — Migration workflow

Eight steps, fully automated

Each step is a discrete API call. Run them sequentially, or let the pipeline endpoint orchestrate them end-to-end.

1
Discover your source environment
Import a snapshot JSON or trigger live discovery via CLI. All six providers support snapshot import; live discovery is exposed via discovery runs. Live OnPrem discovery SSHes every host in your Ansible inventory via ansible -m setup and parses the returned facts.
POST /v1/discovery/import/aws-snapshot POST /v1/discovery/runs
2
Generate a migration plan
The planner consults the 108-entry capability matrix, resolves translations for every resource, builds a dependency-ordered action graph, scores risk, runs a dry-run simulation, and evaluates the two-layer policy engine. The response includes executionAllowed: true/false before you spend a single API call on execution.
POST /v1/migrations/plan
3
Run pre-flight validation
Before touching cloud infrastructure, preflight verifies: CLI tools are installed, credentials are valid, IAM permissions are sufficient, and service quotas are not exceeded — for all six providers. Returns a structured report with passed/warnings/errors. A 422 response means errors must be fixed before proceeding.
POST /v1/migrations/preflight
4
Prepare and approve
Prepare-execution locks the plan into an immutable execution package. Actions with translationConfidence < 0.75, IAM actions, and database provisioning are gated pending per-action approval. Approve them individually or in bulk before execution begins.
POST /v1/migrations/prepare-execution POST /v1/migrations/approve-execution
5
Execute infrastructure provisioning
Before any work begins, the executor atomically claims the execution package in Postgres using UPDATE ... WHERE status NOT IN ('running','completed','failed'). If another pod already claimed it, the request returns 400 immediately — no double-execution is possible in multi-pod environments. For each action, an idempotency check (describe-before-create) runs against the target provider. If the resource already exists, the step is marked already_exists and skipped — safe to re-run after partial failures. In apply mode, the real CLI command executes and the result is signed into the evidence ledger.
POST /v1/migrations/execute
6
Migrate data
Generate the data plan first to review every transfer command before anything runs. The engine is chosen automatically: AWS DMS for AWS targets, GCP DMS for GCP, Azure DMS for Azure, pg_dump/restore for cross-cloud Postgres, and so on. Credentials are injected at runtime from your secrets backend — never stored in logs or evidence.
POST /v1/migrations/data-plan POST /v1/migrations/data-execute
7
Execute DNS / traffic cutover
Preview the exact command first, then execute. Four strategies: full DNS swap, weighted canary shift, load balancer backend swap, or service mesh traffic split. Every cutover stores a rollbackFn — the reverse command — so you can restore in one call.
POST /v1/migrations/cutover/preview POST /v1/migrations/cutover POST /v1/migrations/cutover/rollback
8
Rollback if needed
If anything goes wrong, rollback executes real delete commands in strict reverse order. Rollback artifacts from every completed step are preserved, so the system knows exactly what to undo. Rollback is always available, even after partial execution.
POST /v1/migrations/rollback
04 — Provider support

Seven providers, Oracle assessment, nine actions each

AWS, GCP, Azure, OVHcloud, Kubernetes, and OnPrem implement the same nine action types. Oracle is handled as a specialised assessment connector for database portability. NetApp ONTAP is handled as a specialised storage connector — SVMs, volumes, LUNs, export policies, and SnapMirror relationships — across six deployment variants (on-prem, Cloud Volumes ONTAP, FSx for ONTAP, Azure NetApp Files, Google Cloud NetApp Volumes, and StorageGRID). The six generic-action executors dispatch to the native CLI — no provider SDKs in the binary; NetApp is provisioned over the ONTAP REST API instead.

☁️
AWS
aws CLI
🌐
GCP
gcloud CLI
🔷
Azure
az CLI
🌩️
OVH
openstack
⚙️
Kubernetes
kubectl · helm
🖥️
OnPrem
ansible-playbook
🗄️
NetApp
ONTAP REST API
Action types
create_network
VPC / VNet / network
create_subnetwork
Subnet / subnetwork
create_security_policy
Security group / firewall
create_bucket_and_sync
Object storage bucket
provision_compute_target
VM / instance / node
provision_database
RDS / Cloud SQL / Postgres
provision_cluster
EKS / GKE / AKS
generate_identity
IAM roles / service accounts
manual_review
Requires human gate
04 — Provider support (On-Prem)

One provider, nine actions

The on-prem executor maps every action type to an auto-generated Ansible playbook. All SSH connections use your inventory's configured key — no secrets stored in the API process.

🖥️
Bare-metal
ansible-playbook
💻
VMware vSphere
community.vmware
🔵
Proxmox
community.proxmox
Ansible action types
create_network
VLAN / bridge configuration
create_subnetwork
IP range / subnet slice
create_security_policy
iptables / nftables rules
create_bucket_and_sync
MinIO / NFS share
provision_compute_target
VM clone / bare-metal boot
provision_database
Postgres / MySQL on host
provision_cluster
k3s / kubeadm cluster
generate_identity
Linux users / SSH keys
manual_review
Requires human gate
05 — Data migration

Twelve engines, one command

The engine is chosen automatically based on the resource kind and target provider. Credentials are injected at runtime from your secrets backend — never written to logs.

Databases
aws_dms AWS target
gcp_dms GCP target
azure_dms Azure target
pg_dump Postgres cross-cloud
mysqldump MySQL / MariaDB
mongodump MongoDB
Object storage & files
s3_sync AWS buckets
gsutil GCS buckets
azcopy Azure Blob storage
rsync OnPrem filesystems
ℹ️
Credentials never logged
SOURCE_PASS, TARGET_PASS and all credential env vars are injected via cmd.Env — never written to evidence, logs, or the database.
NetApp storage replication
snapmirror ONTAP → ONTAP, block-level
xcp ONTAP ↔ non-ONTAP, file copy
bash — data migration flow
# Step 1: review the commands before anything runs
curl -X POST http://localhost:8080/v1/migrations/data-plan \
  -H "Authorization: Bearer $JWT" \
  -d '{"executionId":"exec-abc123"}'

# Step 2: inspect the generated commands in the response
# e.g. "pg_dump -h $SOURCE_HOST ... | pg_restore -h $TARGET_HOST ..."

# Step 3: set credentials and execute
export SOURCE_HOST=db.old.internal TARGET_HOST=db.new.internal
export CM_SECRETS_BACKEND=aws-secretsmanager

curl -X POST http://localhost:8080/v1/migrations/data-execute \
  -H "Authorization: Bearer $JWT" \
  -d '{"executionId":"exec-abc123"}'
06 — DNS & traffic cutover

Four strategies, always reversible

Every cutover operation generates a rollbackFn — the exact command to restore the previous state — stored in the database for instant recovery.

dns_swap
Full, immediate cutover via DNS record update. All traffic shifts at once after TTL expiry.
AWS: route53 change-resource-record-sets
GCP: gcloud dns record-sets update
Azure: az network dns record-set update
K8s: kubectl patch ingress
weighted
Canary / gradual shift. Set targetWeight: 10 for 10% canary, increment incrementally.
AWS: Route 53 weighted routing sets
GCP: Cloud Load Balancing / Traffic Director
K8s: Istio VirtualService weight split
load_balancer
Swap ALB/NLB target groups or Application Gateway backends without touching DNS.
AWS: elbv2 modify-listener
Azure: App Gateway address-pool update
service_mesh
Fine-grained per-service weight splitting via Istio or Linkerd VirtualService resources.
K8s: kubectl patch virtualservice
07 — Policy engine

Two-layer governance

Layer 1 is built-in and always enforced. Layer 2 is operator-defined JSON loaded from POLICY_RULES_FILE at startup.

json — /etc/cloudmigrator/policy.json
{
  "allowedTargetProviders": ["gcp", "aws"],
  "allowedRegions": ["us-central1", "eu-west-1"],
  "maxResourceCount": 500,
  "maxAutonomyLevel": 3,
  "blockPublicResources": true,
  "blockIamWithoutReview": true,
  "requireComplianceTags": ["cost-center", "owner"],
  "maxBlastRadius": "medium",
  "customBlockReasons": {
    "has_databases": "Open a JIRA ticket for DBA sign-off first"
  }
}
Custom rule reference
allowedTargetProviders block Migration to any provider not in this list is blocked outright.
allowedRegions review Resources in non-allowed regions require explicit review before execution.
maxResourceCount block Plans exceeding this count are blocked — split into smaller plans.
maxAutonomyLevel block Prevents operators from raising autonomy above the org-permitted ceiling.
blockPublicResources block Prevents migration of databases or buckets with publicAccess: true.
blockIamWithoutReview review Any plan touching IAM resources requires review, even if risk is low.
requireComplianceTags warn Missing required tag keys generate warnings in the policy evaluation.
maxBlastRadius block Blocks plans whose simulation blast radius exceeds low / medium / high.
customBlockReasons block Condition codes: always, has_databases, has_kubernetes, cross_region.
08 — Security model

Defence in depth

Every layer has independent controls. Compromising any one layer does not bypass the others.

🔐
Authentication
HMAC-SHA256 JWT on every request. JWT_SECRET is mandatory — the server refuses to start without it (min 32 chars). Tokens carry tenantId, actorId, and role claims. The exp claim is mandatory and enforced — tokens without an exp claim, or with an expired one, are rejected with 401. The UI calls /auth/refresh automatically when the token has ≤30 minutes remaining.
🛡️
Authorisation
RBAC checks are enforced across the protected /v1 surface, including migration, platform, billing, organisation, marketplace, growth, and evidence routes. Four roles: viewer, operator, approver, admin. Tenant isolation enforced at every store method — row-level separation.
📝
Evidence chain
Ed25519-signed ledger entry for every action. Each entry hashes the previous — a tamper-evident chain. Set ED25519_PRIVATE_KEY to the same value on every pod; generate with --gen-key.
🔏
Secrets handling
Credentials injected as process env vars via cmd.Env — never written to logs, evidence, or the database. Four backends: AWS Secrets Manager, HashiCorp Vault, Kubernetes Secrets, env vars.
🛑
Injection prevention
Zero SQL injection vectors — every query is parameterised. 4 MB request body limit. Every error response (400, 401, 403, 404, 405, 429) is application/json — never text/plain. X-Content-Type-Options, X-Frame-Options security headers. CORS gated by CORS_ORIGINS.
🚦
Rate limiting
Redis INCR/EXPIRE per-tenant distributed rate limiting. In-process per-tenant fallback when Redis is unavailable — rate limiting is never disabled, but in multi-pod deployments the effective rate per tenant multiplies by the number of pods (each pod has its own bucket). For accurate enforcement across replicas, set REDIS_URL. Tune with RATE_LIMIT_RPS and RATE_LIMIT_BURST.
09 — Durable execution

Temporal — without the SDK

The worker binary uses only the Temporal REST API. No gRPC, no SDK — it ships as a 5 MB static binary with zero new dependencies.

Without Temporal
POST /v1/migrations/execute returns 202 Accepted immediately. The execution runs in a background goroutine with context.Background() — client disconnects never cancel an in-flight migration. Poll GET /v1/executions/{id} for status. Concurrent calls to execute the same ID are blocked by an atomic Postgres claim.
With Temporal
Each migration is a durable five-phase workflow. Pod restarts, network blips, and long data transfers (24-hour timeout) are handled transparently. The worker polls Temporal Cloud via REST and calls back into the API for each phase.
bash — start the worker
export TEMPORAL_HOST=https://<ns>.<account>.tmprl.cloud
export TEMPORAL_API_KEY=<temporal-cloud-api-key>
export CLOUDMIGRATOR_API_URL=http://cloudmigrator-api:8080
export CLOUDMIGRATOR_SERVICE_TOKEN=<from-api-startup-log>
export CLOUDMIGRATOR_TENANT_ID=tenant-acme

./cloudmigrator-worker
# → cloudmigrator temporal worker host=https://... ns=default queue=cloudmigrator-executions
⚠️
Service token must survive pod restarts
The service token is auto-generated at startup if CLOUDMIGRATOR_SERVICE_TOKEN is not set, and printed to the startup log. Copy it to a Kubernetes Secret or secrets manager so the worker can authenticate across restarts.

Security note (internal service-to-service calls): Any request that uses X-Tenant-ID / X-Actor / X-Roles headers (used by the worker to act on behalf of a tenant) must also supply a matching X-Service-Token header. The API validates it with a constant-time HMAC comparison against CLOUDMIGRATOR_SERVICE_TOKEN. Requests missing or supplying an incorrect token are rejected with 401 — this prevents any external caller from spoofing tenant identity via headers.
Five-phase workflow — each phase is a retryable activity:
🔍
validatereconcile state
→
📌
checkpointanchor marker
→
⚡
execute30-min timeout
→
💾
data24-hour timeout
→
✅
verifysign chain
10 — Operations

Production systems added in v3

v3 expands the product from a migration API into a full control plane. These sections cover the systems that were missing from the earlier manual.

🧭
Platform API
The Cloud edition now exposes a second API surface in platform_api.go: drift detection, cost intelligence, compliance checks, observability, runbooks, network fabric, collaboration, and tenant operations. Count these 34 platform routes in addition to the migration API, SaaS/billing operations, growth endpoints, and public trust-anchor endpoints.
💳
Stripe billing
Billing supports three subscription tiers. Register creates the tenant/account; Stripe checkout and webhook flows provision the plan, enforce entitlements, and keep billing state synchronized.
📈
Metrics & tracing
Production observability includes Prometheus scrape metrics and OpenTelemetry tracing. Use these for API latency, workflow execution, rate-limit pressure, DB health, and migration job telemetry.
🚦
Rate limiting
Rate limits are tenant-aware and backed by Redis when configured. Tune RATE_LIMIT_RPS and RATE_LIMIT_BURST for production traffic.
☸️
Kubernetes manifests
v3 includes production Kubernetes manifests for API, workers, ingress, secrets/config maps, service accounts, readiness/liveness probes, and metrics exposure.
🔒
JWT revocation
The auth system now supports a deny-list for revoked JWTs. Use it for logout, compromised token response, forced tenant session resets, and high-risk admin actions.
🟠
Oracle assessment connector
The archive includes /v1/oracle/assess, Dockerfile.oracle, and a build-tagged godror connector. Use it to scan Oracle schemas, detect Oracle-specific SQL constructs, estimate licence exposure, and recommend Aurora PostgreSQL, AlloyDB, Azure PostgreSQL, Redshift, BigQuery, or Synapse targets.
🛡️
Independent security audit
A third-party audit found and fixed 19 issues across both trees and the Terraform provider — cross-tenant execution and read access, an on-prem auth bypass, JWT tokens accepted without an exp claim, and a SQLite driver shim that silently dropped all but the first statement in a migration. Every fix is pinned to an executable regression test, and scripts/check_tree_drift.sh now fails CI if the cloud and on-prem auth/tenancy code diverge again.
🗄️
NetApp ONTAP connector
NetApp joins the provider list as a specialised storage connector across six deployment variants — on-prem ONTAP, Cloud Volumes ONTAP, FSx for ONTAP, Azure NetApp Files, Google Cloud NetApp Volumes, and StorageGRID. Discovery runs over the ONTAP REST API; transfers use SnapMirror between ONTAP endpoints or XCP otherwise. The executor polls asynchronous ONTAP jobs to completion, refuses to auto-provision SnapLock (WORM) volumes, and only reads credentials from the environment — never from a persisted plan.
🔑
License key is mandatory
The On-Prem server will not start without CLOUDMIGRATOR_LICENSE_KEY. Put the issued key in the systemd environment file, Docker secret, or Kubernetes secret before first boot.
🗄️
SQLite default for small teams
On-Prem can run with SQLite and no Postgres dependency. Use DATABASE_URL=sqlite:///var/lib/cloudmigrator/cloudmigrator.db for small teams; move to Postgres for HA or heavy concurrency.
👤
First-run admin bootstrap
Set ADMIN_EMAIL and ADMIN_PASSWORD on first boot. The bootstrap creates the initial administrator and should be removed or rotated after setup.
⚙️
One-command installer
install-onprem.sh installs the binary, creates the service user, writes the environment file, applies migrations, and registers a systemd service for no-Docker deployments.
🛡️
Auth hardening from the security audit
The on-prem tree had the sharpest gaps: it accepted X-Tenant-ID/X-Actor/X-Roles headers with no service-token check, accepted JWTs with no exp claim, and never wired up token revocation. All three are now fail-closed and covered by regression tests.
011–014new database migrations
SSEreal-time execution stream
systemdno-Docker deployment path
bash
# No-Docker / systemd path
sudo ./install-onprem.sh
sudo systemctl enable --now cloudmigrator-api
sudo systemctl status cloudmigrator-api

# Real-time execution stream
curl -N -H "Authorization: Bearer $TOKEN" http://localhost:8080/v1/executions/stream
11 — Reference

API routes & environment variables

Archive-synced version: route list and environment variables have been checked against cmd/api/main.go, internal/api/http.go, platform_api.go, and .env.example.

Authentication
POST/auth/registerCreate account — returns JWT + tenantId. First 5 users get free plan
POST/auth/loginSign in with email + password — returns signed JWT (8h TTL)
POST/auth/refreshExtend session — exchange valid/near-expired JWT for a fresh one
System
GET/healthzLiveness probe
GET/readyzReadiness probe — 503 if DB unreachable
GET/metricsexpvar JSON counters
Discovery
POST/v1/discovery/import/{provider}-snapshotImport JSON snapshot for AWS, GCP, Azure, OVH, Kubernetes, or OnPrem
POST/v1/discovery/runsTrigger live discovery
GET/v1/discovery/runsList discovery runs
Planning
POST/v1/migrations/planGenerate migration plan with policy evaluation
GET/v1/migrations/{planId}Get plan
GET/v1/plansList plans for project
POST/v1/migrations/preflightValidate credentials, IAM, quotas
Execution
POST/v1/migrations/prepare-executionLock plan into execution package
POST/v1/migrations/approve-executionApprove execution package
POST/v1/migrations/executeStart async execution — returns 202, poll GET /v1/executions/{id} for status
POST/v1/migrations/rollbackReverse-ordered rollback
GET/v1/executions/{id}Get execution package
POST/v1/executions/reconcileSync status with Temporal workflow
Data migration
POST/v1/migrations/data-planGenerate data migration plan
POST/v1/migrations/data-executeExecute data transfers
GET/v1/executions/data-jobsList data migration job results
Cutover
POST/v1/migrations/cutover/previewPreview cutover command without executing
POST/v1/migrations/cutoverExecute DNS / traffic cutover
POST/v1/migrations/cutover/rollbackRestore previous DNS / traffic state
GET/v1/executions/cutover-jobsList cutover job results
Evidence & audit
GET/v1/executions/eventsExecution event stream
GET/v1/executions/command-evidenceSigned command records
GET/v1/executions/signed-command-artifactsEd25519-signed artifacts
GET/v1/executions/rollback-artifactsRollback state snapshots
GET/v1/executions/action-approvalsPer-action approval records
POST/v1/executions/action-approvals/approveApprove a blocked action
GET/v1/executions/streamServer-Sent Events stream for live execution, data, and cutover updates
Platform API — Drift
POST/v1/drift/scanTrigger infrastructure drift scan
GET/v1/drift/reportsList drift reports
GET/v1/drift/latestLatest drift scan result
PUT/v1/drift/scheduleConfigure scheduled drift scans
Platform API — Intent & Cost
POST/v1/intentCreate migration intent
POST/v1/intent/evaluateEvaluate intent against policy and cost
GET/v1/intent/:idRetrieve intent by ID
POST/v1/cost/estimateEstimate migration cost
GET/v1/cost/latestLatest cost rollup
GET/v1/cost/roiROI projection
POST/v1/cost/compareCompare cost scenarios
Platform API — Compliance & Observe
POST/v1/compliance/checkRun compliance check
GET/v1/compliance/reportsCompliance report list
GET/v1/compliance/latestLatest compliance posture
GET/v1/compliance/controlsControl catalogue
GET/v1/observe/healthHealth indicators
GET/v1/observe/latestLatest telemetry snapshot
GET/v1/observe/slosSLO status
GET/v1/observe/metrics/mapMetrics topology map
Platform API — Runbooks, Network & Collab
GET/v1/runbooksList runbooks
GET/v1/runbooks/builtinBuilt-in runbook catalogue
POST/v1/runbooks/executeExecute a runbook
GET/v1/runbooks/runsRunbook execution history
POST/v1/network/planGenerate network migration plan
GET/v1/network/connectionsDiscovered connections
GET/v1/network/latencyLatency measurements
GET/v1/network/egress-costEgress cost estimates
GET/v1/network/recommend-regionsRegion recommendations
GET/v1/collab/changesPending change requests
POST/v1/collab/changes/approveApprove a change request
POST/v1/collab/changes/commentComment on a change request
GET/v1/collab/changes/:idChange request detail
GET/v1/collab/notificationsTenant notifications
GET/v1/collab/timelineActivity timeline
Billing & auth operations
POST/billing/checkoutCreate Stripe checkout session for Free, Pro, or Enterprise tier
POST/billing/portalOpen Stripe customer portal session
GET/billing/planRetrieve current subscription plan
POST/billing/webhookReceive Stripe subscription and payment events (no JWT — Stripe HMAC)
POST/auth/logoutAdd JWT to revocation deny-list and invalidate session
GET/auth/confirm-emailConfirm email address via token query parameter
POST/auth/forgot-passwordInitiate password-reset flow
POST/auth/reset-passwordComplete password reset with token
Oracle assessment
POST/v1/oracle/assessRun Oracle schema portability assessment; use dsn=stub for demo data or build with -tags oracle for live discovery
Public growth & trust endpoints
POST/roi-calculatorPublic ROI calculator lead-capture endpoint
GET/share/:idPublic shareable migration report
GET/.well-known/signing-key.pubPublic Ed25519 verification key in PEM format
GET/.well-known/signing-key.jsonMachine-readable signing-key metadata
GET/.well-known/verify.pyDownloadable evidence-chain verifier script
GET/.well-known/healthPublic uptime monitor endpoint
GET/debug/pprof/pprof diagnostics, protected by token or localhost-only access
Environment variables
Variable Description Required
JWT_SECRETHMAC-SHA256 signing secret (32+ chars)required
ED25519_PRIVATE_KEYEd25519 seed for evidence signing. Generate with --gen-keyrequired
REDIS_URLRedis DSN for distributed rate limitingoptional
DATABASE_URL_REPLICA_NRead replicas (N = 1..9). Aurora Global / CockroachDB compatibleoptional
PROVIDER_EXECUTION_MODEpreview (default) or applyoptional
CM_SECRETS_BACKENDaws-secretsmanager | vault | kubernetesoptional
POLICY_RULES_FILEPath to custom policy rules JSONoptional
TEMPORAL_HOSTActivates durable workflows. e.g. https://ns.acct.tmprl.cloudoptional
TEMPORAL_API_KEYTemporal Cloud API keyoptional
CLOUDMIGRATOR_SERVICE_TOKENJWT for worker → API calls. Auto-generated if unsetoptional
CORS_ORIGINSAllowed CORS origins. Defaults to same-origin onlyoptional
PGMAXCONNS / PGMAXIDLEDB connection pool tuning (default 25 / 5)optional
RATE_LIMIT_RPS / RATE_LIMIT_BURSTPer-tenant rate limit tuningoptional
DATABASE_URLPostgres DSN or SQLite URL. On-Prem small-team default: sqlite:///var/lib/cloudmigrator/cloudmigrator.db. No insecure default is provided for Cloud deployments — the server refuses to start if unset. For production Postgres use sslmode=require; using sslmode=disable logs a startup warning.required
CLOUDMIGRATOR_LICENSE_KEYRequired for On-Prem startup; server exits if missing.Optional in Cloud; used only for hybrid/on-prem agents.requiredoptional
ADMIN_EMAIL / ADMIN_PASSWORDFirst-run On-Prem administrator bootstrap credentials. Remove or rotate after setup.requiredoptional
PROMETHEUS_ENABLEDExpose Prometheus scrape endpoint at /metricsoptional
METRICS_TOKENBearer token required to scrape /metrics. Unset = localhost-only accessoptional
OTEL_EXPORTER_OTLP_ENDPOINTOpenTelemetry collector endpoint for distributed tracesoptional
JWT_DENYLIST_BACKENDJWT revocation store, typically Redis in productionoptional
STRIPE_SECRET_KEY / STRIPE_WEBHOOK_SECRETCloud billing integration for subscription tiers and webhook verificationrequiredoptional
AWS_REGIONDefault AWS region for executor and secretsoptional
GCP_PROJECT_IDDefault GCP project for executor and preflightoptional
AZURE_SUBSCRIPTION_IDDefault Azure subscription for executoroptional
NETAPP_ENDPOINTDefault ONTAP cluster management endpoint for executoroptional
NETAPP_USERNAME / NETAPP_PASSWORD / NETAPP_API_TOKENONTAP REST credentials — read only from the environment, never from plan metadataoptional
ORACLE_DSNOracle database DSN for live assessment builds; leave unset or use stub for synthetic demo dataoptional
LD_LIBRARY_PATH / ORACLE_HOME / TNS_ADMINOracle Instant Client runtime paths when using Dockerfile.oracle or -tags oracleoptional
KUBE_CONTEXT / KUBE_NAMESPACEKubernetes executor context and namespaceoptional
ANSIBLE_INVENTORYAnsible inventory path for OnPrem live discoveryoptional
MIGRATE_ON_STARTUPSet to false to skip auto-migrations on start (default: runs migrations)optional
PORTHTTP listen port (default: 8080)optional
SMTP_HOSTSMTP relay hostname for email verification and password-reset flowsrequiredoptional
SMTP_PORTSMTP port (default: 587)optional
SMTP_USER / SMTP_PASSSMTP credentials for authenticated relayoptional
APP_BASE_URLBase URL used by billing, password-reset, verification, and shareable-report linksoptional