AI fix
For a small set of SAST rules whose fix is narrow and checkable, AI fix asks your organisation’s own AI model for a fix and opens a pull request with it. The AI fix button sits on each SAST finding of such a rule, under Security › Findings › SAST. The setting that turns it on is AI fixes for code findings, under Security › Fix › AI fix.
AI fix is for code findings only. Vulnerable dependencies and base images are fixed without AI, by security fixes. Until 2026-10-14 both were called AutoFix; the API paths .../autofix/..., the labels and the audit events still use that name.
Your own provider only, off by default
- Bring your own key. The model is your organisation’s own provider under AI integrations, billed to you and under your contract with that vendor, exactly like AI pull request review. fremforge holds no AI key of its own and has no fallback. Without a provider, AI fix is disabled and says why. With AI fixes on, if the provider refused your key the last time it was used (HTTP 401 or 403), the SAST page says so and AI fixes cannot run until you update the key under AI integrations; saving it there tests it again.
- Off by default. An owner turns on AI fixes for code findings under Security › Fix › AI fix, or with
PUT .../code-security/autofix/settingsand"ai_enabled": true. Theautofixfeature must also be switched on under AI integrations: adding a provider switches no AI feature on by itself. Per-repository overrides apply, as do your AI spend caps. - A person clicks. Nothing is proposed automatically, even with automatic security fixes on. Each pull request starts with someone clicking AI fix on one finding, or calling the API for one finding.
What is sent to the model
- the rule’s public description and a fix instruction for that rule;
- at most 60 lines of the affected file, from the commit the finding was raised on: the lines around the finding, plus the file’s import block when it fits in the 60;
- the file path and the finding’s line number.
Never the rest of the repository, other files, issues, pull request text or commit messages. The code is wrapped as untrusted data, with an instruction that it carries no instructions.
The prompt, the code and the diff are not logged and not stored by fremforge. They exist in memory while the fix is prepared, and afterwards only in the pull request in your repository. The request record keeps ids, counts and the outcome: which rule, which provider and model, how many tokens, how many lines changed.
What is checked before a pull request exists
The model’s answer must be exactly a unified diff and one explanation paragraph; anything else is rejected. The diff must then pass every one of these, checked by fremforge and not by the model:
- one file: the finding’s own;
- at most 40 changed lines, and only around the finding or in the file’s imports;
- no change to CI configuration (
.forgejo/,.github/, …),CODEOWNERS, suppression files (.trivyignore*,osv-scanner.toml,.gitleaks.toml,.semgrepignore), tests or dependency manifests; - no added suppression comment (
nosemgrep,nolint,nosec,noqa,eslint-disable,type: ignore, …); - no new dependency: an added import must be the standard library or a module the file already imports.
Then the patched file is re-scanned with the same OpenGrep binary and rule set as the pull request scan. The finding must show up on the original file (so a clean result means something), be gone from the patched file, and no new finding may appear in it. Only then is the pull request opened.
A prompt-injection attempt in the code can at worst produce a bad diff in that one file, inside the window. It still has to pass the checks above, the re-scan, your CI and a person’s review.
The pull request
- Opened by your organisation’s AI fix bot,
<org>-fremforge-bot-autofix, on a new branch underautofix-ai/. The bot only writes to branches it creates and can never approve. - Title
fix(security): <rule> in <path>, labelsautofixandai-generated, attached as soon as the pull request is open. A label the repository does not have yet is created the same way as for security fixes: once, leaving an existing label as it is, and if it cannot be created the pull request stays open without it. - The body names the finding, gives the model’s explanation, the provider and model used and the tokens spent, says how it was checked, and lists what to check before merging. It carries the EU AI Act Art. 50 disclosure: a readable statement that the change is AI-generated, and a machine-readable
fremforge:ai-disclosuremarker naming the feature, vendor and model. - Never armed for auto-merge, and the AI fix bot’s pull requests are not exempt from required approvals: a person reviews and merges it. An auto-merge armed on it without an approving review is cancelled.
Rules covered
| Rule | Language | The fix |
|---|---|---|
SQL string concatenation (go_sql_rule-concat-sqli) | Go | A parameterised query |
Overly permissive file permissions (go_file-permissions_rule-fileperm, -mkdir) | Go | A narrower mode |
HTTP server without timeouts (go_http_rule-http-serve) | Go | An http.Server with ReadHeaderTimeout |
SQL string concatenation (python_sql_rule-hardcoded-sql-expression) | Python | A parameterised query |
Unsafe XML parsing (python_xml_rule-element, python_xml_rule-etree) | Python | defusedxml, only when the file already imports it |
Overly permissive file permissions (python_file-permissions_rule-general-bad-permission) | Python | A narrower mode |
Non-literal RegExp (javascript_dos_rule-non-literal-regexp) | JavaScript, TypeScript | A string operation or literal patterns |
Other rules show Not on the AI fix rule list: their findings need a person’s judgement more than a patch. A rule leaves the list if fewer than 30 % of its pull requests are merged.
When no pull request is opened
The finding then shows No PR: the proposed change did not pass the checks or No PR: the fix could not be completed, and GET .../code-security/autofix/ai-requests gives the reason, for example scope_ci_config, new_dependency, suppression_comment, rescan_finding_still_present, rescan_new_finding or ai_over_cap. You can ask again after 10 minutes.
Limits
- One live request per finding. Ask again after 10 minutes if a request ended without a pull request.
- At most 3 open AI fix pull requests per repository and 20 AI fix requests per organisation in any 24 hours, by default.
These limits are AI fix’s own. They are separate from the security fixes limits, which have their own counter. An owner sets them with max_open_per_repo and max_per_org_per_day on PUT .../code-security/autofix/settings (0 to 3 and 0 to 20). That deprecated call also sets the security fixes limits; see Deprecated API.
API
- Request an AI fix
POST /_app/api/v1/orgs/{org}/code-security/sast/findings/{id}/ai-fix, scopefindings:write. Answers202with the request id and"automerge": false; the pull request follows within a few minutes. A refusal isproblem+jsonwhosetypeisai-fix-<reason>and which carriesreason, for examplenot_curated,ai_disabledorno_provider. The older path.../sast/findings/{id}/autofixis deprecated, keeps working until 2027-10-15, and answersautofix-<reason>. - List AI requests
GET /_app/api/v1/orgs/{org}/code-security/autofix/ai-requests, scopefindings:read: status, reason, pull request, provider, model and token counts. - Turn it on or off
PUT /_app/api/v1/orgs/{org}/code-security/autofix/settingswith"ai_enabled": trueorfalse(policy:write).ai_provider_configuredin theGETsays whether the organisation has its own provider.
Every SAST finding from GET .../code-security/sast/findings carries autofix_eligible, autofix_unavailable_reason and autofix, the latest AI fix request covering it.
Audit
AI fix requests are in the audit log as autofix.proposed, autofix.pr_opened, autofix.rejected, autofix.merged and autofix.closed, with engine: ai, the provider id and token counts, never the prompt or the diff. Turning the switch on or off is autofix.settings.updated.
See also
- AI integrations: where your organisation’s own model provider is configured.
- SAST: the findings the button sits on.
- Security fixes: fixes for vulnerable dependencies and base images, without AI.
- Rule-based fixes: fixes for secret and IaC findings, made by a set rule, without AI.