تخطَّ إلى المحتوى

Syft

Overview

Syft is a CLI utility for generating Software Bill of Materials (SBOM) documents from container images, filesystems, and archives. It performs deep inspection of container layers, identifies installed packages, libraries, and dependencies, and exports results in standardized formats like CycloneDX, SPDX, and JSON. Syft enables organizations to maintain accurate inventories of software components, track vulnerabilities, and ensure compliance with software supply chain security requirements.

Key Features

  • Multiple source support: Docker images, OCI archives, directories, tarballs
  • Multiple formatters: CycloneDX, SPDX, JSON, Table, Markdown
  • Deep cataloging: Packages, libraries, executables, operating system artifacts
  • Vulnerability integration: Optional Grype integration for vulnerability detection
  • Attestation support: SLSA provenance attestation generation
  • Cross-platform: Linux, macOS, Windows
  • Configuration file support: YAML-based configuration for customization
  • Scope filtering: Select specific scopes (all-layers, squashed, etc.)

Installation

Linux Installation

# Using package manager (Debian/Ubuntu)
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin

# Or direct download
curl -OL https://github.com/anchore/syft/releases/download/v0.95.1/syft_0.95.1_linux_amd64.tar.gz
tar xzf syft_0.95.1_linux_amd64.tar.gz
sudo mv syft /usr/local/bin/

# Verify installation
syft --version

macOS Installation

# Using Homebrew
brew install syft

# Or manual installation
curl -OL https://github.com/anchore/syft/releases/download/v0.95.1/syft_0.95.1_darwin_amd64.tar.gz
tar xzf syft_0.95.1_darwin_amd64.tar.gz
sudo mv syft /usr/local/bin/

Container Installation

# Run as Docker container
docker run -v /var/run/docker.sock:/var/run/docker.sock \
           anchore/syft:latest \
           IMAGE_NAME:TAG

# Pull Syft container image
docker pull anchore/syft:latest

Docker Installation (Windows)

# Using Chocolatey
choco install syft

# Or direct binary
# Download from GitHub releases
# Add to PATH

Core Concepts

SBOM (Software Bill of Materials)

Software Bill of Materials = Inventory of Software Components
├─ Direct Dependencies
│  ├─ Package A (version 1.2.3)
│  ├─ Package B (version 2.0.1)
│  └─ Package C (version 3.1.0)

├─ Transitive Dependencies
│  ├─ Library X (from Package A)
│  ├─ Library Y (from Package B)
│  └─ Library Z (from Package C)

├─ Operating System Packages
│  ├─ glibc (version 2.31)
│  ├─ openssl (version 1.1.1)
│  └─ curl (version 7.68.0)

└─ Metadata
   ├─ Component versions
   ├─ License information
   ├─ Copyright notices
   ├─ Known vulnerabilities
   └─ Dependency relationships

Supported Formats

FormatUse CaseAdoption
CycloneDXVulnerability tracking, complianceHigh (OWASP)
SPDXLicense compliance, supply chainHigh (ISO standard)
JSONIntegration, automationHigh (tool interop)
TableHuman readable, quick reviewMedium (CLI display)
MarkdownDocumentation, reportsMedium (static docs)

Scanning Engines

EngineTypeDetails
APKOS packagesAlpine Linux packages
DEBOS packagesDebian/Ubuntu packages
RPMOS packagesRed Hat packages
NPMPackage managerNode.js dependencies
GemPackage managerRuby dependencies
PIPPackage managerPython dependencies
CargoPackage managerRust dependencies
JAVAPackage managerJAR files, Maven
GoPackage managerGo binaries, modules
ExecutableBinary analysisDirect binary scanning

Basic Usage

Simple Container Scan

# Scan Docker image
syft docker.io/library/ubuntu:22.04

# Scan local Docker image
syft docker:ubuntu:22.04

# Scan OCI image archive
syft oci-archive:/path/to/image.tar

# Scan directory
syft dir:/path/to/directory

# Scan tarball
syft tar:/path/to/archive.tar.gz

Output Formats

# JSON format (default)
syft docker.io/library/python:3.11 -o json

# CycloneDX format (for vulnerability tools)
syft docker.io/library/python:3.11 -o cyclonedx

# SPDX format (for compliance/licensing)
syft docker.io/library/python:3.11 -o spdx

# Table format (human readable)
syft docker.io/library/python:3.11 -o table

# Multiple outputs
syft docker.io/library/python:3.11 -o json,cyclonedx,spdx

Save to Files

# Save single format
syft docker.io/library/python:3.11 -o json > sbom.json

# Save with template naming
syft docker.io/library/python:3.11 -o json > python-3.11-sbom.json

# Use output flag for file
syft docker.io/library/python:3.11 --file sbom.json

# Save all formats
syft docker.io/library/python:3.11 \
    -o json > sbom.json \
    -o cyclonedx > sbom.xml \
    -o spdx > sbom.spdx

Advanced Usage

Configuration Files

# Generate default config
syft config list > ~/.syft/config.yaml

# Use custom config
syft docker.io/library/ubuntu:22.04 \
    --config /path/to/config.yaml

# Example config (~/.syft/config.yaml)

Sample Configuration

# Syft configuration file
scan:
  # Which scopes to include
  scope: all-layers  # Options: all-layers, squashed

# Cataloging options
catalog:
  enabled: true

# Package catalogers to use
catalogers:
  - apk
  - deb
  - rpm
  - npm
  - gem
  - pip
  - cargo
  - java
  - go
  - executable

# Search settings
search:
  include-index-servers: true
  include-offline: true

# Output options
output:
  format: json
  pretty: false

# Logging
log:
  level: info
  file: ""

Practical Examples

Example 1: Container Image Analysis

#!/bin/bash
# Comprehensive container image SBOM generation

IMAGE="$1"
OUTPUT_DIR="./sbom-reports"

mkdir -p "$OUTPUT_DIR"

echo "Generating SBOM for: $IMAGE"
echo ""

# Generate all formats
echo "1. Generating JSON SBOM..."
syft "$IMAGE" -o json > "$OUTPUT_DIR/${IMAGE//\//-}-sbom.json"

echo "2. Generating CycloneDX SBOM..."
syft "$IMAGE" -o cyclonedx > "$OUTPUT_DIR/${IMAGE//\//-}-sbom.xml"

echo "3. Generating SPDX SBOM..."
syft "$IMAGE" -o spdx > "$OUTPUT_DIR/${IMAGE//\//-}-sbom.spdx"

echo "4. Generating table output..."
syft "$IMAGE" -o table > "$OUTPUT_DIR/${IMAGE//\//-}-sbom.txt"

echo ""
echo "✓ SBOMs generated in: $OUTPUT_DIR"
ls -lh "$OUTPUT_DIR"

Example 2: Vulnerability Scanning with Grype

#!/bin/bash
# Generate SBOM and scan for vulnerabilities

IMAGE="$1"

echo "Generating SBOM and scanning vulnerabilities..."

# Generate SBOM in JSON
syft "$IMAGE" -o json > temp-sbom.json

# Use with Grype for vulnerability scanning
grype "$IMAGE"

# Or pass SBOM to Grype
grype --input temp-sbom.json

# Cleanup
rm temp-sbom.json

Example 3: Batch SBOM Generation

#!/bin/bash
# Generate SBOMs for multiple images

IMAGES=(
    "python:3.11-slim"
    "node:18-alpine"
    "golang:1.21"
    "ruby:3.2"
    "openjdk:21-slim"
)

OUTPUT_DIR="./container-sboms"
mkdir -p "$OUTPUT_DIR"

for image in "${IMAGES[@]}"; do
    echo "Processing: $image"
    
    # Clean image name for filename
    safe_name="${image//:/-}"
    safe_name="${safe_name//\//-}"
    
    syft "docker.io/library/$image" \
        -o json > "$OUTPUT_DIR/${safe_name}-sbom.json" \
        -o cyclonedx > "$OUTPUT_DIR/${safe_name}-sbom.xml"
    
    echo "✓ Generated: $safe_name"
done

echo ""
echo "SBOM generation complete"
echo "Files saved to: $OUTPUT_DIR"

Example 4: SBOM Comparison

#!/bin/bash
# Compare SBOMs between image versions

IMAGE_V1="$1"
IMAGE_V2="$2"

echo "Comparing SBOMs: $IMAGE_V1 vs $IMAGE_V2"
echo ""

# Generate SBOMs
syft "$IMAGE_V1" -o json > sbom-v1.json
syft "$IMAGE_V2" -o json > sbom-v2.json

# Extract package lists
jq -r '.artifacts[] | "\(.name)-\(.version)"' sbom-v1.json | sort > packages-v1.txt
jq -r '.artifacts[] | "\(.name)-\(.version)"' sbom-v2.json | sort > packages-v2.txt

# Compare
echo "=== Packages in V2 but not V1 (new dependencies) ==="
comm -13 packages-v1.txt packages-v2.txt

echo ""
echo "=== Packages in V1 but not V2 (removed dependencies) ==="
comm -23 packages-v1.txt packages-v2.txt

echo ""
echo "=== Packages in both (common dependencies) ==="
comm -12 packages-v1.txt packages-v2.txt | wc -l

# Cleanup
rm sbom-v1.json sbom-v2.json packages-v1.txt packages-v2.txt

Example 5: License Compliance Report

#!/bin/bash
# Extract license information from SBOM

IMAGE="$1"

echo "License Compliance Report for: $IMAGE"
echo "===================================="
echo ""

# Generate SBOM
syft "$IMAGE" -o json > temp-sbom.json

# Extract licenses
echo "Licenses found:"
jq -r '.artifacts[] | 
    "Package: \(.name) (\(.version))\nLicenses: \(.licenses[] // "UNKNOWN")\n"' \
    temp-sbom.json | sort | uniq

# Count licenses
echo ""
echo "License summary:"
jq -r '.artifacts[].licenses[]' temp-sbom.json | sort | uniq -c | sort -rn

# Cleanup
rm temp-sbom.json

Output Formats Deep Dive

JSON Output Structure

# Generate JSON SBOM
syft docker.io/library/ubuntu:22.04 -o json | jq '.'

Output structure:

{
  "artifacts": [
    {
      "name": "openssl",
      "version": "1.1.1f",
      "type": "deb",
      "locations": [
        {
          "path": "/var/lib/dpkg/status.d/base"
        }
      ],
      "licenses": ["Apache-2.0"],
      "language": "",
      "cpes": ["cpe:2.3:a:openssl:openssl:1.1.1f:*:*:*:*:*:*:*"],
      "purl": "pkg:deb/ubuntu/openssl@1.1.1f"
    }
  ],
  "source": {
    "type": "image",
    "target": {
      "imageID": "sha256:...",
      "userInput": "ubuntu:22.04",
      "imageSize": 77809920,
      "layers": [...]
    }
  },
  "descriptor": {
    "name": "syft",
    "version": "0.95.1"
  }
}

CycloneDX Format (Vulnerability Tools)

# Generate CycloneDX SBOM
syft docker.io/library/python:3.11 -o cyclonedx

# CycloneDX is XML-based, suitable for:
# - Vulnerability scanning (Dependency-Check, Grype)
# - License compliance (Black Duck, Snyk)
# - Supply chain security (SLSA, in-toto)

SPDX Format (Compliance)

# Generate SPDX SBOM
syft docker.io/library/python:3.11 -o spdx

# SPDX is standardized (ISO 5962), suitable for:
# - License compliance reporting
# - Open source compliance
# - Regulatory requirements
# - Long-term archival

Filtering and Analysis

Filter by Package Type

# Extract only OS packages
syft docker.io/library/ubuntu:22.04 -o json | \
    jq '.artifacts[] | select(.type == "deb")'

# Extract only library packages
syft docker.io/library/python:3.11 -o json | \
    jq '.artifacts[] | select(.type == "python")'

# Count packages by type
syft docker.io/library/ubuntu:22.04 -o json | \
    jq -r '.artifacts[] | .type' | sort | uniq -c

Find High-Risk Dependencies

#!/bin/bash
# Identify common vulnerability sources

IMAGE="$1"

echo "High-Risk Dependency Analysis"
echo "=============================="

syft "$IMAGE" -o json | jq -r '.artifacts[] | 
    select(.name | test("openssl|curl|sqlite|log4j|commons|struts|spring")) | 
    "\(.name)-\(.version)"'

Generate License Report

# Extract all licenses
syft docker.io/library/ubuntu:22.04 -o json | \
    jq -r '.artifacts[].licenses[]' | \
    sort | uniq -c | sort -rn

# Find GPL-licensed packages
syft docker.io/library/ubuntu:22.04 -o json | \
    jq '.artifacts[] | 
        select(.licenses[] | contains("GPL")) | 
        {name, version, licenses}'

Integration Examples

With Container Build Pipeline

# Dockerfile with SBOM generation
FROM ubuntu:22.04 as builder
# ... build steps ...

FROM ubuntu:22.04
COPY --from=builder /app /app
# Generate SBOM during build
RUN apt-get update && apt-get install -y curl && \
    curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin && \
    syft /app -o json > /app/sbom.json && \
    rm /usr/local/bin/syft

COPY --from=builder /app/sbom.json /app/sbom.json

GitHub Actions Integration

name: Generate SBOM
on: [push]

jobs:
  sbom:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Install Syft
        run: curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
      
      - name: Generate SBOM
        run: syft docker.io/library/ubuntu:22.04 -o json > sbom.json
      
      - name: Upload SBOM
        uses: actions/upload-artifact@v3
        with:
          name: sbom
          path: sbom.json
      
      - name: Scan with Grype
        uses: anchore/scan-action@v3
        with:
          sbom: sbom.json

Kubernetes Admission Controller

#!/bin/bash
# Scan images before deployment

IMAGE="${1}"

echo "Scanning image: $IMAGE"

# Generate SBOM
syft "$IMAGE" -o json > /tmp/sbom.json

# Check for critical vulnerabilities
grype --input /tmp/sbom.json \
      --fail-on critical

if [ $? -ne 0 ]; then
    echo "❌ Image failed security scan"
    exit 1
else
    echo "✓ Image passed security scan"
    exit 0
fi

Security Considerations

SBOM Security Practices

✓ Store SBOMs securely (restrict access)
✓ Version control SBOMs for tracking changes
✓ Sign SBOMs for authenticity (in-toto)
✓ Regularly update vulnerability databases
✓ Include SBOMs in artifact repositories
✓ Automate SBOM generation in CI/CD
✓ Cross-reference with CVE databases

Privacy Considerations

⚠️ SBOMs contain implementation details
⚠️ Dependency information is sensitive
⚠️ License information must be protected
⚠️ Internal library versions may leak architecture
→ Restrict SBOM access to authorized personnel
→ Don't expose SBOMs in public repositories

Troubleshooting

Common Issues

ProblemSolution
Image not foundVerify image name, pull if remote: docker pull IMAGE
Permission deniedRun with sudo or add user to docker group
Memory issuesIncrease available memory for large images
Slow scanningNormal for large images with many layers
Missing packagesSome formats require specific engines enabled

Diagnostic Commands

# List supported catalogers
syft catalogers

# Check Syft version and capabilities
syft version

# Verbose output for debugging
syft docker.io/library/ubuntu:22.04 -v

# Very verbose logging
syft docker.io/library/ubuntu:22.04 -vv

# Show default configuration
syft config show

Command Reference

Core Options

# Input sources
docker.io/library/image:tag    # Docker Registry
docker:image:tag               # Local Docker
oci-archive:path               # OCI archive
dir:path                        # Directory
tar:path                        # Tarball

# Output formats
-o json                         # JSON format
-o cyclonedx                    # CycloneDX XML
-o spdx                         # SPDX format
-o table                        # Table format
-o markdown                     # Markdown format

# Common flags
--file FILE                     # Write to file
--scope all-layers              # Scan all layers
-v, --verbose                   # Verbose output
--config FILE                   # Use config file
-q, --quiet                     # Quiet mode

# Advanced
--registry-password PASSWORD    # Registry auth
--registry-username USERNAME    # Registry username
--registry-token TOKEN          # Registry token

Best Practices

SBOM Management

# 1. Generate on every build
# Include in CI/CD pipeline

# 2. Store with artifacts
# Keep SBOM with container image/binary

# 3. Regular updates
# Regenerate when dependencies change

# 4. Multiple formats
# Keep both CycloneDX and SPDX versions

# 5. Vulnerability tracking
# Integrate with vulnerability scanner

File Organization

# Organized structure
sbom/
├── cyclonedx/
   ├── ubuntu-22.04-sbom.xml
   ├── python-3.11-sbom.xml
   └── ...
├── spdx/
   ├── ubuntu-22.04-sbom.spdx
   ├── python-3.11-sbom.spdx
   └── ...
├── json/
   ├── ubuntu-22.04-sbom.json
   ├── python-3.11-sbom.json
   └── ...
└── reports/
    ├── license-report.txt
    ├── vulnerability-report.txt
    └── compliance-report.txt

Summary

Syft is an essential tool for software supply chain security, enabling organizations to maintain accurate inventories of software components in container images and filesystems. Its multi-format support, integration capabilities, and deep scanning capabilities make it ideal for vulnerability management, compliance tracking, and security automation in containerized environments.