You can use these integrations to check Sigrid findings as you work on your code, triage findings, and export findings to your issue tracker if you're not able to fix them right away.
Have you tried them? We'd love your feedback: Share it in our short survey.
Triaging security and reliability findings with auto-fix agents
This guide walks through working down a backlog of security and reliability findings with two skills: triage-findings decides what to do with each finding and writes that decision back to Sigrid with its evidence, and autofix fixes the findings marked to fix, as local commits.
Most of the decisions depend on facts about your system that are not in the code, so most of this guide is about handing the agent those facts once and checking afterwards how it used them. For maintainability findings, see reducing technical debt.
Prerequisites
You need the following before you start:
- A system published to Sigrid, with security or reliability findings waiting on it.
- The Claude Code plugin, or another agentic tool with the skills and the Sigrid Axis MCP server.
- A Sigrid profile in the repository, written with
/setup, so you are not naming the customer and system on every run. - A local checkout on a branch that is up to date with the branch Sigrid analyzes, so the findings match your code.
Why this is worth doing
Somewhere in your backlog there is a command injection finding on a deployment script, and you already know it is fine. The script only runs from CI, the value it interpolates comes from a pipeline variable you control, and nothing outside the network can reach it. Deciding that takes you about four seconds.
Sigrid cannot decide it at all, because none of those three facts are in the code. It sees a shell call built from a variable and reports exactly what it sees, correctly. The same goes for an endpoint behind an internal load balancer, or input that was already validated two layers up.
Now multiply by two hundred findings. For as long as we have been shipping findings to customers, that has meant a person reading every one of them to apply about five facts. You learn nothing at finding 140 that you did not know at finding 12. You are checking the same handful of conditions again, with worse attention than the first time, and that is why security backlogs sit.
An agent inverts the labor. It does the reading, at full attention, on all two hundred, and you supply the five facts. Your job becomes stating your system’s security context precisely enough that someone else can triage for you. You should be able to do that anyway, and if you sit down to try it, you will probably find you cannot without checking a few things.
A second benefit shows up later. Every decision lands in Sigrid with a remark, prefixed “Sigrid Auto-fix Agent:”: the file and line it relied on, and one sentence of reasoning. Manual triage almost never leaves that behind. Six months on, “someone marked this accepted in March” is not an answer you can defend to an auditor or to the next developer. “Internal-only admin endpoint, no external route, see routes.py:80” is.
Set up the skills
Everything here applies to any agentic tool, and every tool has its own version of the four primitives involved. The Claude Code column is one example:
| Primitive | Generic | Claude Code |
|---|---|---|
| Persistent instructions | context file | CLAUDE.md |
| Tool access | MCP server | axis plugin |
| Reusable procedures | skills | axis plugin |
| Automatic enforcement | hook, git pre-commit, or a scheduled job | UserPromptSubmit hook, or a scheduled CI job |
1. Install the plugin and record your profile
Install the plugin, then run setup in the repository:
/plugin marketplace add Software-Improvement-Group/agent-integrations
/plugin install axis@sigrid
/axis:setup
Decide which security model you triage against before you start, because it changes the finding list. setup records it in the Security model field of your profile, and the Reliability model field for reliability. Leave the field empty to use your organization’s default. The security models are ow10, sigsec, 5055sec, c25, pci4, owasvs4c, owasvs4s, and lcnc10, and the reliability models are sigrel and 5055rel.
2. Write down your security context
The skill asks you about context it cannot find in the code. That works for a handful of findings and gets tedious for a hundred, so write the facts down once.
We recommend a SECURITY-CONTEXT.md file in the repository, next to the code it describes. That way it is reviewable in a merge request, it changes along with the architecture, and it goes stale where you can see it. Point to it from the Customizing behavior section of your profile, or put the same content in CLAUDE.md or AGENTS.md, which the agent already reads. Here is an example:
# Security context
## Externally reachable
- `src/api/public/` - unauthenticated REST API, internet-facing via ALB
- `src/web/checkout/` - authenticated user session, internet-facing
## Internal-only
- `src/admin/` - enforced by network policy, only reachable from the ops VPC (see `infra/network/admin-policy.tf`)
- `scripts/deploy/` - runs from CI runners only, no HTTP surface
## Input already validated
- Everything under `src/api/public/` passes the schema validator in
`src/api/middleware/validate.ts` before reaching a handler
## Accepted risks
- Legacy XML parser in `src/import/` accepted by the platform team, 2026-02, until
the importer is retired in Q4
Every line in that file is a claim the agent will suppress findings on, so treat it that way. “Internal-only” has to name the thing that enforces it, not the thing you intend. A route that is internal because no one has published the URL is not internal, and an agent cannot tell that apart from a network policy unless you say so.
The accepted risks section is where you speak for someone else. Agree with your security owner up front which categories you may accept on their behalf, and which go to them.
What a session looks like
Start small and scoped, because a first run is really a calibration run: you are checking whether the agent’s judgment matches yours on code you know well.
/triage-findings security under src/import/
The skill fetches the findings under that path. Which statuses it includes comes from your request, or otherwise from the Triage status scope field in your Sigrid profile. If neither says, the skill asks. We recommend including only RAW, so findings that were already evaluated are not triaged again. Adding REFINED and WILL_FIX also picks up findings still waiting for work, but every later run then triages them again.
Each finding gets read at its file and line and put through the same sequence of checks:
- False positive: the check itself is wrong, and the best fix would be to the check, not to the flagged code. If the fix you would reach for is a code change, it is not a false positive.
- Accepted risk: the issue is real, but the risk is acceptable at the re-evaluated severity (see below), and the evidence names the context that mitigates it.
- Needs a person (
REFINED): neither of the above has evidence, and something blocks a mechanical fix. The blockers are a design or product decision, a change to the access control decision itself, an action outside the working tree such as rotating a secret, code the analysis could not locate, or a fix that changes an exported signature or touches more than three files. - Will fix: the default, when nothing above applies.
A false positive or an accepted risk needs evidence: a file, a line, and one sentence. Without it, the finding falls through to one of the last two. The checks are mechanical, with a named trigger for each, and none of them rests on how confident the agent feels.
Once a finding is ruled out as a false positive, the skill scores its severity again. A false positive has no real issue to score. The skill ignores the severity the analysis assigned and sets two labels, impact and exploitability, each INFORMATION, LOW, MEDIUM, HIGH, or CRITICAL. Sigrid derives the severity from those two. A finding that comes out at INFORMATION, such as test-only or unreachable code, is proposed as an accepted risk.
The skill writes WILL_FIX and REFINED to Sigrid straight away. It proposes each false positive and accepted risk to you with its evidence, and writes it only after you confirm. Each finding gets one update with its status and remark. For false positives, the remark holds the evidence and no new scores are included. For other findings, the update also includes the scores, and the remark holds the evidence followed by the justification for the scores.
Your job is to say no to the wrong proposals, and to notice why they were wrong. Usually it is a missing fact rather than bad reasoning, and the fix goes in SECURITY-CONTEXT.md. Expect to reject something on a first run because the context was incomplete.
At the end, the skill lists every finding that needs a person, with its blocker, and offers a handover for the findings to fix. The handover carries each finding’s scores and justification, so you can fix the most severe first. Take it, and fix them:
/autofix security
For each finding, autofix checks that the code still matches the finding, writes the fix, runs Guardrails on the changed code, and commits it on its own, with the message Fix: <title> (Sigrid <id>). A fix that turns out to hit one of the blockers above is reverted, and the finding goes to REFINED. The blocker is added to the end of the existing remark, so the justification for the scores stays.
Run triage on a reasoning model, because each classification depends on how your system works, such as whether an input is reachable from outside. Its per-finding subagents run on your session’s model too. You can switch to a mid-sized model for autofix: once a finding is decided, the fix is procedural, and fixes that need a design decision have already gone to a person. See Choose a model.
Skip the confirmations
Once the context file has survived a couple of rounds, you can let the same scope run without the confirmations. Only you can waive them, by asking explicitly. The skill never assumes a waiver because a run is unattended or scripted:
/triage-findings security under src/import/. Don't ask me to confirm false positives
and accepted risks. Security context is in SECURITY-CONTEXT.md, severity ceiling HIGH.
I'll review the accepted risks afterwards.
A waived run still needs three things before it suppresses anything: which parts of the system are reachable from outside, a severity ceiling, and your acknowledgement that the accepted risks need a human review afterwards. Without them, or for a finding above the ceiling, it writes REFINED with the proposed classification in the remark.
We recommend a ceiling of HIGH. HIGH findings are not more often real than others, but they are the ones where being wrong is expensive.
Promote the fixes to FIXED
Triage never sets FIXED. Committed fixes stay on WILL_FIX, and at the end of the run, autofix lists them and asks whether to set them to FIXED now. Consider the trade-off. On WILL_FIX, a triage run before the branch is merged picks them up again. On FIXED, you have to set them back to WILL_FIX if the branch is never merged. If your profile records a preference, autofix follows it and does not ask.
Reliability findings
Reliability findings go through the same loop, with /triage-findings reliability and /autofix reliability. Four things differ:
- Scoring is about failure in normal operation, not about attacks. Exploitability is the likelihood that the defect triggers, and the justification leaves security out. The skill assumes the system is business critical unless you say otherwise.
- An accepted risk is about impact, not attack surface. The evidence names why the failure cannot occur or is harmless here, such as “the collection is never empty, built from a constant list at
config.py:12”. - A waived run needs a severity ceiling and your acknowledgement, but no reachability facts.
- A fix that would change behavior callers may rely on, such as error types or retry and timeout semantics, is one more blocker, so the finding goes to
REFINED.
Check that it holds up
Here are four checks, in order of how much they matter:
- Audit the suppressions first. Pull everything the run marked
FALSE_POSITIVEorACCEPTEDout of Sigrid, and read each remark against the code it cites. For accepted risks, check that the scores in the justification match what you know about the system, because the risk was accepted at the severity they produce. - Review the diff normally. There is one commit per finding, with the finding ID in the message. It goes through your merge request process like anyone else’s.
- Drain the
REFINEDlist. Everything the agent could not settle mechanically is there, with a named blocker. - Compare against yourself. On a first run, triage ten findings by hand before you look at what the agent did. If it disagrees with you on more than one or two, the context file is the problem.
Where to go next
For the guides and references around this one, see:
- Reducing technical debt with auto-fix agents for maintainability, where the plan comes from ratings instead of a list
- Skills reference for
triage-findings, including open source findings - MCP tools reference for the finding statuses and the tools behind the skills