User Guide
Complete guide to building, deploying, and operating controllers with Magic Runtime.
Overview
Magic Runtime is a sandboxed execution environment for business logic. Controllers are isolated plugins that declare their inputs, outputs, and required capabilities through contracts. The runtime enforces these contracts at boundaries.
Core principles:
- Contract-first: Every controller has a contract that defines its interface
- Default-deny: Controllers have no capabilities unless explicitly granted
- Sandboxed: Each execution is isolated with resource limits
- Observable: Built-in metrics, logging, and tracing
- Hot-deployable: Add or update controllers without restarting
Architecture
The runtime consists of:
| Component | Role |
|---|---|
Runtime Core | Request routing, contract validation, execution orchestration |
Sandbox | Process isolation, resource limits, capability enforcement |
Controller Registry | Tracks deployed controllers and their versions |
Capability Broker | Mediates access to db, http, secrets, queue, cache |
Observability Layer | Metrics, structured logs, trace propagation |
Request Flow
- Request arrives at
/api/execute/{controller} - Runtime validates input against controller's contract schema
- Sandbox spawns isolated execution environment
- Controller executes with access only to declared capabilities
- Runtime validates output against contract schema
- Response returned with request ID and metrics
Controllers
A controller is a Python class that handles a specific unit of business logic.
from magic import Controller, contract
@contract("./contract.yaml")
class InvoiceSyncController(Controller):
"""Syncs invoice data to external billing system."""
async def execute(self, input: dict) -> dict:
customer_id = input["customer_id"]
invoice_data = input["invoice_data"]
# Database access (requires db:read capability)
# Structured DB API — table identity enforced by contract allowlist
customer = await self.db.query_one(
"customers", where={"id": customer_id}
)
# HTTP egress (requires http:egress capability)
stripe_key = await self.secrets.get("STRIPE_KEY")
response = await self.http.post(
"https://api.stripe.com/v1/invoices",
json=invoice_data,
headers={"Authorization": f"Bearer {stripe_key}"}
)
# Emit custom metric
self.metrics.histogram(
"invoice_sync_duration_seconds",
self.elapsed_ms / 1000
)
return {
"sync_id": response["id"],
"status": "completed",
"request_id": self.request_id
}
Controller Lifecycle
- Deploy:
docker compose exec runtime magic deploy ./controllers/invoice_sync/ - Validate: Contract is validated and registered
- Available: Controller appears in registry, ready for execution
- Execute: Each request creates a new sandboxed instance
- Update: Deploy new version, old continues serving until rollover
- Rollback:
docker compose exec runtime magic rollback InvoiceSync --to v1.0.0
Contracts
Every controller requires a contract file. See the Contract Specification for full details.
name: MyController
version: 1.0.0
input:
type: object
required: [id]
properties:
id: { type: string }
output:
type: object
required: [result]
properties:
result: { type: string }
capabilities: []
resources:
timeout: 10s
Capabilities
Controllers must declare all external access. The runtime denies any undeclared capability use.
| Capability | Provides | Options |
|---|---|---|
db:read | self.db.query(), self.db.query_one() | tables |
db:write | self.db.insert(), self.db.update(), self.db.delete() | tables |
http:egress | self.http.get/post/put/delete() | allow (domains) |
secrets:read | self.secrets.get() | keys |
queue:publish | self.queue.publish() | queues |
cache:read | self.cache.get() | prefix |
cache:write | self.cache.set() | prefix, max_ttl |
Capability Audit
All capability usage is logged with the request's X-Request-ID. Logs include: capability name, target (table/domain/key), timestamp, and outcome.
Raw SQL Escape Hatch (db:rawsql)
By default, all database access uses the structured DB API (self.db.query(), self.db.insert(), self.db.update()). For cases where raw SQL is unavoidable (complex joins, legacy migrations, analytics queries), the db:rawsql capability is available as an explicit escape hatch.
Production Policy
db:rawsql is denied by default in production policy. It must be declared in the controller's contract and approved through the policy engine. All raw SQL queries are audit-logged with full query text.
capabilities:
- db:read
- db:rawsql # Explicit opt-in — requires policy approval
# Only available if db:rawsql is declared AND policy-approved
result = await self.db.raw(
"SELECT c.name, COUNT(o.id) FROM customers c JOIN orders o ON c.id = o.customer_id GROUP BY c.name",
[]
)
See Security Model and Enterprise Standards → Database for the full structured-first policy.
Execution Model
Sandbox Isolation
Each controller execution runs in an isolated sandbox with:
- Process isolation: Separate process with restricted syscalls
- Resource limits: CPU, memory, timeout enforced by cgroups
- Network isolation: Only declared egress domains reachable
- Filesystem: No persistent access; temp only if declared
Resource Limits
| Resource | Default | Max |
|---|---|---|
| CPU | 0.5 cores | 2.0 cores |
| Memory | 256Mi | 2Gi |
| Timeout | 30s | 300s |
Concurrency
The runtime manages concurrent executions per controller. Default: 10 concurrent. Configure via CONTROLLER_MAX_CONCURRENT.
Observability
Metrics (Prometheus)
The runtime exports at /metrics:
magic_controller_executions_total{controller, status}magic_controller_duration_seconds{controller}magic_controller_errors_total{controller, error_code}magic_capability_usage_total{controller, capability}magic_resource_limit_exceeded_total{controller, resource}
Structured Logging
All logs are JSON with standard fields:
{
"timestamp": "2026-02-10T12:34:56.789Z",
"level": "info",
"controller": "InvoiceSync",
"version": "1.2.0",
"request_id": "req_abc123xyz",
"event": "execution_completed",
"duration_ms": 142,
"capabilities_used": ["db:read", "http:egress"],
"customer_id": "cust_789"
}
Request Tracing
Every request gets an X-Request-ID. Pass this header to correlate across services. The runtime propagates it to all capability calls.
Security
Authentication
The runtime supports multiple auth methods:
- API Key:
X-API-Keyheader - JWT:
Authorization: Bearer {token} - mTLS: Client certificate validation
Threat Model
The sandbox is designed to contain:
- Malicious or buggy controller code
- Resource exhaustion (CPU/memory/disk)
- Unauthorized network access
- Credential theft (secrets are scoped per controller)
Not Designed For
The sandbox is not designed to run untrusted third-party code. It's for isolating your own (or AI-generated) business logic.
Production Hardening
- Run with
CONTROLLER_EXECUTION_MODE=process - Set explicit
CONTROLLER_ALLOWLIST - Enable TLS termination at Nginx
- Rotate
JWT_SECRETand API keys regularly - Review capability audit logs
Deployment
Docker Compose (Recommended)
The Production Stack includes:
- Nginx: TLS termination, rate limiting, static assets
- Magic Runtime: FastAPI + Uvicorn
- PostgreSQL: Primary data store
- Redis: Cache and queue
- Prometheus: Metrics collection
# Download and verify
wget https://magic.threadsync.io/deploy/magic-runtime-2.0.0-production.tar.gz
wget https://magic.threadsync.io/deploy/SHA256SUMS
sha256sum -c SHA256SUMS --ignore-missing
# Extract and enter directory
tar -xzf magic-runtime-2.0.0-production.tar.gz
cd magic-runtime
# Configure
cp .env.example .env
# Edit .env with production values
# Deploy
docker compose -f docker-compose.prod.yml up -d
# Initialize database
./scripts/init_db.sh
# Verify
curl https://your-domain.com/api/health
Controller Deployment
Magic CLI
The magic CLI is bundled inside the runtime container. Prefix commands with docker compose exec runtime, or run them directly if inside the container.
# Validate first
docker compose exec runtime magic validate ./controllers/invoice_sync/
# Deploy (hot-reload)
docker compose exec runtime magic deploy ./controllers/invoice_sync/
# Check deployment
docker compose exec runtime magic list
docker compose exec runtime magic status InvoiceSync
# Rollback if needed
docker compose exec runtime magic rollback InvoiceSync --to v1.0.0
Operations
Health Checks
| Endpoint | Purpose |
|---|---|
/api/health | Basic liveness (runtime up) |
/api/readyz | Readiness (DB connected, migrations applied) |
/metrics | Prometheus metrics |
Backup & Recovery
# Database backup
./scripts/backup_db.sh
# Controller export
docker compose exec runtime magic export --all --output ./backup/controllers/
# Full snapshot
./scripts/snapshot.sh
Troubleshooting
- Controller not found: Check
docker compose exec runtime magic listand verify deployment - Capability denied: Add capability to contract and redeploy
- Timeout exceeded: Increase
resources.timeoutor optimize code - Schema validation failed: Check input/output against contract