Architecture
System diagram, microservices overview, data flow pipelines, network topology, and RabbitMQ exchanges.
System Diagram
Internet
|
[HAProxy]
/ | \ \
/ | \ \
[NextJS] [Inbound] [Corp] [Docs]
| |
| [RabbitMQ]
| / | \
[API] / | \
| [Store] | [Alert]
| | [Scanner]
[Valkey]| |
| [MySQL] |
| | |
[Enricher] [TacoDB]
|
[VulnDB CLI]
[Fetcher] ---> [Inbound] [Secrets] ---> [MySQL]
(registries) (SBOM scanning)
Microservices
| Service | Language | Framework | Port | Role |
|---|---|---|---|---|
| taco-api | Go | Echo v4 | 8090 | REST API for frontend, manages users/subscriptions/projects/findings |
| taco-nextjs | TypeScript | Next.js 16 | 3000 | Web frontend (portal.taco-sec.com) |
| taco-inbound | Go | Echo v4 | 8080 | SBOM ingestion gateway, publishes to RabbitMQ |
| taco-auth | Go | Echo v4 | 8081 | Project token validation, Redis-cached lookups |
| taco-store | Go | stdlib | 8082 | RabbitMQ consumer, parses CycloneDX/SPDX SBOMs, stores components in MySQL |
| taco-alert | Go | stdlib | 8083 | RabbitMQ consumer, dispatches alerts (Slack, email, webhook, PagerDuty) |
| taco-scanner | Go | stdlib | 8084 | Vulnerability scanner, matches components against TacoDB |
| taco-fetcher | Go | stdlib | 8085 | Fetches SBOMs from registries (Nexus, Artifactory, AWS, Azure, GCP) |
| taco-secrets | Go | stdlib | 8086 | Scans SBOM content for leaked secrets/credentials |
| taco-enricher | Go | stdlib | 8087 | Enriches findings with EPSS, NVD CVSS, CISA KEV, OSV.dev data |
| taco-vulndb | Go | Cobra CLI | -- | CLI tool to build/update/distribute vulnerability database |
| taco-lib | Go | library | -- | Shared library: vulndb engine, types, matching logic |
| taco-corp | TypeScript | Next.js | 3000 | Corporate website (taco-sec.com) |
| taco-support-bot | TypeScript | Node.js | 3100 | Discord support bot |
Infrastructure
| Component | Image | Purpose |
|---|---|---|
| MySQL 8.0 | mysql:8.0 | Primary datastore for all services |
| RabbitMQ 3 | rabbitmq:3-management-alpine | Message broker for async SBOM/alert pipelines |
| Valkey 8 | valkey/valkey:8-alpine | Session store (taco-api), token cache (taco-auth) |
| HAProxy 3.1 | haproxy:3.1-alpine | TLS termination, subdomain routing |
| Nexus 3 | sonatype/nexus3:latest | Development artifact repository |
Data Flow
SBOM Ingestion Pipeline
- Ingest -- An SBOM is submitted to
taco-inboundviaPOST /api/v1/sbomwith a project token in theAuthorizationheader. - Authenticate --
taco-inboundvalidates the token by callingtaco-authatGET /api/v1/token/validate. - Publish -- The validated SBOM is published to RabbitMQ on the
taco.sbomexchange with routing keysbom.ingest. - Parse & Store --
taco-storeconsumes from thetaco.sbom.storequeue, parses the SBOM (CycloneDX or SPDX), extracts components, and inserts them into MySQL (sboms,components,sbom_componentstables). - Scan --
taco-scannerruns on a configurable interval (default 5m). It loads the TacoDB vulnerability database, queries all components from MySQL, and matches package URLs against known vulnerabilities. New findings are inserted into thefindingstable; resolved findings are marked withresolved_at. - Alert -- When the scanner produces new findings, it publishes an event to RabbitMQ.
taco-alertconsumes these events, checks per-project alert configurations, filters by severity threshold, and dispatches notifications via configured channels (Slack, email, webhook, PagerDuty). - Enrich --
taco-enricherruns a background worker that periodically queries findings withenrichment_status = 'pending'. For each CVE, it fetches EPSS scores from FIRST, CVSS vectors from NVD, checks CISA KEV status, and computes a composite risk score. Non-CVE IDs (GHSA, ALAS, etc.) are enriched via OSV.dev. - Display --
taco-nextjscallstaco-apito fetch projects, SBOMs, components, findings, secrets, and dashboard data. The API serves all data from MySQL.
Secret Detection Pipeline
taco-secretspolls MySQL for SBOMs that haven't been scanned for secrets (secrets_scan_statetable).- For each unscanned SBOM, it runs regex-based rules against the raw SBOM content (AWS keys, GitHub tokens, private keys, database URLs, etc.).
- Matches are masked before storage -- raw secrets are never persisted.
- Results are written to the
secretstable with severity, category, confidence, and file location.
Automated Fetching Pipeline
taco-fetcherruns on a configurable interval (default 10m).- It connects to configured artifact sources: Nexus, JFrog Artifactory, AWS (ECR, Lambda, CodeArtifact), Azure (ACR, Functions, Artifacts), GCP (Artifact Registry, Cloud Functions, Cloud Run).
- For each source, it fetches component lists and submits them to
taco-inboundas SBOMs, triggering the standard ingestion pipeline.
Vulnerability Database Update
taco-vulndbCLI (or the scanner's built-in updater) fetches vulnerability data from 9 sources: NVD, OSV, GHSA, Alpine SecDB, Debian, Ubuntu, Red Hat, ALAS, CISA KEV.- Data is merged with source-priority deduplication and compiled into a single compressed database file (
taco.db.gz). taco-scannerloads this database file and uses it for component matching.- The database can be distributed via OCI registries using
taco-vulndb push/pull.
Network Topology
All services run on a single Docker Compose network (taco). External traffic enters through HAProxy, which terminates TLS and routes by subdomain:
| Subdomain | Backend |
|---|---|
portal.taco-sec.com | taco-nextjs:3000 |
taco-inbound.taco-sec.com | taco-inbound:8080 |
docs.taco-sec.com | taco-documentation:3001 |
internaldocs.taco-sec.com | taco-internal-documentation:3001 |
taco-sec.com | taco-corp:3000 |
Internal services communicate via Docker DNS names (e.g., http://taco-api:8090, amqp://rabbitmq:5672).
RabbitMQ Exchanges and Queues
| Exchange | Type | Routing Key | Consumer Queue | Producer | Consumer |
|---|---|---|---|---|---|
taco.sbom | topic | sbom.ingest | taco.sbom.store | taco-inbound | taco-store |
taco.sbom | topic | findings.* | taco.alert.queue | taco-scanner | taco-alert |
taco.sbom.dlx | fanout | -- | -- | dead-letter | -- |
taco.secrets | topic | secrets.ingest | taco.secrets.store | taco-inbound | taco-store (secrets consumer) |