mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-04 00:23:53 +08:00
* feat(core): add shared GCP constants module Single source of truth for GCP naming: env var aliases, provider config keys, token search order, and Vertex-specific env vars. Consumed by openshell-server, openshell-providers, and openshell-sandbox. - Add google_cloud.rs with metadata emulator host and loopback address - Define PROJECT_ID, REGION, and SERVICE_ACCOUNT_EMAIL env var aliases - Add provider config key constants for gcp provider implementations - Define TOKEN_ENV_KEYS search order (SA token takes priority over ADC) - Add Vertex-specific env vars for Goose and Claude Code SDK integration - Add STATIC_CONFIG_KEYS as union of all alias arrays for env resolution - Export module via openshell-core lib.rs Signed-off-by: Robert Sturla <rsturla@redhat.com> * feat(providers): add google-cloud and vertex provider plugins Add GoogleCloudProvider and VertexProvider implementing inject_env to project GCP config (project ID, region, SA email, metadata host) into sandbox environment variables. Replace the inline Vertex AI env injection in the server with the registry-based inject_env dispatch. Also adds the google-cloud.yaml provider profile with SA JWT and ADC OAuth2 credential refresh flows. Signed-off-by: Robert Sturla <rsturla@redhat.com> * feat(sandbox): add GCE metadata emulator for GCP Add a loopback HTTP server on 127.0.0.1:8174 inside the sandbox network namespace that emulates the GCE instance metadata API. GCP client SDKs discover it via GCE_METADATA_HOST and obtain credential placeholders that the proxy resolves to real tokens at egress. Add metadata_server module with MetadataHandler trait and netns-aware TCP binding via std::thread (not spawn_blocking) to avoid tokio pool namespace contamination Add google_cloud_metadata module implementing the GCE metadata API subset (token, project-id, email, scopes, service-accounts) Add child_env_resolved() and gcp_token_response() to ProviderCredentialState for GCP-aware credential projection Wire metadata server into sandbox lifecycle before SSH handler Collapse multi-line HTTP response format string into single line Signed-off-by: Robert Sturla <rsturla@redhat.com> * docs(sandbox): add GCP credentials documentation Document the google-cloud provider setup for ADC and service account flows, injected environment variables, metadata emulator behavior, and network policy configuration for GCP APIs. Signed-off-by: Robert Sturla <rsturla@redhat.com> * feat(cli): support --from-gcloud-adc for google-cloud providers Widen --from-gcloud-adc to accept google-cloud providers. The ADC credential key is derived from the provider profile rather than hardcoded per type, so future GCP provider types get ADC support by declaring the right refresh metadata in their profile YAML. Add ProviderTypeProfile::adc_credential() to find the ADC-compatible credential from a profile's refresh metadata. Remove unused VERTEX_AI_ADC_TOKEN_KEY and GCP_ADC_TOKEN_KEY constants. Signed-off-by: Robert Sturla <rsturla@redhat.com> --------- Signed-off-by: Robert Sturla <rsturla@redhat.com>
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.
|