- Добавлен статус {"status": "analyzing"} в finding.report на время LLM-анализа
- Кнопка рескана (Retry) под LLM-отчётом в ручном режиме
- LLM-статистика на дашборде: analysed / pending
- Защита от двойного анализа через per-finding asyncio.Lock
- _llm_spinner.html — фрагмент спиннера для состояния analysing
- Удалён мёртвый код: constants, i18n, CSS, queries
- Фиксы: _env_int, индексы БД, UnicodeDecodeError, time.mktime и др.
- Шаблоны: shared includes (_status_badge, _pagination)
- AGENTS.md: workflow (lint, test, commit, rebuild)
GuardDog Nexus
Integration of GuardDog (package vulnerability scanner) with Sonatype Nexus Repository Manager. Automatically scans packages stored in Nexus for vulnerabilities, malware, and suspicious patterns via webhooks.
Features
- Automatic scanning via Nexus webhooks on package cache updates
- Multi-ecosystem support — PyPI, Go, npm (any format via proxy repositories)
- REST API for scan results, findings, statistics, and CSV export
- Web dashboard with scan tables, filtering, and LLM-powered analysis
- LLM analysis — automated security analysis of each finding via OpenAI-compatible APIs (optional, configurable)
- Deduplication by URL and SHA256 — identical content scanned only once
- Structured JSON logging with optional syslog output
- Docker Compose — full stack deployment with Nexus in one command
Architecture
Nexus ──(webhook)──> GuardDog Nexus ──(REST API)──> Web UI
│
├──> GuardDog CLI (scanning)
├──> LLM API (finding analysis)
├──> SQLite (result storage)
└──> REST API (data for UI + CSV export)
Quick Start
Prerequisites
- Docker and Docker Compose
- Python 3.10+ (for local development)
Docker Deployment
cp .env.example .env
# edit .env: NEXUS_PASSWORD, optionally LLM_* vars
make docker-up
After startup:
| Service | URL | Port |
|---|---|---|
| GuardDog Nexus | http://localhost:8080 | 8080 |
| Sonatype Nexus | http://localhost:8081 | 8081 |
Environment Variables
| Variable | Default | Description |
|---|---|---|
NEXUS_URL |
http://localhost:8081 |
Sonatype Nexus URL |
NEXUS_USERNAME |
admin |
Nexus username |
NEXUS_PASSWORD |
(required) | Nexus password |
DATABASE_PATH |
data/guarddog.db |
SQLite database path |
HOST |
0.0.0.0 |
Listen host |
PORT |
8080 |
Listen port |
LOG_LEVEL |
INFO |
Logging level |
WEBHOOK_SECRET |
(empty) | HMAC-SHA256 webhook validation secret |
SCAN_TIMEOUT_SECONDS |
300 |
Scan timeout per package |
TEMP_DIR |
/tmp/guarddog-nexus |
Temporary download directory |
MAX_CONCURRENT_SCANS |
4 |
Maximum simultaneous GuardDog processes |
LLM_ENABLED |
0 |
Set to 1 to enable LLM analysis |
LLM_API_KEY |
(empty) | API key (OpenAI / Groq / Ollama / etc.) |
LLM_API_BASE |
https://api.openai.com/v1 |
OpenAI-compatible base URL |
LLM_MODEL |
gpt-4o-mini |
Model name |
LLM_TIMEOUT_SECONDS |
30 |
LLM request timeout |
LLM_MAX_CONCURRENT_ANALYSES |
2 |
Max parallel LLM analysis calls |
Nexus Configuration
Proxy Repositories
The setup script (scripts/setup-nexus.sh) creates three proxy repositories:
pypi-proxy→https://pypi.orggo-proxy→https://proxy.golang.orgnpm-proxy→https://registry.npmjs.org
Webhooks
GuardDog Nexus accepts UPDATED webhook events from Nexus.
- In Nexus admin panel: System → Capabilities
- Create Webhook: Repository capability
- URL:
http://guarddog-nexus:8080/webhooks/nexus - Event type: Repository → Asset → Updated
- Repository filter:
pypi-proxy,go-proxy,npm-proxy - Set
WEBHOOK_SECRETin.envfor HMAC-SHA256 signature validation
For local testing without real webhooks, POST manually:
curl -X POST http://localhost:8080/webhooks/nexus \ -H "Content-Type: application/json" \ -d '{"action":"UPDATED","repositoryName":"pypi-proxy","asset":{"format":"pypi","name":"/packages/pkg/1.0/pkg-1.0.tar.gz","downloadUrl":"http://nexus:8081/repository/pypi-proxy/packages/pkg/1.0/pkg-1.0.tar.gz"}}'
REST API
Scans
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/scans |
List scans (pagination, filters) |
| GET | /api/v1/scans/stats |
Statistics |
| GET | /api/v1/scans/{id} |
Scan detail with findings |
| GET | /api/v1/scans/export |
Export scans to CSV |
Packages
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/packages |
List aggregated packages |
| GET | /api/v1/packages/{name}/{version} |
Package detail with scans and findings |
| GET | /api/v1/packages/export |
Export packages to CSV |
Findings
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/findings |
List findings (filter by rule, severity, scan_id) |
| POST | /api/v1/findings/{id}/analyze |
Trigger LLM analysis for a finding |
Other
| Method | Path | Description |
|---|---|---|
| GET | /health |
Health check |
| GET | /metrics |
Prometheus-compatible metrics |
LLM Analysis
GuardDog Nexus can automatically analyze each finding through an LLM. When enabled (LLM_ENABLED=1), every flagged scan gets an AI breakdown: threat assessment, code analysis, and recommendations.
Auto mode: after a flagged scan completes, each finding is sent to the LLM. Reports are saved to the database and included in JSON log output.
Manual mode: the web UI has an "Analyze with LLM" button next to each finding — click to get an inline verdict.
Supported providers: any OpenAI-compatible API (OpenAI, Groq, Ollama, vLLM, etc.).
LLM response format (JSON):
verdict—safe/suspicious/malicioussummary— one-line verdictanalysis— detailed breakdown (2–3 paragraphs)severity_rating—low/medium/high/critical
Project Structure
guarddog-nexus/
├── guarddog_nexus/ # Main package
│ ├── core/ # Business logic (scanner, harvester, nexus, llm)
│ ├── db/ # Database (engine, models, queries)
│ ├── routes/ # HTTP layer (webhooks, api, web, metrics)
│ ├── web/ # Static assets (templates, CSS, JS)
│ ├── config.py # Environment configuration
│ ├── constants.py # Centralized constants
│ ├── i18n.py # RU/EN translations
│ ├── logging_setup.py # JSON structured logging
│ └── main.py # FastAPI app entry point
├── tests/ # pytest tests (50+)
├── scripts/ # Setup scripts
├── docker-compose.yml
├── Dockerfile
└── pyproject.toml
License
MIT
⚠ All code in this repository was generated by an AI assistant (Claude). Review carefully before using in production.