mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-11-07 08:55:37 +08:00
195 lines
6.5 KiB
Plaintext
195 lines
6.5 KiB
Plaintext
---
|
|
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
title: "Google Cloud"
|
|
sidebar-title: "Google Cloud"
|
|
description: "Authenticate with GCP APIs inside OpenShell sandboxes."
|
|
keywords: "Generative AI, Google Cloud, Vertex AI, GCP, OAuth2, Credentials, Sandbox"
|
|
---
|
|
|
|
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:
|
|
|
|
```shell
|
|
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.
|
|
|
|
```shell
|
|
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:
|
|
|
|
```shell
|
|
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:
|
|
|
|
```shell
|
|
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.
|
|
|
|
```shell
|
|
openshell provider create \
|
|
--name my-gcp \
|
|
--type google-cloud \
|
|
--config project_id=my-project \
|
|
--config region=us-central1 \
|
|
--credential GCP_SA_ACCESS_TOKEN=placeholder
|
|
```
|
|
|
|
```shell
|
|
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
|
|
```
|
|
|
|
```shell
|
|
openshell provider refresh rotate my-gcp \
|
|
--credential-key GCP_SA_ACCESS_TOKEN
|
|
```
|
|
|
|
## Configuration Keys
|
|
|
|
Set these with `--config key=value` during provider creation:
|
|
|
|
| Key | Description | Example |
|
|
|-----|-------------|---------|
|
|
| `project_id` | GCP project ID | `my-project-123` |
|
|
| `region` | GCP region | `us-central1` |
|
|
| `service_account_email` | SA email for metadata endpoint | `sa@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.
|
|
|
|
| Variable | Value | Purpose |
|
|
|----------|-------|---------|
|
|
| `GCE_METADATA_HOST` | `127.0.0.1:8174` | GCP SDK metadata discovery (loopback server) |
|
|
| `GCE_METADATA_IP` | `127.0.0.1:8174` | Python google-auth ping detection |
|
|
| `METADATA_SERVER_DETECTION` | `assume-present` | Node.js gcp-metadata skip detection |
|
|
| `GCP_PROJECT_ID` | from `project_id` config | GCP SDK project |
|
|
| `GOOGLE_CLOUD_PROJECT` | from `project_id` config | Alternative project var |
|
|
| `CLOUD_ML_REGION` | from `region` config | GCP region |
|
|
| `GCP_LOCATION` | from `region` config | Alternative 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:
|
|
|
|
```yaml
|
|
network_policies:
|
|
gcp_apis:
|
|
name: gcp-apis
|
|
endpoints:
|
|
- host: "*.googleapis.com"
|
|
port: 443
|
|
protocol: rest
|
|
access: read-write
|
|
enforcement: enforce
|
|
binaries:
|
|
- { path: /usr/bin/curl }
|
|
- { path: /usr/bin/node }
|
|
- { path: "/sandbox/.uv/python/**" }
|
|
- { path: "/sandbox/.venv/**" }
|
|
```
|
|
|
|
Or update a live sandbox directly:
|
|
|
|
```shell
|
|
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.
|