githubinferredactive
Multi-Agent-AI-Security-Pipeline
provenance:github:luca-bellipanni/Multi-Agent-AI-Security-Pipeline
Multi-agent AI security pipeline for GitHub Action. AI agents that think like AppSec engineers, backed by a deterministic gate that no prompt injection can bypass.
README
[](https://opensource.org/licenses/MIT)
[](https://www.python.org/downloads/release/python-3120/)
[](https://github.com/luca-bellipanni/Multi-Agent-AI-Security-Pipeline/actions)
[](#security-model)
[](https://github.com/huggingface/smolagents)
[](https://github.com/BerriAI/litellm)
# Agentic AppSec Pipeline
A GitHub Action that uses **AI agents** instead of static scanners for PR security analysis and **automated remediation**. Agents read the diff, assess risk, **choose which security tools and rulesets to run**, filter noise, and explain findings. A deterministic gate ensures the final verdict can't be manipulated. When findings need fixing, a Remediation Agent generates fixes on a draft PR, keeping humans in the loop.
```
WORKFLOW 1: Scan (automatic on PR)
─────────────────────────────────────
PR opened
│
▼
┌──────────┐ context ┌──────────────┐ raw findings ┌──────────────┐
│ Triage │──────────► │ AppSec │──(side channel)─►│ Gate │
│ Agent │ │ Agent │ │(deterministic)│
│(3 steps) │ │(OODA, 10 st) │ AI report │ │
└──────────┘ └──────────────┘─────────────────►│ ┌────────┐ │
reads file metadata reads diff, │ │verdict │ │
assesses risk selects & runs │ └───┬────┘ │
routes to specialist security tools, └──────┼───────┘
filters findings
│
scan-results.json ◄────┘
+ PR comment with findings
│
───────────────────────────────────── │
WORKFLOW 2: Remediation (human-triggered)
───────────────────────────────────── │
▼
maintainer comments /remediate
│
▼
┌─────────────────┐
│ Remediation │
│ Agent │
│ (OODA, 10 st) │
└────────┬────────┘
│
reads code, generates fix,
AST-validates, commits
│
▼
Draft PR
(human reviews & merges)
```
**Key design choices:**
- **AI advises, code decides** – agents produce analysis, the Gate produces the verdict from raw scanner data via a side channel the agent can't tamper with
- **OODA loop** – agents observe, orient, decide, act, and can escalate with additional scans or fix attempts
- **Human-in-the-loop remediation** – fixes only trigger when a maintainer comments `/remediate`, land on a draft PR, never auto-merge
- **Severity mismatch detection** – if the agent downgrades a HIGH to MEDIUM, the Gate flags it as a warning
- **Works without AI** – no API key? Falls back to deterministic rules
## Quick Start
### Workflow 1 – Scan (runs on every PR)
```yaml
name: Security Scan
on: [pull_request]
jobs:
scan:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: luca-bellipanni/Multi-Agent-AI-Security-Pipeline@main
id: appsec
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
command: scan
mode: shadow
ai_api_key: ${{ secrets.AI_API_KEY }}
ai_model: gpt-4o-mini
- uses: actions/upload-artifact@v4
with:
name: scan-results
path: .appsec/scan-results.json
```
### Workflow 2 – Remediation (triggered by `/remediate` comment)
```yaml
name: Security Remediation
on:
issue_comment:
types: [created]
jobs:
remediate:
if: |
github.event.issue.pull_request &&
startsWith(github.event.comment.body, '/remediate') &&
contains(fromJson('["MEMBER","OWNER"]'),
github.event.comment.author_association)
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: dawidd6/action-download-artifact@v6
with:
workflow: Security Scan
name: scan-results
path: .appsec/
search_artifacts: true
- uses: luca-bellipanni/Multi-Agent-AI-Security-Pipeline@main
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
command: remediate
ai_api_key: ${{ secrets.AI_API_KEY }}
```
## Configuration
| Input | Required | Default | Description |
|-------|----------|---------|-------------|
| `github_token` | Yes | – | GitHub token for API access |
| `command` | No | `scan` | `scan` (analysis) or `remediate` (generate fixes) |
| `mode` | No | `shadow` | `shadow` (observe only) or `enforce` (can block PRs) |
| `ai_api_key` | No | – | API key for any LLM provider via [LiteLLM](https://docs.litellm.ai/docs/providers) |
| `ai_model` | No | `gpt-4o-mini` | Any model supported by LiteLLM |
| Output | Description |
|--------|-------------|
| `decision` | `allowed` · `manual_review` · `blocked` |
| `continue_pipeline` | `true` / `false` |
| `findings_count` | Total raw findings from scanner |
| `reason` | Human-readable explanation with AI reasoning |
| `safety_warnings_count` | Safety net warnings (agent vs raw data discrepancies) |
**Enforce mode policy:** CRITICAL → `blocked` · Any findings → `manual_review` · Clean → `allowed` · Tool failure → `manual_review` (fail-closed)
## Security Model
The pipeline defends against prompt injection and AI manipulation at four layers:
1. **System prompt hardening** – agents treat all code/comments as untrusted
2. **Side channel** – raw scanner findings bypass the agent entirely; the Gate reads tool output directly
3. **Safety net** – Gate compares agent claims vs raw data; dismissed HIGH/CRITICAL or severity downgrades trigger warnings
4. **Tool guardrails** – secrets injected via constructor (invisible to LLM), ruleset allowlists, output caps, timeouts
The Remediation Agent adds a fifth layer: **fixes only apply to Gate-confirmed findings** (not raw tool output, not agent opinions), land on a draft PR branch, and require human merge. Every modification is logged in a fix audit trail via a side channel the agent can't alter.
> For a deep dive, see the docs in [`docs/`](docs/).
## Project Structure
```
src/
main.py Entry point and GitHub Actions I/O
github_context.py GitHub Actions environment parser
models.py Data contracts: Finding, Decision, Verdict, Severity
decision_engine.py Orchestrator: triage → analyzer → gate + safety net
agent.py
[truncated…]PUBLIC HISTORY
First discoveredMar 22, 2026
IDENTITY
inferred
Identity inferred from code signals. No PROVENANCE.yml found.
Is this yours? Claim it →METADATA
platformgithub
first seenFeb 8, 2026
last updatedFeb 19, 2026
last crawled1 day ago
version—
README BADGE
Add to your README:
