Automated Security Scanning and Remediation with Kiro

Kiro agents perform continuous security audits that detect vulnerabilities, generate fixes, and enforce security policies before code reaches production.

#kiro#security#audit#automation
Cover image for the article: Automated Security Scanning and Remediation with Kiro

Security audits are typically quarterly events that produce a spreadsheet of findings, half of which are stale by the time engineers get to them. We replaced that model with continuous, automated security scanning powered by Kiro. Vulnerabilities are detected at write time, fixes are generated immediately, and our security posture improves with every commit rather than every quarter.

The Problem: Reactive Security at Scale

Our application spans twelve services, 340,000 lines of code, and 187 npm packages across the dependency tree. Before Kiro, security was handled by:

  • Dependabot alerts (noisy, often ignored until they accumulated)
  • Quarterly penetration tests (expensive, findings arrive too late)
  • Manual code review for auth/authz changes (bottlenecked on two senior engineers)
  • Snyk in CI (caught issues, but only after code was already written)

The result: we averaged 23 open critical/high vulnerabilities at any given time. Remediation took an average of 18 days from detection to fix. Engineers treated security findings as a separate backlog that competed with feature work — and feature work usually won.

How Kiro's Security Automation Works

We configured Kiro with a multi-layer security scanning approach using hooks and steering:

Layer 1: Write-Time Detection

A PostFileSave hook runs targeted security checks on every change:

{
  "version": "v1",
  "hooks": [
    {
      "name": "Security scan on save",
      "trigger": "PostFileSave",
      "matcher": "src/.*\\.(ts|js)$",
      "action": {
        "type": "command",
        "command": "scripts/security-scan.sh ${FILE_PATH}"
      }
    },
    {
      "name": "Dependency audit on package change",
      "trigger": "PostFileSave",
      "matcher": "package\\.json$",
      "action": {
        "type": "command",
        "command": "npm audit --audit-level=high --json | scripts/parse-audit.sh"
      }
    }
  ]
}

Layer 2: Context-Aware Security Rules

Our steering file encodes security patterns that Kiro enforces during implementation:

# Security Standards (.kiro/steering/security.md)

## Authentication
- All API endpoints must verify JWT tokens via middleware
- Token validation must check: expiry, issuer, audience, and signature
- Never decode JWT without verification (no jwt.decode() without verify)

## Data Access
- All database queries must use parameterized statements
- Raw SQL concatenation is never acceptable
- User input must be validated with zod schemas before use

## Secrets
- Never log request bodies that may contain credentials
- Environment variables for secrets, never hardcoded
- API keys must be loaded from AWS Secrets Manager, not .env files

## Output
- All API responses must sanitize error messages (no stack traces in production)
- PII fields must be masked in logs (email, phone, SSN)
- CORS must specify exact origins, never wildcard in production

Layer 3: Automated Remediation

When Kiro detects a vulnerability, it does not just report it — it generates a fix:

// BEFORE: Vulnerability detected - SQL injection risk
async function getUser(userId: string) {
  const query = `SELECT * FROM users WHERE id = '${userId}'`;
  return await db.query(query);
}

// AFTER: Kiro-generated fix - parameterized query
async function getUser(userId: string) {
  const query = 'SELECT * FROM users WHERE id = $1';
  return await db.query(query, [userId]);
}
// BEFORE: Vulnerability detected - missing input validation
app.post('/api/users', async (req, res) => {
  const user = req.body;
  await userService.create(user);
  res.json({ success: true });
});

// AFTER: Kiro-generated fix - zod validation with sanitization
import { z } from 'zod';

const CreateUserSchema = z.object({
  email: z.string().email().max(255),
  name: z.string().min(1).max(100).trim(),
  role: z.enum(['user', 'admin']),
});

app.post('/api/users', async (req, res) => {
  const parsed = CreateUserSchema.safeParse(req.body);
  if (!parsed.success) {
    return res.status(400).json({ error: 'Invalid input', details: parsed.error.issues });
  }
  await userService.create(parsed.data);
  res.json({ success: true });
});

The Continuous Audit Pipeline

Beyond individual file changes, we run a weekly comprehensive security audit as a Kiro orchestration:

{
  task: "Weekly security audit",
  stages: [
    { name: "dependency-scan", role: "context-gatherer",
      prompt: "Run npm audit and analyze all high/critical findings. Check for known exploits." },
    { name: "code-patterns", role: "context-gatherer",
      prompt: "Scan for dangerous patterns: eval(), innerHTML assignment, unchecked deserialization, hardcoded secrets." },
    { name: "auth-review", role: "context-gatherer",
      prompt: "Verify all API routes have authentication middleware. Flag any unprotected endpoints." },
    { name: "generate-fixes", role: "implementer",
      depends_on: ["dependency-scan", "code-patterns", "auth-review"],
      prompt: "Generate fixes for all critical findings. Create a PR for each category." }
  ]
}

Before and After: Security Posture

MetricBefore KiroAfter KiroChange
Open critical/high vulnerabilities23 avg2 avg-91%
Mean time to remediation18 days4 hours-99%
Quarterly pentest findings14 avg3 avg-79%
Security-related incidents4/year0/year-100%

Security vulnerability count over time

The most significant metric is mean time to remediation. When vulnerabilities are fixed at write time rather than queued into a backlog, the window of exposure shrinks from weeks to hours.

Patterns That Catch Real Vulnerabilities

Over six months, Kiro caught these categories most frequently:

  1. Missing input validation (34% of findings) — Endpoints accepting unvalidated user input
  2. Overly permissive CORS (18%) — Wildcard origins in staging configs leaking to production
  3. Dependency vulnerabilities (16%) — Transitive dependencies with known CVEs
  4. Logging sensitive data (14%) — Request bodies containing tokens or PII written to logs
  5. Missing auth middleware (10%) — New endpoints added without copying the auth decorator
  6. Insecure defaults (8%) — Development configurations (debug mode, verbose errors) in production paths

Category 5 is particularly interesting. When engineers add new endpoints by copying existing ones, they sometimes remove the auth middleware during development and forget to add it back. Kiro's PostFileCreate hook catches this immediately.

What Kiro Security Scanning Cannot Replace

Automated scanning catches known patterns and enforced rules. It does not replace:

  • Threat modeling — Understanding your attack surface requires human judgment about business context
  • Penetration testing — Chained exploits and business logic vulnerabilities need creative adversarial thinking
  • Security architecture review — Decisions about trust boundaries, encryption strategies, and key management are design choices

We still run quarterly pentests, but the findings are now architectural ("consider adding rate limiting to this endpoint") rather than basic ("this endpoint lacks input validation"). Kiro handles the mechanical security work so that expensive human expertise focuses on strategic decisions.

Implementing This In Your Team

Start with three steps:

  1. Encode your security rules in a steering file. Be specific — "validate all input" is too vague. "All API endpoints must validate request bodies with zod schemas" is actionable.

  2. Add a PostFileSave hook that runs your security scanner on changed files. Start with one check (input validation) and expand.

  3. Run a weekly audit orchestration that scans for categories your realtime hooks do not cover (dependency vulnerabilities, missing auth, logging issues).

Conclusion

Security does not have to be a quarterly event or a competing backlog item. With Kiro enforcing security standards at write time and generating fixes immediately, your security posture improves with every commit. The vulnerabilities that used to accumulate for weeks now live for minutes.

The compound effect is significant. After six months of continuous security automation, our quarterly pentest results improved so dramatically that we reduced the scope (and cost) of external testing. The automation paid for itself in the first quarter.

Comments

    No comments yet. Be the first to share your thoughts.