- File references must be repo-root relative (example:
internal/api/handlers.go:42); never absolute paths. - When answering questions, verify claims in source code; do not guess or hallucinate.
AgentScan is an AI Agent network asset discovery and security audit platform targeting exposed OpenClaw, clawhive, GoGogot, Hermes Agent, and Pincer instances. The system performs layered scanning (L1 port scan → L2 fingerprint → L3 vulnerability check) with a React dashboard frontend.
AgentScan/
├── cmd/agentscan/ # CLI entry (Cobra: server/scan/migrate/version)
├── cmd/mock-openclaw/ # Mock OpenClaw server for testing
├── configs/ # Config template (config.yaml.example)
├── _data/ # Runtime data (db + config overrides, gitignored)
├── docs/ # Design docs (gitignored, local only)
├── internal/ # All Go business logic
│ ├── core/ # Infrastructure (zero business deps)
│ │ ├── config/ # Viper config + env vars (AGENTSCAN_*) + validation
│ │ ├── eventbus/ # Async event bus (goroutine pool + panic recovery)
│ │ └── logger/ # zap structured logging (console/json + file)
│ ├── utils/ # Pure utility functions (stateless)
│ │ ├── iputil/ # IP/CIDR/Range parsing + file import
│ │ └── version/ # Semantic version comparison
│ ├── api/ # Gin REST API + WebSocket + middleware
│ ├── alert/ # Alert engine (rule matching + Webhook)
│ ├── auth/ # JWT auth + bcrypt password hashing
│ ├── engine/ # L1→L2→L3 scan pipeline orchestration
│ ├── geoip/ # GeoIP + ASN region scanning
│ ├── intel/ # Threat intel (FOFA client)
│ ├── models/ # GORM data models + JSONMap
│ ├── report/ # Excel report generation (4 sheets)
│ ├── scanner/ # Scanner implementations
│ │ ├── l1/ # TCP CONNECT port scanner
│ │ ├── l2/ # HTTP/WS/mDNS fingerprinting probes
│ │ └── l3/ # CVE matching + auth check + Skills enum + PoC
│ ├── store/ # GORM persistence (SQLite/PostgreSQL + versioned migration)
│ └── task/ # Task manager + Cron scheduler
├── web/ # Frontend (React + Ant Design + ECharts)
├── third_party/openclaw-src/ # OpenClaw source (git submodule, reference only)
└── scripts/ # Utility scripts
- Dependency direction:
core/→utils/→models/→store/→ business packages →api/→cmd/. Never import backwards. - Event-driven:
internal/core/eventbusdecouples scan events from handlers. Topics defined ineventbus/topics.go. - Pipeline pattern:
internal/engine/pipeline.goorchestrates L1→L2→L3 with progress callbacks. - Store interface:
internal/store/store.godefines theStoreinterface;gorm.goimplements it. - Versioned migrations:
internal/store/migrator.go— migrations are Go code (not SQL files). Append new migrations tovar migrationsslice; never reorder or modify existing ones.
- Backend: Go 1.23+ (Gin, GORM, Cobra, Viper, zap, cron/v3)
- Frontend: React + TypeScript + Ant Design + ECharts + Zustand
- Database: SQLite (dev) / PostgreSQL (prod)
- Build:
go build(backend), Vite (frontend)
- Build all:
go build ./... - Run tests:
go test ./... - Static analysis:
go vet ./... - Tidy deps:
go mod tidy - Start server:
go run cmd/agentscan/main.go server - Quick scan:
go run cmd/agentscan/main.go scan --targets 192.168.1.0/24 - Run migrations:
go run cmd/agentscan/main.go migrate - Mock OpenClaw:
go run cmd/mock-openclaw/main.go(listens on :18789) - CGO is required for SQLite (
mattn/go-sqlite3).
- Install deps:
cd web && npm install - Dev server:
cd web && npm run dev - Build:
cd web && npm run build - Output goes to
web/dist/(gitignored).
- Start mock:
go run cmd/mock-openclaw/main.go - Start backend:
go run cmd/agentscan/main.go server - Start frontend:
cd web && npm run dev - Login:
admin/agentscan(default credentials)
- Config template:
configs/config.yaml.example— copy to_data/config.yamlfor local use. - Viper search order:
./config.yaml→./configs/→./_data/→/etc/agentscan/ - Environment override prefix:
AGENTSCAN_(e.g.AGENTSCAN_SERVER_PORT=9090) - Default database DSN:
_data/agentscan.db(SQLite) - Production validation:
auth.jwt_secretmust be changed from default when using PostgreSQL driver.
- Language: Go (backend), TypeScript (frontend). Use Chinese comments when the codebase already does (project is bilingual).
- Go files should target ~500 LOC max; split when it improves clarity.
- Use
internal/core/logger(zap) for all logging; never usefmt.Printlnorlog.Println. - Use
internal/core/configfor all configuration; never hardcode values. - Use
internal/core/eventbusfor async cross-module communication; never import business packages intocore/. - Error handling: always wrap errors with context using
fmt.Errorf("context: %w", err). - Models: all GORM models live in
internal/models/. UseJSONMaptype for flexible JSON fields. - API handlers: follow the pattern in
internal/api/handlers.go— input validation → service call → response. - API errors: use
internal/api/errors.gohelpers for consistent JSON error responses.
- State management: Zustand stores in
web/src/stores/. - API client:
web/src/api/client.ts— all backend calls go through this. - Type definitions:
web/src/types/models.ts(backend mirror) +web/src/types/index.ts. - Components: Ant Design Pro components; custom components in
web/src/components/.
- Colocate test files:
*_test.gonext to source. - Use
github.com/stretchr/testifyfor assertions. - Store tests use
t.TempDir()for ephemeral SQLite databases. - Pipeline tests use mock scanners (see
internal/engine/pipeline_test.go). - Run
go build ./...andgo vet ./...before pushing; both must pass cleanly. - Packages with tests:
api,eventbus,engine,scanner/l3,store,iputil,version.
- Use concise, action-oriented commit messages:
module: action description(e.g.api: add pagination to asset list). - Group related changes; avoid bundling unrelated refactors.
- Run
go build ./...andgo test ./...before committing. - Never commit
_data/,agentscan.db,.envfiles, or secrets. - Never commit
node_modules/,web/dist/, or build artifacts.
configs/config.yaml.examplecontains dev-only default credentials; these must be changed in production.auth.jwt_secretvalidation enforces non-default in postgres mode.- Never commit real API keys (FOFA, GeoIP license keys).
- The mock OpenClaw server (
cmd/mock-openclaw/) is for testing only; it simulates vulnerabilities.
The scan pipeline has three layers:
- L1 (Port Scan):
internal/scanner/l1/tcp.go— TCP CONNECT scan with configurable concurrency/rate-limit. - L2 (Fingerprint):
internal/scanner/l2/— HTTP health/config/MCP probes, WebSocket handshake, mDNS discovery. - L3 (Vulnerability):
internal/scanner/l3/— CVE matching (7 CVEs), auth bypass check, Skills enumeration, PoC verification.
Pipeline orchestration lives in internal/engine/pipeline.go. It emits events via eventbus for real-time progress tracking.
- GORM is the ORM. Both SQLite and PostgreSQL are supported.
- Migrations are code-based in
internal/store/migrator.go(not external SQL files). - To add a new migration: append a new
Migration{}entry to themigrationsslice with an incremented version string. Never modify existing migrations. - Connection pool defaults: 25 max open, 5 max idle, 5m max lifetime.
third_party/openclaw-src— OpenClaw source code for reference and feature analysis. Read-only; do not modify.
- Create
internal/scanner/l2/new_probe.go - Implement probe function matching the pattern in
http.go/websocket.go - Wire it into
internal/engine/pipeline.goL2 stage - Add corresponding
AgentTypeconstant ininternal/models/asset.goif needed
- Add CVE struct to
internal/scanner/l3/cve.gocveRulesslice - Implement checker function following existing pattern
- Add test case in
cve_test.go
- Add handler in
internal/api/handlers.go - Register route in
internal/api/server.goroute group - Add input validation using Gin binding tags
- Use
internal/api/errors.gohelpers for error responses - If new Store method needed, add to
Storeinterface first, then implement ingorm.go
- Open
internal/store/migrator.go - Append a new
Migration{}tovar migrationswith next version (e.g. "003") - Never modify or reorder existing migrations
- Test with
go run cmd/agentscan/main.go migrate
- Create
internal/core/eventbus/redis.go - Implement
EventBusinterface (Publish + Subscribe) - Use
MarshalPayload/UnmarshalPayloadfor serialization (already provided) - Wire via config flag in
cmd/agentscan/main.goserver startup
- Auth state: Zustand store (
web/src/store/auth.ts) — JWT token + user info - Server data: TanStack Query v5 — all API data uses query hooks with cache invalidation
- WebSocket → Query bridge:
useWSInvalidationhook invalidates relevant query caches on WS events
- React Router v6 with
React.lazycode splitting per page - Protected routes check auth token; redirect to
/loginif missing - Layout component (
web/src/components/Layout.tsx) wraps all authenticated pages
- Create page component in
web/src/pages/NewPage.tsx - Add lazy route in
web/src/App.tsx - Add API functions in
web/src/api/(follow existing patterns liketasks.ts) - Add types in
web/src/types/models.tsmirroring backend models - Use Ant Design components; follow existing color/tag constants in
web/src/constants/
- SQLite lock errors: ensure only one server instance runs at a time.
- CGO build failures: install C compiler (
xcode-select --installon macOS). - Frontend API 404: ensure backend server is running and API base URL matches.
- WebSocket disconnects: check JWT token expiry (default 24h TTL).
- Migration failures: check
schema_migrationstable for partial state; fix and re-run. - Event delivery issues: check
eventbusworker pool logs; panics are recovered but logged.