ANTIGRAVITY LABJP
Articles/Agents & Manager
Agents & Manager/2026-03-27Intermediate

Antigravity Agent Safety Guide — Preventing Runaway AI and Implementing Guardrails

A comprehensive guide to AI coding agent safety. Learn sandboxing techniques, resource controls, network policies, and defense-in-depth strategies for Antigravity.

antigravity429agent-safety2guardrails4sandboxingsecurity16best-practices4

Setup and context

AI coding agents are powerful but risky. Without proper safeguards, an agent can:

  • Consume CPU indefinitely in an infinite loop
  • Delete critical files through careless automation
  • Exfiltrate API keys via log output or untracked requests
  • Execute injected instructions hidden in user input
  • Make unauthorized network calls to external services

Five Critical Agent Risks

Risk 1: Infinite Loops & Resource Exhaustion

// ❌ Dangerous
while (true) {
  const result = await generateCode();
  if (!result) break; // Exit condition never met
}
 
// ✅ Safe
const MAX_ITERATIONS = 5;
let iterations = 0;
 
while (iterations < MAX_ITERATIONS) {
  const result = await generateCode();
  iterations++;
  if (result.success) break;
}

Mitigations:

  • Hard cap on iteration count
  • CPU/memory monitoring at the hypervisor level
  • Strict per-stage timeouts

Risk 2: Unintended File Deletion

// ❌ Dangerous (agent follows injected deletion instruction)
async function deleteFiles(agentCommand) {
  const pathToDelete = agentCommand.parse();
  await fs.rm(pathToDelete, { recursive: true, force: true });
}
 
// ✅ Safe (allowlist enforcement)
const SAFE_DELETE_PATHS = ['/tmp/build', '/tmp/artifacts'];
 
async function deleteFiles(agentCommand) {
  const pathToDelete = agentCommand.parse();
  if (!SAFE_DELETE_PATHS.some(p => pathToDelete.startsWith(p))) {
    throw new Error(`Deletion blocked: ${pathToDelete} not in allowlist`);
  }
  await fs.rm(pathToDelete, { recursive: true });
}

Mitigations:

  • Whitelist allowed deletion directories
  • Require multi-stage approval for deletions
  • Implement dry-run mode first

Risk 3: Credential Leakage

// ❌ Dangerous (logs contain API key)
const output = `Processing complete. API_KEY=${process.env.OPENAI_API_KEY}`;
console.log(output);
 
// ✅ Safe (redaction)
function sanitizeOutput(output) {
  let sanitized = output.replace(/sk_[a-z0-9]{48}/g, 'sk_***');
  sanitized = sanitized.replace(/AIzaSy[a-zA-Z0-9_-]{33}/g, 'AIzaSy***');
  return sanitized;
}
 
console.log(sanitizeOutput(output));

Mitigations:

  • Exclude environment variables from artifacts
  • Regex-based output redaction
  • Enable GitHub Secret Scanning

Risk 4: Prompt Injection

// ❌ Dangerous (user input merged into prompt)
const userInput = getUserInput(); // Could contain injection
const prompt = `You are a coder. ${userInput}. Generate code.`;
const response = await model.generate(prompt);
 
// ✅ Safe (structured input)
const userInstruction = {
  action: "create_button",
  filePath: "components/Button.tsx",
  allowedMethods: ["add", "modify"] // Explicitly constrained
};
 
const prompt = `You are a coder. Follow the JSON instruction below exactly:
${JSON.stringify(userInstruction)}`;
const response = await model.generate(prompt);

Mitigations:

  • Accept structured JSON input, not free-form text
  • Whitelist allowed actions
  • Use prompt templates with fixed structure

Risk 5: Unauthorized Network Access

// ❌ Dangerous (any URL is allowed)
const response = await fetch(agentGeneratedUrl);
 
// ✅ Safe (allowlist)
const ALLOWED_DOMAINS = ['api.github.com', 'api.stripe.com'];
 
async function safeFetch(url) {
  const parsed = new URL(url);
  if (!ALLOWED_DOMAINS.includes(parsed.hostname)) {
    throw new Error(`Network access denied: ${parsed.hostname}`);
  }
  return fetch(url);
}

Mitigations:

  • Whitelist external API domains
  • Enforce zero-trust egress (deny by default)
  • Monitor and rate-limit API calls

Defense-in-Depth Architecture

Single-layer defenses are insufficient. Combine multiple layers:

┌─────────────────────────────────────────────┐
│ Layer 1: Input Validation                   │
│ (structured JSON, injection detection)      │
└─────────────────────────────────────────────┘
              ↓
┌─────────────────────────────────────────────┐
│ Layer 2: Execution Sandbox                  │
│ (Firecracker VM, gVisor kernel)             │
└─────────────────────────────────────────────┘
              ↓
┌─────────────────────────────────────────────┐
│ Layer 3: Resource Limits                    │
│ (CPU, memory, disk, bandwidth cgroups)      │
└─────────────────────────────────────────────┘
              ↓
┌─────────────────────────────────────────────┐
│ Layer 4: Network Policy                     │
│ (allowlist egress, rate limiting)           │
└─────────────────────────────────────────────┘
              ↓
┌─────────────────────────────────────────────┐
│ Layer 5: Output Validation                  │
│ (secret scanning, credential redaction)     │
└─────────────────────────────────────────────┘
              ↓
┌─────────────────────────────────────────────┐
│ Layer 6: Human Review (Artifacts)           │
│ (mandatory approval before deployment)      │
└─────────────────────────────────────────────┘

Implementation Patterns

Pattern 1: Rules (Passive Guardrails)

const agentRules = {
  rules: [
    {
      id: "block_production_delete",
      trigger: "action === 'delete' AND path.includes('production')",
      action: "block",
      message: "Production deletions forbidden"
    },
    {
      id: "enforce_iteration_limit",
      trigger: "iterations > 10",
      action: "stop",
      message: "Too many iterations. Manual review required."
    },
    {
      id: "flag_high_impact",
      trigger: "affectedLines > 1000",
      action: "pause",
      message: "Large changes require approval"
    }
  ]
};

Pros: Declarative, easy to audit, applied before execution. Cons: Reactive; can't handle all edge cases.

Pattern 2: Workflows (Active Monitoring)

const agentWorkflow = {
  pipeline: [
    {
      stage: "generate",
      agent: "writer",
      timeout: "30s",
      onFailure: "rollback"
    },
    {
      stage: "validate",
      agent: "critic",
      rules: [
        "no_hardcoded_secrets",
        "passes_lint",
        "memory_efficient"
      ],
      onFailure: "reject_and_notify"
    },
    {
      stage: "test",
      agent: "tester",
      environment: "firecracker", // Isolated VM
      coverage_threshold: "80%",
      timeout: "60s"
    },
    {
      stage: "approve",
      agent: "human",
      type: "artifacts_review",
      required: true // Mandatory human gate
    }
  ]
};

Pros: Clear stage separation, automatic fail-safes. Cons: Requires orchestration infrastructure.

Pattern 3: Skills (Fine-Grained Access Control)

class SecurityAwareFilesystem {
  constructor(allowlist) {
    this.allowlist = allowlist;
  }
 
  async readFile(path) {
    this.validateAccess('read', path);
    return fs.readFile(path, 'utf-8');
  }
 
  async writeFile(path, content) {
    this.validateAccess('write', path);
    // Scan for embedded secrets before write
    if (this.containsSecret(content)) {
      throw new Error("Credentials detected in output");
    }
    return fs.writeFile(path, content);
  }
 
  async deleteFile(path) {
    this.validateAccess('delete', path);
    // Extra validation for deletions
    const size = await fs.stat(path);
    if (size.size > 10 * 1024 * 1024) {
      throw new Error("Large file deletion requires approval");
    }
    return fs.rm(path);
  }
 
  validateAccess(action, path) {
    const allowed = this.allowlist[action].some(pattern =>
      path.match(new RegExp(pattern))
    );
    if (!allowed) {
      throw new Error(`${action} denied on ${path}`);
    }
  }
 
  containsSecret(content) {
    const patterns = [/sk_[a-z0-9]{48}/, /AIzaSy[a-zA-Z0-9_-]{33}/];
    return patterns.some(p => p.test(content));
  }
}

Pros: Fine-grained, reusable across agents. Cons: Requires careful implementation.

Sandbox Technology Comparison

TechnologySecurityPerformanceComplexityUse Case
FirecrackerExcellent (kernel-isolated)Fast (VM)HighProduction SaaS
gVisorVery good (syscall sandboxing)GoodMediumMulti-tenant
DockerFair (easy escape)ExcellentLowDev/test only
Process isolationWeak (kernel shared)FastestMinimalDemos only

Recommendation:

  • Production: Firecracker
  • Scalable SaaS: gVisor + cgroup
  • Team environments: Docker on VM

Resource Limit Configuration

{
  execution: {
    limits: {
      cpu_cores: 2,           // Max 2 CPUs
      memory_gb: 4,           // Max 4 GB RAM
      disk_gb: 20,            // Max 20 GB temp
      bandwidth_mbps: 100     // Max 100 Mbps egress
    },
    timeout: {
      generation_seconds: 30,
      testing_seconds: 60,
      total_seconds: 300      // 5 min hard cap
    },
    monitoring: {
      cpu_alert_percent: 80,  // Warn at 80%
      memory_alert_percent: 90,
      rate_limit_requests_per_minute: 100
    }
  }
}

Multi-Agent Validation Chain

Serial validation across agents increases safety:

const validationPipeline = [
  {
    stage: 1,
    agent: "Writer",
    responsibility: "Generate code"
  },
  {
    stage: 2,
    agent: "Critic",
    checks: [
      "code_quality",
      "security_scan",
      "performance_baseline"
    ]
  },
  {
    stage: 3,
    agent: "Tester",
    environment: "isolated_vm",
    threshold: { test_coverage: 80 }
  },
  {
    stage: 4,
    agent: "SecurityValidator",
    checks: [
      "dependency_vulnerabilities",
      "static_analysis",
      "secret_detection"
    ]
  },
  {
    stage: 5,
    agent: "Human",
    type: "final_review",
    required: true
  }
];

Each stage catches different issues. Together they drastically reduce oversight.

Summary

Safe Antigravity agent operation requires:

  1. Input validation — Structured JSON, no free-form text
  2. Execution isolation — Firecracker or gVisor
  3. Resource limits — CPU, memory, disk, network quotas
  4. Defense-in-depth — Rules + Workflows + Skills + Human Review
  5. Monitoring — Secret scanning + performance + rate limiting

Combine these layers, and you can harness agent power safely.

To dive deeper:

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 →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

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-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.
Agents & Manager2026-06-19
Your Antigravity Sandbox Isolates Multi-Agents Less Than You Think — Notes on Containing the Blast Radius
An Antigravity sandbox gives you the feeling of isolation, but isolation leaks through three real gaps: shared volumes, over-broad allowed domains, and approval fatigue. Field notes on plugging the leaks, containing the blast radius by design, and proving isolation holds with tests.
📚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 →