Skip to main content
AI tutorials

Audit and Improve AI-Generated Code with Iron Laws

Learn how to install Iron Laws, scan a project, generate AI-ready repair instructions, configure enforcement thresholds, manage baselines and suppressions, verify AI patches, and integrate SARIF reports with GitHub Actions.

Audit and Improve AI-Generated Code with Iron Laws
Iron Laws project logo

What Is Iron Laws?

Iron Laws, also known as 오철칙, is a static inspection tool designed to catch security and maintainability problems commonly found in AI-generated projects. It applies lessons drawn from enterprise and public-sector system integration audits, then explains each finding in accessible language.

The tool looks beyond whether an application merely runs. It checks for problems such as hardcoded secrets, unsafe input handling, swallowed exceptions, unauthenticated administrative APIs, missing Supabase or Firebase access controls, committed .env files, duplicated functions, circular dependencies, and type-safety bypasses.

Iron Laws also generates structured repair instructions that can be pasted into an AI coding assistant. This creates a repeatable workflow:

Build with AI → iron-laws check → iron-laws fix-prompt
→ ask the AI to fix the findings → run check again

Iron Laws is a development-time review aid, not an official certification product or proof that an application is secure. Use it alongside tests, code review, and other security tools.

Key Features

Security and quality inspection

The project includes 90 rules spanning several areas:

  • Reference rules: Coverage for all 49 implementation-stage items from the referenced Korean Ministry of the Interior and Safety software development security guide, including injection, XSS, SSRF, XXE, weak cryptography, certificate-validation disabling, unsafe deserialization, error handling, and memory safety.
  • AI code corrections: Hardcoded configuration, secret fallback values, frontend secret exposure, unsafe CORS, missing access rules, dangerous Docker or CI settings, dependency typos, unpinned dependencies, sensitive logging, IDOR, and cookie attributes.
  • Architecture checks: Oversized functions and files, improper layer dependencies, direct database access from request handlers, circular dependencies, duplicate functions, repeated string constants, and missing tests.
  • Type-safety checks: TypeScript any and @ts-ignore, Python type: ignore and casts, Java raw types, C# dynamic, and type-system bypasses in other supported languages.

Readable findings and repair guidance

Every finding includes an explanation of the problem, why it is dangerous, and how it can be corrected. Where a rule corresponds to a published guide item, the report includes that item number and its CWE mapping. Project-specific quality rules are explicitly identified as Iron Laws rules rather than external requirements.

AI-ready fix prompts

The fix-prompt command organizes findings by severity and turns them into instructions for an AI coding tool. The prompt also reinforces principles such as not swallowing errors, not placing secrets in source code, not bypassing type checking, and not creating duplicate implementations.

Local parsing

The required parsers are included in the package, so inspections can run without network access after installation.

Language and File Support

Support depth varies by language and file type:

  • Deep support: Python, JavaScript, TypeScript, Java, and C# receive syntax analysis, input tracking, and the broadest rule coverage.
  • Basic support: Go and PHP receive syntax analysis and important injection, error-handling, and cryptography checks.
  • Limited support: Rust and C/C++ receive checks for error handling, memory usage, format strings, APIs, and type bypasses.
  • Configuration and definition files: SQL, YAML, JSON, .env, Dockerfile, Compose, GitHub Actions, MyBatis XML, and HTML templates are inspected for relevant secret, access-control, deployment, and escaping problems.

Within functions, Iron Laws analyzes flow through branches, loops, and exceptions. It follows same-file helper calls up to four levels deep. Python additionally has experimental cross-file tracking through imports, subject to analysis limits. Cross-file flows in other languages may be missed or reported as requiring review.

Installation

Iron Laws requires Python 3.12 or newer. Installing it as a standalone tool with uv is the recommended approach:

uv tool install git+https://github.com/JinHo-von-Choi/iron-laws.git

You can alternatively install it with pip:

pip install git+https://github.com/JinHo-von-Choi/iron-laws.git

After installation, confirm that the command is available by listing the bundled rules:

iron-laws rules

To inspect implementation and validation status by language and rule, run:

iron-laws support

This distinction matters because the presence of a parser does not necessarily mean that every rule has been validated for that language.

Run Your First Inspection

Scan the current project

Open a terminal in the project directory and run:

iron-laws check .

By default, the command fails when it finds a finding at HIGH severity or above. The exit codes are:

  • 0: The inspection passed under the selected severity policy.
  • 1: At least one finding met or exceeded the configured failure severity.
  • 2: Input or configuration was invalid, no files were inspected, or the inspection could not finish because of issues such as rule errors or file-read failures.

An incomplete inspection does not receive a confirmed grade or pass result. Its reasons are recorded under diagnostics. An empty target is also not treated as a successful scan unless --allow-empty is explicitly supplied.

Understand an individual rule

Use explain when you need a plain-language explanation of a rule:

iron-laws explain IL-501

You can also inspect which of the 49 referenced implementation items are covered:

iron-laws coverage

Generate a report

For a Markdown report containing the inspection status of all 49 referenced items, run:

iron-laws audit . --format markdown -o report.md

To produce a SARIF file for GitHub Code Scanning or another compatible system, use:

iron-laws audit . --format sarif -o iron-laws.sarif

Generate Instructions for an AI Coding Assistant

After reviewing the findings, generate an AI-ready repair prompt:

iron-laws fix-prompt .

Paste the generated instructions into your coding assistant, review the proposed changes, and then run the inspection again:

iron-laws check .

The fix-prompt command returns exit code 0 even when findings exist because its purpose is to generate instructions. Do not use it as a deployment gate. Use check or audit for enforcement.

Recognized secret values are masked as **** in reports and generated prompts. However, unrecognized secrets cannot be masked automatically, so review generated text before sending it to an external AI service.

Configure Project Policies

Generate an initial configuration file with:

iron-laws init

The project uses .iron-laws.yml. A typical configuration is:

fail_on: HIGH
excludes: [".git", "node_modules", "dist"]
disabled_rules: ["ARC-206"]
limits:
  max_function_lines: 80
  max_file_lines: 600
  max_parameters: 7
  max_nesting: 5
  duplicate_similarity: 0.9

The fail_on setting accepts CRITICAL, HIGH, MEDIUM, or LOW. The effective priority order is the --fail-on command-line option, then the configuration file, then the default value of HIGH. Reports record which source supplied the active threshold.

By default, Iron Laws uses the configuration in the inspected directory. Use --config to choose a particular file or --search-parents to look in parent directories. Unknown keys and invalid settings are not silently ignored; they produce exit code 2.

Handle Intentional Exceptions

A false positive or intentional exception can be suppressed only when the suppression includes a reason. A comment without a reason is ignored.

To suppress one finding in Python:

except ImportError:  # iron-laws: ignore[IL-301] Optional dependency disables this feature
    yaml = None

To suppress a rule for an entire file, place an ignore-file directive within the first 30 lines:

# iron-laws: ignore-file[IL-102] Pattern definitions intentionally identify weak algorithms

Suppressions can include an expiration date:

# iron-laws: ignore[IL-101] until=2026-12-31 Temporary exception with documented reason

Expired suppressions stop applying and appear in reports. Iron Laws also reports unused suppressions and references to unknown rule IDs.

Adopt Iron Laws in an Existing Project

Create a baseline

If an existing repository already has accepted findings, record them as approved technical debt:

iron-laws baseline create .

Then evaluate only newly introduced findings against the saved baseline:

iron-laws check . --baseline .iron-laws-baseline.json

Inspect changed files

For pull-request feedback focused on modified files, compare against the main branch:

iron-laws check . --changed-since origin/main

The README recommends pairing changed-file inspection with full and periodic scans so that repository-wide issues are not overlooked.

Record review feedback

Findings marked as requiring review can be classified and assigned a review cost:

iron-laws feedback add IL-501 src/a.py:3 --verdict false-positive --minutes 10

Verify AI-Generated Patches

Iron Laws includes an advanced workflow for retaining evidence about what was and was not verified after an AI modifies the code.

Check an evidence contract

An evidence contract distinguishes a completed scan from a scan that actually produced the required evidence:

iron-laws check . --contract .iron-laws-contract.yml

Unresolved input sources are not automatically converted into clean results. The current evidence-contract coverage includes Python command execution, path access, and SQL construction families.

Create a patch verification receipt

To inspect a proposed patch and save a verification receipt, run a command such as:

iron-laws verify-patch . --patch fix.diff \
  --finding IL-504@app.py:6 \
  --runner docker \
  --image IMAGE_NAME \
  -o receipt.json

The verifier compares the original and candidate using the same policy. It separately reports suspicious changes such as deleted tests, additional skips, new ignore comments, or weakened policies. A warning disappearing is not, by itself, considered proof of a valid fix.

Tests are run only in a disposable isolated environment without credentials. If isolation cannot be obtained, Iron Laws does not silently execute the tests on the host; it leaves the result indeterminate.

Propose a distinguishing regression test

You can generate a candidate regression-test specification for a finding:

iron-laws regression propose . --finding IL-504@app.py -o spec.yml

The intended validation pattern checks that the original fails because of the defect, the candidate passes, and a mutant with the fix reverted fails again. The README describes repeating this sequence three times. The generated test remains a proposal until it is confirmed.

Record human approval

Store an approval with its reason:

iron-laws approvals add . \
  --finding IL-504@app.py \
  --reason "Documented review reason" \
  --store approvals.jsonl

Apply valid approvals during a scan:

iron-laws check . --approvals approvals.jsonl

Approvals remain valid only while their assumptions hold. Changes to callers, data flow, sanitizers, access scope, or rule meaning can require renewed review. Duplicated vulnerable code does not inherit an existing approval.

Integrate with GitHub Actions

The following workflow installs Iron Laws, uploads a SARIF report, and then enforces a high-severity deployment gate:

name: Iron Laws
on: [push, pull_request]
jobs:
  audit:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/setup-uv@v3
      - run: uv tool install git+https://github.com/JinHo-von-Choi/iron-laws.git
      - run: iron-laws audit . --format sarif -o iron-laws.sarif || true
      - uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: iron-laws.sarif
      - run: iron-laws check . --fail-on HIGH

The report-generation step uses || true so the SARIF file can still be uploaded when findings exist. The final check command provides the actual pass-or-fail gate.

Practical Limitations

  • A clean result means that no issue was found within the implemented rules and supported analysis scope. It does not prove that the application is vulnerability-free.
  • Cross-file input tracking is experimental for Python and limited for other languages. Some flows may be missed or reported as requiring manual review.
  • Sanitizers are recognized only for the context they protect, such as HTML, SQL, shell commands, or paths.
  • Patch verification, regression testing, and approval tracking have not yet received independent evaluation or a real-world pilot according to the README.
  • OWASP Benchmark results cited by the project show improvements in several categories, but false positives remain, including safely sanitized SQL and command-injection cases.
  • Without consulting a package repository, the tool cannot reliably identify every fabricated dependency. It reports names that resemble popular packages instead.
  • Compressed and generated files are skipped, with reasons recorded under skipped_files.

For more detail, consult the repository documentation for patch verification, accuracy measurements, language and rule support, and report formats.

Conclusion

Iron Laws provides a structured way to review AI-generated software before hidden security and maintenance problems become production incidents. Start with iron-laws check ., inspect the explanations, generate a repair prompt, review the AI's changes, and scan again. As the project matures, add configuration, baselines, SARIF reporting, patch receipts, and human approvals to make the process repeatable and auditable.

The project is available under the MIT License. Its results should support, rather than replace, testing, manual code review, and broader security assessment.