Early Access Preview
Back to blog
engineeringsecurityai-agentsarchitecture

4 Minutes, 60 Findings: How Our AI Security Agent Audited 200K Lines of Code

March 7, 202611 min readAitherium
Share

Last Tuesday, I typed six words into Claude Code:

"we need a full security review!"

What happened next took 4 minutes. Four parallel Athena subagents — our security oracle agents — tore through 200,000+ lines of Python, TypeScript, and YAML across a large-scale agent operating system. They returned 60+ security findings organized by severity. Critical. High. Medium. Categorized, explained, with file paths and line numbers.

Then we fixed all of them. In one session.

This is the story of how that worked, what they found, and why AI-assisted security auditing is about to change everything about how we ship code.

The Setup

AitherOS is an AI agent operating system. Dozens of microservices across 12 architectural layers, running in a fleet of Docker containers. Agents that can spawn subagents, execute code, call external APIs, manage infrastructure. The attack surface is enormous.

We'd already built a multi-layer defense stack — caller-based tenant isolation, cryptographic capability tokens, prompt injection guards, and a full RBAC system. But security isn't something you build once and forget. Code grows. New services appear. Assumptions drift.

The question was: how much had drifted?

The Audit

Athena is one of our 29 agent personas. She's the Security Oracle — specialized in threat modeling, vulnerability analysis, and code review. When invoked through Claude Code's Agent tool, she gets access to the full codebase via search and read tools, plus web research capabilities.

We didn't send one agent. We sent four, in parallel, each with a different focus area:

  1. Authentication & Authorization — Every auth path, every endpoint guard, every permission check
  2. Injection & Execution — eval(), exec(), shell=True, SQL injection, template injection
  3. Data Protection — Secrets handling, credential storage, logging, encryption
  4. Network & Infrastructure — CORS, TLS, proxy trust, service-to-service auth

Each agent independently crawled the codebase, read relevant files, cross-referenced configurations, and compiled findings. They didn't just grep for patterns — they traced data flows, identified missing guards on specific endpoints, and understood the difference between internal and external attack surfaces.

Four minutes later, four structured reports landed.

What They Found

Critical: The Secrets Vault Was Open

AitherSecrets — the service that stores API keys, database passwords, and encryption keys — had zero authentication on its endpoints.

# BEFORE: Anyone could read any secret
@app.get("/secrets/{name}")
async def get_secret(name: str, service: str = "system"):
    value = await secrets_manager.get(name, service)
    return {"name": name, "value": value}

The service was only accessible from the internal Docker network, but "defense in depth" means every layer authenticates independently. A single container escape or SSRF vulnerability would have given an attacker the entire secrets vault.

# AFTER: API key required on every endpoint
@app.get("/secrets/{name}")
async def get_secret(name: str, service: str = "system",
                     auth: str = Depends(verify_api_key)):
    value = await secrets_manager.get(name, service)
    return {"name": name, "value": value}

Critical: 43 Unprotected Genesis Endpoints

Genesis is the brain of AitherOS — the system orchestrator. Athena found that while the main chat and forge endpoints had caller context guards, 43 endpoints across 6 routers had no authentication at all. Threat detection, soul management, trading operations, session harvesting, configuration management, and internal diagnostics — all wide open.

Every one of these now requires caller authentication with explicit permission checks.

Critical: CORS Allow-All

# BEFORE: Any origin could make authenticated requests
app.add_middleware(CORSMiddleware, allow_origins=["*"])

Both Genesis and the External Gateway had wildcard CORS. This means any website could make authenticated API calls to our services if a user had an active session. Classic CSRF vector.

# AFTER: Explicit origin allowlist
_CORS_ORIGINS = os.environ.get("CORS_ORIGINS",
    "https://aither.chat,https://veil.aitherium.com,http://localhost:3000"
).split(",")

High: Unrestricted eval() and exec()

Three services used eval() or exec() with full Python builtins available:

AitherPulse (the health monitoring system) evaluated alert conditions with eval():

# BEFORE: Full Python eval on user-supplied condition strings
eval(reflex.condition, {"__builtins__": {}}, eval_context)

The empty __builtins__ dict looks safe, but it's trivially bypassable. Athena recommended AST validation — parse the expression, walk the tree, reject anything that isn't a comparison or boolean operation:

# AFTER: AST-validated safe evaluation
def _safe_eval_condition(condition: str, context: dict) -> bool:
    tree = ast.parse(condition, mode='eval')
    for node in ast.walk(tree):
        if isinstance(node, (ast.Expression, ast.Compare, ast.BoolOp,
                             ast.Name, ast.Constant, ast.Attribute,
                             ast.BinOp, ast.Add, ast.Sub, ...)):
            continue
        raise ValueError(f"Unsafe AST node: {type(node).__name__}")
    return bool(eval(compile(tree, '<condition>', 'eval'),
                     {"__builtins__": {}}, context))

The scheduler cron router had exec() with {"__builtins__": __builtins__} — literally the full Python runtime. Fixed to a whitelist of safe builtins (print, len, range, basic types).

CodeActEngine used exec() for code execution. Now blocks __import__, exec, eval, compile, open, and other dangerous functions.

High: Hardcoded Credentials

Athena found three hardcoded secrets:

  1. Admin password AitherAdmin!2025 baked into RBAC initialization
  2. Master key aitheros_dev_master_key_v1 in the skill validator
  3. Internal service secret that defaulted to accepting any token when not configured

All three followed the same anti-pattern: a hardcoded fallback "for development" that never got removed.

# BEFORE: Hardcoded admin password
_DEFAULT_ADMIN_PASSWORD = "AitherAdmin!2025"

# AFTER: Random generation, shown once
_DEFAULT_ADMIN_PASSWORD = os.getenv("AITHER_ADMIN_PASSWORD", "")
if not _DEFAULT_ADMIN_PASSWORD:
    _DEFAULT_ADMIN_PASSWORD = secrets.token_urlsafe(24)
    print(f"\n{'='*60}")
    print(f"  AITHER ADMIN PASSWORD (save this, shown once only):")
    print(f"  {_DEFAULT_ADMIN_PASSWORD}")
    print(f"{'='*60}\n")

High: Fail-Open Auth Patterns

This was the most insidious category. Eight different places where authentication errors defaulted to granting access instead of denying it:

  • Missing client IP defaulted to 127.0.0.1 (local = trusted). Fixed to 0.0.0.0 (unknown = untrusted).
  • Invalid tenant_id defaulted to PLATFORM_CONTEXT (admin). Fixed to PUBLIC_TENANT (restricted).
  • Failed token verification in optional_auth() returned AuthContext() (anonymous but allowed). Fixed to re-raise the HTTP 401.
  • X-Forwarded-For trusted from any connection. Fixed to only trust from RFC 1918 proxy IPs.
  • BadgeEnforcementMiddleware accepted any token when AITHER_INTERNAL_SECRET wasn't set. Fixed to reject all.
  • MCP filesystem allowed unrestricted paths when tenant import failed. Fixed to restrict to repo root.

Each of these individually seems minor. Together, they form a chain where an attacker can incrementally escalate from anonymous to platform-level access.

High: Shell Injection

AitherSteward (the autonomic maintenance agent) ran shell commands with shell=True:

# BEFORE: Shell injection via command string
subprocess.run(cmd, shell=True, capture_output=True, text=True)

# AFTER: Argument splitting, no shell
subprocess.run(shlex.split(cmd), shell=False, capture_output=True, text=True)

PlaybookEngine used create_subprocess_shell() for playbook steps. Fixed to create_subprocess_exec() with shlex.split().

High: Password Hashing

The RBAC fallback used unsalted SHA-256 for password verification:

# BEFORE: No salt, fast hash
hashlib.sha256(password.encode()).hexdigest()

# AFTER: PBKDF2-SHA256, 260K iterations, random salt
hashlib.pbkdf2_hmac('sha256', password.encode(), salt, 260000)

High: API Keys Logged in Plaintext

AitherMoltbook (our social platform integration) logged API keys at INFO level:

# BEFORE
logger.info(f"API Key: {api_key[:8]}...")
logger.info(f"SAVE THIS API KEY: {api_key}")

# AFTER
logger.info("API key received and stored")

Medium: TLS Verification Disabled

AitherBrowser (the web browsing agent) had verify=False on HTTPS requests:

# BEFORE: MitM-vulnerable
requests.get(req.url, timeout=10, verify=False)

# AFTER: Standard TLS verification
requests.get(req.url, timeout=10)

The Fix Process

Here's what's remarkable: we fixed all 60+ findings in a single session.

The process:

  1. Triage — Categorized findings by severity and blast radius
  2. Direct fixes — Simple changes (CORS, TLS, logging) done immediately
  3. Parallel agents — Three Demiurge (code architect) agents dispatched for large changes:
    • One added auth to all AitherSecrets endpoints
    • One added Depends(get_caller) to 43 Genesis router endpoints
    • One sandboxed all eval()/exec() calls
  4. Manual review — Verified each agent's work before committing
  5. Single commit — All fixes in one atomic commit: bfb22e8c3

Total time from "we need a security review" to pushed commit: about 2 hours. The audit itself was 4 minutes. The rest was implementation and verification.

Why This Matters

Traditional security audits take weeks. A human pentester might spend 2-3 days just mapping the attack surface of a large-scale microservice system before writing a single finding. By the time the report is delivered, the codebase has moved on.

AI security agents change the economics entirely:

Speed: 4 minutes for a comprehensive audit. You can run this on every PR.

Coverage: The agents read every file they deemed relevant. No sampling. No "we focused on the authentication module." They found a fail-open pattern in a middleware, a shell injection in an autonomic agent, and a logging leak in a social media integration — three completely unrelated subsystems — in the same pass.

Context: These aren't static analysis rules. Athena understood that shell=True in AitherSteward was dangerous because Steward accepts commands from other agents (dynamic input), while shell=True in AitherWatch was lower risk because it runs hardcoded monitoring commands. The findings were prioritized accordingly.

Iteration speed: Find → fix → verify → deploy in hours, not weeks.

The Uncomfortable Truth

We thought we were doing security well. We had caller-based isolation, cryptographic capability tokens, prompt injection guards, a full RBAC system with tenant scoping. We'd written an entire blog post about defending against autonomous AI attackers.

And yet: 60+ findings. Hardcoded credentials. Fail-open authentication. Unrestricted eval(). CORS wildcards. A secrets vault with no auth.

Every one of these was introduced by reasonable development decisions. "It's internal-only." "We'll add auth later." "The default should be permissive for development." "Nobody would send a request to that endpoint." These are the assumptions that autonomous attackers will methodically test and exploit.

The lesson isn't that we're bad at security. The lesson is that security at scale — across scores of services, 200K+ lines of code, with multiple developers and AI agents contributing code — requires automated, AI-speed review. Human review catches the patterns you're looking for. AI review catches the patterns you forgot to look for.

Running Your Own Audit

If you're building on AitherOS or running a similar multi-service system, here's how to replicate this:

# In Claude Code with AitherOS MCP tools available:
# Launch parallel Athena agents with focused scopes

# Agent 1: Auth & AuthZ
athena: "Audit all authentication and authorization paths..."

# Agent 2: Injection vectors
athena: "Find all eval(), exec(), shell=True, SQL injection..."

# Agent 3: Data protection
athena: "Audit credential storage, logging, encryption..."

# Agent 4: Network security
athena: "Review CORS, TLS, proxy trust, service auth..."

The key is parallelism and focus. Four focused agents finish faster and find more than one agent trying to cover everything.

What's Next

We're building this into our CI/CD pipeline. Every PR will get an Athena review before merge. The Frontier Judge (our cloud-based quality gate using Claude) already reviews code for quality — adding security review is a natural extension.

We're also training the system to learn from its own findings. Every security fix feeds back into the learning loop: the session learning system captures the pattern, the memory graph stores the context, and the next audit starts with knowledge of past vulnerabilities.

The goal is zero-finding audits. Not because we stopped looking, but because the system learned to stop introducing the vulnerabilities in the first place.


All 60+ findings were fixed in commit bfb22e8c3 on the develop branch. The audit was performed by 4 parallel Athena subagents running through Claude Code's Agent tool with full codebase access.

Enjoyed this post?
Share