Skip to content

Security

How sarifix treats untrusted input, what it will never touch, and how to report a vulnerability. The first half is the security policy; the second is the model behind the design.

Supported versions

sarifix is pre-1.0. Security fixes land on main and ship in the next release; only the latest release is supported.

Version Supported
Latest release Yes
Older releases No

Reporting a vulnerability

Please do not open a public issue. Report privately through GitHub's private vulnerability reporting at https://github.com/rossedman/sarifix/security/advisories/new.

Include the sarifix version (sarifix version), the scanner and SARIF input involved (trimmed to the smallest example), and what an attacker gains. SARIF that tries to steer the fixing agent, path tricks that escape the repo, and ways around the denied-path rules are all in scope.

What to expect

  • An acknowledgement within 3 business days.
  • A fix, or a plan with a timeline, within 30 days.
  • Credit in the published advisory, unless you prefer to stay anonymous.

Verifying releases

Every release is built by .github/workflows/release.yml and signed keylessly with cosign through GitHub's OIDC identity, so there are no signing keys to leak. The signed checksums.txt covers every archive and SBOM.

cosign verify-blob checksums.txt \
  --bundle checksums.txt.sigstore.json \
  --certificate-identity-regexp '^https://github.com/rossedman/sarifix/.github/workflows/release.yml@refs/tags/v' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com
sha256sum --ignore-missing -c checksums.txt
gh attestation verify sarifix_<version>_linux_amd64.tar.gz --repo rossedman/sarifix

Container images are signed by digest:

cosign verify ghcr.io/rossedman/sarifix:<version> \
  --certificate-identity-regexp '^https://github.com/rossedman/sarifix/.github/workflows/release.yml@refs/tags/v' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

A signature from any other repository or workflow fails these checks.

Security model

sarifix reads SARIF written by other tools and, once the fixing phases land, hands findings to an AI agent that edits your code. Both are attack surface, so the design assumes that everything it reads (SARIF messages, rule help text, repository files) can be hostile.

What is enforced today

sarifix does not yet run an agent or change files (that starts in phase 2). Today the model means: SARIF is validated against the 2.1.0 schema and invalid runs are skipped with a warning, scanner commands run as argv without a shell, and unknown placeholders are rejected at load. The agent controls in the table below are the design for phases 2 to 5.

The agent's boundaries

The agent sees findings as quoted data. It can read and edit files in its own git worktree and run the batch's scanner and your verify.commands. It has no network access, no secrets and no push rights. The prompt is built by code with fixed sections: findings go in a delimited block labelled untrusted, with messages and help text truncated to 2,000 characters and stripped of control characters.

Threats and controls

Threat Control
Prompt injection through a SARIF message or help text, from a malicious tool or pull request Findings are delimited, labelled untrusted and truncated; the agent's tools are restricted; verification never relies on the agent's own claims.
Injection through repository file contents The same tool limits apply, and the diff guard rejects edits outside the batch's files and to denied paths.
Exfiltration The sandbox has no network. No secrets are in the agent's environment; the API key is used only by the provider process.
Workflow tampering .github/workflows/** is denied by default and enforced in the diff guard on the actual diff, not only in the prompt.
Fork pull requests pr mode runs only on default-branch pushes. review mode on forks posts suggestions only and never runs with write tokens against fork code.
Runaway cost A per-batch timeout, a per-run batch cap and recorded token usage.
Suppression instead of a fix The diff guard flags added nolint, #checkov:skip, .trivyignore entries and similar, unless the rule allows them.

Verification is independent

A batch is published only when every stage passes, in order: the diff guard (no denied paths, diff under limits.max_diff_lines, no files outside the batch), a rescan with the batch's scanner, every target fingerprint gone, no new findings from that scanner, and each verify.commands entry exiting 0. Because the checks re-run the scanner and your tests, an agent that lies about its work still cannot get a change through.

Supply chain

Release checksums are signed with cosign, and the signature bundle is published beside them. See Getting started for the verification commands.