Every commit your AI coding assistant writes goes into your codebase without a static gate. Claude Code and Cursor generate code fast, but neither one runs automatically on push, neither one fails the build when a critical finding appears, and neither one produces identical output for identical input. That gap is what a CI security scanner fills. Adding BrassCoders to GitHub Actions closes it.
Why a Static Gate Belongs in CI (Not Just in Your Editor)
BrassCoders running in GitHub Actions produces deterministic, repeatable output on every push — the same codebase produces the same findings every time, regardless of which developer ran the scan, which machine it ran on, or what prompt produced the code under review.
AI-assisted code review in your editor is conversational. You ask, it suggests, you accept or reject. It runs when you think to run it. A CI gate is the opposite: automatic on every push, non-interactive, and capable of blocking a merge. These two things solve different problems. The editor assistant helps you write code faster. The CI gate catches what slipped through.
The distinction matters most for AI-generated code specifically. An AI assistant that generated a function isn't also auditing it against Bandit's security rules or checking it for hardcoded secrets via detect-secrets. That work belongs to a separate tool running outside the editor's context.
The GitHub Actions Workflow (Copy-Paste Ready)
BrassCoders ships a ready-made GitHub Actions workflow in its open-source repository that installs the scanner, runs brasscoders --offline scan, and uploads the .brass/ directory as a PR artifact — so reviewers can download the ranked findings without running the scan themselves.
The workflow lives at .github/workflows/brasscoders-scan.yml in the BrassCoders OSS repo. Here's the full content:
name: BrassCoders Scan
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
brasscoders:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install BrassCoders
run: pip install brasscoders==2.0.8
- name: Run BrassCoders scan
run: brasscoders --offline scan .
- name: Upload .brass artifact
uses: actions/upload-artifact@v4
with:
name: brasscoders-findings
path: .brass/
Copy this file into your repository at .github/workflows/brasscoders-scan.yml. GitHub will pick it up automatically. No additional configuration is required for the OSS core.
The --offline flag makes explicit that no network calls happen during the scan. It's redundant with the OSS core's default behavior, but it documents intent and prevents accidental enrichment calls if you later add a license key to the environment without updating the workflow.
The actions/upload-artifact@v4 step follows GitHub's recommended artifact upload pattern. The .brass/ directory is uploaded as a named artifact (brasscoders-findings) that persists for the default retention period and is accessible from the Actions run summary.
What the PR Artifact Contains
The .brass/ artifact uploaded by the workflow contains three files: ai_instructions.yaml, a short severity-ranked list of findings designed to be pasted directly into Claude Code or Cursor; detailed_analysis.yaml, which records every finding with its file path, line number, scanner name, and evidence; and security_report.yaml, a security-only view that includes Bandit, Pysa, Semgrep, and detect-secrets findings for use in audit records.
ai_instructions.yaml is the file you'll reach for most often. Download the artifact from the Actions run, open that file, and paste it into your AI assistant's context. The assistant sees the ranked findings without running any scan itself. That's a useful division: BrassCoders does the pattern detection, the AI assistant does the triage and fix reasoning.
The artifact approach means reviewers never need BrassCoders installed locally to see the findings on a PR. They download once, read the YAML, and carry the context into whatever tool they're using.
Failing the Build on Critical Findings
BrassCoders exits with code 1 when any CRITICAL finding is detected, which fails the GitHub Actions step and can block a merge when branch protection is configured to require the check to pass.
To wire this up: go to your repository's Settings → Branches → Branch protection rules and add or edit the rule for your main branch. Check Require status checks to pass before merging and add brasscoders (the job name from the workflow) as a required check. After the first successful workflow run, the job name appears in the search box. Save the rule.
After that, any push that produces a CRITICAL finding will fail the brasscoders job and prevent the merge. The --offline flag guarantees the scan can't be skipped due to a network issue. The scan either passes or it fails — there's no degraded middle state where some findings get checked and others don't.
CRITICAL findings in the OSS core come primarily from Bandit (SQL injection, shell injection, unsafe deserialization), Pysa/Pyre (taint flows from user input to sensitive sinks), and the custom secrets detector (hardcoded credentials, API keys matching known formats).
Adding the Paid Plan for Noise Reduction
The OSS core scan works without an account and makes no network calls — 12 scanners run locally and emit everything they find. BrassCoders Paid ($12/month) adds an AI-powered semantic deduplication pass that reduces a typical scan's 1500+ raw findings to roughly 300 actionable ones, ranked against a signature derived from your project's README and manifest.
The enrichment runs through BrassCoders's hosted gateway. It receives already-redacted findings — never raw source code. The per-token cost is passed through at upstream cost with no markup.
To use BrassCoders Paid in CI, store your license key as a GitHub Actions secret (BRASS_LICENSE_KEY is the conventional name), then expose it to the workflow step:
- name: Run BrassCoders scan
run: brasscoders scan .
env:
BRASS_LICENSE_KEY: ${{ secrets.BRASS_LICENSE_KEY }}
Drop the --offline flag when using the Paid plan — that flag prevents the enrichment call. The scan will detect the license key, validate it, run the local scanner pass, then send the redacted findings to the gateway for the deduplication and ranking step. The .brass/ artifact then contains enriched YAML with the ranked, deduplicated finding set.
The Paid plan doesn't change the workflow structure. It changes what's in the artifact at the end.
Install the scanner:
pip install brasscoders
Or pin the current release in your workflow: pip install brasscoders==2.0.8. The OSS repo is at github.com/CopperSunDev/brasscoders, and the PyPI listing is at pypi.org/project/brasscoders/. BrassCoders Paid pricing is at coppersun.dev/pricing. Cancel any time via brasscoders portal.
Top comments (0)