taco-store

The SBOM parser and storage service. Consumes SBOMs from RabbitMQ, parses them, and stores components in MySQL.

The SBOM parser and storage service. Consumes SBOMs from RabbitMQ, parses them, and stores components in MySQL.

Overview

PropertyValue
LanguageGo
FrameworkStandard library HTTP
Port8082 (health check)
ExposedInternal only
DependenciesMySQL, RabbitMQ
Repositorytacosec/taco-store

Architecture

taco-store is a RabbitMQ consumer that processes SBOM messages published by taco-inbound. It runs two independent consumers:

  1. SBOM Consumer -- Consumes from taco.sbom.store queue, parses SBOMs, and stores components.
  2. Secrets Consumer -- Consumes from taco.secrets.store queue, stores secret scan results.

Key Packages

PackagePurpose
consumer/RabbitMQ consumers for SBOMs and secrets
parser/SBOM parsing: CycloneDX, SPDX, and layer extraction
store/MySQL data access for SBOM/component storage
config/Environment variable loading

SBOM Parsing

The parser supports two formats:

CycloneDX

Extracts components from the CycloneDX JSON structure:

  • Component name, version, type
  • Package URL (purl) -- the primary identifier for vulnerability matching
  • Subject metadata (image name, version) from metadata.component

SPDX

Extracts packages from the SPDX JSON structure:

  • Package name, version
  • External references for purl extraction
  • Document-level metadata

Layer Extraction

For container image SBOMs, the parser also extracts layer information to associate components with specific image layers.

Message Format

Messages on the taco.sbom.store queue follow this envelope format:

json{
  "event_id": "uuid-v4",
  "event_type": "sbom.ingest",
  "timestamp": "2024-01-15T10:00:00Z",
  "project_id": 123,
  "project_name": "my-project",
  "format": "cyclonedx",
  "sbom": { ... raw SBOM JSON ... }
}

Storage Logic

  1. Deduplication -- Events are deduplicated by event_id (unique constraint on sboms.event_id).
  2. Component upsert -- Components are identified by purl. Existing components are reused; new ones are inserted.
  3. Linking -- The sbom_components junction table links SBOMs to their components.
  4. Component limits -- A per-project component limit is enforced. SBOMs that exceed the limit are rejected (not requeued).

Dead-Letter Handling

Messages that fail processing after 3 retries (tracked via x-death headers) are sent to the dead-letter exchange (taco.sbom.dlx) instead of being requeued indefinitely.

Tables Owned

  • sboms -- SBOM metadata and raw content
  • components -- Unique components identified by purl
  • sbom_components -- Many-to-many relationship between SBOMs and components

Environment Variables

VariableRequiredDefaultDescription
MYSQL_DSNYes--MySQL connection string
RABBITMQ_URLYes--RabbitMQ AMQP URL
CONSUMER_PREFETCHNo10RabbitMQ prefetch count (concurrency)
HEALTH_PORTNo8082Health check HTTP port

Health Check

GET /healthz -- Returns 200 OK when both MySQL and RabbitMQ are reachable. Returns 503 with detail if either is down.