ai-guard-dev/eslint-plugin-ai-guard

ESLint plugin with 18 rules that catch AI-generated code patterns — empty catch, floating promises, missing auth, and more

TypeScript

15

128 commits

updated Sep 14, 2026

See the code
ai
async
claude-ai
code-quality
coding
copilot
cursor
eslint
eslint-plugin
security
typescript

See what people are saying (1)

SourceMessageScoreDate

3 days after launching my open-source tool on Product Hunt — the feedback that actually changed the roadmap (r/SideProject)

launched AI Guard on Product Hunt on Tuesday. it's an open-source ESLint plugin with 18 deterministic rules that catch the patterns AI coding assistants keep slipping into JS/TS: floating promises, empty catch blocks, hardcoded secrets, SQL string concat, missing authz checks. ships as a CLI, a…

1

Sep 18, 2026

README

AI Guard Logo

AI Guard

Deterministic AST safety layer and CI guardrails for AI-assisted JavaScript and TypeScript code.

Website  •  npm Package  •  GitHub Repository  •  Rules Catalog  •  Documentation

npm version CI Status npm downloads MIT License Security Policy Website


What is AI Guard?

AI Guard (eslint-plugin-ai-guard) is a deterministic ESLint plugin, CLI, and GitHub Action engineered to detect reliability bugs, async hazards, security vulnerabilities, and code-scaffolding defects frequently introduced during AI-assisted development (GitHub Copilot, Cursor, Claude Code, Gemini Code Assist, etc.).

AI Guard analyzes Abstract Syntax Trees (AST) using ESLint's native engine. It runs locally in your editor, in your terminal via the zero-config CLI, and in your CI/CD pipelines via native SARIF 2.1.0 integration with GitHub Code Scanning.

What AI Guard is NOT

[!IMPORTANT]

  • AI Guard is NOT an AI detector. It does not attempt to predict whether code was authored by an LLM or a human.
  • AI Guard detects dangerous or fragile code patterns that LLMs repeatedly introduce due to incomplete context, hallucinated patterns, or probabilistic generation.
  • AI Guard does NOT replace ESLint. It extends ESLint with 18 specialized, high-impact rules that core ESLint and standard configurations omit.

Why AI Guard?

AI coding assistants write code at remarkable velocity, but generated code repeatedly suffers from predictable reliability and security anti-patterns that conventional linters miss:

PatternWhy AI Assistants Generate ItReal-World Impact
Floating PromisesOmits await, return, or .catch() on async callsUnhandled promise rejections, silent failures in background jobs
Async Array IterationPasses async callbacks into array.map() or .filter()Returns unawaited Promise[] instead of resolved values
Sequential Awaits in LoopsLoops over items with sequential awaitSignificant latency bottlenecks; blocks event loop execution
Empty Catch BlocksInserts generic try { ... } catch (e) {} blocksSwallows production exceptions silently without telemetry
Hardcoded SecretsInjects placeholder or real API keys/tokensCredential leakage in version control and deployment bundles
Dynamic eval()Generates dynamic function compilationArbitrary code execution and code injection
Raw SQL ConcatenationConcatenates query strings with variablesSevere SQL injection vulnerabilities
Unsafe DeserializationCalls JSON.parse(req.body) directly without schema checksDenial of service and unhandled runtime crashes
Missing Route Auth & AuthzEmits boilerplate endpoints without auth middlewareUnprotected API endpoints and IDOR privilege escalations
Dead Branches & ScaffoldingLeaves if (true) or conflicting conditions from prompt iterationsBloated bundles and dead code paths

AI Guard provides an instantaneous, deterministic feedback loop that catches these issues before they reach pull requests or production.


Architecture & Workflow

flowchart TD
    subgraph Dev["1. Development & Prompt Phase"]
        A["Developer + AI Coding Assistant\n(Copilot, Cursor, Claude Code)"] --> B["JavaScript / TypeScript Code"]
    end

    subgraph ShiftLeft["Shift Left — Context Injection"]
        SL["npx ai-guard init-context"] -.-> CTX["CLAUDE.md\n.cursorrules\ncopilot-instructions.md"]
        CTX -.-> A
    end

    subgraph Analysis["2. Deterministic AST Analysis"]
        B --> C["ESLint Parser\n(espree / @typescript-eslint/parser)"]
        C --> D["AST Representation"]
        D --> E["AI Guard Rules Engine\n(18 Deterministic Rules)"]
    end

    subgraph Tiers["3. Classification & Presets"]
        E --> F{"Active Preset\n(recommended | strict | security)"}
        F --> G["Confidence Tiering & AST Filtering"]
    end

    subgraph Outputs["4. Output & Remediation"]
        G --> H["Local CLI Scanning\n(ai-guard run / changed)"]
        G --> I["Autofix Remediation\n(eslint --fix)"]
        G --> J["HTML Dashboard\n(ai-guard report)"]
        G --> K["SARIF 2.1.0 Artifact\n(ai-guard --sarif)"]
    end

    subgraph CI["5. GitHub Pull Request & CI/CD"]
        K --> L["GitHub Action\nai-guard-dev/eslint-plugin-ai-guard@v1"]
        L --> M["GitHub Code Scanning Alerts"]
        L --> N["Inline PR Code Annotations"]
        L --> O["PR Status Check (Blocks Merge)"]
    end

Rules Catalog

AI Guard includes 18 deterministic rules divided into four specialized categories. Every rule is engineered with low false-positive heuristics and validated against real-world production codebases:

🔴 Security (6 Rules)

RuleRecommendedWhat It CatchesFixable?
no-hardcoded-secreterrorAPI keys, bearer tokens, passwords, and private keys committed directly in source code.Yes (process.env.*)
no-eval-dynamicerroreval(), new Function(), and setTimeout/setInterval with dynamic/non-literal string expressions.No
no-sql-string-concatwarnSQL queries constructed by string concatenation or raw template literals — SQL injection risks.No
no-unsafe-deserializewarnUnchecked JSON.parse() called directly on HTTP request inputs (req.body, req.query, req.params).No
require-auth-middlewarewarnExpress and Fastify route definitions exposed without authentication middleware.No
require-authz-checkwarnEndpoints accessing sensitive resources or user IDs without tenant/ownership authorization checks.No

🟠 Reliability (4 Rules)

RuleRecommendedWhat It CatchesFixable?
no-empty-catcherrorEmpty catch (e) {} blocks that silently swallow exceptions without logging or rethrowing.Yes (inserts /* TODO: handle error */)
no-broad-exceptionwarnCatching broad exception types like catch (e: any) that mask system faults and typing.No
no-catch-log-rethrowoff*Catch blocks that only log to console and rethrow without adding context or diagnostic info.No
no-catch-without-useoff*Caught error variables that are declared in catch parameters but never referenced.No

🟡 Async Stability (5 Rules)

RuleRecommendedWhat It CatchesFixable?
no-floating-promiseerrorAsync function invocations without await, .catch(), or return — leading to silent dropped errors.Yes (marks with void)
no-async-array-callbackwarnAsync callbacks passed to map(), filter(), forEach(), or reduce() returning Promise[].No
no-await-in-loopwarnSequential await in loops where iterations can be safely executed concurrently with Promise.all.Yes (rewrites to Promise.all)
no-async-without-awaitwarnFunctions declared async that never execute an await expression, adding unnecessary Promise overhead.No
no-redundant-awaitoff*Redundant return await statements outside of try...catch blocks.No

🔵 AI Patterns (3 Rules)

RuleRecommendedWhat It CatchesFixable?
no-dead-branchwarnUnreachable or tautological branches (if (true), if (false), x && !x) left behind from LLM code synthesis.No
no-duplicate-logic-blockoff*Consecutive duplicate code blocks or repeated conditional branches duplicated during AI edits.No
no-console-in-handleroff*Unstructured console.log statements left in HTTP route handlers instead of production loggers.No

* Enabled at error level in the strict preset.


Presets

AI Guard exports three official configurations ready for flat config or legacy setups:

PresetDescriptionConfiguration Focus
recommendedDefault. Balanced adoption preset. Enables 4 high-confidence critical rules at error, 9 context-sensitive rules at warn, and disables 5 noisy rules. Zero noise on day one.Production codebases, new teams
strictEnforces all 18 rules at error. Designed for zero-tolerance CI gates, high-assurance software, and mature teams.Strict CI/CD quality gates
securityFocuses exclusively on the 6 security rules (no-hardcoded-secret, no-eval-dynamic, no-sql-string-concat at error; remainder at warn).AppSec auditing & security scans

Quick Start & Installation

Install the package as a development dependency using your package manager:

# npm
npm install --save-dev eslint-plugin-ai-guard

# pnpm
pnpm add -D eslint-plugin-ai-guard

# yarn
yarn add -D eslint-plugin-ai-guard

# bun
bun add -d eslint-plugin-ai-guard

Requirements

  • Node.js: >= 20.0.0
  • ESLint: >= 8.0.0 (Supports both Flat Config and legacy configs)
  • TypeScript (optional): @typescript-eslint/parser >= 6.0.0 for TypeScript AST parsing

ESLint Configuration

1. Modern Flat Config (eslint.config.mjs / eslint.config.js)

AI Guard exports full native support for modern ESLint Flat Config:

// eslint.config.mjs
import aiGuard from 'eslint-plugin-ai-guard';

export default [
  {
    plugins: {
      'ai-guard': aiGuard,
    },
    rules: {
      ...aiGuard.configs.recommended.rules,
      // Custom overrides if desired:
      'ai-guard/no-floating-promise': 'error',
    },
  },
];

To use the strict or security preset in flat config:

// Strict preset — all 18 rules at error
rules: {
  ...aiGuard.configs.strict.rules,
}

// Security preset — security rules only
rules: {
  ...aiGuard.configs.security.rules,
}

2. Legacy Config (.eslintrc.js / .eslintrc.json)

// .eslintrc.js
module.exports = {
  plugins: ['ai-guard'],
  extends: ['plugin:ai-guard/recommended'],
};

CLI Reference

AI Guard includes a full-featured CLI binary (ai-guard) that runs out of the box with zero ESLint configuration files required:

npx ai-guard <command> [options]

Core Commands

CommandPurposeCommon Options
runScan your workspace using AI Guard AST rules--path <dir>, --strict, --security, --json, --sarif, --fail-on <level>, --max-warnings <n>
changedFast CI scan — only scans modified files in git--pr, --staged, --base <branch>, --strict, --sarif, --sarif-output <file>, --fail-on <level>
initAutomatically detect environment & configure ESLint--preset <name>, --flat, --dry-run, -y, --yes
init-contextGenerate prompt instruction files for AI coding agents-a, --all, --force, --dry-run, --rules <categories>
doctorDiagnose your ESLint, parser, and plugin environment(No options needed — prints actionable diagnostic report)
baselineSnapshot current issues to track only new regressions--save, --check, --mode <strict|stable>, --preset <name>
reportGenerate an interactive standalone HTML audit report--path <dir>, --preset <name>, --output <file>, --no-open, --json
presetInteractively select and switch active preset in config(Interactive prompt with automatic config patch & backup)
ignoreAdd standard ignore paths (.next, dist, build) to config(Patches flat config or legacy ignores safely)

CLI Usage Examples

# 1. Immediate scan of current directory
npx ai-guard run

# 2. Strict CI scan failing only on high-confidence issues
npx ai-guard run --strict --fail-on high

# 3. Pull Request scan (diffs against PR target branch)
npx ai-guard changed --pr --sarif --sarif-output results.sarif

# 4. Generate AI agent guardrails for Cursor, Claude Code, and Copilot
npx ai-guard init-context --all

# 5. Generate interactive HTML diagnostic report
npx ai-guard report --output ai-guard-report.html

# 6. Save existing issues as baseline and only fail on new regressions
npx ai-guard baseline --save
npx ai-guard baseline --check

AI Agent Integration (init-context)

Standard linters only run after code has already been written. The init-context command shifts your guardrails left by embedding AI Guard's rules directly into the instruction files loaded by your AI coding tools:

npx ai-guard init-context --all

This generates three targeted context files:

  1. CLAUDE.md — Automatically loaded by Claude Code
  2. .cursorrules — Automatically loaded by Cursor
  3. .github/copilot-instructions.md — Automatically loaded by GitHub Copilot

How Shift-Left Works

AI Guard (init-context)
       ↓
Generates project guardrail files (CLAUDE.md, .cursorrules, copilot-instructions.md)
       ↓
AI coding assistant reads safety rules before generating code
       ↓
Model avoids floating promises, empty catches, and hardcoded secrets at prompt time
       ↓
AI Guard CLI & GitHub Action deterministically verifies the output in CI

This dual-layer defense minimizes review friction and ensures generated code meets your security standard on the first pass.


GitHub Action

The official AI Guard GitHub Action runs on PRs, detects changed files, provides step summaries, outputs SARIF 2.1.0, and posts inline PR annotations directly on GitHub:

# .github/workflows/ai-guard.yml
name: AI Guard

on:
  pull_request:
    branches: [main, develop]
  push:
    branches: [main]

jobs:
  ai-guard-scan:
    name: AI Guard Code Review
    runs-on: ubuntu-latest

    permissions:
      contents: read
      security-events: write
      actions: read

    steps:
      - name: Checkout Code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0 # Required for git diff comparison

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'

      - name: Run AI Guard
        uses: ai-guard-dev/eslint-plugin-ai-guard@v1
        with:
          preset: 'recommended'
          fail-on: 'high'
          changed-only: 'true'
          upload-sarif: 'true'

Action Inputs (action.yml)

InputDescriptionDefault
presetRule preset: recommended | strict | security'recommended'
fail-onSeverity threshold to fail CI: high | medium | any | none'high'
changed-onlyScan only files changed in this PR / commit'true'
pathTarget file or directory to scan'.'
upload-sarifUpload results to GitHub Code Scanning'true'
github-summaryWrite an execution breakdown to the GitHub Actions Job Summary'true'
working-directoryWorking directory for scanning (ideal for monorepos)'.'
package-managerPackage manager: auto | npm | pnpm | yarn'auto'
sarif-outputOutput filepath for generated SARIF report'ai-guard-results.sarif'
install-depsInstall project dependencies prior to scanning'true'

Action Outputs

OutputDescription
issues-foundTotal number of issues found across scanned files
high-confidence-countNumber of high-confidence issues flagged
medium-confidence-countNumber of medium-confidence issues flagged
files-scannedCount of files analyzed during the execution
sarif-fileAbsolute path to the generated SARIF 2.1.0 artifact
duration-msTotal scan execution duration in milliseconds

SARIF & GitHub Code Scanning

AI Guard natively outputs SARIF 2.1.0 (Static Analysis Results Interchange Format). When uploaded via the GitHub Action or github/codeql-action/upload-sarif@v3, findings integrate directly with GitHub Advanced Security:

  • Inline PR Annotations: Direct comments on the exact source lines where flaws exist.
  • Security Dashboard: Persistent alerts under your repository's Security → Code scanning tab.
  • Merge Protection: Block merges automatically when high-confidence security or async bugs are detected.

Visual Previews

Inline Pull Request Annotations

AI Guard PR Inline Annotations

GitHub Advanced Security Summary

GitHub Advanced Security Summary for AI Guard

Persistent Code Scanning Dashboard

GitHub Code Scanning Alerts List

Rule Examples (Before & After)

1. no-floating-promise (Unhandled Promises)

// ❌ BAD: Floating promise. Errors are dropped silently.
async function syncUserProfile(user: User) {
  sendTelemetryEvent('user_sync', user.id);
  database.save(user);
}

// ✅ GOOD: Awaited, explicitly handled, or marked with void
async function syncUserProfile(user: User) {
  await database.save(user);
  void sendTelemetryEvent('user_sync', user.id); // Explicitly unhandled
}

2. no-hardcoded-secret (Committed Credentials)

// ❌ BAD: Secret committed inline
const client = new PaymentGateway({
  apiKey: 'sk-prod-983427598273498273948273',
});

// ✅ GOOD: Read from environment variable (Autofixable!)
const client = new PaymentGateway({
  apiKey: process.env.API_KEY,
});

3. no-await-in-loop (Sequential Latency Trap)

// ❌ BAD: Consecutive awaits block each iteration sequentially
async function fetchAllUsers(ids: string[]) {
  const users = [];
  for (const id of ids) {
    users.push(await fetchUser(id));
  }
  return users;
}

// ✅ GOOD: Concurrently fetched with Promise.all (Autofixable!)
async function fetchAllUsers(ids: string[]) {
  return await Promise.all(ids.map((id) => fetchUser(id)));
}

4. no-empty-catch (Swallowed Errors)

// ❌ BAD: Exception swallowed without trace
try {
  parseConfiguration(rawConfig);
} catch (e) {}

// ✅ GOOD: Logged, rethrown, or documented (Autofixable!)
try {
  parseConfiguration(rawConfig);
} catch (e) {
  logger.error('Configuration parsing failed', { error: e });
  throw e;
}

5. no-sql-string-concat (SQL Injection)

// ❌ BAD: Dynamic string interpolation in SQL
const query = `SELECT * FROM users WHERE organization_id = '${orgId}' AND role = '${role}'`;
await db.query(query);

// ✅ GOOD: Parameterized query binding
const query = 'SELECT * FROM users WHERE organization_id = $1 AND role = $2';
await db.query(query, [orgId, role]);

Automatic Remediation (Autofix)

Rules that have deterministic solutions provide automatic autofix handlers. Run ESLint's native --fix flag to automatically resolve them:

npx eslint . --fix
RuleAutomatic Fix Behavior
no-hardcoded-secretReplaces hardcoded string literal with process.env.VARIABLE_NAME
no-empty-catchInserts /* TODO: handle error */ comment to prevent silent swallowing
no-floating-promisePrepends void expression to intentionally unawaited calls
no-await-in-loopRewrites straightforward sequential loops to await Promise.all(...)

Performance & Philosophy

  • Zero LLM Overhead: AI Guard does not call external APIs, does not incur token costs, and does not add LLM latency. A scan of 100+ files executes in milliseconds.
  • 100% Deterministic: Every finding is derived strictly from Abstract Syntax Tree analysis. No probabilistic drift, no non-deterministic hallucinated findings.
  • Low False Positives: Built with precision-first design. Context-sensitive rules are configured at warn or off in the recommended preset so developers are never blocked by noise.
  • Self-Scanning: AI Guard enforces its own rules on its own codebase in CI using the strict preset.

Learn More & Ecosystem

Visit getaiguard.dev to explore interactive documentation, rule catalogs, benchmarks, and deep-dive engineering articles.


Contributing

We welcome contributions, new rule ideas, bug reports, and false-positive reports!

  1. Check out our Contributing Guide for local setup and testing standards.
  2. Review our Security Policy to report vulnerabilities responsibly.
  3. Check open issues or submit new ones on our Issue Tracker.

License

MIT © AI Guard Authors. Free and open source forever.

Contributors

ai-guard-dev/eslint-plugin-ai-guard

ESLint plugin with 18 rules that catch AI-generated code patterns — empty catch, floating promises, missing auth, and more

TypeScript

15

128 commits

updated Sep 14, 2026

See the code
ai
async
claude-ai
code-quality
coding
copilot
cursor
eslint
eslint-plugin
security
typescript

See what people are saying (1)

SourceMessageScoreDate

3 days after launching my open-source tool on Product Hunt — the feedback that actually changed the roadmap (r/SideProject)

launched AI Guard on Product Hunt on Tuesday. it's an open-source ESLint plugin with 18 deterministic rules that catch the patterns AI coding assistants keep slipping into JS/TS: floating promises, empty catch blocks, hardcoded secrets, SQL string concat, missing authz checks. ships as a CLI, a…

1

Sep 18, 2026

README

AI Guard Logo

AI Guard

Deterministic AST safety layer and CI guardrails for AI-assisted JavaScript and TypeScript code.

Website  •  npm Package  •  GitHub Repository  •  Rules Catalog  •  Documentation

npm version CI Status npm downloads MIT License Security Policy Website


What is AI Guard?

AI Guard (eslint-plugin-ai-guard) is a deterministic ESLint plugin, CLI, and GitHub Action engineered to detect reliability bugs, async hazards, security vulnerabilities, and code-scaffolding defects frequently introduced during AI-assisted development (GitHub Copilot, Cursor, Claude Code, Gemini Code Assist, etc.).

AI Guard analyzes Abstract Syntax Trees (AST) using ESLint's native engine. It runs locally in your editor, in your terminal via the zero-config CLI, and in your CI/CD pipelines via native SARIF 2.1.0 integration with GitHub Code Scanning.

What AI Guard is NOT

[!IMPORTANT]

  • AI Guard is NOT an AI detector. It does not attempt to predict whether code was authored by an LLM or a human.
  • AI Guard detects dangerous or fragile code patterns that LLMs repeatedly introduce due to incomplete context, hallucinated patterns, or probabilistic generation.
  • AI Guard does NOT replace ESLint. It extends ESLint with 18 specialized, high-impact rules that core ESLint and standard configurations omit.

Why AI Guard?

AI coding assistants write code at remarkable velocity, but generated code repeatedly suffers from predictable reliability and security anti-patterns that conventional linters miss:

PatternWhy AI Assistants Generate ItReal-World Impact
Floating PromisesOmits await, return, or .catch() on async callsUnhandled promise rejections, silent failures in background jobs
Async Array IterationPasses async callbacks into array.map() or .filter()Returns unawaited Promise[] instead of resolved values
Sequential Awaits in LoopsLoops over items with sequential awaitSignificant latency bottlenecks; blocks event loop execution
Empty Catch BlocksInserts generic try { ... } catch (e) {} blocksSwallows production exceptions silently without telemetry
Hardcoded SecretsInjects placeholder or real API keys/tokensCredential leakage in version control and deployment bundles
Dynamic eval()Generates dynamic function compilationArbitrary code execution and code injection
Raw SQL ConcatenationConcatenates query strings with variablesSevere SQL injection vulnerabilities
Unsafe DeserializationCalls JSON.parse(req.body) directly without schema checksDenial of service and unhandled runtime crashes
Missing Route Auth & AuthzEmits boilerplate endpoints without auth middlewareUnprotected API endpoints and IDOR privilege escalations
Dead Branches & ScaffoldingLeaves if (true) or conflicting conditions from prompt iterationsBloated bundles and dead code paths

AI Guard provides an instantaneous, deterministic feedback loop that catches these issues before they reach pull requests or production.


Architecture & Workflow

flowchart TD
    subgraph Dev["1. Development & Prompt Phase"]
        A["Developer + AI Coding Assistant\n(Copilot, Cursor, Claude Code)"] --> B["JavaScript / TypeScript Code"]
    end

    subgraph ShiftLeft["Shift Left — Context Injection"]
        SL["npx ai-guard init-context"] -.-> CTX["CLAUDE.md\n.cursorrules\ncopilot-instructions.md"]
        CTX -.-> A
    end

    subgraph Analysis["2. Deterministic AST Analysis"]
        B --> C["ESLint Parser\n(espree / @typescript-eslint/parser)"]
        C --> D["AST Representation"]
        D --> E["AI Guard Rules Engine\n(18 Deterministic Rules)"]
    end

    subgraph Tiers["3. Classification & Presets"]
        E --> F{"Active Preset\n(recommended | strict | security)"}
        F --> G["Confidence Tiering & AST Filtering"]
    end

    subgraph Outputs["4. Output & Remediation"]
        G --> H["Local CLI Scanning\n(ai-guard run / changed)"]
        G --> I["Autofix Remediation\n(eslint --fix)"]
        G --> J["HTML Dashboard\n(ai-guard report)"]
        G --> K["SARIF 2.1.0 Artifact\n(ai-guard --sarif)"]
    end

    subgraph CI["5. GitHub Pull Request & CI/CD"]
        K --> L["GitHub Action\nai-guard-dev/eslint-plugin-ai-guard@v1"]
        L --> M["GitHub Code Scanning Alerts"]
        L --> N["Inline PR Code Annotations"]
        L --> O["PR Status Check (Blocks Merge)"]
    end

Rules Catalog

AI Guard includes 18 deterministic rules divided into four specialized categories. Every rule is engineered with low false-positive heuristics and validated against real-world production codebases:

🔴 Security (6 Rules)

RuleRecommendedWhat It CatchesFixable?
no-hardcoded-secreterrorAPI keys, bearer tokens, passwords, and private keys committed directly in source code.Yes (process.env.*)
no-eval-dynamicerroreval(), new Function(), and setTimeout/setInterval with dynamic/non-literal string expressions.No
no-sql-string-concatwarnSQL queries constructed by string concatenation or raw template literals — SQL injection risks.No
no-unsafe-deserializewarnUnchecked JSON.parse() called directly on HTTP request inputs (req.body, req.query, req.params).No
require-auth-middlewarewarnExpress and Fastify route definitions exposed without authentication middleware.No
require-authz-checkwarnEndpoints accessing sensitive resources or user IDs without tenant/ownership authorization checks.No

🟠 Reliability (4 Rules)

RuleRecommendedWhat It CatchesFixable?
no-empty-catcherrorEmpty catch (e) {} blocks that silently swallow exceptions without logging or rethrowing.Yes (inserts /* TODO: handle error */)
no-broad-exceptionwarnCatching broad exception types like catch (e: any) that mask system faults and typing.No
no-catch-log-rethrowoff*Catch blocks that only log to console and rethrow without adding context or diagnostic info.No
no-catch-without-useoff*Caught error variables that are declared in catch parameters but never referenced.No

🟡 Async Stability (5 Rules)

RuleRecommendedWhat It CatchesFixable?
no-floating-promiseerrorAsync function invocations without await, .catch(), or return — leading to silent dropped errors.Yes (marks with void)
no-async-array-callbackwarnAsync callbacks passed to map(), filter(), forEach(), or reduce() returning Promise[].No
no-await-in-loopwarnSequential await in loops where iterations can be safely executed concurrently with Promise.all.Yes (rewrites to Promise.all)
no-async-without-awaitwarnFunctions declared async that never execute an await expression, adding unnecessary Promise overhead.No
no-redundant-awaitoff*Redundant return await statements outside of try...catch blocks.No

🔵 AI Patterns (3 Rules)

RuleRecommendedWhat It CatchesFixable?
no-dead-branchwarnUnreachable or tautological branches (if (true), if (false), x && !x) left behind from LLM code synthesis.No
no-duplicate-logic-blockoff*Consecutive duplicate code blocks or repeated conditional branches duplicated during AI edits.No
no-console-in-handleroff*Unstructured console.log statements left in HTTP route handlers instead of production loggers.No

* Enabled at error level in the strict preset.


Presets

AI Guard exports three official configurations ready for flat config or legacy setups:

PresetDescriptionConfiguration Focus
recommendedDefault. Balanced adoption preset. Enables 4 high-confidence critical rules at error, 9 context-sensitive rules at warn, and disables 5 noisy rules. Zero noise on day one.Production codebases, new teams
strictEnforces all 18 rules at error. Designed for zero-tolerance CI gates, high-assurance software, and mature teams.Strict CI/CD quality gates
securityFocuses exclusively on the 6 security rules (no-hardcoded-secret, no-eval-dynamic, no-sql-string-concat at error; remainder at warn).AppSec auditing & security scans

Quick Start & Installation

Install the package as a development dependency using your package manager:

# npm
npm install --save-dev eslint-plugin-ai-guard

# pnpm
pnpm add -D eslint-plugin-ai-guard

# yarn
yarn add -D eslint-plugin-ai-guard

# bun
bun add -d eslint-plugin-ai-guard

Requirements

  • Node.js: >= 20.0.0
  • ESLint: >= 8.0.0 (Supports both Flat Config and legacy configs)
  • TypeScript (optional): @typescript-eslint/parser >= 6.0.0 for TypeScript AST parsing

ESLint Configuration

1. Modern Flat Config (eslint.config.mjs / eslint.config.js)

AI Guard exports full native support for modern ESLint Flat Config:

// eslint.config.mjs
import aiGuard from 'eslint-plugin-ai-guard';

export default [
  {
    plugins: {
      'ai-guard': aiGuard,
    },
    rules: {
      ...aiGuard.configs.recommended.rules,
      // Custom overrides if desired:
      'ai-guard/no-floating-promise': 'error',
    },
  },
];

To use the strict or security preset in flat config:

// Strict preset — all 18 rules at error
rules: {
  ...aiGuard.configs.strict.rules,
}

// Security preset — security rules only
rules: {
  ...aiGuard.configs.security.rules,
}

2. Legacy Config (.eslintrc.js / .eslintrc.json)

// .eslintrc.js
module.exports = {
  plugins: ['ai-guard'],
  extends: ['plugin:ai-guard/recommended'],
};

CLI Reference

AI Guard includes a full-featured CLI binary (ai-guard) that runs out of the box with zero ESLint configuration files required:

npx ai-guard <command> [options]

Core Commands

CommandPurposeCommon Options
runScan your workspace using AI Guard AST rules--path <dir>, --strict, --security, --json, --sarif, --fail-on <level>, --max-warnings <n>
changedFast CI scan — only scans modified files in git--pr, --staged, --base <branch>, --strict, --sarif, --sarif-output <file>, --fail-on <level>
initAutomatically detect environment & configure ESLint--preset <name>, --flat, --dry-run, -y, --yes
init-contextGenerate prompt instruction files for AI coding agents-a, --all, --force, --dry-run, --rules <categories>
doctorDiagnose your ESLint, parser, and plugin environment(No options needed — prints actionable diagnostic report)
baselineSnapshot current issues to track only new regressions--save, --check, --mode <strict|stable>, --preset <name>
reportGenerate an interactive standalone HTML audit report--path <dir>, --preset <name>, --output <file>, --no-open, --json
presetInteractively select and switch active preset in config(Interactive prompt with automatic config patch & backup)
ignoreAdd standard ignore paths (.next, dist, build) to config(Patches flat config or legacy ignores safely)

CLI Usage Examples

# 1. Immediate scan of current directory
npx ai-guard run

# 2. Strict CI scan failing only on high-confidence issues
npx ai-guard run --strict --fail-on high

# 3. Pull Request scan (diffs against PR target branch)
npx ai-guard changed --pr --sarif --sarif-output results.sarif

# 4. Generate AI agent guardrails for Cursor, Claude Code, and Copilot
npx ai-guard init-context --all

# 5. Generate interactive HTML diagnostic report
npx ai-guard report --output ai-guard-report.html

# 6. Save existing issues as baseline and only fail on new regressions
npx ai-guard baseline --save
npx ai-guard baseline --check

AI Agent Integration (init-context)

Standard linters only run after code has already been written. The init-context command shifts your guardrails left by embedding AI Guard's rules directly into the instruction files loaded by your AI coding tools:

npx ai-guard init-context --all

This generates three targeted context files:

  1. CLAUDE.md — Automatically loaded by Claude Code
  2. .cursorrules — Automatically loaded by Cursor
  3. .github/copilot-instructions.md — Automatically loaded by GitHub Copilot

How Shift-Left Works

AI Guard (init-context)
       ↓
Generates project guardrail files (CLAUDE.md, .cursorrules, copilot-instructions.md)
       ↓
AI coding assistant reads safety rules before generating code
       ↓
Model avoids floating promises, empty catches, and hardcoded secrets at prompt time
       ↓
AI Guard CLI & GitHub Action deterministically verifies the output in CI

This dual-layer defense minimizes review friction and ensures generated code meets your security standard on the first pass.


GitHub Action

The official AI Guard GitHub Action runs on PRs, detects changed files, provides step summaries, outputs SARIF 2.1.0, and posts inline PR annotations directly on GitHub:

# .github/workflows/ai-guard.yml
name: AI Guard

on:
  pull_request:
    branches: [main, develop]
  push:
    branches: [main]

jobs:
  ai-guard-scan:
    name: AI Guard Code Review
    runs-on: ubuntu-latest

    permissions:
      contents: read
      security-events: write
      actions: read

    steps:
      - name: Checkout Code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0 # Required for git diff comparison

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'

      - name: Run AI Guard
        uses: ai-guard-dev/eslint-plugin-ai-guard@v1
        with:
          preset: 'recommended'
          fail-on: 'high'
          changed-only: 'true'
          upload-sarif: 'true'

Action Inputs (action.yml)

InputDescriptionDefault
presetRule preset: recommended | strict | security'recommended'
fail-onSeverity threshold to fail CI: high | medium | any | none'high'
changed-onlyScan only files changed in this PR / commit'true'
pathTarget file or directory to scan'.'
upload-sarifUpload results to GitHub Code Scanning'true'
github-summaryWrite an execution breakdown to the GitHub Actions Job Summary'true'
working-directoryWorking directory for scanning (ideal for monorepos)'.'
package-managerPackage manager: auto | npm | pnpm | yarn'auto'
sarif-outputOutput filepath for generated SARIF report'ai-guard-results.sarif'
install-depsInstall project dependencies prior to scanning'true'

Action Outputs

OutputDescription
issues-foundTotal number of issues found across scanned files
high-confidence-countNumber of high-confidence issues flagged
medium-confidence-countNumber of medium-confidence issues flagged
files-scannedCount of files analyzed during the execution
sarif-fileAbsolute path to the generated SARIF 2.1.0 artifact
duration-msTotal scan execution duration in milliseconds

SARIF & GitHub Code Scanning

AI Guard natively outputs SARIF 2.1.0 (Static Analysis Results Interchange Format). When uploaded via the GitHub Action or github/codeql-action/upload-sarif@v3, findings integrate directly with GitHub Advanced Security:

  • Inline PR Annotations: Direct comments on the exact source lines where flaws exist.
  • Security Dashboard: Persistent alerts under your repository's Security → Code scanning tab.
  • Merge Protection: Block merges automatically when high-confidence security or async bugs are detected.

Visual Previews

Inline Pull Request Annotations

AI Guard PR Inline Annotations

GitHub Advanced Security Summary

GitHub Advanced Security Summary for AI Guard

Persistent Code Scanning Dashboard

GitHub Code Scanning Alerts List

Rule Examples (Before & After)

1. no-floating-promise (Unhandled Promises)

// ❌ BAD: Floating promise. Errors are dropped silently.
async function syncUserProfile(user: User) {
  sendTelemetryEvent('user_sync', user.id);
  database.save(user);
}

// ✅ GOOD: Awaited, explicitly handled, or marked with void
async function syncUserProfile(user: User) {
  await database.save(user);
  void sendTelemetryEvent('user_sync', user.id); // Explicitly unhandled
}

2. no-hardcoded-secret (Committed Credentials)

// ❌ BAD: Secret committed inline
const client = new PaymentGateway({
  apiKey: 'sk-prod-983427598273498273948273',
});

// ✅ GOOD: Read from environment variable (Autofixable!)
const client = new PaymentGateway({
  apiKey: process.env.API_KEY,
});

3. no-await-in-loop (Sequential Latency Trap)

// ❌ BAD: Consecutive awaits block each iteration sequentially
async function fetchAllUsers(ids: string[]) {
  const users = [];
  for (const id of ids) {
    users.push(await fetchUser(id));
  }
  return users;
}

// ✅ GOOD: Concurrently fetched with Promise.all (Autofixable!)
async function fetchAllUsers(ids: string[]) {
  return await Promise.all(ids.map((id) => fetchUser(id)));
}

4. no-empty-catch (Swallowed Errors)

// ❌ BAD: Exception swallowed without trace
try {
  parseConfiguration(rawConfig);
} catch (e) {}

// ✅ GOOD: Logged, rethrown, or documented (Autofixable!)
try {
  parseConfiguration(rawConfig);
} catch (e) {
  logger.error('Configuration parsing failed', { error: e });
  throw e;
}

5. no-sql-string-concat (SQL Injection)

// ❌ BAD: Dynamic string interpolation in SQL
const query = `SELECT * FROM users WHERE organization_id = '${orgId}' AND role = '${role}'`;
await db.query(query);

// ✅ GOOD: Parameterized query binding
const query = 'SELECT * FROM users WHERE organization_id = $1 AND role = $2';
await db.query(query, [orgId, role]);

Automatic Remediation (Autofix)

Rules that have deterministic solutions provide automatic autofix handlers. Run ESLint's native --fix flag to automatically resolve them:

npx eslint . --fix
RuleAutomatic Fix Behavior
no-hardcoded-secretReplaces hardcoded string literal with process.env.VARIABLE_NAME
no-empty-catchInserts /* TODO: handle error */ comment to prevent silent swallowing
no-floating-promisePrepends void expression to intentionally unawaited calls
no-await-in-loopRewrites straightforward sequential loops to await Promise.all(...)

Performance & Philosophy

  • Zero LLM Overhead: AI Guard does not call external APIs, does not incur token costs, and does not add LLM latency. A scan of 100+ files executes in milliseconds.
  • 100% Deterministic: Every finding is derived strictly from Abstract Syntax Tree analysis. No probabilistic drift, no non-deterministic hallucinated findings.
  • Low False Positives: Built with precision-first design. Context-sensitive rules are configured at warn or off in the recommended preset so developers are never blocked by noise.
  • Self-Scanning: AI Guard enforces its own rules on its own codebase in CI using the strict preset.

Learn More & Ecosystem

Visit getaiguard.dev to explore interactive documentation, rule catalogs, benchmarks, and deep-dive engineering articles.


Contributing

We welcome contributions, new rule ideas, bug reports, and false-positive reports!

  1. Check out our Contributing Guide for local setup and testing standards.
  2. Review our Security Policy to report vulnerabilities responsibly.
  3. Check open issues or submit new ones on our Issue Tracker.

License

MIT © AI Guard Authors. Free and open source forever.

Contributors

Languages

TypeScript

98.5%

JavaScript

1.5%