Antigravity × AI-Driven Security Audit Automation— Building an Agent Pipeline That Detects and Fixes Vulnerabilities
Learn how to build an automated security audit pipeline using Antigravity's multi-agent system. Covers dependency scanning, OWASP-based code reviews, and CI/CD integration for continuous security monitoring.
Security is often the last thing developers think about — until something goes wrong. Studies in 2026 show that roughly 40% of production incidents stem from security-related issues, many of which could have been caught during development.
With Antigravity's multi-agent capabilities, you can run security audits alongside your coding workflow, catching vulnerabilities early and getting actionable fix suggestions in real time. The walkthrough below covers how to:
Design agents that automatically scan dependencies for known vulnerabilities
Automate code reviews based on the OWASP Top 10
Detect SQL injection, XSS, and authentication bypass patterns
Integrate continuous security auditing into your CI/CD pipeline
Who this is for: Intermediate to advanced developers who are comfortable with Antigravity's basics and understand multi-agent concepts.
Prerequisites
Before diving in, make sure you have the following set up:
Basic CI/CD configuration with GitHub Actions or Cloudflare Workers
✦
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
✦Automated security audit pipeline using AI agents with design and implementation details
✦Agent role distribution across vulnerability detection, classification, and remediation proposal stages
✦Operational practices for continuous security improvement and compliance management
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.
By separating each agent's domain, you get both parallel execution speed and deep, specialized analysis for each security dimension.
Defining Agents in agents.md
Create .antigravity/agents.md at your project root:
# Security Audit ManagerYou are the security audit orchestrator.Manage the three specialized agents below and produce a comprehensive security report.## Delegation Rules1. Delegate dependency vulnerability checks to `dependency-scanner`2. Delegate source code security reviews to `code-reviewer`3. Delegate infrastructure and environment audits to `infra-checker`4. Aggregate all results into a severity-sorted report---# dependency-scannerYou are a dependency security specialist.- Analyze package.json and package-lock.json- Cross-reference against known CVE databases- Check if patched versions are available- Classify severity as Critical / High / Medium / Low---# code-reviewerYou are an application security specialist.Review source code against the OWASP Top 10:- SQL Injection- Cross-Site Scripting (XSS)- Broken Authentication & Authorization- Hardcoded Secrets- Insecure Deserialization---# infra-checkerYou are an infrastructure security specialist.- Verify environment variable management- Validate CORS configuration- Confirm HTTPS enforcement- Audit security headers (CSP, HSTS, etc.)
Automating Dependency Scanning
Integrating with npm audit
Have Antigravity's agent parse npm audit results and suggest concrete fixes.
In the Antigravity terminal, you can prompt the agent like this:
@dependency-scanner Analyze package.json and package-lock.json
for known vulnerabilities. For each one, include whether a fix
is available and your recommended action.
The agent parses the npm audit output and generates a structured report:
Teach the agent pattern-matching rules for common vulnerability types.
// lib/security-patterns.ts// Security pattern detection libraryexport const SQL_INJECTION_PATTERNS = [ // String concatenation in queries (dangerous) /`SELECT.*\$\{.*\}`/g, /['"]SELECT.*['"] \+ /g, /query\(.*\+.*\)/g, // Direct template literal interpolation (dangerous) /\.query\(`[^`]*\$\{[^}]+\}[^`]*`\)/g, // eval or Function constructor (extremely dangerous) /eval\s*\(/g, /new\s+Function\s*\(/g,] as const;export const XSS_PATTERNS = [ // Unsanitized input to innerHTML /\.innerHTML\s*=\s*(?!['"`])/g, // dangerouslySetInnerHTML (React) /dangerouslySetInnerHTML\s*=\s*\{\s*\{\s*__html:\s*(?!DOMPurify)/g, // document.write /document\.write\s*\(/g,] as const;export const AUTH_PATTERNS = [ // Hardcoded secrets /(?:password|secret|api[_-]?key|token)\s*[:=]\s*['"][^'"]{8,}['"]/gi, // Skipping JWT verification /verify\s*:\s*false/g, // Insecure random generation /Math\.random\(\)/g,] as const;/** * Scan a file for security issues */export function scanFile( content: string, filePath: string): SecurityIssue[] { const issues: SecurityIssue[] = []; // SQL Injection checks SQL_INJECTION_PATTERNS.forEach((pattern) => { const matches = content.matchAll(new RegExp(pattern)); for (const match of matches) { issues.push({ type: "SQL_INJECTION", severity: "critical", file: filePath, line: getLineNumber(content, match.index!), message: "Unsanitized input directly interpolated in SQL query", recommendation: "Use parameterized queries or an ORM instead", }); } }); // XSS checks XSS_PATTERNS.forEach((pattern) => { const matches = content.matchAll(new RegExp(pattern)); for (const match of matches) { issues.push({ type: "XSS", severity: "high", file: filePath, line: getLineNumber(content, match.index!), message: "Unsanitized input may be injected into the DOM", recommendation: "Use DOMPurify or text nodes instead", }); } }); return issues;}interface SecurityIssue { type: string; severity: "critical" | "high" | "medium" | "low"; file: string; line: number; message: string; recommendation: string;}function getLineNumber(content: string, index: number): number { return content.substring(0, index).split("\n").length;}// Expected output (when running scanFile):// [// {// type: "SQL_INJECTION",// severity: "critical",// file: "src/api/users.ts",// line: 42,// message: "Unsanitized input directly interpolated in SQL query",// recommendation: "Use parameterized queries or an ORM instead"// }// ]
Automated Fixes via Agents
When a vulnerability is detected, the agent can propose a fix automatically:
@code-reviewer A SQL injection vulnerability was detected in the
following file. Please refactor to use parameterized queries.
Before:
const user = await db.query(`SELECT * FROM users WHERE id = ${userId}`);
After (agent-generated):
const user = await db.query('SELECT * FROM users WHERE id = $1', [userId]);
Infrastructure Security Auditing
Security Headers Checker
// scripts/check-security-headers.ts// Validates security headers for a web applicationinterface SecurityHeaderCheck { header: string; expected: string | RegExp; severity: "critical" | "high" | "medium"; description: string;}const REQUIRED_HEADERS: SecurityHeaderCheck[] = [ { header: "Strict-Transport-Security", expected: /max-age=\d{8,}/, severity: "critical", description: "HSTS: Enforce HTTPS (max-age of at least 1 year recommended)", }, { header: "Content-Security-Policy", expected: /default-src/, severity: "high", description: "CSP: Defend against XSS and data injection attacks", }, { header: "X-Content-Type-Options", expected: "nosniff", severity: "medium", description: "Prevent MIME-type sniffing", }, { header: "X-Frame-Options", expected: /DENY|SAMEORIGIN/, severity: "medium", description: "Prevent clickjacking attacks", }, { header: "Referrer-Policy", expected: /strict-origin|no-referrer/, severity: "medium", description: "Prevent referrer information leakage", },];async function checkSecurityHeaders(url: string) { const response = await fetch(url, { method: "HEAD" }); console.log(`\n🛡️ Security Headers Audit: ${url}`); console.log("=".repeat(60)); let issues = 0; for (const check of REQUIRED_HEADERS) { const value = response.headers.get(check.header); const passed = value ? typeof check.expected === "string" ? value === check.expected : check.expected.test(value) : false; const status = passed ? "✅" : "❌"; console.log(`${status} ${check.header}`); if (!passed) { console.log(` Severity: ${check.severity}`); console.log(` ${check.description}`); console.log(` Current value: ${value || "(not set)"}`); issues++; } } console.log(`\nTotal: ${issues} issue(s) found`); return issues;}// Usage// checkSecurityHeaders("https://your-app.example.com");// Expected output:// 🛡️ Security Headers Audit: https://your-app.example.com// ============================================================// ✅ Strict-Transport-Security// ❌ Content-Security-Policy// Severity: high// CSP: Defend against XSS and data injection attacks// Current value: (not set)// ✅ X-Content-Type-Options// ✅ X-Frame-Options// ✅ Referrer-Policy//// Total: 1 issue(s) found
Environment Variable Safety Checks
// scripts/check-env-security.ts// Audits environment variable management and secret handlingimport * as fs from "fs";import * as path from "path";const SENSITIVE_PATTERNS = [ /API[_-]?KEY/i, /SECRET/i, /PASSWORD/i, /TOKEN/i, /PRIVATE[_-]?KEY/i, /DATABASE[_-]?URL/i, /STRIPE[_-]?SECRET/i,];function auditEnvSecurity(projectRoot: string): void { const issues: string[] = []; // Check if .env is in .gitignore const gitignorePath = path.join(projectRoot, ".gitignore"); if (fs.existsSync(gitignorePath)) { const gitignore = fs.readFileSync(gitignorePath, "utf-8"); if (!gitignore.includes(".env")) { issues.push( "⚠️ CRITICAL: .env is not listed in .gitignore" ); } } // Scan source code for hardcoded secrets const srcDir = path.join(projectRoot, "src"); if (fs.existsSync(srcDir)) { scanDirectory(srcDir, issues); } console.log("\n🔐 Environment Variable Security Audit"); console.log("=".repeat(50)); if (issues.length === 0) { console.log("✅ No issues detected"); } else { issues.forEach((issue) => console.log(issue)); }}function scanDirectory(dir: string, issues: string[]): void { const files = fs.readdirSync(dir, { withFileTypes: true }); for (const file of files) { const fullPath = path.join(dir, file.name); if (file.isDirectory() && file.name !== "node_modules") { scanDirectory(fullPath, issues); } else if ( file.isFile() && /\.(ts|js|tsx|jsx)$/.test(file.name) ) { const content = fs.readFileSync(fullPath, "utf-8"); const lines = content.split("\n"); lines.forEach((line, index) => { SENSITIVE_PATTERNS.forEach((pattern) => { if ( pattern.test(line) && /['"][^'"]{8,}['"]/.test(line) ) { issues.push( `⚠️ HIGH: ${fullPath}:${index + 1} — ` + `Possible hardcoded secret detected` ); } }); }); } }}// Run the audit// auditEnvSecurity(process.cwd());// Expected output:// 🔐 Environment Variable Security Audit// ==================================================// ⚠️ HIGH: src/config/database.ts:15 — Possible hardcoded secret detected// ⚠️ CRITICAL: .env is not listed in .gitignore
CI/CD Pipeline Integration
GitHub Actions Workflow
Integrate security auditing into your CI/CD so every pull request gets automatically checked.
Here's the workflow for feeding CI/CD results back to Antigravity agents for automated remediation:
1. Create a PR → GitHub Actions runs
2. Security scan results are posted as PR comments
3. Open the fix branch in Antigravity
4. Share scan results with @code-reviewer
5. Agent generates fix code
6. Commit fixes → re-scan → merge
A Note from an Indie Developer
Wrapping Up — Bake Security Into Your Development Process
In this guide, we covered how to build an automated security audit pipeline using Antigravity's multi-agent system.
Here are the key takeaways. First, separating specialized agents lets you run dependency, code, and infrastructure audits in parallel for faster results. Second, OWASP Top 10-based pattern detection gives you broad coverage of common web application vulnerabilities. And third, CI/CD integration makes continuous security auditing automatic and frictionless.
Security isn't something you set up once and forget. It's an ongoing process that improves over time. With Antigravity's agents handling the heavy lifting, you can maintain high security standards without sacrificing development speed.
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.