Skip to content

sbom

๐Ÿค– AI-Generated Content

This documentation was generated with AI assistance and is still being audited. Some, or potentially a lot, of this information may be inaccurate. Learn more.

flavor.psp.format_2025.sbom

CycloneDX 1.6 SBOM generation for PSPF attestation slots.

Functions

build_sbom

build_sbom(
    package_info: dict[str, Any], *, enabled: bool = True
) -> dict[str, Any] | None

Build a CycloneDX 1.6 SBOM document.

Parameters:

Name Type Description Default
package_info dict[str, Any]

Dict with keys: packages: list of {name, version, purl, hash, license} python_version: str python_hash: str launcher_language: str ("go" or "rust") launcher_version: str launcher_hash: str builder_name: str builder_version: str

required
enabled bool

If False, returns None (opt-out support).

True

Returns:

Type Description
dict[str, Any] | None

CycloneDX 1.6 SBOM as a dict, or None if disabled.

Source code in flavor/psp/format_2025/sbom.py
def build_sbom(
    package_info: dict[str, Any],
    *,
    enabled: bool = True,
) -> dict[str, Any] | None:
    """Build a CycloneDX 1.6 SBOM document.

    Args:
        package_info: Dict with keys:
            packages: list of {name, version, purl, hash, license}
            python_version: str
            python_hash: str
            launcher_language: str ("go" or "rust")
            launcher_version: str
            launcher_hash: str
            builder_name: str
            builder_version: str
        enabled: If False, returns None (opt-out support).

    Returns:
        CycloneDX 1.6 SBOM as a dict, or None if disabled.
    """
    if not enabled:
        return None

    components: list[dict[str, Any]] = []

    # Python packages
    for pkg in package_info.get("packages", []):
        component: dict[str, Any] = {
            "type": "library",
            "name": pkg["name"],
            "version": pkg["version"],
            "purl": pkg["purl"],
        }
        if pkg.get("license"):
            component["licenses"] = [{"expression": pkg["license"]}]
        if pkg.get("hash"):
            alg, value = _parse_hash(pkg["hash"])
            component["hashes"] = [{"alg": alg, "content": value}]
        components.append(component)

    # Python runtime
    py_version = package_info.get("python_version", "unknown")
    py_component: dict[str, Any] = {
        "type": "framework",
        "name": "python",
        "version": py_version,
        "description": "CPython runtime interpreter",
    }
    if package_info.get("python_hash"):
        alg, value = _parse_hash(package_info["python_hash"])
        py_component["hashes"] = [{"alg": alg, "content": value}]
    components.append(py_component)

    # Launcher binary
    launcher_lang = package_info.get("launcher_language", "unknown")
    launcher_component: dict[str, Any] = {
        "type": "application",
        "name": f"flavor-{launcher_lang}-launcher",
        "version": package_info.get("launcher_version", "unknown"),
        "description": f"PSPF launcher binary ({launcher_lang})",
    }
    if package_info.get("launcher_hash"):
        alg, value = _parse_hash(package_info["launcher_hash"])
        launcher_component["hashes"] = [{"alg": alg, "content": value}]
    components.append(launcher_component)

    # FlavorPack builder
    components.append(
        {
            "type": "application",
            "name": package_info.get("builder_name", "flavor-python"),
            "version": package_info.get("builder_version", "unknown"),
            "description": "FlavorPack PSPF builder",
        }
    )

    return {
        "bomFormat": "CycloneDX",
        "specVersion": "1.6",
        "serialNumber": f"urn:uuid:{uuid.uuid4()}",
        "version": 1,
        "metadata": {
            "timestamp": datetime.now(UTC).isoformat(),
            "tools": [
                {
                    "vendor": "provide.io",
                    "name": "flavorpack",
                    "version": package_info.get("builder_version", "unknown"),
                }
            ],
        },
        "components": components,
    }