Skip to main content

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 SSH ProxyCommand.
  • 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-keys metadata field via the GCP console (Compute Engine > Metadata > SSH Keys). The VM's guest agent will sync it to authorized_keys automatically.
  • Manual: If you have existing access (e.g. from another machine), append your public key to ~/.ssh/authorized_keys directly.
  • 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:

  1. Starts a temporary HTTP server on 127.0.0.1 (random port)
  2. Prints an authorization URL to stderr
  3. Waits for the browser redirect with the authorization code
  4. Exchanges the code for a refresh token
  5. 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:

  1. --credentials <path> — Explicit path to a JSON credentials file
  2. GOOGLE_APPLICATION_CREDENTIALS environment variable — Standard GCP env var pointing to a credentials JSON file
  3. ~/.config/gcp-lite/credentials.json — Default location, written by gcp-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 what gcp-lite login produces. 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 optional cryptography dependency (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.0
  • cryptography >= 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gcp_lite-2.0.3.tar.gz (50.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gcp_lite-2.0.3-py3-none-any.whl (52.9 kB view details)

Uploaded Python 3

File details

Details for the file gcp_lite-2.0.3.tar.gz.

File metadata

  • Download URL: gcp_lite-2.0.3.tar.gz
  • Upload date:
  • Size: 50.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.12 {"installer":{"name":"uv","version":"0.11.12","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

Hashes for gcp_lite-2.0.3.tar.gz
Algorithm Hash digest
SHA256 aacd5cf663b44e1cc235d5437d768b75e36182a2a69547f0ce77fe350b33541d
MD5 268ddac22bfd4db40d3177802e2e5c89
BLAKE2b-256 cff7bcb3667e1acb77fb0d3575d6393f4e51daccba92b4e9c1ad72a9b4979af9

See more details on using hashes here.

File details

Details for the file gcp_lite-2.0.3-py3-none-any.whl.

File metadata

  • Download URL: gcp_lite-2.0.3-py3-none-any.whl
  • Upload date:
  • Size: 52.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.12 {"installer":{"name":"uv","version":"0.11.12","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

Hashes for gcp_lite-2.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 bf5ba7b9e0de6b153a13fd95fa55e81130f39ab3e25622ca892d6bbf7de6ca82
MD5 f800080862c65d434e1e60497f70112f
BLAKE2b-256 1aa1df712a8174f5b68b7ff1f3c8c893fdb5958270aada8a073654e1eeaf6957

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page