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:

ComponentRole
Runtime CoreRequest routing, contract validation, execution orchestration
SandboxProcess isolation, resource limits, capability enforcement
Controller RegistryTracks deployed controllers and their versions
Capability BrokerMediates access to db, http, secrets, queue, cache
Observability LayerMetrics, structured logs, trace propagation

Request Flow

  1. Request arrives at /api/execute/{controller}
  2. Runtime validates input against controller's contract schema
  3. Sandbox spawns isolated execution environment
  4. Controller executes with access only to declared capabilities
  5. Runtime validates output against contract schema
  6. Response returned with request ID and metrics

Controllers

A controller is a Python class that handles a specific unit of business logic.

controllers/invoice_sync/controller.py
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

  1. Deploy: docker compose exec runtime magic deploy ./controllers/invoice_sync/
  2. Validate: Contract is validated and registered
  3. Available: Controller appears in registry, ready for execution
  4. Execute: Each request creates a new sandboxed instance
  5. Update: Deploy new version, old continues serving until rollover
  6. 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.

Minimal contract
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.

CapabilityProvidesOptions
db:readself.db.query(), self.db.query_one()tables
db:writeself.db.insert(), self.db.update(), self.db.delete()tables
http:egressself.http.get/post/put/delete()allow (domains)
secrets:readself.secrets.get()keys
queue:publishself.queue.publish()queues
cache:readself.cache.get()prefix
cache:writeself.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.

contract.yaml (declaring rawsql)
capabilities:
  - db:read
  - db:rawsql       # Explicit opt-in — requires policy approval
controller.py (using rawsql)
# 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

ResourceDefaultMax
CPU0.5 cores2.0 cores
Memory256Mi2Gi
Timeout30s300s

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:

Log entry example
{
  "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-Key header
  • 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_SECRET and 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
Deploy production stack
# 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.

Deploy workflow
# 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

EndpointPurpose
/api/healthBasic liveness (runtime up)
/api/readyzReadiness (DB connected, migrations applied)
/metricsPrometheus metrics

Backup & Recovery

Backup commands
# 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 list and verify deployment
  • Capability denied: Add capability to contract and redeploy
  • Timeout exceeded: Increase resources.timeout or optimize code
  • Schema validation failed: Check input/output against contract