Cloud Run Setup Guide
One-time setup steps Alan needs to run (requires Owner/Editor on alanblount-demo).
TL;DR: Run the commands in order. After completing §1–§5, run
./deploy.shfor first deploy, then update theRELAY_PUBLIC_URLsecret with the real Cloud Run URL.
Prerequisites
-
gcloudCLI installed and authenticated:gcloud auth login - Docker installed
-
Project set:
gcloud config set project alanblount-demo
§1 — Enable Required APIs
gcloud services enable \
run.googleapis.com \
artifactregistry.googleapis.com \
secretmanager.googleapis.com \
cloudbuild.googleapis.com \
iam.googleapis.com \
--project=alanblount-demo
§2 — Create Artifact Registry Repository
gcloud artifacts repositories create a2a-relay \
--repository-format=docker \
--location=us-central1 \
--description="a2a-relay Docker images" \
--project=alanblount-demo
§3 — Create Secret Manager Secrets
Generate secure keys (or use the pre-generated values below):
# Generate fresh keys if you want (or use the ones below)
python3 -c "import secrets; print(secrets.token_hex(32))"
Create the secrets:
# RELAY_ADMIN_KEY (admin operations — keep this very safe)
printf '%s' '30b09a96c4fbd9a0e6a73cc1e95a0e46930ea24899072f62423ce73586da4ff3' \
| gcloud secrets create RELAY_ADMIN_KEY \
--data-file=- \
--replication-policy=automatic \
--project=alanblount-demo
# RELAY_API_KEY (legacy agent compat)
printf '%s' '7d9dd4092fc6719571a68995c250c73f7a8d2be54693af04e981bbca37d4d7bb' \
| gcloud secrets create RELAY_API_KEY \
--data-file=- \
--replication-policy=automatic \
--project=alanblount-demo
# RELAY_PUBLIC_URL (placeholder — update after first deploy)
printf '%s' 'https://a2a-relay-PLACEHOLDER-uc.a.run.app' \
| gcloud secrets create RELAY_PUBLIC_URL \
--data-file=- \
--replication-policy=automatic \
--project=alanblount-demo
⚠️ Security: The keys above were pre-generated for convenience. You may regenerate them with
python3 -c "import secrets; print(secrets.token_hex(32))". Store the final values in a password manager.
§4 — Create a Deployment Service Account
# Create the SA
gcloud iam service-accounts create a2a-relay-deployer \
--display-name="a2a-relay Cloud Run Deployer" \
--project=alanblount-demo
SA_EMAIL="a2a-relay-deployer@alanblount-demo.iam.gserviceaccount.com"
# Grant permissions
gcloud projects add-iam-policy-binding alanblount-demo \
--member="serviceAccount:${SA_EMAIL}" \
--role="roles/run.admin"
gcloud projects add-iam-policy-binding alanblount-demo \
--member="serviceAccount:${SA_EMAIL}" \
--role="roles/artifactregistry.writer"
gcloud projects add-iam-policy-binding alanblount-demo \
--member="serviceAccount:${SA_EMAIL}" \
--role="roles/secretmanager.secretAccessor"
gcloud projects add-iam-policy-binding alanblount-demo \
--member="serviceAccount:${SA_EMAIL}" \
--role="roles/iam.serviceAccountUser"
# Allow Cloud Run's default service account to access secrets
CR_SA="service-$(gcloud projects describe alanblount-demo --format='value(projectNumber)')@serverless-robot-prod.iam.gserviceaccount.com"
gcloud projects add-iam-policy-binding alanblount-demo \
--member="serviceAccount:${CR_SA}" \
--role="roles/secretmanager.secretAccessor"
§5 — Configure GitHub Actions Authentication
Option A: Workload Identity Federation (Recommended — no long-lived keys)
SA_EMAIL="a2a-relay-deployer@alanblount-demo.iam.gserviceaccount.com"
GITHUB_REPO="zeroasterisk/a2a-relay"
PROJECT_NUMBER=$(gcloud projects describe alanblount-demo --format='value(projectNumber)')
# Create WIF pool
gcloud iam workload-identity-pools create "github-actions" \
--project=alanblount-demo \
--location=global \
--display-name="GitHub Actions"
# Create OIDC provider
gcloud iam workload-identity-pools providers create-oidc "github" \
--project=alanblount-demo \
--location=global \
--workload-identity-pool="github-actions" \
--display-name="GitHub" \
--issuer-uri="https://token.actions.githubusercontent.com" \
--attribute-mapping="google.subject=assertion.sub,attribute.repository=assertion.repository,attribute.actor=assertion.actor,attribute.ref=assertion.ref" \
--attribute-condition="assertion.repository=='${GITHUB_REPO}'"
# Bind the SA to the pool
gcloud iam service-accounts add-iam-policy-binding "${SA_EMAIL}" \
--project=alanblount-demo \
--role="roles/iam.workloadIdentityUser" \
--member="principalSet://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/github-actions/attribute.repository/${GITHUB_REPO}"
# Get the WIF provider resource name (use this as WIF_PROVIDER secret in GitHub)
echo "WIF_PROVIDER:"
gcloud iam workload-identity-pools providers describe github \
--project=alanblount-demo \
--location=global \
--workload-identity-pool=github-actions \
--format='value(name)'
Then add these GitHub Actions secrets (repo → Settings → Secrets and variables → Actions):
| Secret | Value |
|---|---|
WIF_PROVIDER |
Output of the last gcloud command above |
WIF_SERVICE_ACCOUNT |
a2a-relay-deployer@alanblount-demo.iam.gserviceaccount.com |
Option B: Service Account Key (simpler, less secure)
SA_EMAIL="a2a-relay-deployer@alanblount-demo.iam.gserviceaccount.com"
gcloud iam service-accounts keys create sa-key.json \
--iam-account="${SA_EMAIL}" \
--project=alanblount-demo
# Add to GitHub Actions secrets as GCP_SA_KEY (paste entire JSON)
cat sa-key.json
# Delete local copy after adding to GitHub
rm sa-key.json
Add GitHub secret GCP_SA_KEY with the JSON content.
§6 — First Deploy
# Authenticate gcloud locally
gcloud auth login
gcloud config set project alanblount-demo
# Run the deploy script
./deploy.sh
§7 — Update RELAY_PUBLIC_URL Secret
After the first deploy, you’ll see the Cloud Run URL (e.g. https://a2a-relay-abc123-uc.a.run.app).
Update the secret:
SERVICE_URL=$(gcloud run services describe a2a-relay \
--region=us-central1 \
--format='value(status.url)' \
--project=alanblount-demo)
printf '%s' "${SERVICE_URL}" \
| gcloud secrets versions add RELAY_PUBLIC_URL \
--data-file=- \
--project=alanblount-demo
echo "Updated RELAY_PUBLIC_URL to: ${SERVICE_URL}"
# Trigger re-deploy to pick up the new URL (or just push a commit to master)
gcloud run services update a2a-relay \
--region=us-central1 \
--update-secrets=RELAY_PUBLIC_URL=RELAY_PUBLIC_URL:latest \
--project=alanblount-demo
§8 — Verify
SERVICE_URL=$(gcloud run services describe a2a-relay \
--region=us-central1 \
--format='value(status.url)' \
--project=alanblount-demo)
# Health check
curl "${SERVICE_URL}/health"
# Check agent catalog
curl "${SERVICE_URL}/catalog"
Cheat Sheet: Useful Commands
# View logs
gcloud run services logs read a2a-relay --region=us-central1 --project=alanblount-demo
# List secret versions
gcloud secrets versions list RELAY_ADMIN_KEY --project=alanblount-demo
# Update a secret value
printf '%s' 'new-value' | gcloud secrets versions add SECRET_NAME --data-file=- --project=alanblount-demo
# Force new Cloud Run revision (e.g., pick up new secret version)
gcloud run services update a2a-relay --region=us-central1 --project=alanblount-demo
# Cloud Run service details
gcloud run services describe a2a-relay --region=us-central1 --project=alanblount-demo