Skip to content

v1.0.0 — Cloud Runtime & Production Foundation

Latest

Choose a tag to compare

@Tarcroi Tarcroi released this 30 Aug 20:41

Highlights

  • Agents are private by default, and every run is authorized. A private agent (the new default) runs only for its owner or an instance admin — anyone else gets a 404 indistinguishable from a missing agent. API keys now carry enforced operation and resource scopes (agent:run / agent:push, optionally pinned to specific agents), operators choose who may attest a version (SKRUN_VERIFICATION_POLICY), and an agent's owner can attach their own LLM key to it, encrypted at rest.
  • Run untrusted skills in a throwaway sandbox. Each POST /run can execute in its own short-lived machine with an egress allowlist enforced at the network layer, built from a multi-runtime image you can pull directly — ghcr.io/skrun-dev/skrun-runtime, carrying Python 3.12, Node 22, Go, Rust, Ruby and Java. The first backend is Fly.io (SKRUN_RUNTIME=flyio); operators using it can keep machines warm ahead of demand with SKRUN_RUNNER_POOL_SIZE, and each run reports a per-phase startup breakdown.
  • Self-host in one command, dashboard included. infra/docker-compose.yml brings up API + Postgres + MinIO + Caddy at production parity, and the published image now serves the operator dashboard at /dashboard — previously it was API-only and the console had to be hosted separately.
  • Postgres, without a vendor. DATABASE_URL takes any standard Postgres ≥ 14. Migrations apply automatically on boot, serialised by an advisory lock so rolling deploys don't race. SQLite remains the zero-config local default.
  • A credential only travels to an endpoint its owner chose. An agent.yaml may declare model.base_url, so the server no longer sends its own key there, and it refuses your X-LLM-API-Key unless you name the destination yourself with X-LLM-Base-URL. Both relaxations are explicit operator opt-ins, off by default.
  • Hardening, four internal audit cycles' worth. Request forgery is blocked on the resolved IP rather than the hostname, sandbox egress is contained on IPv6 as well as IPv4, the runner control RPC is authenticated per run, bundles are integrity-checked on download, max_cost is enforced rather than merely logged, and 16 outstanding high-severity advisories are down to none.

Known issue

The boot error message names the wrong Supabase pooler port. When the api-server starts without DATABASE_URL, the error it prints suggests the "Supabase pooler URL on port 6543". That is transaction mode, and it silently breaks the pg_advisory_lock the migrations runner takes to serialise concurrent boots. Use the Session Pooler on port 5432, as the Migration section below says — the documentation is right, the message is wrong. Corrected after this release; the fix is not in the 1.0.0 artifacts.

Breaking

  • Agents are private by default and POST /run is run-authorized. Any authenticated caller could previously run any verified agent in any namespace. Existing agents migrate to private on upgrade; the public set-path is disabled in this release.
  • The server's own LLM key is no longer sent to an agent-declared model.base_url. Opt in with SKRUN_ALLOW_SERVER_KEY_CUSTOM_BASE_URL=true only where every agent on the instance is yours.
  • A caller-supplied X-LLM-API-Key is refused when the agent declares a model.base_url you did not name. Send X-LLM-Base-URL to state the endpoint your key belongs to.
  • The Docker Compose stack has no default credentials. POSTGRES_PASSWORD, S3_ACCESS_KEY_ID and S3_SECRET_ACCESS_KEY must be set — the stack refuses to start otherwise.
  • DATABASE_URL takes a postgres:// URI, not a Supabase HTTPS project URL. The API validates the prefix at boot and refuses a stale value.

Migration

This is a security upgrade as much as a feature release. The Breaking section above describes behaviour that 0.8.0 and earlier still exhibit; upgrading is how you leave it behind.

  • Node 22+ is now the floor.
  • Set POSTGRES_PASSWORD, S3_ACCESS_KEY_ID and S3_SECRET_ACCESS_KEY before bringing the Compose stack up — see .env.example.
  • Move DATABASE_URL to a standard connection string. On Supabase use the Session Pooler on port 5432: transaction mode on port 6543 breaks the advisory lock the migrations runner relies on.
  • If you point a model at Ollama or another local endpoint, set SKRUN_ALLOW_LOCAL_MODEL_HOSTS=true — private and loopback addresses are refused by default.
  • Callers sending their own key to an agent they do not own must add X-LLM-Base-URL.

Stats

  • 1836 unit + integration tests pass (was 1222 at v0.8.0)
  • 140 E2E in-memory, plus the live multi-provider suite
  • Four internal security audit cycles closed; 16 high-severity advisories down to zero
  • OpenAPI 3.1 spec at 1.0.0

Install

npx @skrun-dev/cli@1.0.0 --version
# or
npm i -g @skrun-dev/cli@1.0.0

Full changelog: CHANGELOG.md