ANTIGRAVITY LABJP
Articles/Agents & Manager
Agents & Manager/2026-04-27Advanced

Giving Antigravity Agents Safe Write Access — Production Permission Boundary Design

A practical guide to designing Permission Boundaries that let AI agents safely touch production databases, deploys, and billing APIs — with dry-runs, approval queues, and audit logs.

antigravity429agents123security16permission-boundaryproduction71architecture19

Premium Article

import Image from 'next/image';

I'll start with a confession. I once gave an Antigravity agent UPDATE access to a production database, and it managed to overwrite 1,200 user records with the wrong values. The transaction wrapper saved me — I rolled back within thirty seconds — but the cold sweat I felt while making the "rewind history" decision is something I won't forget.

What I learned was that guardrails and sandboxes are not enough. An agent cannot reliably tell, from context alone, where it is allowed to write and where it is not. The set of allowed write operations has to be enforced from the outside as a Permission Boundary.

This article describes how I design and implement that boundary. The patterns below are running in production behind my own Antigravity agent execution environment, and they have caught real mistakes since the day I added them.

Why a Sandbox Alone Is Not Enough

The Antigravity sandbox feature is excellent at isolating filesystems and network access. But the kinds of incidents that hurt the most in production happen inside the sandbox.

Concretely:

  • The agent connects to production with valid credentials, but mis-writes the WHERE clause and updates every row in the table.
  • The agent intends to write to a staging S3 bucket, but a hard-coded production bucket name slips through.
  • The agent has a deploy API key for testing, runs what it thinks is a dry deploy, and ships untested code to production.

A sandbox controls which resources the agent can touch. A Permission Boundary controls what it is allowed to do with the resources it touched. They are complementary, and neither alone is enough.

The mental model I prefer is "the sandbox shrinks the universe of reachable resources, and the boundary shrinks the universe of allowed actions on those resources." This is structurally the same as the relationship between AWS SCPs and IAM policies — two independent layers, both enforcing limits.

In practice I think of it as defense in depth, but with a specific structure: the sandbox enforces capability (what tools and endpoints exist at all), while the boundary enforces intent (what operations on those endpoints are allowed in the current context). Failing one layer should never automatically grant access through the other.

A Four-Tier Permission Boundary Model

The cleanest way I've found to organize permissions is to bucket every operation into one of four tiers.

  • Tier 0 — Read-only. SELECT, GET, list. Log it and allow it.
  • Tier 1 — Sandbox write. Test database, staging S3 bucket, PR branch pushes. Auto-approve.
  • Tier 2 — Production write. Production DB UPDATE, production deploy, billing API. Human approval required.
  • Tier 3 — Destructive. DROP TABLE, DELETE without WHERE, rollback, account closure. Human approval plus a second factor required.

The classification lives as metadata on each operation, and it is enforced at runtime. Writing "please don't do destructive things" in the agent prompt does not work — the boundary has to be enforced from outside the agent.

// src/permission-boundary/tier.ts
// Type definitions for permission tiers
export type PermissionTier = 0 | 1 | 2 | 3;
 
export interface AgentOperation {
  resource: string;          // e.g. "db:users", "s3:bucket-prod-uploads"
  action: string;            // e.g. "select", "update", "delete", "deploy"
  tier: PermissionTier;
  reason: string;            // The agent's stated reason — kept for auditing
}
 
// Single source of truth for the resource × action matrix
export function classifyOperation(resource: string, action: string): PermissionTier {
  // Production resources
  if (resource.startsWith('db:prod:') || resource.startsWith('s3:bucket-prod-')) {
    if (['drop', 'truncate', 'delete-bucket'].includes(action)) return 3;
    if (['update', 'insert', 'delete', 'deploy'].includes(action)) return 2;
    return 0;
  }
  // Staging
  if (resource.startsWith('db:staging:') || resource.startsWith('s3:bucket-staging-')) {
    return action === 'select' ? 0 : 1;
  }
  // Unknown resources default to Tier 3 — deny by default
  return 3;
}

The most important line is the last one: unknown resources default to Tier 3. If you forget to classify a new resource you've added, the system fails closed instead of granting elevated privileges. I've made this rule a permanent operational principle, and it has saved me more than once when a junior engineer added a new bucket and forgot to update the classifier.

A subtle but useful side effect of this design is that the classifyOperation function becomes a kind of executable inventory. If you want to audit "what production resources can my agents touch?", you read this one file. There's no need to crawl through configuration scattered across IAM, secrets managers, and deployment scripts.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
A four-tier classification for agent write operations, enforced from outside the agent as a Permission Boundary
Working code for reversible production writes: dry-runs, SQL-hash verification, reverse-operation SQL, and append-only audit logs
How to test the boundary itself in CI and keep it from breaking as your agent fleet grows — central policy, budgets, and trust scoring
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

Agents & Manager2026-04-22
Prompt Injection Defense in Antigravity — A Production Security Playbook for LLM Apps
A practical, code-first guide to defending LLM applications against prompt injection inside Antigravity. Covers direct, indirect, and multi-turn attacks with working Python implementations of a four-layer defense.
Agents & Manager2026-07-05
Protecting Your Agent Stack's Known-Good State with a Single Lockfile — Change-Budget Design for an Era of Simultaneously Moving Parts
When the IDE build, CLI, model, and dependencies all move at once, you can no longer tell which one caused a regression. Here is a change-budget design that pins your known-good state to one lockfile, with working code and operational logs.
Agents & Manager2026-06-28
The Day the Article I Asked It to Format Became the Agent's Instructions
When you run an unattended content-formatting pipeline with Antigravity CLI, instruction-like text buried in the file you are processing can hijack the agent. Here is how I separate the instruction channel from the data channel and add an output-scope acceptance gate to reject anything out of bounds.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →