If you want Cursor cloud agents to debug production-like behavior, access to logs is often the missing piece.
Here is a read-only setup based on Cloud Run service logs example:
- create a dedicated service account with Terraform
- grant only
logging.viewerandrun.viewer - materialize the JSON key inside the cloud agent at runtime
- verify access with
gcloud logging read
1) Provision a dedicated read-only service account (Terraform)
Create the following resources in your Terraform stack:
resource "google_service_account" "cursor_cloud_agent" {
account_id = "cursor-cloud-agent"
display_name = "Cursor Cloud Agent"
description = "Read-only access to Cloud Run logs for Cursor cloud agents"
}
resource "google_project_iam_member" "cursor_cloud_agent_roles" {
for_each = toset([
"roles/logging.viewer",
"roles/run.viewer",
])
project = var.project_id
role = each.value
member = "serviceAccount:${google_service_account.cursor_cloud_agent.email}"
}
resource "google_service_account_key" "cursor_cloud_agent" {
service_account_id = google_service_account.cursor_cloud_agent.name
}
resource "google_secret_manager_secret" "cursor_cloud_agent_key" {
secret_id = "cursor-cloud-agent-sa-key"
replication {
auto {}
}
depends_on = [google_project_service.apis]
}
resource "google_secret_manager_secret_version" "cursor_cloud_agent_key" {
secret = google_secret_manager_secret.cursor_cloud_agent_key.id
secret_data = base64decode(google_service_account_key.cursor_cloud_agent.private_key)
}Why this shape:
roles/logging.viewer: allows reading logsroles/run.viewer: allows discovering Cloud Run services/revisions you are inspecting- dedicated SA: easy to rotate/revoke without impacting humans or CI identities
2) Retrieve the key JSON from Secret Manager
After Terraform apply, fetch the latest key version directly from Secret Manager:
gcloud secrets versions access latest \
--secret=cursor-cloud-agent-sa-key \
--project=<YOUR_GCP_PROJECT>Treat it as highly sensitive: do not commit it, paste it in chat, or store it in shared plaintext locations.
3) Add the secret in Cursor Cloud and scope it correctly
In the Cursor Cloud environment setup UI:
- Go to https://cursor.com/dashboard/cloud-agents and create new environment.
- Add a secret named
GOOGLE_APPLICATION_CREDENTIALS_JSON. - Paste the JSON content fetched with:
- Keep it scoped to the repository unless you intentionally need cross-repo reuse.
This keeps credentials attached to the agent runtime without checking secrets into git.
4) Materialize credentials inside the agent
Use this script in your repo at scripts/cursor_cloud_env_setup.sh:
#!/bin/bash
set -euo pipefail
if [[ -z "${GOOGLE_APPLICATION_CREDENTIALS_JSON:-}" ]]; then
echo "ERROR: GOOGLE_APPLICATION_CREDENTIALS_JSON is not set." >&2
exit 1
fi
GCP_CREDS_DIR="${HOME}/.config/gcloud"
GCP_CREDS_FILE="${GCP_CREDS_DIR}/cursor-cloud-agent-sa.json"
mkdir -p "${GCP_CREDS_DIR}"
printf '%s' "${GOOGLE_APPLICATION_CREDENTIALS_JSON}" > "${GCP_CREDS_FILE}"
chmod 600 "${GCP_CREDS_FILE}"
export GOOGLE_APPLICATION_CREDENTIALS="${GCP_CREDS_FILE}"
echo "GOOGLE_APPLICATION_CREDENTIALS set to ${GCP_CREDS_FILE}"
gcloud auth activate-service-account --key-file="$GOOGLE_APPLICATION_CREDENTIALS"
gcloud auth print-access-token >/dev/null && echo "Auth OK"In an agent terminal:
source scripts/cursor_cloud_env_setup.sh5) Read Cloud Run logs from the agent
Example commands:
# List services first (sanity check)
gcloud run services list --region=europe-north1
# Read recent logs for one service
gcloud logging read \
'resource.type="cloud_run_revision" AND resource.labels.service_name="YOUR_SERVICE_NAME"' \
--limit=100 \
--format="value(timestamp,severity,textPayload)"If your app writes structured JSON logs, use:
gcloud logging read \
'resource.type="cloud_run_revision" AND resource.labels.service_name="YOUR_SERVICE_NAME"' \
--limit=100 \
--format=json6) How Cursor Cloud repository routing works (practical view)
Cursor Cloud environments are attached to repositories. In practice:
- you choose the repository during setup
- repo-scoped secrets (for example
GOOGLE_APPLICATION_CREDENTIALS_JSON) are injected only for that repo’s agents - agent runs for that repo are routed to the prepared environment, so startup scripts/dependencies are reusable
This is why secret scope matters: keep sensitive credentials scoped to the repo that actually needs Cloud Run log access.
Security notes and operating tips
- Prefer least privilege (viewer roles only).
- Rotate service account keys periodically.
- Revoke immediately if exposed.
- Avoid sharing one privileged key across many repos/workspaces.
Need help implementing this in your repo? Start with:
- Terraform SA + IAM + secret resources
- Secret Manager retrieval command + repo secret wiring
scripts/cursor_cloud_env_setup.sh- A smoke-check command your agents can run before debugging