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
| Property | Value |
|---|---|
| Language | Go |
| Framework | Standard library HTTP |
| Port | 8082 (health check) |
| Exposed | Internal only |
| Dependencies | MySQL, RabbitMQ |
| Repository | tacosec/taco-store |
Architecture
taco-store is a RabbitMQ consumer that processes SBOM messages published by taco-inbound. It runs two independent consumers:
- SBOM Consumer -- Consumes from
taco.sbom.storequeue, parses SBOMs, and stores components. - Secrets Consumer -- Consumes from
taco.secrets.storequeue, stores secret scan results.
Key Packages
| Package | Purpose |
|---|---|
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
- Deduplication -- Events are deduplicated by
event_id(unique constraint onsboms.event_id). - Component upsert -- Components are identified by purl. Existing components are reused; new ones are inserted.
- Linking -- The
sbom_componentsjunction table links SBOMs to their components. - 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 contentcomponents-- Unique components identified by purlsbom_components-- Many-to-many relationship between SBOMs and components
Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
MYSQL_DSN | Yes | -- | MySQL connection string |
RABBITMQ_URL | Yes | -- | RabbitMQ AMQP URL |
CONSUMER_PREFETCH | No | 10 | RabbitMQ prefetch count (concurrency) |
HEALTH_PORT | No | 8082 | Health 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.