A $10/month kill switch for GCP
I give AI agents access to cloud providers. That’s useful, and dangerous. An agent with GCP credentials can provision resources, and a misconfigured loop can run up a bill before you notice. I wanted a hard ceiling: if total monthly spend crosses $10, shut everything down. No human in the loop. No “warning” email I might miss.
The setup
GCP has budget alerts that can publish to Pub/Sub. A Cloud Function subscribes to the topic and fires when spend hits a threshold. The function has one job: disable billing on the project. No billing = no resources can run.
The implementation is a single Python function deployed to Cloud Functions (gen2). It receives the Pub/Sub budget notification, checks if the cost has crossed the threshold, and if so, calls cloudbilling.projects.updateBillingInfo with an empty billing account, effectively unlinking the project from its payment method.
I set three alert thresholds: 50%, 90%, and 100% of the $10 budget. The 50% and 90% alerts send Telegram messages so I can see spend approaching the limit. The 100% alert triggers the kill.
The IAM
The function’s service account needs billing.resourceAssociations.delete at the project level and billing.accounts.get at the billing account level. I also granted the 6 project-level roles the AI agent needs for its actual work, compute, storage, IAM viewer and the like, on the same SA, so there’s one credential set for both “do work” and “kill if too expensive.”
The budget itself is created via gcloud billing budgets create with a Pub/Sub notification channel. The whole thing, SA, IAM bindings, budget, Pub/Sub topic, subscription, and Cloud Function, deploys from a single shell script that runs in Cloud Shell.
Testing
The function has a DRY_RUN flag. First deployment runs with DRY_RUN=true: it logs what it would do and sends a Telegram message but doesn’t actually kill billing. I triggered a test alert, confirmed the message arrived, then flipped to DRY_RUN=false.
Total time from “I want a cost ceiling” to “kill switch is armed”: about 45 minutes. Monthly cost of the kill switch itself: effectively zero (Cloud Functions free tier covers the occasional invocation).
Why this matters
If you’re giving AI agents cloud credentials, and you should, because that’s where the leverage is, you need a circuit breaker that doesn’t depend on you being awake. A budget alert email is not a kill switch. A Cloud Function with billing.resourceAssociations.delete is.