From threatmodel-skills
Generates SBOMs using Syft for container images, filesystems, and archives across 28+ ecosystems. Outputs CycloneDX, SPDX, syft-json for vulnerability scanning, license compliance, CI/CD integration, and supply chain security.
npx claudepluginhub agentsecops/secopsagentkit --plugin offsec-skillsThis skill uses the workspace's default tool permissions.
Syft is a CLI tool and Go library for generating comprehensive Software Bills of Materials (SBOMs) from container images and filesystems. It provides visibility into packages and dependencies across 28+ ecosystems, supporting multiple SBOM formats (CycloneDX, SPDX) for vulnerability management, license compliance, and supply chain security.
Designs and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
Compares coding agents like Claude Code and Aider on custom YAML-defined codebase tasks using git worktrees, measuring pass rate, cost, time, and consistency.
Designs, implements, and audits WCAG 2.2 AA accessible UIs for Web (ARIA/HTML5), iOS (SwiftUI traits), and Android (Compose semantics). Audits code for compliance gaps.
Syft is a CLI tool and Go library for generating comprehensive Software Bills of Materials (SBOMs) from container images and filesystems. It provides visibility into packages and dependencies across 28+ ecosystems, supporting multiple SBOM formats (CycloneDX, SPDX) for vulnerability management, license compliance, and supply chain security.
Languages & Package Managers: Alpine (apk), C/C++ (conan), Dart (pub), Debian/Ubuntu (dpkg), Dotnet (deps.json), Go (go.mod), Java (JAR/WAR/EAR/Maven/Gradle), JavaScript (npm/yarn), PHP (composer), Python (pip/poetry/setup.py), Red Hat (RPM), Ruby (gem), Rust (cargo), Swift (cocoapods)
Container & System: OCI images, Docker images, Singularity, container layers, Linux distributions
Generate SBOM for container image:
# Using Docker
docker run --rm -v $(pwd):/out anchore/syft:latest <image> -o cyclonedx-json=/out/sbom.json
# Local installation
syft <image> -o cyclonedx-json=sbom.json
# Examples
syft alpine:latest -o cyclonedx-json
syft docker.io/nginx:latest -o spdx-json
syft dir:/path/to/project -o cyclonedx-json
For creating SBOMs of container images:
syft <image-name:tag> -o cyclonedx-json=sbom-cyclonedx.json
syft <image-name:tag> \
-o cyclonedx-json=sbom-cyclonedx.json \
-o spdx-json=sbom-spdx.json \
-o syft-json=sbom-syft.json
Progress: [ ] 1. Add Syft to build pipeline after image creation [ ] 2. Generate SBOM in standard format (CycloneDX or SPDX) [ ] 3. Store SBOM as build artifact [ ] 4. Scan SBOM for vulnerabilities (using Grype or similar) [ ] 5. Fail build on critical vulnerabilities or license violations [ ] 6. Publish SBOM alongside container image [ ] 7. Integrate with vulnerability management platform
Work through each step systematically. Check off completed items.
For generating SBOMs from source code or filesystems:
syft dir:/path/to/project -o cyclonedx-json=app-sbom.json
.syft.yaml)Combining SBOM generation with vulnerability assessment:
syft <target> -o cyclonedx-json=sbom.json
grype sbom:sbom.json -o json --file vulnerabilities.json
For creating cryptographically signed SBOM attestations:
# macOS
brew install cosign
# Linux
wget https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64
chmod +x cosign-linux-amd64
mv cosign-linux-amd64 /usr/local/bin/cosign
syft <image> -o cyclonedx-json=sbom.json
cosign attest --predicate sbom.json --type cyclonedx <image>
cosign verify-attestation --type cyclonedx <image>
Syft supports multiple SBOM formats for different use cases:
| Format | Use Case | Specification |
|---|---|---|
cyclonedx-json | Modern SBOM standard, wide tool support | CycloneDX 1.4+ |
cyclonedx-xml | CycloneDX XML variant | CycloneDX 1.4+ |
spdx-json | Linux Foundation standard | SPDX 2.3 |
spdx-tag-value | SPDX text format | SPDX 2.3 |
syft-json | Syft native format (most detail) | Syft-specific |
syft-text | Human-readable console output | Syft-specific |
github-json | GitHub dependency submission | GitHub-specific |
template | Custom Go template output | User-defined |
Specify with -o flag:
syft <target> -o cyclonedx-json=output.json
Create .syft.yaml in project root or home directory:
# Cataloger configuration
package:
cataloger:
enabled: true
scope: all-layers # Options: all-layers, squashed
search:
unindexed-archives: false
indexed-archives: true
# Exclusions
exclude:
- "**/test/**"
- "**/node_modules/**"
- "**/.git/**"
# Registry authentication
registry:
insecure-skip-tls-verify: false
auth:
- authority: registry.example.com
username: user
password: pass
# Output format defaults
output: cyclonedx-json
# Log level
log:
level: warn # Options: error, warn, info, debug, trace
Scan all architectures of multi-platform images:
# Scan specific architecture
syft --platform linux/amd64 <image> -o cyclonedx-json=sbom-amd64.json
syft --platform linux/arm64 <image> -o cyclonedx-json=sbom-arm64.json
# Or scan manifest list (all architectures)
syft <image> --platform all -o cyclonedx-json
Access images from private registries:
# Using Docker credentials
docker login registry.example.com
syft registry.example.com/private/image:tag -o cyclonedx-json
# Using environment variables
export SYFT_REGISTRY_AUTH_AUTHORITY=registry.example.com
export SYFT_REGISTRY_AUTH_USERNAME=user
export SYFT_REGISTRY_AUTH_PASSWORD=pass
syft registry.example.com/private/image:tag -o cyclonedx-json
# Using config file (recommended)
# Add credentials to .syft.yaml
Scan saved container images (OCI or Docker format):
# Save image to archive
docker save nginx:latest -o nginx.tar
# Scan archive
syft oci-archive:nginx.tar -o cyclonedx-json=sbom.json
# Or scan Docker archive
syft docker-archive:nginx.tar -o cyclonedx-json=sbom.json
Track dependency changes across releases:
# Generate SBOMs for two versions
syft myapp:v1.0 -o syft-json=sbom-v1.0.json
syft myapp:v2.0 -o syft-json=sbom-v2.0.json
# Compare with jq
jq -s '{"added": (.[1].artifacts - .[0].artifacts), "removed": (.[0].artifacts - .[1].artifacts)}' \
sbom-v1.0.json sbom-v2.0.json
Extract specific package information:
# Generate detailed SBOM
syft <target> -o syft-json=full-sbom.json
# Extract only Python packages
cat full-sbom.json | jq '.artifacts[] | select(.type == "python")'
# Extract packages with specific licenses
cat full-sbom.json | jq '.artifacts[] | select(.licenses[].value == "MIT")'
# Count packages by ecosystem
cat full-sbom.json | jq '.artifacts | group_by(.type) | map({type: .[0].type, count: length})'
GitHub Actions:
- name: Generate SBOM with Syft
uses: anchore/sbom-action@v0
with:
image: ${{ env.IMAGE_NAME }}:${{ github.sha }}
format: cyclonedx-json
output-file: sbom.json
- name: Upload SBOM
uses: actions/upload-artifact@v3
with:
name: sbom
path: sbom.json
GitLab CI:
sbom-generation:
image: anchore/syft:latest
script:
- syft $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA -o cyclonedx-json=sbom.json
artifacts:
reports:
cyclonedx: sbom.json
Jenkins:
stage('Generate SBOM') {
steps {
sh 'syft ${IMAGE_NAME}:${BUILD_NUMBER} -o cyclonedx-json=sbom.json'
archiveArtifacts artifacts: 'sbom.json'
}
}
Integrate with Grype for vulnerability scanning:
# Generate SBOM and scan in one pipeline
syft <target> -o cyclonedx-json=sbom.json
grype sbom:sbom.json
Attach SBOMs to container images:
# Using ORAS
oras attach <image> --artifact-type application/vnd.cyclonedx+json sbom.json
# Using Docker manifest
# Store SBOM as additional layer or separate artifact
Create custom output formats using Go templates:
# Create template file
cat > custom-template.tmpl <<'EOF'
{{- range .Artifacts}}
{{.Name}}@{{.Version}} ({{.Type}})
{{- end}}
EOF
# Use template
syft <target> -o template -t custom-template.tmpl
Analyze specific layers in container images:
# Squashed view (default - final filesystem state)
syft <image> --scope squashed -o cyclonedx-json
# All layers (every layer's packages)
syft <image> --scope all-layers -o cyclonedx-json
Configure Syft via environment variables:
export SYFT_SCOPE=all-layers
export SYFT_OUTPUT=cyclonedx-json
export SYFT_LOG_LEVEL=debug
export SYFT_EXCLUDE="**/test/**,**/node_modules/**"
syft <target>
Solution: Enable all-layers scope or check for package manager files:
syft <target> --scope all-layers -o syft-json
Verify package manifest files exist (package.json, requirements.txt, go.mod, etc.)
Solution: Ensure Docker credentials are configured or use explicit auth:
docker login <registry>
# Then run syft
syft <registry>/<image> -o cyclonedx-json
Solution: Use squashed scope and exclude test/dev dependencies:
# In .syft.yaml
package:
cataloger:
scope: squashed
exclude:
- "**/test/**"
- "**/node_modules/**"
- "**/.git/**"
Solution: Disable unindexed archive scanning for faster results:
# In .syft.yaml
package:
search:
unindexed-archives: false
Extract license information from SBOM:
# Generate SBOM
syft <target> -o syft-json=sbom.json
# Extract unique licenses
cat sbom.json | jq -r '.artifacts[].licenses[].value' | sort -u
# Find packages with specific licenses
cat sbom.json | jq '.artifacts[] | select(.licenses[].value | contains("GPL"))'
# Generate license report
cat sbom.json | jq -r '.artifacts[] | "\(.name):\(.licenses[].value)"' | sort
Complete workflow integrating SBOM generation with vulnerability management:
Progress: [ ] 1. Generate SBOM for application/container [ ] 2. Scan SBOM for known vulnerabilities [ ] 3. Classify vulnerabilities by severity and exploitability [ ] 4. Check for available patches and updates [ ] 5. Update vulnerable dependencies [ ] 6. Regenerate SBOM after updates [ ] 7. Re-scan to confirm vulnerability remediation [ ] 8. Document accepted risks for unfixable vulnerabilities [ ] 9. Schedule periodic SBOM regeneration and scanning
Work through each step systematically. Check off completed items.