* refactor(ui): share neutral capability contracts across editions Move SiriusCapability, SiriusPrincipal, the capability snapshot/provider types, and the Community catalog into a React-free contracts module so the browser registry and the incoming server registry cannot hold divergent catalogs. The UI extension modules re-export the same names, so consumers are unchanged. Pin the Community catalog to documentation/product/edition-boundary.yaml with a contract test, since that file is the source of truth for the edition boundary. Co-authored-by: mtoussain <mtoussain@gmail.com> * feat(ui): add server principal resolver and tRPC extension seam Mirror the browser extension registry on the server. A SiriusServerExtension declares tRPC namespaces with their required capabilities, at most one principal resolver, and optional session enrichers; registered.ts is the build-time overlay a private build replaces. protectedProcedure now enforces the capabilities declared for the procedure's namespace, so a contributed namespace is authorized without patching Core procedures. Principal resolution fails closed: a resolver that throws yields no principal instead of inheriting another edition's capability set. Community resolves any authenticated session to its static catalog, leaving Community behavior unchanged. root.ts cross-checks declared namespaces against the composed router in both directions, so an overlay that ships a router without declaring it (or declares a namespace it never serves) fails at startup rather than at request time. The routers stay object literals so tRPC keeps inferring client types. Co-authored-by: mtoussain <mtoussain@gmail.com> * test(ui): run extension contract tests in CI Add the server and capability suites alongside the UI registry suite behind a single test:extensions script, and make it a blocking CI step so the contracts private builds overlay are actually guarded. Co-authored-by: mtoussain <mtoussain@gmail.com> * docs: record the server-side extension seam in ADR-004 and the task board Co-authored-by: mtoussain <mtoussain@gmail.com> * fix(server): allow private principal resolver to replace Community fallback * test(server): prove private resolver can replace Community fallback * docs: record resolver replacement semantics and freeze server contracts at v1 Co-authored-by: mtoussain <mtoussain@gmail.com> * fix(server): split overlay router slot out of the declaration slot Contributing routers from registered.ts cycles: trpc.ts imports the registry to enforce capabilities, so an overlay router module importing createTRPCRouter loads while trpc.ts is still initializing and dies with 'Cannot access createTRPCRouter before initialization'. This was found by composing a private extension against the seam. Routers now come from registered-routers.ts, which only root.ts imports, so they load after trpc.ts is ready. root.ts still cross-checks declared namespaces against composed ones, and a contract test keeps the declaration modules free of tRPC imports. Co-authored-by: mtoussain <mtoussain@gmail.com> * docs: document the overlay module split and cycle constraint Co-authored-by: mtoussain <mtoussain@gmail.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Sirius Scan
Sirius is an open-source vulnerability scanner with automated discovery, CVE-based detection, and a modern web UI. Clone, run four commands, start scanning.
Quick Start
git clone https://github.com/SiriusScan/Sirius.git
cd Sirius
docker compose -f docker-compose.installer.yaml run --rm sirius-installer
docker compose up -d
Open http://localhost:3000 and log in:
admin@example.com |
|
| Password | printed by the installer (look for INITIAL_ADMIN_PASSWORD in the output) |
That's it. All six services start automatically. The installer generates secure secrets on first run and is safe to re-run.
By default the installer leaves IMAGE_TAG unset, so Compose pulls latest from GHCR. To pin a release (for example v1.0.0 in .env), only do so after that tag exists for all six container images; verify with bash scripts/verify-ghcr-public-access.sh v1.0.0 from a shell that is not logged in to ghcr.io.
Requirements: Docker Engine 20.10+ with Compose V2, 4 GB RAM, 10 GB disk. Works on Linux, macOS, and Windows (WSL2).
What Sirius Does
- Network Discovery -- automated host and service enumeration via Nmap
- Vulnerability Detection -- CVE-based scanning with CVSS scoring
- Risk Dashboards -- real-time scanning progress, severity trends, and remediation guidance
- Remote Agents -- distributed scanning across multiple environments via gRPC
- Interactive Terminal -- PowerShell console for advanced scripting and automation
- REST API -- integrate with existing security workflows (
X-API-Keyauth on port 9001)
Deployment Options
The installer step is always the same. Only the docker compose up command changes.
| Mode | Command | Use case |
|---|---|---|
| Standard | docker compose up -d |
Most users -- pulls the full release stack from GHCR |
| Development | docker compose -f docker-compose.yaml -f docker-compose.dev.yaml up -d |
Live-reload for local code work |
| Source Build | docker compose -f docker-compose.yaml -f docker-compose.build.yaml up -d --build |
Explicit local full-stack builds |
| Production | docker compose -f docker-compose.yaml -f docker-compose.prod.yaml up -d |
Hardened settings, pull_policy: always |
Non-interactive setup (CI / Terraform / automation)
docker compose -f docker-compose.installer.yaml run --rm sirius-installer --non-interactive --no-print-secrets
docker compose up -d
Rotate secrets
docker compose -f docker-compose.installer.yaml run --rm sirius-installer --force
docker compose up -d --force-recreate
Verify Installation
docker compose ps # all 6 services should show "healthy" or "running"
curl http://localhost:3000 # UI responds
curl http://localhost:9001/health # API responds
Expected services: sirius-ui (3000), sirius-api (9001), sirius-engine (5174, 50051), sirius-postgres (5432), sirius-rabbitmq (5672, 15672), sirius-valkey (6379).
Architecture
graph TD
subgraph clients [Clients]
UI["Sirius UI (Next.js)"]
CLI["Terminal and Agent Runtime"]
end
subgraph core [Core Services]
API["Sirius API (Go/Gin)"]
Engine["Sirius Engine"]
end
subgraph infra [Infrastructure]
MQ["RabbitMQ"]
DB["PostgreSQL"]
Cache["Valkey"]
end
UI -->|"HTTP/WebSocket"| API
CLI -->|"gRPC"| Engine
API -->|"AMQP publish"| MQ
MQ -->|"Queue consume"| Engine
API -->|"SQL read/write"| DB
Engine -->|"SQL read/write"| DB
API -->|"Session/cache ops"| Cache
Engine -->|"Scan state cache ops"| Cache
| Service | Technology | Ports | Purpose |
|---|---|---|---|
| sirius-ui | Next.js 14, React, Tailwind | 3000 | Web interface |
| sirius-api | Go, Gin | 9001 | REST API and business logic |
| sirius-engine | Go + embedded gRPC agent | 5174, 50051 | Scanner, terminal, agent services |
| sirius-postgres | PostgreSQL 15 | 5432 | Vulnerability and scan data |
| sirius-rabbitmq | RabbitMQ | 5672, 15672 | Inter-service messaging |
| sirius-valkey | Valkey (Redis-compatible) | 6379 | Cache and session data |
Interface
| Dashboard | Scanner | Vulnerability Navigator |
|---|---|---|
![]() |
![]() |
![]() |
| Environment | Host Details | Terminal |
|---|---|---|
![]() |
![]() |
![]() |
API
Sirius exposes REST endpoints on port 9001, protected by the internal service API key. Prefer the Docker secret file (SIRIUS_API_KEY_FILE, default /run/secrets/sirius_api_key); SIRIUS_API_KEY remains a supported env fallback. The installer writes ./secrets/sirius_api_key.txt (mode 0644 so non-root app UIDs can read the bind-mounted secret) and configures both.
curl http://localhost:9001/health -H "X-API-Key: $SIRIUS_API_KEY"
curl http://localhost:9001/api/v1/scan/get/all -H "X-API-Key: $SIRIUS_API_KEY"
Full API docs: REST API Reference
Security Recommendations
For production deployments:
- Rotate secrets -- run the installer with
--forceto regenerate all credentials - Restrict ports -- only expose port 3000 (UI); keep 5432, 6379, 5672 internal
- Use a reverse proxy -- put nginx or Traefik in front with TLS
- Keep images updated --
docker compose pull && docker compose up -d
Troubleshooting
Quick fixes for common problems:
| Problem | Fix |
|---|---|
| Services won't start | docker compose logs <service> to find the error |
| Dev overlay missing infra | Use both files: -f docker-compose.yaml -f docker-compose.dev.yaml |
| Port conflict | lsof -i :3000 to find the conflicting process |
| Database connection error | docker exec sirius-postgres pg_isready |
| Stale secrets after reset | Re-run the installer, then docker compose up -d --force-recreate |
For detailed operational runbooks, verification procedures, and emergency recovery, see Operations & Troubleshooting.
Contributing
See CONTRIBUTING.md for development setup, coding standards, and PR guidelines.
Quick links: Issues | Discussions | Discord
Further Reading
- Installation Guide
- Interface Tour
- Scanning Guide
- Docker Architecture
- System Architecture
- CI/CD Guide
- Operations & Troubleshooting





