Architecture overview
An Excalidraw schema is available here.
High-level view
servasec is an ASPM (Application Security Posture Management) platform that centralizes security scan results from multiple tools and provides a unified view of vulnerabilities across the entire application portfolio.
┌─────────────┐
│ CI/CD │
└──────┬──────┘
│ POST /api/ingest
┌──────▼──────┐
│ Caddy │
└──┬──────┬───┘
│ │
┌────▼──┐ ┌─▼───────────┐
│Backend│ │ Frontend │
└──┬────┘ └─────────────┘
│
┌────▼────┐
│ Postgres│
└─────────┘
Core concepts
Group
A logical container for organizing applications (e.g. backend-services, frontend-apps).
A Group has many Applications.
Application
Maps to a software project (Git repository, service, microservice).
Each application has:
- API token - used to authenticate scan uploads from CI/CD
- Asset criticality -
low,medium,high, orcritical
An Application belongs to a Group, and has many ApplicationVersions and Webhooks.
ApplicationVersion
Represents a version or environment of the application (e.g. main, v1.0.0, develop).
Belongs to an Application.
ScannerType
Represents a supported scan tool. Supported scanners include semgrep, trivy, gitleaks, grype, snyk, checkov, trufflehog, nuclei, and a generic sarif fallback.
Scan
Represents the upload of a result file for a given version. Acts as a container for parsed findings.
Status: pending, processing, completed, or failed.
Belongs to an ApplicationVersion and a ScannerType. Has many Findings.
Finding
A vulnerability or security issue detected by a scan.
Each finding shows:
- Severity -
critical,high,medium,low,info - Scanner - source scanner (Semgrep, Trivy, etc.)
- Location - file path and line number
- Description - detailed explanation of the vulnerability
- Remediation - suggested fix
- RiskScore - combines severity (40%), EPSS (35%), age (15%), and asset criticality (10%)
- References - links to CVEs or documentation
- Assignee - responsible team member
- Comments - threaded discussion per finding
- Timeline - status change history
Belongs to a Scan, an ApplicationVersion, and a ScannerType.
Webhook
HTTP notification triggered by events. Configurable per application with optional HMAC signing.
Supported events: finding.created, finding.status_changed, finding.reassigned, scan.completed.
Policy
An automated rule that triggers actions when conditions are met. A policy has:
- Scope -
application,group, orglobal - Event types - what triggers the policy (e.g.
finding.created) - Conditions - filters on severity, scanner type, risk score, status, etc.
- Actions - what to do: change finding status, assign to a user, or fire a webhook
Team
A group of users for collective permissions. Roles: admin (full access) or member (can create applications, manage own assignments).
Permissions can be granted at the resource level: read (view findings and scans) or write (full CRUD, ingest, manage webhooks).
A Team has many Users through TeamMember.
Ingestion flow
- CI/CD pushes a result file via
POST /api/ingest - The application is identified
- The version is created or updated
- The scanner type is detected
- The file is parsed
- Findings are created with deduplication
- Risk scores are calculated
- Policies are evaluated
- Webhooks are triggered
CI/CD ──POST /ingest──► Backend
│
┌────▼────┐
│ Find │
│ app │
└────┬────┘
┌────▼────┐
│ Upsert │
│ version │
└────┬────┘
┌────▼────┐
│ Detect │
│ scanner │
└────┬────┘
┌────▼────┐
│ Parse │
│ file │
└────┬────┘
┌────▼────┐
│ Create │
│ findings│
└────┬────┘
┌────▼────┐
│ Eval │
│ policies│
└─────────┘
Finding lifecycle
A finding moves through these statuses:
- Open - newly ingested, awaiting review
- Confirmed - triaged and acknowledged as a real issue
- Fixed - remediation applied, pending verification
- False Positive - determined not to be a real issue
open ──→ confirmed ──→ fixed ──→ open
│ │
└──→ false_positive ←───┘
Permission model
Two levels of access control:
- Global - defines what each role can access
- Resource-level - per-resource permissions granted at creation time
Request ──→ Admin ? ──yes──→ Accepted
│ no
▼
User has permission ? ──yes──→ Accepted
│ no
▼
User's team has permission ? ──yes──→ Accepted
│ no
▼
Rejected
Tech stack
| Layer | Technology |
|---|---|
| Backend | Go / Gin / GORM / Casbin |
| Database | PostgreSQL (migrations via Goose) |
| Frontend | Next.js / shadcn/ui / Tailwind CSS |
| Reverse proxy | Caddy (auto TLS) |
| Deployment | Docker Compose |
Dashboard
The dashboard provides a high-level overview of your security posture: total and overdue findings, severity distribution, top risks, and breakdowns by status and scanner.