콘텐츠로 이동

Syft

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.

  • 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.)
# 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
# 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/
# 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
# Using Chocolatey
choco install syft

# Or direct binary
# Download from GitHub releases
# Add to PATH
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
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)
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
# 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
# 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 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
# 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)
# 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: ""
#!/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

섹션 제목: “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
#!/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"
#!/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
#!/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
# 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"
  }
}
# 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)
# 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
# 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
#!/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)"'
# 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}'
# 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
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
#!/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
✓ 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
⚠️ 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
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
# 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
# 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
# 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
# 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

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.