Skip to main content

Upload a software bill of materials

Push an inventory of what an agent, container image or platform is made of. Bairav matches the components against advisories and raises vulnerability findings under Security, Assets.

Supported documents​

CycloneDX 1.4 to 1.6 JSON, SPDX 2.3 JSON, requirements.txt and package-lock.json (v2 and v3). The body is the raw document. Gzip is accepted with Content-Encoding: gzip.

What you need​

  • An ingest token bound to a telemetry source of kind imported, sensor or infrastructure. A token bound to any other kind gets 403 token_not_allowed. See Security events.

Upload from CI​

samples/ingest/sbom_upload.sh
#!/usr/bin/env bash
# Upload a CycloneDX software bill of materials for one container image from CI.
# export BAIRAV_HOST=your-tenant.example.com
# export BAIRAV_INGEST_TOKEN=obt_xxxxxxxx.xxxxxxxx # must be bound to an imported, sensor or infrastructure source
set -euo pipefail
: "${BAIRAV_HOST:?Set BAIRAV_HOST}"
: "${BAIRAV_INGEST_TOKEN:?Set BAIRAV_INGEST_TOKEN}"
SBOM_FILE="${1:-sbom.cdx.json}"

# The body is the raw document. subject_key is a stable name you choose; the same snapshot sent twice is deduplicated.
curl --fail-with-body --silent --show-error \
-X POST "https://${BAIRAV_HOST}/api/ingest/sbom?subject_type=container_image&subject_key=registry.example.com/support-bot&source=ci&filename=$(basename "$SBOM_FILE")" \
-H "X-Ingest-Token: ${BAIRAV_INGEST_TOKEN}" \
-H "Content-Type: application/json" \
-H "Content-Encoding: gzip" \
--data-binary @<(gzip -c "$SBOM_FILE")
echo

Query parameters:

ParameterMeaning
subject_type (required)agent, container_image, dependency_set or platform
subject_idThe agent or asset ID, when it already exists
subject_keyA stable key you choose, for example an image name. Use it when you have no subject_id.
subject_nameA display name
sourceci, sensor or self_inventory. Default self_inventory for platform, otherwise ci.
filenameThe original file name

Behaviour​

  • Idempotent. The same snapshot for the same subject (same SHA-256) answers 200 with "deduplicated": true and changes nothing. Retrying is safe.
  • Limits. 20 MB (compressed and decompressed) and 30 documents a minute per token.
  • Errors carry a stable code in detail.code, not only a message:
Statusdetail.codeMeaning
401Token missing, malformed or revoked
403token_not_allowedThe token's source kind may not push inventories
404subject_not_foundsubject_id does not exist in your tenant
413too_largeOver 20 MB
422invalid_subject and parse codesThe document or subject is invalid
429rate_limitedWait Retry-After seconds
503rate_limiter_unavailable, temporarily_unavailableRetry after Retry-After; safe because the store is idempotent

Rate-limiting fails closed: with the limiter down you get 503, never unlimited traffic.