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-3.5.2.tar.gz (66.2 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-3.5.2-py3-none-any.whl (66.4 kB view details)

Uploaded Python 3

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

Hashes for gcp_lite-3.5.2.tar.gz
Algorithm Hash digest
SHA256 2653c10b0a671679624ba8b2cc2fc6ecbec49c4b5725691d7758b2a49ad74d49
MD5 ef0bec83a8841aeba163ed61e3f37117
BLAKE2b-256 20af5ee1229fc057caa71daf4f29a2860489f9d0122aade04421bf7910f4a22b

See more details on using hashes here.

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

Hashes for gcp_lite-3.5.2-py3-none-any.whl
Algorithm Hash digest
SHA256 35fa312277d653b8ac5395e1047c0ebaabd67c6b6d72d07654e1d91363d95ec1
MD5 4129051250b026e0cede004a1e437a60
BLAKE2b-256 6d9f29c6dc4ce1611bdd8e00393d3b811bfc6795b9196c123ed479a15441090a

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