Nova Admin Docs
Integrations

Google Compute Engine

Set up the dedicated service account, sandbox VPC, firewall rules, and Cloud Run preview proxy that back the GCE sandbox provider.

The google-compute-engine integration wraps the ~150 low-level gce_* REST actions plus the high-level gce_sandbox_* orchestration tools that the GCE-backed SandboxProvider uses. None of those tools work until the GCP-side scaffolding below is in place: an IAM-scoped service account, an isolated VPC, an IAP-only firewall rule, and (for preview URLs) a Cloud Run reverse proxy.

This guide assumes the project nova-admin and zone us-central1-a. Swap names if you're working in a different project.

Prerequisites

  • gcloud CLI authenticated as a principal with Owner or Project IAM Admin on nova-admin.
  • compute.googleapis.com and iap.googleapis.com enabled (commands below enable them if not).
  • One free-tier e2-standard-2 quota slot in us-central1 (matches the existing crabbox quota; nothing new to request).
gcloud config set project nova-admin
gcloud services enable compute.googleapis.com iap.googleapis.com run.googleapis.com

1. Service account

The sandbox provider acts as nova-admin-gce-sandbox@nova-admin.iam.gserviceaccount.com. Its key is the only credential that ends up in nova-admin; it never touches user identity.

gcloud iam service-accounts create nova-admin-gce-sandbox \
  --display-name="Nova Admin GCE sandbox provider" \
  --description="Non-human SA used by nova-admin's GCE SandboxProvider"

2. IAM roles

Two roles, both scoped narrowly. compute.admin is wide but required for VM lifecycle + image baking; the trade-off is documented in the GCE sandbox provider design.

SA="nova-admin-gce-sandbox@nova-admin.iam.gserviceaccount.com"

gcloud projects add-iam-policy-binding nova-admin \
  --member="serviceAccount:${SA}" \
  --role="roles/compute.admin"

gcloud projects add-iam-policy-binding nova-admin \
  --member="serviceAccount:${SA}" \
  --role="roles/iap.tunnelResourceAccessor"

3. Sandbox VPC

Sandbox VMs live in their own VPC with no public IPs. All ingress is funneled through Identity-Aware Proxy (IAP) — the proxy and Cloud Functions reach VMs only via IAP tunnels.

gcloud compute networks create sandbox-vpc \
  --subnet-mode=custom \
  --description="Isolated VPC for nova-admin sandbox VMs"

gcloud compute networks subnets create sandbox-us-central1 \
  --network=sandbox-vpc \
  --region=us-central1 \
  --range=10.20.0.0/16

4. Firewall rule (IAP → 22 + 3000 + 8443)

IAP's TCP-forwarding source range is the well-known 35.235.240.0/20. The rule below allows that range to reach the SSH port plus the two app ports the sandbox provider expects (3000 for bun run dev, 8443 for the WSS terminal). Everything else is denied by VPC default.

gcloud compute firewall-rules create sandbox-allow-iap \
  --network=sandbox-vpc \
  --direction=INGRESS \
  --action=ALLOW \
  --rules=tcp:22,tcp:3000,tcp:8443 \
  --source-ranges=35.235.240.0/20 \
  --target-tags=sandbox-vm \
  --description="IAP-only ingress to sandbox VMs (SSH + dev server + terminal)"

Every sandbox VM the provider creates is tagged sandbox-vm automatically — the tag is what binds VMs to this rule.

5. Service-account key for nova-admin

Generate the JSON key the integration dialog will consume. Keep this file off git and out of .env.local-tracked paths.

gcloud iam service-accounts keys create ~/nova-admin-gce-sandbox.json \
  --iam-account="nova-admin-gce-sandbox@nova-admin.iam.gserviceaccount.com"

In Nova Admin, go to /agents/integrations, find Google Compute Engine, and paste:

  • projectId: nova-admin
  • clientEmail: nova-admin-gce-sandbox@nova-admin.iam.gserviceaccount.com
  • privateKey: the private_key string from the JSON file (preserve \n line breaks)

Save. The dialog will run a credential-validation ping against the live GCE API before persisting.

The gce-sandbox-proxy Cloud Run service is what makes gce_sandbox_share_create URLs actually loadable in a browser. It opens an IAP tunnel to the target VM on demand and proxies HTTP/WSS through to it.

Without this service deployed, the gce_sandbox_* action surface still works — agents can claim, exec, bake, etc. — but the share URLs return 502. Skip this step if you're not yet shipping shared previews.

# Deploy the proxy. Code lands in PR 8 of the GCE roadmap.
gcloud run deploy gce-sandbox-proxy \
  --source=apps/admin/services/gce-sandbox-proxy \
  --service-account="nova-admin-gce-sandbox@nova-admin.iam.gserviceaccount.com" \
  --region=us-central1 \
  --vpc-connector=sandbox-vpc-connector \
  --no-allow-unauthenticated

After it deploys, copy the *.run.app URL into GCE_SANDBOX_PROXY_BASE_URL in Firebase Secret Manager. The provider reads this env var when minting share links.

7. Smoke test

From a thread, ask any agent that has gce_* in its allowedTools:

"ping the GCE sandbox tools"

The agent should invoke gce_sandbox_ping. A response of "pong" confirms the credentials parse and the action registry sees the integration. Then try:

"list GCE pools"

This invokes gce_sandbox_pool_list and returns the seeded pooriaarab/Nova pool. If the pool is missing, run bun packages/cli/src/index.ts seed run sandbox-pools.

What lives where

WhereWhat
gcloud (this guide)Service account + IAM roles + VPC + firewall rule + Cloud Run deploy
/agents/integrationsService-account credentials (projectId, clientEmail, privateKey)
/agents/skillsPer-repo GCE config (machine type, bake script, ingress ports, cost cap) — see the sandbox provider design
/agents/sandboxesPools + claimed VMs + bake jobs (live state)
Firebase Secret ManagerGCE_SANDBOX_PROXY_BASE_URL, any future provider-wide secrets

Cost notes

  • Idle: ~$0/day. The shared warm box (one e2-standard-2) is the only thing that runs 24/7 if you leave it on. bin/crabbox-warm-shared.sh --stop brings it to zero overnight.
  • Per claim: one e2-standard-2 × claim duration. A typical PR-verification flow costs <$0.10 round-trip.
  • Cloud Run: scales to zero. Per-share-URL traffic adds ~$5–20/mo at moderate demo volume.

Troubleshooting

  • PERMISSION_DENIED on compute.instances.insert: SA is missing compute.admin on the project — re-run step 2.
  • IAP tunnel hangs at "establishing tunnel": firewall rule's source-ranges doesn't match 35.235.240.0/20, or the target VM isn't tagged sandbox-vm.
  • invalid_grant: Invalid JWT signature from nova-admin: the privateKey in the integration dialog had its \n line breaks stripped on paste. Re-paste from the original JSON.
  • Share URL returns 502: the Cloud Run proxy isn't deployed or GCE_SANDBOX_PROXY_BASE_URL is wrong.

On this page