Skip to content

semayellow/vuln-commander

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

8 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Vuln Commander

Vuln Commander is an open-source Application Security platform. It aggregates findings from DevSecOps scanners and service connectors into a single database, exposes a REST API, provides a web UI for vulnerability management, and ships Grafana dashboards for analytics.

Table of contents

  1. Platform overview
  2. Web UI
  3. Grafana dashboards
  4. Technology stack
  5. Architecture and data model
  6. SDK
  7. Clean install and run

1. Platform overview

The platform provides centralized vulnerability tracking across repositories:

  • GitHub service connector β€” registers projects (repositories), default branch metadata, and the latest commit.
  • DevSecOps connectors β€” periodically clone projects, run scanners, and sync findings with the API:
  • API β€” stores projects, vulnerabilities, and scan history; JWT authentication for users and connectors; role-based access control.
  • Web UI β€” dark-themed browser interface (Lunaris design) for dashboards, project registry, connector monitoring, and vulnerability triage.
  • Dashboards β€” Grafana reads aggregated PostgreSQL views (overall stats and per-scanner breakdowns).

Key capabilities

Area Description
Projects Repository registration, teams (ti / sandbox), status (active / archived)
Vulnerabilities Bulk create/update/close; lifecycle: new β†’ closed / reopened
Connectors Accounts with scope service or devsecops; per-project scan history
Users Roles user / admin; access + refresh JWT
Observability Connector logs in Graylog (GELF UDP), metrics in Grafana

2. Web UI

The platform ships a server-rendered web interface at /api/v1/. Pages share a common shell: sidebar navigation, user profile with logout, and a dark Lunaris theme (JetBrains Mono + Inter, orange accent).

Authentication uses HTTP-only cookies (vc_access_token, vc_refresh_token). After sign-in, the session is renewed automatically while you browse. Web session lifetime: access token 15 minutes, refresh token 30 minutes. Connector API access via Bearer JWT is unchanged (5 / 30 minutes).

Sign in

Open /api/v1/auth/ and sign in with a platform user email and password. After login you are redirected to the home page (or the page you originally requested).

Sign in

Home

URL: /api/v1/

Dashboard with live platform metrics (open vulnerabilities, active projects, connectors, scans today) and quick links to pgAdmin, Grafana, and Graylog.

Home dashboard

Projects

URL: /api/v1/projects

Registry of all tracked repositories. The table supports search, pagination, and configurable page size. Each row shows team, status, last commit timestamp, open vulnerability count, and an Open action that opens vulnerability management for that project.

Projects

Connectors

URL: /api/v1/connectors

Monitor scanner and service integrations: connector name, scope (service / devsecops), runtime status (Running, Waiting, Error, Inactive), and last run time. The table refreshes automatically every minute; the footer shows Last updated with the timestamp of the latest data fetch.

Connectors

Vulnerability management

URL: /api/v1/vuln/manage/{project_name}

Per-project triage view. Filter by status and severity, sort by created/closed dates, select rows for bulk actions, and open individual findings. Pagination and page size match the shared data-table controls used across the UI.

Vulnerability management

Vulnerability details

URL: /api/v1/vuln/details/{vuln_id}

Single-finding view with severity, status, file location, code snippet, metadata (commit, rule, branch), and navigation between related vulnerabilities in the same project. Actions: mark as False Positive, create task (in development).

Vulnerability details

UI routes summary

Page URL
Sign in /api/v1/auth/
Home /api/v1/
Projects /api/v1/projects
Connectors /api/v1/connectors
Vulnerabilities (project) /api/v1/vuln/manage/{project_name}
Vulnerability detail /api/v1/vuln/details/{vuln_id}

3. Grafana dashboards

Grafana provides analytics on top of aggregated PostgreSQL views. The vuln-commander dashboard is provisioned automatically from grafana/main_dashboard.json and reads data from the Vuln Commander Postgres datasource.

URL: http://localhost:3000 (credentials: GF_SECURITY_ADMIN_USER / GF_SECURITY_ADMIN_PASSWORD from .env)

You can also open Grafana from the Home page quick actions (/api/v1/ β†’ Open Grafana).

Filters

The dashboard exposes template variables for slicing data across the whole report:

Variable Description
project_name Filter by repository / project
control_type Filter by scanner (gss, iac, sca_vuln, sca_license)
severity Filter by finding severity
team Filter by project team (ti, sandbox)

Main dashboard

Per-project summary table: vulnerability counts by severity (info β†’ critical), last commit time, and links to the project repository and vulnerability management UI.

Grafana β€” main dashboard

General statistic

High-level breakdowns: vulnerabilities by severity, status, scanner type, and a combined scanner + severity bar chart. Use this section for portfolio-wide trends and triage prioritization.

Grafana β€” general statistic

IAC and SCA statistics

Scanner-specific analytics:

  • IAC β€” findings by cloud/platform (Terraform, Kubernetes, CloudFormation, etc.) and by CWE.
  • SCA β€” top packages with the most vulnerability occurrences across scanned projects.

Grafana β€” IAC and SCA statistics

Vulnerability details by scanner

Drill-down tables for individual findings:

Panel Content
GSS vulnerabilities details Secret findings: severity, status, filepath
IAC vulnerabilities details Misconfiguration rules and CWE references
SCA license details License identifiers with SPDX links
SCA vulnerabilities details CVE titles and descriptions

Grafana β€” vulnerability details by scanner

Data sources

Panels query SQL views created during API migration (api/migrations/views_generation_spec):

  • vc_view_general_vulnerabilities_statistic β€” project summary
  • vc_view_project_vulnerabilities_statistic β€” per-project detail
  • vc_view_gss_vulnerabilities_statistic, vc_view_iac_*, vc_view_sca_* β€” per-scanner breakdown

4. Technology stack

Backend and data

Component Technology
API Python 3.12, FastAPI, Uvicorn, Gunicorn
ORM / migrations SQLAlchemy 2, Alembic, asyncpg
Schema validation Pydantic v2
Database PostgreSQL (Bitnami image)
Authentication JWT (PyJWT), bcrypt
UI templates Jinja2, Lunaris CSS (api/src/static/css/lunaris.css)

Connectors and SDK

Component Technology
HTTP client aiohttp
Scheduler cron-converter (Scheduler)
Git operations GitPython
Logging loguru, pygelf β†’ Graylog
Dependency management uv
Shared schemas shared/ package (vuln-commander-shared)

Infrastructure (Docker Compose)

Service Purpose Host port
api REST API + static assets 8000
db PostgreSQL 5432
db-ui pgAdmin 8080
github, gss, iac, sca-license, sca-vuln Connectors β€”
graylog + graylog-datanode + graylog-mongodb Centralized logs 9000 (UI)
grafana Dashboards 3000

External scanners (bundled in connector images)

  • Nosey Parker (GSS)
  • KICS (IAC)
  • Trivy (SCA)

5. Architecture and data model

High-level diagram

flowchart LR
  subgraph connectors [Connectors]
    GH[GitHub service]
    GSS[GSS]
    IAC[IAC]
    SCA_V[SCA Vuln]
    SCA_L[SCA License]
  end

  SDK[Vuln Commander SDK]
  API[FastAPI API]
  PG[(PostgreSQL)]
  GL[Graylog]
  GF[Grafana]

  GH --> SDK
  GSS --> SDK
  IAC --> SDK
  SCA_V --> SDK
  SCA_L --> SDK
  SDK -->|JWT REST| API
  API --> PG
  connectors -->|GELF| GL
  GF -->|SQL views| PG
Loading

Repository layout

vuln-commander/
β”œβ”€β”€ api/                 # REST API, Alembic migrations, UI templates
β”œβ”€β”€ sdk/                 # Client library for connectors
β”œβ”€β”€ shared/              # Shared Pydantic schemas and enums
β”œβ”€β”€ connectors/
β”‚   β”œβ”€β”€ connectors_spec.yml   # Connector registry for DB bootstrap
β”‚   β”œβ”€β”€ service/github/       # Service connector
β”‚   └── devsecops/            # GSS, IAC, SCA-*
β”œβ”€β”€ grafana/             # Provisioning and dashboards
β”œβ”€β”€ static/              # Docs assets, SQL for views
└── docker-compose.yml

Data flow

  1. GitHub reads a list of repository URLs on a schedule and calls POST /api/v1/projects β€” projects and commits are stored in the database.
  2. A DevSecOps connector calls GET /api/v1/projects/{connector_type}, clones the repository, and runs a scanner.
  3. The SDK performs vulnerability synchronization (process_vulns): new findings are created, missing ones are closed, previously closed ones are reopened when detected again.
  4. After a scan, history is recorded via POST /api/v1/connectors/history (severity counters).
  5. Grafana builds reports from SQL views (vc_view_*).

REST API (/api/v1)

Prefix Purpose Called by
/auth Issue and refresh JWT Users, connectors
/users User management Admin
/projects Project CRUD / scanner project list GitHub (service), connectors (devsecops)
/vuln Bulk vulnerability operations, HTML UI pages DevSecOps connectors, browser
/connectors Connector management, scan history, UI data API Admin, DevSecOps, browser

Access control is based on JWT scope: user (admin/user role), connector (scope service / devsecops).

PostgreSQL tables

Table Purpose
vc_project Project: name, team, clone URL, branch, status
vc_commit Latest known commit for a project
vc_user Platform users
vc_connector Connector accounts
vc_refresh_token Refresh tokens (user or connector)
vc_vuln Vulnerabilities (unique hash)
vc_connector_scan_history Severity snapshot after a scan

Enumerations

  • UserTeam: ti, sandbox
  • UserRole: user, admin
  • ProjectStatus: active, archived
  • ConnectorScope: service, devsecops
  • ConnectorType: iac, gss, sca_license, sca_vuln, github
  • VulnSeverity: info, low, medium, high, critical
  • VulnStatus: new, awaiting_review, closed, false_positive, reopened

Vulnerability hash

Finding uniqueness is defined by an MD5 over:

project_id, connector_type, severity, filepath, line, custom_fields (JSON).

The same formula is used in shared/schemas/vuln.py and sdk.src.utils.helpers.generate_vuln_hash.

SQL views (Grafana)

Created during migration from api/migrations/views_generation_spec:

  • vc_view_general_vulnerabilities_statistic β€” project summary
  • vc_view_project_vulnerabilities_statistic β€” per-project detail
  • vc_view_gss_vulnerabilities_statistic, vc_view_iac_*, vc_view_sca_* β€” per-scanner breakdown

Connector registry

The file connectors/connectors_spec.yml defines connectors for one-time registration on API startup (see api/docker-entrypoint.sh):

- name: github
  env: GITHUB          # β†’ CONNECTOR_GITHUB_UUID / CONNECTOR_GITHUB_PASSWORD
  scope: service
  type: github

6. SDK

Python library for building connectors: HTTP client to the API, vulnerability sync, cron scheduler, and Graylog logging.

Full class and method reference: sdk/README.md

Quick example:

from sdk import Scheduler, VulnCommanderSDK
from shared.schemas.constants import ConnectorType

async def main():
    scheduler = Scheduler("0 12 */1 * *")  # cron
    for _ in scheduler:
        async with VulnCommanderSDK(connector_id, connector_password) as sdk:
            projects = await sdk.get_projects(ConnectorType.gss)
            # ... scan ...
            await sdk.process_vulns(actual_vulns, project.vulns)

Inside the Docker network, the default API URL is http://api:8000/api/v1 (sdk/src/utils/config.py).


7. Clean install and run

Requirements

  • Docker and Docker Compose v2
  • ~8 GB free RAM (Graylog + PostgreSQL + connectors)
  • Internet access to pull/build images

Step 1. Clone and environment variables

git clone <repository-url> vuln-commander
cd vuln-commander
cp .env.example .env

Edit .env:

  • PostgreSQL, pgAdmin, Grafana, and Graylog passwords (GRAYLOG_PASSWORD_SECRET β‰₯ 16 characters)
  • GRAYLOG_ROOT_PASSWORD_SHA2 β€” SHA-256 hex of the Graylog admin password
  • ADMIN_* β€” API admin account (created only when the database has no users yet)
  • CONNECTOR_*_UUID and CONNECTOR_*_PASSWORD β€” must match CONNECTOR_ID / CONNECTOR_PASSWORD in each connector’s .env

Step 2. Connector configuration

Create a .env file for each service in docker-compose.yml (not committed to the repo):

connectors/service/github/.env

CONNECTOR_ID=<same UUID as CONNECTOR_GITHUB_UUID>
CONNECTOR_PASSWORD=<same password as CONNECTOR_GITHUB_PASSWORD>
CRON_SCHEDULE=0 12 */1 * *
PARALLEL_TASKS_COUNT=2
GRAYLOG_UDP_PORT=12201

connectors/devsecops/gss/.env (same pattern for iac, sca-license, sca-vuln with the matching UUIDs from .env):

CONNECTOR_ID=<CONNECTOR_GSS_UUID>
CONNECTOR_PASSWORD=<CONNECTOR_GSS_PASSWORD>
CRON_SCHEDULE=0 12 */1 * *
PARALLEL_TASKS_COUNT=2
VULNS_REQUEST_BATCH_SIZE=100
GRAYLOG_UDP_PORT=12201

Step 3. GitHub repository list

mkdir -p connectors/service/github
cat > connectors/service/github/projects.txt <<'EOF'
https://github.com/org/example-repo.git
EOF

One clone URL per line. The file is listed in .gitignore.

Step 4. Start the stack

docker compose up -d --build

On first api startup:

  1. Waits for PostgreSQL to become ready
  2. Runs alembic upgrade head
  3. Creates the admin user (if the DB is empty) and connectors from connectors_spec.yml

Full database initialization may take 1–2 minutes (PostgreSQL healthcheck start_period is up to 120 s).

Step 5. Verify

Service URL Notes
Web UI (Home) http://localhost:8000/api/v1/ Sign in required; metrics and quick links
Sign in http://localhost:8000/api/v1/auth/ Platform user email + password
Projects http://localhost:8000/api/v1/projects Project registry and vulnerability entry point
Connectors http://localhost:8000/api/v1/connectors Live connector status (auto-refresh every 60 s)
API / OpenAPI http://localhost:8000/docs Swagger UI
pgAdmin http://localhost:8080 Credentials from .env
Grafana http://localhost:3000 Pre-provisioned vuln-commander dashboard; GF_SECURITY_ADMIN_*
Graylog http://localhost:9000 Root password from SHA2 in .env
Vulnerability management http://localhost:8000/api/v1/vuln/manage/{project_name} Open from Projects table after data is available

API authentication for connectors and scripts: POST /api/v1/auth/ with Basic Auth (CONNECTOR_ID + connector password, or user email + password for programmatic access).

Step 6. Stop and full reset

# Stop
docker compose down

# Remove volumes (clean DB, Graylog, Grafana)
docker compose down -v

After down -v, the next up will run migrations and bootstrap again.

Local development without Docker

# API (from repo root; PostgreSQL must be running)
export PYTHONPATH=$(pwd)
export POSTGRESQL_HOST=localhost
# ... remaining POSTGRESQL_* from .env
uv sync --project api
uv run --project api alembic -c api/alembic.ini upgrade head
uv run --project api python -m api.src.core.orm.initialisation.session
uv run --project api uvicorn api.src.main:app --reload --host 0.0.0.0 --port 8000

Run connectors from the sdk/ directory with PYTHONPATH pointing at the monorepo root and API_BASE_URL=http://localhost:8000/api/v1 (adjust sdk/src/utils/config.py or move the URL into an environment variable if needed).


License

See LICENSE.

About

An OpenSource ASOC platform

Topics

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors