cloud-run-readonly-proxy
A local reverse proxy for read-only access to IAM-protected Google Cloud Run
services. It uses Application Default Credentials (ADC), either directly or as
the source for service-account impersonation, and renews Cloud Run ID tokens
without restarting the local listener. Only GET and HEAD requests are
accepted.
Requirements
- Python 3.11 or newer and uv
- The Google Cloud CLI (
gcloud) for initializing or refreshing ADC - ADC initialized with
gcloud auth login --update-adc roles/run.invokeron the Cloud Run service for either the ADC user or the impersonated service account
Service-account impersonation additionally requires
roles/iam.serviceAccountTokenCreator on the impersonated service account.
Run
From PyPI:
uvx cloud-run-readonly-proxy@0.1.1 \
--target-url TAGGED_OR_UNTAGGED_URL
Or install it with pip and invoke the Python module (module names use
underscores rather than dashes):
python -m pip install cloud-run-readonly-proxy
python -m cloud_run_readonly_proxy \
--target-url TAGGED_OR_UNTAGGED_URL
Directly from a pinned public Git commit:
uvx --from 'git+https://github.com/alexei-ciobanu/cloud-run-readonly-proxy@COMMIT_SHA' \
cloud-run-readonly-proxy \
--target-url TAGGED_OR_UNTAGGED_URL
The local page opens automatically at http://localhost:8080. Pass
--no-browser to leave it unopened, such as when running in a headless
environment.
Direct mode uses the user represented by ADC. That user must have Cloud Run Invoker on the service. Google documents these generic user ID tokens for development use; they are not bound to one target audience and are therefore more replayable than service-account ID tokens.
For an audience-bound token, use service-account impersonation:
uvx cloud-run-readonly-proxy@0.1.1 \
--target-url TAGGED_OR_UNTAGGED_URL \
--audience UNTAGGED_SERVICE_URL \
--impersonate-service-account INVOKER_SA
For a traffic-tag URL, --target-url is the tagged URL while --audience
remains the untagged service URL. --audience and
--impersonate-service-account must be supplied together.
Other options:
--port PORT Local port; default: 8080
--auth-retry-seconds N Delay after a failed token refresh; default: 5
--reauth-command COMMAND Command launched or shown when ADC needs refreshing
--no-browser Do not open the local proxy in the default browser
Authentication and proxying
In direct mode the tool:
- loads user ADC directly through the Google authentication library;
- refreshes ADC and reads the returned OpenID Connect ID token; and
- starts a listener bound to
127.0.0.1only.
When impersonation is requested, it instead uses ADC to call the IAM Credentials API and mint an audience-bound ID token for the explicitly configured service account.
The proxy reads each token's JWT expiration and refreshes it before expiry. If ADC expires while the process is running, the listener remains alive and serves a local recovery page instead of exiting. Select Sign in to run:
gcloud auth login --update-adc --quiet
The command opens the Google Cloud login flow in the system browser. After authentication succeeds, the originally requested page reloads automatically. The command is also displayed for manual use.
Only GET and HEAD requests are proxied. Authorization headers supplied by
the browser are discarded and replaced with the generated Cloud Run token.
Responses are streamed, redirects back to the Cloud Run origins are rewritten
to localhost, and the system trust store is used for outbound TLS.
Local development
uv sync --dev
uv run ruff check .
uv run ruff format --check .
uv run ty check src
uv run cloud-run-readonly-proxy --help
License
MIT
Metadata
Release files for cloud-run-readonly-proxy 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cloud_run_readonly_proxy-0.1.1.tar.gz | 90.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cloud_run_readonly_proxy-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 103.6 kB
Release files / cloud_run_readonly_proxy-0.1.1.tar.gz
| Download URL | cloud_run_readonly_proxy-0.1.1.tar.gz |
|---|---|
| Size | 90.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
85b31efb03baee0eb245f9c22ef95504e3fec1fbc873cf089acfe7f0a19c3d76
|
|
BLAKE2b-256 checksum How to use checksums |
8a2c316477d22a8777d8209a1ea5bae4f98871058e7e80e382bdd71d0455793c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / cloud_run_readonly_proxy-0.1.1-py3-none-any.whl
| Download URL | cloud_run_readonly_proxy-0.1.1-py3-none-any.whl |
|---|---|
| Size | 13.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
72b80aa59b0f58115f26b76526b93e637e1dad5bd3158923acbd87694b8726c8
|
|
BLAKE2b-256 checksum How to use checksums |
c45416335d06ee0f490343eccb3f1047afd2d3c4111fa16bb23f858f0f2044de
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|