Skip to content

Deploy on Cloud Run (Sandbox)

This guide deploys a single-node Scion Hub on a Cloud Run Instance. Agents run as Cloud Run Sandboxes inside the same Instance — one container image, one deploy command, no external database or storage to provision.

What you will set up:

Component Provided by Purpose
Hub + Broker Cloud Run Instance Control plane, API, web UI
Agent runtime Cloud Run Sandboxes Isolated agent containers
Database Embedded SQLite State (ephemeral)
Auth perimeter Identity-Aware Proxy (IAP) Zero-trust access control

You need a GCP project with billing enabled and the following APIs:

Terminal window
export PROJECT_ID="your-project-id"
gcloud services enable \
run.googleapis.com \
iap.googleapis.com \
iam.googleapis.com \
--project=$PROJECT_ID
Tool Verify
gcloud 582.0.0 or later (verified; 575.0.0 does not have beta run instances) gcloud version and gcloud beta run instances deploy --help
git git --version

The deploy requires two credentials. gcloud auth and Application Default Credentials (ADC) are separate credential stores — both must be configured:

Terminal window
gcloud auth login
gcloud auth application-default login
Credential Verify Used by
gcloud auth login gcloud auth list gcloud commands (instance create, IAM bindings)
gcloud auth application-default login gcloud auth application-default print-access-token REST API call that enables IAP (step 3b)

The identity running the deploy needs these IAM roles on the target project:

Role Why
roles/run.admin Create and update Cloud Run Instances
roles/iam.serviceAccountUser Attach a service account to the Instance (if using --service-account)
roles/iap.admin Enable IAP and bind access policies

The deploy requires a pre-built omni image — a single image containing the Hub and all supported harnesses. There is no public image; you must build your own.

Build your own image with Cloud Build:

The repository includes a Cloud Build config that builds the full omni image chain. Before building, create an Artifact Registry repository to push to:

Terminal window
gcloud artifacts repositories create scion \
--repository-format=docker \
--location=us-central1 \
--project=$PROJECT_ID

Then submit the build:

Terminal window
git clone https://github.com/GoogleCloudPlatform/scion.git
cd scion
gcloud builds submit \
--project=$PROJECT_ID \
--config=image-build/cloudbuild-omni.yaml \
--substitutions="_TAG=$(git rev-parse --short HEAD),_SHORT_SHA=$(git rev-parse --short HEAD),_COMMIT_SHA=$(git rev-parse HEAD),_REGISTRY=us-central1-docker.pkg.dev/$PROJECT_ID/scion" \
--ignore-file=image-build/gcloudignore-omni \
.

The build runs eight images in a chain (thick-prep → scion-base → claude → codex → opencode → antigravity → grok-build → omni). Each step builds in the Cloud Build worker and feeds the next. Only the final scion-omni image is pushed to your registry. Workers start fresh each run — there is no warm cache between builds.

Monitor progress in the Cloud Build console or with gcloud builds list --project=$PROJECT_ID.

When it completes, your image is:

us-central1-docker.pkg.dev/$PROJECT_ID/scion/scion-omni:$(git rev-parse --short HEAD)

The deploy derives the agent image registry from --image automatically; if derivation fails, the error names --image-registry as the explicit override. When this value is wrong, agent creation fails — not the deploy itself.

Stay in the clone directory for the rest of this guide — the deploy script and teardown script are repository-relative paths.


A single command creates the Instance, enables IAP, and verifies the perimeter:

Terminal window
./scripts/single-node/deploy.sh \
--name my-scion-hub \
--project $PROJECT_ID \
--region us-east4 \
--image us-central1-docker.pkg.dev/YOUR_PROJECT/scion/scion-omni:YOUR_TAG

What the command does, step by step:

  1. Resolves your gcloud identity and the project number.
  2. Creates the Cloud Run Instance with --sandbox-launcher enabled (this is what allows agents to run as sandboxes inside the Instance).
  3. Enables IAP via a REST API PATCH (iapEnabled: true, invokerIamDisabled: true).
  4. Waits for IAP enforcement to activate (~30–75 seconds).
  5. Binds your identity as an IAP-authorized user.
  6. Asserts the perimeter — fetches the Instance URL with no credentials and fails the deploy if the app answers. This is the safety gate.
  7. Prints the Instance URL.
Flag Default Description
--region us-east4 GCP region
--cpu 4 CPU allocation
--memory 8Gi Memory allocation
--admin-email deployer’s gcloud account Override the Hub admin email
--service-account (default compute SA) GCP service account for the Instance
--image-registry derived from --image Override the image registry the broker uses to pull agent images

Open the Instance URL printed by the deploy command in your browser:

https://my-scion-hub-PROJECT_NUMBER.us-east4.run.app
  1. IAP challenge — Google sign-in. Use the email that was bound as the IAP user during deploy (your gcloud account, or the --admin-email value).
  2. Hub access — After sign-in you land directly in the Hub. There is no second login. The deployer is automatically seeded as the first admin.

From the Hub web UI, click New Project. Provide a name and a git remote URL (e.g. a GitHub repository the agent will work in).

Create an agent via the web UI or the API. The web UI is the simplest path — click a project, then New Agent, pick a harness (e.g. Claude), and start it.

Once the agent reaches a running state, click Attach in the web UI to open a live tmux session in your browser. You can watch the agent work, send it messages, and inspect its output in real time.


Instance size Idle agents Working agents
4 CPU / 8 GiB (default) 20 6
8 CPU / 32 GiB (maximum) 51 14

8 CPU / 32 GiB is the largest size Cloud Run allows. Larger deploys are refused.

Each number is a single observation — one stress-test run per size. Repeatability is unmeasured. These are the points past which the Instance was observed to fail, not thresholds to design against.

Do not extrapolate a per-CPU or per-GiB rule. Four times the memory and twice the CPU bought about three times the idle capacity and about twice the working capacity. Two points cannot establish a curve, and the relationship is not linear in either resource.

The numbers are context. The operating signal is create latency. Agent creates under two seconds mean headroom. Creates at ten seconds or more mean the Instance is near its ceiling — stop adding agents. That rule was measured at both sizes and, unlike a headcount, adapts to what the agents are actually doing. See the overload warning below for details.

Sizing to the measured ceiling is not the safe choice. Running fewer agents than you could costs only capacity. Running more destroys every workspace on the Instance with no warning and no recovery. The two errors are not the same size.

There are no per-agent resource limits. All agents share the Instance’s CPU and memory budget. A single compute-heavy agent can starve its neighbours.

To change the Instance size:

Terminal window
./scripts/single-node/deploy.sh \
--name my-scion-hub \
--project $PROJECT_ID \
--cpu 8 --memory 32Gi \
--image us-central1-docker.pkg.dev/YOUR_PROJECT/scion/scion-omni:YOUR_TAG

This tier is Tier 0: pure ephemeral.

  • Workspaces live on the Instance’s ephemeral filesystem.
  • The SQLite database (projects, agent metadata) lives on the same ephemeral filesystem.
  • The admin seed (your email) is set by an environment variable in the deploy command, so it is re-established automatically.

All state on the Instance is destroyed when the container restarts — whether by a planned redeploy, an overload that crashes the container, or any other restart. A redeploy you can plan for; a crash you cannot. The only durable copy of any agent’s work is what it has pushed to a git remote.

This is a deliberate design trade for fast, cheap, disposable deployments — not an oversight. Treat the Instance as a workspace, not as infrastructure. If you need durable workspaces, use the VM (GCE) path or the HA tier.


Delete the Instance:

Terminal window
./scripts/single-node/teardown.sh \
--name my-scion-hub \
--project $PROJECT_ID

Or directly:

Terminal window
gcloud beta run instances delete my-scion-hub \
--region=us-east4 \
--project=$PROJECT_ID \
--quiet

A Cloud Run Instance is billed for CPU and memory for the entire time it exists, regardless of whether it is handling requests. There is no scale-to-zero. Delete the Instance when you are not using it.

IAP access bindings are region-scoped, not per-instance. If this was the only instance in the region, review and clean up bindings:

Terminal window
gcloud iap web get-iam-policy \
--project=$PROJECT_ID \
--region=us-east4 \
--resource-type=cloud-run

If the Instance fails to start with a confusing image-pull error that names a cache mirror rather than your image, this is a known platform behavior (ptone/scion#1291). Verify:

  1. The image coordinate is correct (check for typos in the digest or tag).
  2. The image is accessible to the Instance’s service account.
  3. Re-run the deploy — transient pull failures sometimes resolve on retry.

The deploy command includes a perimeter assertion that fails the deploy if IAP is not enforcing. If you see the Instance URL responding without an IAP challenge:

Terminal window
# Check IAP status
curl -s -o /dev/null -w "%{http_code}" "https://INSTANCE_URL"
# Expected: 302 (redirect to Google sign-in)
# Bad: 200 (app is answering directly — IAP is not enforcing)

Re-run the deploy command — it is idempotent and will re-enable IAP.

Agent create returns 502: harness-config "antigravity" not found

Section titled “Agent create returns 502: harness-config "antigravity" not found”

If creating an agent without harnessConfig returns a 502 with failed to find harness-config "antigravity", the fix is to specify harnessConfig explicitly (e.g. "harnessConfig": "claude"). See the note in Section 3.