Google Cloud

View as Markdown

The google-cloud provider gives sandboxes native GCP credentials so any Google Cloud SDK works out of the box — Cloud Storage, BigQuery, Drive, Maps, Discovery Engine, or any other GCP API. A GCE metadata server emulator on loopback provides credential placeholders that the sandbox proxy resolves to real tokens at request time. The sandbox process never holds a real GCP credential.

Quick Start

If you already have gcloud configured with Application Default Credentials, create a provider with automatic credential refresh in one command:

$openshell provider create \
> --name my-gcp \
> --type google-cloud \
> --from-gcloud-adc \
> --config project_id="$(gcloud config get-value project)" \
> --config region=global

--from-gcloud-adc reads your ADC file, configures OAuth2 refresh on the gateway, and mints the first access token before the command returns. The gateway rotates the token automatically — no manual refresh needed.

Authentication Flows

Two credential flows are supported. Choose based on your environment.

Application Default Credentials (gcloud ADC)

Use credentials from gcloud auth application-default login. The gateway exchanges the refresh token for short-lived access tokens automatically.

$openshell provider create \
> --name my-gcp \
> --type google-cloud \
> --config project_id=my-project \
> --config region=us-central1 \
> --credential GCP_ADC_ACCESS_TOKEN=placeholder

Configure credential refresh with the ADC JSON fields:

$openshell provider refresh configure my-gcp \
> --credential-key GCP_ADC_ACCESS_TOKEN \
> --strategy oauth2-refresh-token \
> --material client_id=YOUR_CLIENT_ID \
> --material client_secret=YOUR_CLIENT_SECRET \
> --material refresh_token=YOUR_REFRESH_TOKEN \
> --secret-material-key client_secret \
> --secret-material-key refresh_token

Find these values in your ADC file at ~/.config/gcloud/application_default_credentials.json.

Trigger the first token mint:

$openshell provider refresh rotate my-gcp \
> --credential-key GCP_ADC_ACCESS_TOKEN

Service Account Key

Use a GCP service account JSON key file. The gateway signs JWTs and exchanges them for access tokens using the google-service-account-jwt strategy.

$openshell provider create \
> --name my-gcp \
> --type google-cloud \
> --config project_id=my-project \
> --config region=us-central1 \
> --credential GCP_SA_ACCESS_TOKEN=placeholder
$openshell provider refresh configure my-gcp \
> --credential-key GCP_SA_ACCESS_TOKEN \
> --strategy google-service-account-jwt \
> --material client_email=sa@my-project.iam.gserviceaccount.com \
> --material private_key="$(jq -r .private_key /path/to/sa-key.json)" \
> --secret-material-key private_key
$openshell provider refresh rotate my-gcp \
> --credential-key GCP_SA_ACCESS_TOKEN

Configuration Keys

Set these with --config key=value during provider creation:

KeyDescriptionExample
project_idGCP project IDmy-project-123
regionGCP regionus-central1
service_account_emailSA email for metadata endpointsa@proj.iam.gserviceaccount.com

How It Works

When a sandbox starts with the google-cloud provider attached:

  1. The gateway mints a fresh GCP access token and stores it in the sandbox proxy’s credential resolver.
  2. A loopback HTTP server on 127.0.0.1:8174 emulates the GCE instance metadata API, serving credential placeholders (not real tokens) to GCP SDKs. The sandbox process never holds a real GCP credential.
  3. When the SDK makes an API call, it sends the placeholder in the Authorization header. The sandbox proxy TLS-terminates the outbound connection, resolves the placeholder to the real token, and forwards the request to GCP.
  4. When the token approaches expiry, the gateway refreshes it. The proxy’s resolver is updated atomically — subsequent API calls use the new token automatically.

Configuration values (project_id, region, service_account_email) are visible in plain text inside the sandbox — they appear as environment variables and are served by the metadata endpoint. These are non-secret identifiers, not credentials. Access tokens are never exposed; only placeholders reach the sandbox process.

Injected Environment Variables

The provider automatically injects these into the sandbox. Non-secret vars are resolved to real values at process spawn time; token vars stay as placeholders for proxy-time resolution.

VariableValuePurpose
GCE_METADATA_HOST127.0.0.1:8174GCP SDK metadata discovery (loopback server)
GCE_METADATA_IP127.0.0.1:8174Python google-auth ping detection
METADATA_SERVER_DETECTIONassume-presentNode.js gcp-metadata skip detection
GCP_PROJECT_IDfrom project_id configGCP SDK project
GOOGLE_CLOUD_PROJECTfrom project_id configAlternative project var
CLOUD_ML_REGIONfrom region configGCP region
GCP_LOCATIONfrom region configAlternative region var

Using with GCP APIs

The metadata emulator serves tokens with the cloud-platform OAuth2 scope, which grants access to any GCP API the underlying service account has IAM permissions for. Add the target API hosts to your sandbox network policy:

1network_policies:
2 gcp_apis:
3 name: gcp-apis
4 endpoints:
5 - host: "*.googleapis.com"
6 port: 443
7 protocol: rest
8 access: read-write
9 enforcement: enforce
10 binaries:
11 - { path: /usr/bin/curl }
12 - { path: /usr/bin/node }
13 - { path: "/sandbox/.uv/python/**" }
14 - { path: "/sandbox/.venv/**" }

Or update a live sandbox directly:

$openshell policy update my-sandbox \
> --add-endpoint "*.googleapis.com:443:read-write:rest:enforce" \
> --binary "/usr/bin/curl" \
> --binary "/usr/bin/node" \
> --binary "/sandbox/.uv/python/**" \
> --binary "/sandbox/.venv/**" \
> --wait

Network Policy

The google-cloud provider type does not include any network policy endpoints by default. You must add endpoint rules to your sandbox policy for each GCP API the sandbox needs to reach. See “Using with GCP APIs” above for an example.