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
| Technology | Security | Performance | Complexity | Use Case |
|---|---|---|---|---|
| Firecracker | Excellent (kernel-isolated) | Fast (VM) | High | Production SaaS |
| gVisor | Very good (syscall sandboxing) | Good | Medium | Multi-tenant |
| Docker | Fair (easy escape) | Excellent | Low | Dev/test only |
| Process isolation | Weak (kernel shared) | Fastest | Minimal | Demos 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:
- Input validation — Structured JSON, no free-form text
- Execution isolation — Firecracker or gVisor
- Resource limits — CPU, memory, disk, network quotas
- Defense-in-depth — Rules + Workflows + Skills + Human Review
- Monitoring — Secret scanning + performance + rate limiting
Combine these layers, and you can harness agent power safely.
To dive deeper:
- Antigravity Agent Memory Patterns — State management best practices
- Antigravity Multi-Agent Production Patterns — Real-world deployment patterns
- Antigravity TDD Test Automation — Test-driven safety