Repository navigation
bug(alpine): apk dependencies that use the ~ version operator are dropped from the dependency graph #11383
Description
Description
When a dependency in /lib/apk/db/installed uses the ~ (prefix match) operator, e.g. D:python3~3.12, Trivy silently drops it from the OS package dependency graph.
As a result, the SBOM (CycloneDX dependsOn, SPDX relationships) is incomplete.
Vulnerability detection is not affected.
Reproduced on v0.75.0 and main:
cat > Dockerfile <<'EOF'
FROM alpine:3.20
RUN apk add --no-cache libxml2-static
EOF
docker build -t trivy-fuzzy-dep .
docker run --rm trivy-fuzzy-dep apk info -R libxml2-static # python3~3.12
trivy image --format cyclonedx --output sbom.json trivy-fuzzy-dep
jq -c '.dependencies[] | select(.ref | contains("libxml2-static"))' sbom.jsonlibxml2-static is expected to depend on python3, but its dependsOn is empty, even though python3 is installed and present in the SBOM.
Discussed in #11342
Root cause
trimRequirement() in pkg/fanal/analyzer/pkg/apk/apk.go strips the version from a dependency name only at <, > and =.
The token python3~3.12 is kept as-is, isn't found in provides, and consolidateDependencies drops it.
In apk, a dependency name ends at the first character from the set <, =, >, ~:
- The
apk-world(5)docs describe the=,<,>,>=,~,>~,<~and><operators (apk-world.5.scd). - apk-tools 2.x: the comparer character set is
apk_spn_dependency_comparer(package.c), and the operators are parsed inapk_blob_pull_dep(package.c). - apk-tools 3.x:
APK_CTYPE_DEPENDENCY_COMPARER(ctype.c, ctype.c).
Implementation challenges
1. All apk operators
The whole apk dependency notation has to be covered, not just ~: ~, >~, <~, ><, plus ! (conflict), which is already handled separately.
The operators and the format are described in apk-world(5).
trimRequirement() is used for both D: and p:, so a change affects both lines.
2. Cache
Analyzer results are cached per layer.
Without bumping analyzerVersion, already cached layers stay without these dependencies, and the fix will look like it doesn't work.
3. Tests
pkg/fanal/analyzer/pkg/apk/testdata/apk currently has no ~ at all.
It should be checked whether the golden files of the integration tests with Alpine images change (integration/testdata/alpine-*.golden, pkg/fanal/test/integration/testdata/goldens/packages/).
Before implementation
Before implementing, the approach should be discussed and agreed on in this issue, and only then should the implementation start.
Activity
sairex53 commentedon Oct 12, 2026
I would like to work on this. The proposed approach is to split requirements at the first
<,>,=or~, keeping the existing conflict filtering, and bump the APK analyzer version to invalidate cached results. I would add parser regression coverage for the supported operators, including versioned provides and dependencies resolved to package IDs, and check the Alpine integration fixtures for affected relationships. Does this approach sound right?DmitriyLewen commentedon Oct 12, 2026
Hi @sairex53.
Sounds great.
I’ve assigned the task to you.
We have a lot of work right now, but we’ll definitely review your PR.
Regards, Dmitriy