TL;DR: A graph-based vulnerability management platform that tracks CVEs from discovery through production deployment to remediation, with multi-tenant RBAC, SLA compliance tracking, and automated workflows.
- Complete Design Document - Full technical architecture, API specs, and implementation details
- Hub-and-Spoke Architecture - Deep dive into graph database design and performance
For every high-risk OSS vulnerability, security teams need answers to four questions:
graph LR
Q1[β What's the threat?] --> A1[β
CVE-2024-1234<br/>CRITICAL 9.8 CVSS]
Q2[β Where do I fix it?] --> A2[β
frontend-app repo<br/>[email protected]]
Q3[β Where is it running?] --> A3[β
prod-k8s-us-east<br/>edge-device-001]
Q4[β How do I fix it?] --> A4[β
Upgrade [email protected]<br/>Auto-create Jira ticket]
style Q1 fill:#ff6b6b
style Q2 fill:#ffd43b
style Q3 fill:#cc5de8
style Q4 fill:#51cf66
graph LR
CVE[CVE Data<br/>1M+ records] -->|affects| PURL[PURL Hubs<br/>100K packages]
PURL -->|used in| SBOM[SBOMs<br/>500K documents]
SBOM -->|describes| REL[Releases<br/>1M versions]
REL -->|deployed to| EP[Endpoints<br/>10K systems]
REL -.->|belongs to| ORG[Organizations<br/>Multi-tenant]
style PURL fill:#4dabf7
style ORG fill:#cc5de8
Key Innovation: Hub-and-Spoke architecture with PURL nodes = 99.89% less edges, <3s queries
# 1. Start ArangoDB
docker run -p 8529:8529 -e ARANGO_ROOT_PASSWORD=password arangodb:latest
# 2. Run PDVD Backend
export ARANGO_HOST=localhost ARANGO_PASS=password
go run main.go
# 3. Access APIs
# REST: http://localhost:3000/api/v1
# GraphQL: http://localhost:3000/api/v1/graphqlsequenceDiagram
participant User
participant API
participant Git as GitHub Repo
participant DB as ArangoDB
participant Email
User->>API: POST /signup<br/>(username, email, org)
API->>Git: Update rbac.yaml
Git-->>API: Commit pushed
API->>DB: Create user (pending)<br/>Create org (if new)
API->>Email: Send invitation token
User->>API: Click invitation link
API->>User: Prompt for password
User->>API: Set password + accept
API->>DB: Activate user<br/>is_active=true
API->>User: Auto-login (JWT cookie)
# rbac.yaml (stored in Git)
orgs:
- name: acme-corp
display_name: ACME Corporation
members:
- username: alice
role: owner # Full access + billing
- username: bob
role: editor # Read + write
users:
- username: alice
email: [email protected]
auth_provider: local4 Roles:
owner- Full access + billing managementadmin- Full access + user managementeditor- Read/write to resourcesviewer- Read-only access
Features:
- β Token-based email invitations (48h expiry)
- β JWT auth with HttpOnly cookies
- β GitHub App integration
- β Org-scoped data isolation
- β GitOps workflow with auto-sync
graph TB
subgraph Executive["Executive Summary"]
MTTR[MTTR: 23.4 days]
OPEN[Mean Open Age: 45.2 days]
SLA[SLA Compliance: 87%]
BACK[Backlog Delta: -12]
end
subgraph BySeverity["By Severity"]
CRIT[Critical: 3 open<br/>MTTR 8.2 days]
HIGH[High: 15 open<br/>MTTR 21.7 days]
MED[Medium: 42 open<br/>MTTR 38.5 days]
end
subgraph Endpoints["Endpoint Impact"]
EP1[prod-us-east: 23 CVEs]
EP2[edge-001: 8 CVEs]
EP3[mission-sat-7: 2 CVEs]
end
style CRIT fill:#ff6b6b
style HIGH fill:#ffa94d
style MED fill:#ffd43b
SLA Targets:
| Severity | Standard | Mission-Critical |
|---|---|---|
| Critical | 15 days | 7 days |
| High | 30 days | 15 days |
| Medium | 90 days | 90 days |
| Low | 180 days | 180 days |
# Sign-up (creates org + sends invitation)
POST /api/v1/signup
{
"username": "alice",
"email": "[email protected]",
"first_name": "Alice",
"last_name": "Smith",
"organization": "acme-corp"
}
# Login
POST /api/v1/auth/login
{ "username": "alice", "password": "secure-pass" }
# Returns: Set-Cookie: auth_token=<jwt>; HttpOnly
# Upload Release + SBOM
POST /api/v1/releases
{
"name": "payment-service",
"version": "2.1.0",
"gitcommit": "abc123",
"org": "acme-corp",
"sbom": { "content": { /* CycloneDX */ } }
}
# Sync Deployment
POST /api/v1/sync
{
"endpoint_name": "prod-us-east-1",
"releases": [{
"release": { "name": "payment-service", "version": "2.1.0" }
}],
"endpoint": {
"name": "prod-us-east-1",
"endpoint_type": "eks",
"environment": "production"
}
}# Get vulnerabilities (org-scoped)
query {
release(name: "payment-service", version: "2.1.0") {
vulnerabilities {
cve_id
severity_rating
severity_score
package
fixed_in
}
synced_endpoints {
endpoint_name
environment
}
}
}
# Dashboard with MTTR (org-filtered)
query {
dashboardMTTR(days: 180, org: "acme-corp") {
executive_summary {
total_new_cves
mttr_all
mttr_post_deployment
open_cves_beyond_sla_pct
}
by_severity {
severity
mttr
open_count
fixed_within_sla_pct
}
}
}erDiagram
USERS ||--o{ ORGS : "member_of"
ORGS ||--o{ RELEASES : "owns"
ORGS ||--o{ ENDPOINTS : "manages"
RELEASES ||--|| SBOM : "has"
RELEASES ||--o{ SYNC : "deployed_in"
ENDPOINTS ||--o{ SYNC : "hosts"
SBOM ||--o{ PURL : "contains"
CVE ||--o{ PURL : "affects"
RELEASES ||--o{ CVE : "vulnerable_to"
CVE ||--o{ CVE_LIFECYCLE : "tracked_by"
USERS ||--o{ INVITATIONS : "invited_as"
USERS {
string username PK
string email
string password_hash
string role
array orgs
bool is_active
}
ORGS {
string name PK
string display_name
}
RELEASES {
string name
string version
string org
bool is_public
}
CVE {
string id PK
float cvss_base_score
string severity_rating
}
CVE_LIFECYCLE {
string cve_id
datetime introduced_at
datetime remediated_at
}
Collections: cve, purl, sbom, release, endpoint, sync, cve_lifecycle, users, invitations, roles, orgs
- 99.89% edge reduction vs traditional graph
- <3s queries on millions of records
- Linear scalability O(N+M)
- Org isolation: Data scoped by membership
- Empty org = global: Users with
orgs: []see all - 4-level roles: owner β admin β editor β viewer
stateDiagram-v2
[*] --> Detected: CVE discovered
Detected --> Active: Deployed
Active --> Remediated: Fixed
Remediated --> [*]
- Tracks: introduced_at, remediated_at, days_to_remediate
- Post-deployment detection flags
- MTTR calculation
| Metric | Target | Actual |
|---|---|---|
| API Response | <3s | <1s (p95) |
| CVE Ingestion | 50K/hour | β |
| Concurrent Users | 100+ | β |
| Database Scale | 1M+ releases | β |
- Backend: Go 1.21+, Fiber, GraphQL
- Database: ArangoDB 3.11+
- Auth: JWT, bcrypt, HttpOnly cookies
- CVE Data: OSV.dev API
- GitOps: go-git
ARANGO_HOST=localhost
ARANGO_PASS=your-password
JWT_SECRET=change-me-in-production
ADMIN_USERNAME=admin
ADMIN_PASSWORD=secure-password
RBAC_REPO=https://github.com/org/rbac
SMTP_HOST=smtp.gmail.com
[email protected]
BASE_URL=https://pdvd.example.com
GITHUB_APP_ID=123456# Docker Compose
docker-compose up -d
# Kubernetes
helm install pdvd ./helm/pdvd-backendApache License 2.0
Built with β€οΈ by the Ortelius community | Website