AgentMsg

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.sh for first deploy, then update the RELAY_PUBLIC_URL secret with the real Cloud Run URL.


Prerequisites


§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