PAL Runtime · for builders · Apache-2.0
Agents that finish, stay contained, and stay yours.
An open-source runtime for the agents you build. Write one on your laptop and run the same thing in your cloud: runs that survive a crash, code in a microVM, spend capped before the model is called, and a receipt for every run.
01 · Laptop to cloud
Design on your laptop. Ship the same agent.
The full stack runs locally with one command, including real Firecracker microVMs on an Apple Silicon Mac. An agent is one agent.yaml; each version is stored as an immutable bundle with a digest, so what you tested is what runs.
- Point the CLI at another control plane and deploy the same file.
- The data plane runs in your VPC (EKS, GKE, AKS or a plain host) and dials out. No inbound ports.
Describe
pal onboardturns one sentence into a running agent. Or scaffold withpal init.Iterate
pal agents devwatches the folder, republishes on save and streams run events.Gate
pal testruns the eval suite against your baseline. A regression returns 422 and blocks the deploy.Deploy
pal deploysends the sameagent.yamlto whichever control plane you’re logged in to.
The CLI is pal (pal still works as an alias). pal doctor checks health, auth, your model provider and a live run.
02 · Checkpoints and crash-resume
A crash doesn’t start the run over.
Every step is written to the run’s journal as it finishes. If a worker dies, a recovery sweep reclaims the run: finished steps come back from the journal and only the unfinished step runs again.
- The sweep runs every 30 seconds; a lock makes sure one worker resumes a run.
- Side effects carry an idempotency key from run, step and attempt, so a retried model call is billed once.
- Child runs are created and driven by the engine itself, with a depth cap of 5.
03 · Sandboxes
Untrusted code runs in a microVM you can pause, resume and fork.
Firecracker or Kata, never a bare container. Pause snapshots a VM and frees its quota slot; resume brings back the same id. Set an idle timeout and it suspends itself, then wakes on the next exec.
—
Press Spawn to start a sandbox.
Times measured on a dev laptop under nested virtualization (Apple M4 Max, Lima; 1 vCPU, 128 MiB VM; 2026-10-27), not production hardware. Method and raw numbers.
Nothing leaks.
In broker mode the VM has no network device at all. Its only way out is a broker on the host, which checks each request against the allowlist, adds credentials the guest never sees, and audits every decision.
- Requests to hosts off the allowlist are refused and audited.
- Injected credentials never enter the VM, its logs or its audit trail.
Broker mode is opt-in and Firecracker-only1.
Egress and secrets04 · Invoke
Call it the way your system already works.
Request
POST /v1/runsStart a run from the SDK, CLI or HTTP, then read its result.
Stream
GET /v1/runs/{id}/eventsServer-sent events as steps run, end to end with no buffering.
Webhook
POST /v1/hooks/{id}A signed URL per agent, so GitHub, Sentry or any HMAC sender can start runs.
Cron
POST /v1/schedulesCron expressions in the timezone you choose.
Batch & callbackscoming soon
—Many inputs in one call, with a callback when they finish.
05 · Budgets and routing
A budget before the first token.
Cap what an agent may spend. Over the cap, the run is refused with HTTP 402 and the model is never called. Code asks for a capability like reasoning-large; the router picks the vendor and fails over when one is down.
const pal = new PalClient({
baseUrl: "http://localhost:8080",
apiKey: process.env.PAL_API_KEY,
});
await pal.agents.create({ name: "triage" });
await pal.budgets.upsert("triage", {
maxCostUsdPerDay: 25,
hardFail: true,
});
await pal.runs.create({ agent: "triage", input });TypeScript shown; Python and Go SDKs cover the same surface.
{
"error": "agent budget limit reached: daily spend would reach $25.0318 exceeding limit $25.0000",
"reason": "daily spend would reach $25.0318 exceeding limit $25.0000"
}06 · Telemetry
Every request and step is a span.
OpenTelemetry traces on every HTTP request, gRPC call and run step, tagged with tenant, run, step and agent version, so one filter finds one run across every service.
- Prometheus alerts, dashboards and runbooks ship in the repo.
- Each run’s journal streams live and replays later.
- Off by default and free when off: no endpoint, no cost.
- POST /v1/runs
- budget check
- step plan · llm
- step fetch · tool (microVM)
- step reply · llm
- receipt
07 · Resilience
Built to keep going, and to fail loudly.
Provider failover
Four routing strategies (cheap, fast, best, balanced). A rate-limited provider is skipped and the next one answers.
Retries that don’t double-bill
The same idempotency key rides every retry, so the provider dedups instead of charging twice.
Runs get reclaimed
A run whose worker vanished is picked up by the recovery sweep within 30 seconds and resumed, not restarted.
Heartbeats
Each VM’s harness reports every 5 seconds; one silent for 30 is marked stale.
No fake success
With no model router or VM manager wired, a step fails with a typed error instead of inventing an answer.
Refuses unsafe prod
In production, services refuse to start without their service token, scheduler or real VM manager.
08 · Security
Built for more than one tenant from day one.
Tenant isolation
Every row carries a tenant, every internal call carries it too, and row-level security policies cover every tenant table3.
Trust boundaries
Internal gRPC ports accept a tenant only from callers holding the service token.
Secrets by reference
Code refers to a secret by name; the value is resolved at execution time and never lands in logs, traces or run state.
Signed receipts
A finished run gets an Ed25519-signed receipt over its journal; anyone can verify it, and any later edit breaks the signature4.
Scoped API keys
Keys carry scopes, and a key can’t mint another key with more power than it has.
Open to audit
Apache-2.0, Go and Rust, with tests and linters gating every change in CI.
Proof, not promises
PAL runs on PAL Runtime.
The personal agent we use every day runs on this layer. Try the whole stack with Docker, no API key: the demo replays recorded model answers.
git clone https://github.com/dshakes/pal.git && cd pal && make demo- 1.Without broker mode the allowlist is enforced inside the VM by a proxy, and secrets you vend to the workload do enter the guest.
- 2.Enforced today: per-agent daily cost, runs and tokens, and a tenant-wide daily cost cap. Workflow runs also stop mid-run at a per-run cap and at per-tool limits.
- 3.Policies are in place on every tenant table. Enforcement is on in production whenever PAL_APP_DB_PASSWORD is set; without it the control plane refuses to start unless you set PAL_RLS_ENFORCE=0.
- 4.Ed25519 once a signing key is configured; development falls back to HMAC.