Portable GCP tooling in pure Python
Project description
gcp-lite
Portable GCP tooling in pure Python. Replaces common gcloud commands — SSH
tunneling through IAP, VM start/stop, and machine type changes — on platforms
where the full Cloud SDK is unavailable (e.g. Termux on Android/ARM).
How it works
gcp-lite authenticates with GCP via standard OAuth2, then talks directly to
GCP APIs using only Python and a single dependency
(websockets):
- IAP tunneling: Opens a WebSocket to Google's IAP tunnel relay
(
tunnel.cloudproxy.app) and relays stdin/stdout, acting as an SSHProxyCommand. - VM management: Calls the Compute Engine REST API to start/stop instances and change machine types.
GCP-side prerequisites
Before using gcp-lite, ensure the following are in place on your GCP project:
IAP tunnel access
The user or service account must have the IAP-Secured Tunnel User role
(roles/iap.tunnelResourceAccessor) on the project, folder, or specific VM
instance. This role grants the iap.tunnelInstances.accessViaIAP permission
that authorizes the WebSocket connection.
You can grant it via the GCP console (Security > Identity-Aware Proxy) or with:
gcloud projects add-iam-policy-binding PROJECT_ID \
--member='user:you@example.com' \
--role='roles/iap.tunnelResourceAccessor'
Firewall rule for IAP
GCP must be able to reach your VM on port 22 from the IAP IP range. The default
default-allow-ssh rule may already cover this. If not, create a firewall rule
allowing ingress on TCP port 22 from 35.235.240.0/20 (Google's IAP range).
SSH key on the VM
gcp-lite does not manage SSH keys. You need to ensure the VM has your public
key in ~/.ssh/authorized_keys for the target user. Options:
- Project or instance metadata: Add your public key to the
ssh-keysmetadata field via the GCP console (Compute Engine > Metadata > SSH Keys). The VM's guest agent will sync it toauthorized_keysautomatically. - Manual: If you have existing access (e.g. from another machine), append
your public key to
~/.ssh/authorized_keysdirectly. - Serial console: As a last resort, use the GCP console serial port to log in and add the key.
VM with IAP enabled
The target VM must be in a project with the IAP API enabled
(iap.googleapis.com). The VM itself does not need a public IP address — that's
the point.
Compute Engine permissions (for VM management)
To use start, stop, and set-machine-type, the authenticated user or
service account needs permissions to manage instances. The Compute Instance
Admin (v1) role (roles/compute.instanceAdmin.v1) covers all three operations.
Installation
pip install .
For service account authentication (optional):
pip install '.[sa]'
This adds the cryptography package, needed for JWT/RS256 signing.
Quick start
1. Authenticate (one-time)
gcp-lite login
This initiates a browser-based OAuth2 flow. It prints the URL to the terminal —
open it in your browser. After you consent, the browser redirects to a local
listener and gcp-lite saves a refresh token to
~/.config/gcp-lite/credentials.json.
2. Configure SSH
Add an entry to ~/.ssh/config:
Host gcp-vm
User your-username
IdentityFile ~/.ssh/id_ed25519
ProxyCommand gcp-lite iap --project my-project --zone us-central1-a --instance my-vm
3. Connect
ssh gcp-vm
Commands
gcp-lite login
Runs an interactive OAuth2 Authorization Code flow with PKCE:
- Starts a temporary HTTP server on
127.0.0.1(random port) - Prints an authorization URL to stderr
- Waits for the browser redirect with the authorization code
- Exchanges the code for a refresh token
- Saves credentials to
~/.config/gcp-lite/credentials.json
The refresh token is long-lived. You only need to re-run login if you revoke
access or the token expires.
gcp-lite iap
Opens an IAP tunnel and relays stdin/stdout, designed for use as an SSH
ProxyCommand.
| Option | Required | Default | Description |
|---|---|---|---|
--project |
yes | GCP project ID | |
--zone |
yes | Compute Engine zone (e.g. us-central1-a) |
|
--instance |
yes | VM instance name | |
--port |
no | 22 |
Target port on the VM |
--interface |
no | nic0 |
Network interface |
--credentials |
no | Path to a credentials JSON file (see below) |
gcp-lite status
Prints the current status of a VM instance (e.g. RUNNING, STOPPED,
TERMINATED, STAGING) to stdout.
| Option | Required | Default | Description |
|---|---|---|---|
--project |
yes | GCP project ID | |
--zone |
yes | Compute Engine zone | |
--instance |
yes | VM instance name | |
--credentials |
no | Path to a credentials JSON file |
gcp-lite metadata
Prints the full instance description as JSON to stdout. This includes machine type, network interfaces, disks, metadata, scheduling, status, and all other fields from the Compute Engine API.
| Option | Required | Default | Description |
|---|---|---|---|
--project |
yes | GCP project ID | |
--zone |
yes | Compute Engine zone | |
--instance |
yes | VM instance name | |
--credentials |
no | Path to a credentials JSON file |
gcp-lite start
Starts a stopped VM instance. By default, waits for the operation to complete.
| Option | Required | Default | Description |
|---|---|---|---|
--project |
yes | GCP project ID | |
--zone |
yes | Compute Engine zone | |
--instance |
yes | VM instance name | |
--credentials |
no | Path to a credentials JSON file | |
--no-wait |
no | Return immediately after the API call succeeds |
Exits with code 4 if the instance is already running.
gcp-lite stop
Stops a running VM instance. By default, waits for the operation to complete.
| Option | Required | Default | Description |
|---|---|---|---|
--project |
yes | GCP project ID | |
--zone |
yes | Compute Engine zone | |
--instance |
yes | VM instance name | |
--credentials |
no | Path to a credentials JSON file | |
--no-wait |
no | Return immediately after the API call succeeds |
Exits with code 4 if the instance is already stopped.
gcp-lite set-machine-type
Changes the machine type of a VM instance. The instance must be stopped.
| Option | Required | Default | Description |
|---|---|---|---|
--project |
yes | GCP project ID | |
--zone |
yes | Compute Engine zone | |
--instance |
yes | VM instance name | |
--machine-type |
yes | New machine type (e.g. e2-standard-4) |
|
--credentials |
no | Path to a credentials JSON file | |
--no-wait |
no | Return immediately after the API call succeeds | |
--force |
no | Stop the instance, change the type, and restart it |
--force and --no-wait are mutually exclusive (exit code 3 if combined).
Without --force, exits with code 4 if the instance is not stopped, printing
instructions to stop it first or use --force.
With --force, the full lifecycle is: stop (if running) -> set machine type ->
start. Each step waits for the previous to complete.
Authentication
Credential resolution
All subcommands except login resolve credentials in this order:
--credentials <path>— Explicit path to a JSON credentials fileGOOGLE_APPLICATION_CREDENTIALSenvironment variable — Standard GCP env var pointing to a credentials JSON file~/.config/gcp-lite/credentials.json— Default location, written bygcp-lite login
Supported credential types
The credentials JSON file must have a "type" field:
-
"authorized_user"— Contains a refresh token, client ID, and client secret. This is whatgcp-lite loginproduces. The refresh token is exchanged for a short-lived access token on each invocation. -
"service_account"— A GCP service account key file (downloaded from the console). Requires the optionalcryptographydependency (pip install 'gcp-lite[sa]'). A JWT is signed locally and exchanged for an access token.
Using existing gcloud credentials
If you have gcloud configured on another machine, you can copy its Application
Default Credentials file to ~/.config/gcp-lite/credentials.json:
# On the machine with gcloud:
cat ~/.config/gcloud/application_default_credentials.json
# Copy the output to ~/.config/gcp-lite/credentials.json on your device
Configuration files
| Path | Purpose |
|---|---|
~/.config/gcp-lite/credentials.json |
Stored OAuth2 credentials (written by gcp-lite login) |
~/.ssh/config |
SSH client configuration with ProxyCommand |
Environment variables
| Variable | Purpose |
|---|---|
GOOGLE_APPLICATION_CREDENTIALS |
Fallback path to a credentials JSON file (standard GCP convention) |
Requirements
- Python >= 3.11
websockets>= 14.0cryptography>= 41.0 (optional, for service account auth only)
Exit codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Authentication error (invalid or missing credentials) |
| 2 | IAP tunnel error (connection closed by server) |
| 3 | Invalid invocation (e.g. --force combined with --no-wait) |
| 4 | Invalid state (e.g. starting an already-running instance) |
| 5 | Operation failed (server-side error during a Compute Engine operation) |
Troubleshooting
Common IAP tunnel errors:
| Error | Meaning |
|---|---|
| Not authorized | Missing roles/iap.tunnelResourceAccessor on the project or instance |
| Instance not found | Wrong project, zone, or instance name |
| Failed to connect to backend VM | The VM may be stopped, or port 22 is blocked by a firewall rule |
| Backend VM closed the connection after accept | sshd is not running on the VM, an OS-level firewall reset the connection, or SSH is on a non-default port |
| Write to backend VM failed | sshd terminated the connection mid-stream — check journalctl -u ssh on the VM |
| Reauthentication required | OAuth refresh token revoked or expired; run gcp-lite login again |
| Session ID already in use | Another client is holding the same tunnel session; close it or wait for it to expire |
Common Compute Engine errors:
| Error | Meaning |
|---|---|
| Permission denied | Missing roles/compute.instanceAdmin.v1 or equivalent |
| Instance is already running (exit 4) | Attempted start on a running VM |
| Instance is already stopped (exit 4) | Attempted stop on a stopped VM |
| Instance must be stopped (exit 4) | Attempted set-machine-type on a running VM without --force |
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gcp_lite-3.5.2.tar.gz.
File metadata
- Download URL: gcp_lite-3.5.2.tar.gz
- Upload date:
- Size: 66.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":null,"id":"forky","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2653c10b0a671679624ba8b2cc2fc6ecbec49c4b5725691d7758b2a49ad74d49
|
|
| MD5 |
ef0bec83a8841aeba163ed61e3f37117
|
|
| BLAKE2b-256 |
20af5ee1229fc057caa71daf4f29a2860489f9d0122aade04421bf7910f4a22b
|
File details
Details for the file gcp_lite-3.5.2-py3-none-any.whl.
File metadata
- Download URL: gcp_lite-3.5.2-py3-none-any.whl
- Upload date:
- Size: 66.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":null,"id":"forky","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
35fa312277d653b8ac5395e1047c0ebaabd67c6b6d72d07654e1d91363d95ec1
|
|
| MD5 |
4129051250b026e0cede004a1e437a60
|
|
| BLAKE2b-256 |
6d9f29c6dc4ce1611bdd8e00393d3b811bfc6795b9196c123ed479a15441090a
|