AI & CI/CD
AI Explanation Layer
The AI layer is an optional component that translates structured findings from the rule engine into plain-language developer guidance. It does not make security decisions.
Important: The AI explanation layer is completely optional. If you do not configure an API key, all findings will still be emitted with full rule metadata, severity, and suggestions — just without the AI narrative.
What the AI layer does
After the rule engine produces structured findings, the AI layer (if enabled) does the following for each finding:
- Receives the rule ID, severity, code snippet, and rule suggestion
- Constructs a focused prompt that describes the finding
- Calls the configured language model
- Returns a plain-language explanation of the issue and how to fix it
- Populates the
explanationfield in the JSON output
What the AI layer does NOT do
- It does not determine whether a finding is a real vulnerability
- It does not add or remove findings
- It does not modify severity levels
- It does not have access to the full contract source (only the relevant snippet)
- It cannot produce false positives from its own inference
Note: The boundary between the rule engine and the AI layer is intentional. It means AI-related failures (rate limits, model errors, bad keys) never affect the core security analysis.
Enabling AI explanations
Set your API key
# Set via environment variable
$export OPENAI_API_KEY=sk-your-api-key-here
Run the explain command
# Plain text output with AI explanations
$openaudit-ai explain ./contracts
# JSON output with explanation field populated
$openaudit-ai explain ./contracts --json
Example output
finding with explanationjson
{
"ruleId": "reentrancy-guard",
"severity": "CRITICAL",
"file": "contracts/Token.sol",
"line": 147,
"message": "External call precedes state update",
"explanation": "The withdraw() function sends ETH to msg.sender before zeroing the user's balance stored in balances[msg.sender]. A malicious contract can implement a receive() function that calls withdraw() again before the first call completes, since the balance has not been zeroed yet. This is a classic reentrancy attack and can drain all ETH from the contract.\n\nFix: Move balances[msg.sender] = 0 above the .call() invocation, or apply OpenZeppelin's ReentrancyGuard modifier to the function.",
"suggestion": "Move all state updates before external calls."
}Configuration
| Config | Default | Description |
|---|---|---|
| OPENAI_API_KEY | — | Required. OpenAI-compatible API key. |
| --model | gpt-4o-mini | Language model to use for explanations. |
| OPENAUDIT_AI_TIMEOUT | 30s | Timeout for AI explanation requests. |