Multi-agent CI/CD security gate β five specialist AI agents that review every pull request together and block vulnerable code before it ships.
Built for the Band of Agents Hackathon (Track 2). Live, deployed, and end-to-end automated.
DeployGuard turns code review from a human bottleneck into an autonomous, auditable team. When a pull request opens, a GitHub webhook spins up a Band chat room where five agents β Scan, Security, Risk, Deploy, Report β collaborate via @mentions, each with a distinct job. Critical findings block the deployment and escalate to a human in the same chat. Remove Band and the chain collapses: DeployAgent never receives its green light.
Most "AI code reviewers" are a single model with a long prompt. DeployGuard is a real review team:
- π§© True multi-agent collaboration β five independent Band identities, separate tools and prompts, communicating through real chat hand-offs (not one model role-playing five).
- π¦ It takes a real action β gates an actual GitHub Actions deployment (
workflow_dispatch), not just text output. - π€ Human-in-the-loop, in-channel β escalations
@mentionthe on-call engineer, who repliesAPPROVE/REJECTinline. - π Deterministic where it matters β verdicts, the CRIT block comment, and the audit report are produced by code, not model judgment, so the security outcome is reliable even on small open-source models. (See Engineering for reliability.)
- βοΈ Actually deployed β live webhook + all five agents running in the cloud on Railway.
flowchart TD
Dev([Developer opens / updates PR]) -->|"webhook + HMAC-SHA256"| WH["FastAPI Webhook<br/>(Railway)"]
WH --> V{"valid signature<br/>& base = main?"}
V -->|no| Drop["ignore / 401"]
V -->|yes| Room["Create Band room<br/>add 5 agents + engineer<br/>ping @ScanAgent"]
Room --> Scan
subgraph BAND["π£ Band multi-agent chat room"]
direction TB
Scan["π ScanAgent<br/>lint Β· tests Β· deps"] -->|PASS / WARN| Sec["π‘οΈ SecurityAgent<br/>vuln + secrets scan"]
Scan -->|BLOCK| Eng
Sec -->|"PASS / WARN"| Risk["βοΈ RiskAgent<br/>risk score 0β100"]
Sec -->|"CRIT β BLOCK<br/>(auto-posts PR comment)"| Eng
Risk -->|"score < 71 β PASS"| Deploy["π DeployAgent<br/>workflow_dispatch"]
Risk -->|"score β₯ 71 β ESCALATE"| Eng["π€ On-call Engineer<br/>(human, in-chat)"]
Eng -->|APPROVE| Deploy
Eng -->|REJECT| Report
Deploy --> Report["π ReportAgent<br/>audit report"]
end
Sec -.-> PR[["PR comments"]]
Deploy -.-> PR
Report --> PR
Report --> Done([Chain complete])
- Clean PR (happy path):
Scan β Security β Risk β Deploy β Reportβ deploys automatically and posts an audit report. - Vulnerable PR (block path): the chain fails fast β SecurityAgent catches the issue, auto-posts a
CRITICALPR comment, blocks the deploy, and escalates to the engineer.
π Full pipeline, decision branches, risk weights, and deployment topology: ARCHITECTURE.md
| # | Agent | Responsibility | Tools | Outcome |
|---|---|---|---|---|
| 1 | π ScanAgent | static analysis, tests, dependency CVEs | ruff, pytest, pip-audit, GitHub |
PASS / WARN / BLOCK |
| 2 | π‘οΈ SecurityAgent | deep vulnerability + secrets scan | security_review (OWASP regex + auto-comment) |
PASS / WARN / BLOCK |
| 3 | βοΈ RiskAgent | weighted risk score (auth/payment files, diff size, day) | risk_scorer |
PASS / ESCALATE |
| 4 | π DeployAgent | fires the real deployment only if approved | deploy_trigger (workflow_dispatch) |
DEPLOYED / HELD |
| 5 | π ReportAgent | posts the final audit report | post_audit_report |
always closes the chain |
A human gate sits between Risk and Deploy: on ESCALATE, the engineer replies APPROVE / REJECT directly in the Band room.
Small open-source models are cheap but inconsistent at multi-step orchestration. DeployGuard pushes every security-critical decision into deterministic code, so the model only does the talking:
security_reviewfetches the diff, scans it, and auto-posts the CRITICAL block comment itself β the block never depends on the model remembering to.post_audit_reportreconstructs the outcome from real signals (the block comment + the deploy run) and posts a clean audit table β no chat-history parsing required.- Self-healing identifiers β if a model passes a placeholder repo/PR, the GitHub tools snap to the configured target and its open PR, so the chain always acts on the real PR.
- Fail-closed β if a diff can't be fetched, SecurityAgent escalates for manual review; it never silently approves.
- Hand-off discipline β one delivery per turn, mention allow-listing, and reconnect-resilient agents (
temperature 0for deterministic decoding).
Result: the demo's hero artifacts β the CRITICAL block and the audit report β land on every run.
| Layer | Technology |
|---|---|
| Multi-agent orchestration | Band (band-sdk[langgraph]) β @mention routing is the chain |
| Agent runtime | LangGraph ReAct agents |
| LLMs | Featherless (Qwen, OpenAI-compatible) |
| Ingress | FastAPI webhook, HMAC-SHA256 verified |
| Source / CI | GitHub PRs + Actions (workflow_dispatch), PyGithub |
| Hosting | Railway β 2 services: webhook (public) + agents (all five) |
| Quality | pytest Β· ruff Β· black Β· Docker Β· GitHub Actions CI |
python -m venv .venv && .venv/Scripts/activate # Windows (use source .venv/bin/activate on *nix)
pip install -r requirements.txt
cp .env.example .env # fill in Band + Featherless + GitHub credentials
pytest -q # 22 passing β no network/credentials neededRun locally
python -m webhook.main # webhook on :8000 (binds $PORT in the cloud)
python -m run_all_agents # all five agents in one processDeploy (Railway) β two services from this repo:
| Service | Start command | Public domain |
|---|---|---|
webhook |
python -m webhook.main |
β
(GitHub webhook target β¦/webhook) |
agents |
python -m run_all_agents |
β |
Then add a Pull requests webhook on the target repo pointing at https://<webhook-domain>/webhook with your GITHUB_WEBHOOK_SECRET. Open a PR and watch the chain run.
agents/ five chain agents (scan, security, risk, deploy, report)
tools/ deterministic tools: security scan, risk scoring, GitHub, deploy, audit
shared/ Band runtime wiring, LLM factory, handles, schemas
webhook/ FastAPI receiver: HMAC verify β parse β initiate Band chain
run_all_agents.py run all five agents in one service (fits PaaS service caps)
ARCHITECTURE.md full pipeline + topology diagrams
β Live and end-to-end automated β webhook + five agents deployed on Railway; PRs auto-trigger the chain; the security block and audit report are deterministic. See current-state.md for the detailed log and ARCHITECTURE.md for the design.
Single-token demo today; multi-tenant review across arbitrary repositories is the production path via a GitHub App.
- Dan16ssd β Project Leader β @Dan16ssd
- KRIT β @thavisoukdouangphachanh-boop
- MichelBLV64 β @MichelBLV64
Built for the Band of Agents Hackathon (Track 2).