Using BrassCoders for SOC 2 Audit Evidence: What the .brass/ Artifacts Prove

SOC 2 Type II requires evidence of continuous vulnerability monitoring. The .brass/detailed_analysis.yaml file — retained 90 days in CI artifacts — provides machine-readable evidence of what was scanned, when, and what was found.

Copper Sun Brass Team · · 7 min read
soc2compliancesecurity

SOC 2 Type II doesn’t ask you to install any particular scanner. It asks you to prove that you ran scanning, that you retained the output, and that you had a process for acting on what you found. The .brass/ directory is where BrassCoders writes that proof on every commit.

This post is a practical guide for security-conscious teams: what the .brass/ files contain, how to retain them for 90 days in CI, and what BrassCoders honestly doesn’t cover.

What SOC 2 Actually Requires for Code Scanning

BrassCoders maps to two SOC 2 Trust Services Criteria directly: CC8.1 (change management) and CC7.1 (system monitoring), which together require evidence that code changes are reviewed for security issues before reaching production and that vulnerabilities are monitored continuously.

The AICPA publishes the Trust Services Criteria at aicpa-cima.com. The criteria don’t prescribe a tool. What CC8.1 asks for under change management is evidence that changes were tested and reviewed before implementation. What CC7.1 asks for under system monitoring is evidence of ongoing vulnerability detection. Your auditor will want to see artifacts that demonstrate (a) scanning ran on each commit, (b) the output was retained, and (c) your team had a defined process for acting on findings.

BrassCoders gives you (a) and (b). Your triage process — a ticket system, a severity policy, a code-review gate — gives you (c). That division matters: BrassCoders doesn’t replace a vulnerability management process, but it does generate the scan-time evidence that process needs to be credible.

The auditor’s question is simple: if you found a critical finding six weeks ago, what happened to it? The answer lives in your ticket tracker. The evidence that the finding was detected lives in the .brass/ artifact.

What the .brass/ Artifacts Contain

BrassCoders writes four YAML files to the .brass/ directory on every scan. The detailed_analysis.yaml file captures the BrassCoders version, the git commit hash at scan time, per-scanner status (ran, skipped, or errored), and per-finding detail: scanner name, rule ID, severity, file path, and line number.

That per-finding detail matters for auditors. A finding in detailed_analysis.yaml is traceable: you can tell which scanner flagged it, which rule fired, and exactly which line in which file the scanner identified. The version and commit hash anchor the finding to a specific point in time and a specific state of the code.

The statistics.yaml file gives auditors a quick summary — finding counts by scanner and severity — without requiring them to parse hundreds of raw findings. This is useful as a cover page for the audit package: it shows scanning ran and gives them a top-level picture before they dig into specifics.

The security_report.yaml file contains the security-focused subset of findings. Handing an auditor the full detailed_analysis.yaml on a large codebase can mean navigating thousands of entries that include style, performance, and AI-pattern findings alongside security ones. The security_report.yaml isolates what they actually need to see. The ai_instructions.yaml file is structured for AI assistant consumption (Claude Code, Cursor) rather than human audit review — you typically don’t need to include it in an audit package.

These files are YAML, not proprietary binary formats. Your auditor can open them in a text editor, import them into a spreadsheet, or feed them into an audit management platform that accepts structured data.

Retaining Artifacts for 90 Days

BrassCoders’s OSS core writes .brass/ artifacts locally; CI retention makes them the durable audit evidence. GitHub Actions and GitLab CI both support artifact expiration, and 90 days covers a standard SOC 2 Type II audit window.

For GitHub Actions, add an actions/upload-artifact step after the scan and set retention-days: 90:

- name: Install BrassCoders
  run: pip install brasscoders

- name: Run BrassCoders scan
  run: brasscoders scan .

- name: Upload .brass/ artifacts
  uses: actions/upload-artifact@v4
  with:
    name: brasscoders-scan-${{ github.sha }}
    path: .brass/
    retention-days: 90

For GitLab CI, use the expire_in key under artifacts:

brasscoders-scan:
  script:
    - pip install brasscoders
    - brasscoders scan .
  artifacts:
    paths:
      - .brass/
    expire_in: 90 days

Naming the artifact with ${{ github.sha }} (GitHub) or equivalent in GitLab means each artifact is immediately traceable to its commit without cross-referencing logs. Your auditor can pull the artifact directly from the build list and see the commit hash in the name and inside the YAML. For teams also working toward ISO 27001, A.12.6.1 (technical vulnerability management) and A.12.1.2 (change management) both benefit from a longer trail — set expire_in: 365 days in that case.

Linking Artifacts to Commits

BrassCoders captures the git commit hash in detailed_analysis.yaml at scan time, creating a provable chain from code state to scan output without requiring any additional scripting.

The evidence chain an auditor follows: the git commit hash in detailed_analysis.yaml maps to the exact version of the code that was scanned. The CI run timestamp in GitHub Actions or GitLab CI logs shows when the scan ran. The artifact, tied to that CI run, holds the YAML. That three-link chain — commit hash, timestamp, artifact — is the audit trail entry for every build.

If you want to reinforce the chain in CI logs without depending on the artifact, you can log git show --stat HEAD in the step before the scan. That puts the commit summary directly in the build log alongside the scan output. The commit hash in the log and the commit hash in the YAML will match. For auditors who prefer narrative evidence in build logs over YAML inspection, this can simplify review.

The GitHub Actions workflow run URL is a stable reference: it contains the commit SHA in the URL path, links to all artifacts, and persists for the artifact lifetime. A single URL from a GitHub Actions run is a complete audit trail entry.

What BrassCoders Doesn’t Cover

BrassCoders is a SAST tool — it scans source code patterns. The 12 scanners (Bandit, Pylint, Pyre/Pysa, Semgrep, ast-grep, Yelp’s detect-secrets, and six custom detectors for secrets, privacy/PII, AI patterns, performance, content moderation, and JavaScript/TypeScript) operate entirely on source code at rest.

Source-code scanning doesn’t cover everything a SOC 2 program needs. Dynamic application security testing (DAST) tests the running application, not the source. Dependency vulnerability scanning — tools like Snyk or Dependabot — checks your package dependencies against CVE databases, not the code you write. Infrastructure misconfiguration scanning — Checkov or Terrascan — checks your Terraform and Kubernetes manifests. Access control evidence comes from your IAM logs and access review records. A complete SOC 2 program layers all of these. BrassCoders is the source-code scanning layer.

For teams in regulated environments with PHI-adjacent code, the --offline flag is relevant: it enforces zero outbound network calls from the OSS core at runtime, meaning no source code leaves the machine during the scan. The .brass/ artifacts write locally and upload to your CI artifact store inside your environment. This is worth documenting to auditors reviewing your data handling posture for CC6 (logical and physical access controls) and CC9 (risk mitigation with vendors).

BrassCoders is also honest about what it is: an open-source CLI that runs pattern-based static analysis. It is not a compliance platform, it is not SOC 2 certified itself, and it does not produce a certification or attestation. The evidence it produces is a function of the deterministic scanner layer — same code, same configuration, same output. Auditors can reproduce any scan by running the same BrassCoders version against the same commit.


Install with pip install brasscoders and run brasscoders scan . in your project root. The .brass/ directory appears immediately. Wire it into CI, set 90-day artifact retention, and you have a continuous audit trail for CC7.1 and CC8.1 from your first build.

Full install guide and CI integration recipes →

Frequently Asked Questions

Does BrassCoders produce SOC 2-compliant audit evidence?

BrassCoders is not a compliance platform. The .brass/detailed_analysis.yaml file — which captures the BrassCoders version, git commit hash at scan time, per-scanner status, and per-finding details — is machine-readable evidence of continuous vulnerability monitoring. When retained for 90 days in CI artifacts, it addresses the CC7.1 and CC8.1 requirements for change management and system monitoring evidence.

Which .brass/ file should I give my auditor?

Start with security_report.yaml — it contains security-focused findings only and is easier to review than the full output. For the complete evidence chain (scanner status, version, commit hash), the auditor should also see detailed_analysis.yaml. The statistics.yaml provides a quick count-by-severity summary that shows scanning ran.

How long should I retain .brass/ artifacts for SOC 2?

90 days covers a standard SOC 2 Type II audit window. For teams also pursuing ISO 27001, extend retention to 365 days. Set retention-days: 90 in GitHub Actions or expire_in: 90 days in GitLab CI.

How do I prove BrassCoders scanned a specific commit?

BrassCoders captures the git commit hash in .brass/detailed_analysis.yaml at scan time. The CI run timestamp in your GitHub Actions or GitLab CI log proves when the workflow ran. That chain — commit hash in the YAML, timestamp in the CI log, artifact tied to the build — is the provable audit trail.

Does BrassCoders cover runtime security, dependencies, or infrastructure?

No. BrassCoders is a SAST tool for source code patterns across 12 scanners. It does not perform runtime testing (DAST), dependency CVE scanning, or infrastructure misconfiguration checks. A SOC 2 program needs all of those layers; BrassCoders covers the source-code scanning layer.

Can I use BrassCoders with the --offline flag in a regulated environment?

Yes. The --offline flag makes BrassCoders's OSS core make zero outbound network calls, which is relevant for teams with strict egress controls or PHI-adjacent codebases. The .brass/ artifacts are written locally and can be uploaded to your CI artifact store without leaving your environment.