Skip to content
Draft
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .github/workflows/build-samples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,35 @@ jobs:
fi
done

# Regression test for #1944: multi-arch builds with Alpine signing keys
# This tests the scenario where Alpine Linux returns the same ETag for
# different architecture-specific signing keys, which caused cache collisions.
build-alpine-multiarch-keys:
name: alpine-multiarch-keys-regression
runs-on: ubuntu-latest

permissions:
contents: read

steps:
- uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
with:
egress-policy: audit
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
persist-credentials: false

- uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
with:
go-version-file: 'go.mod'
check-latest: true
- name: Setup QEMU
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
- run: |
make apko
# Build multi-arch image that triggers Alpine signing key ETag collision
./apko build ./examples/alpine-multiarch-keys.yaml alpine-test:latest /tmp/alpine-multiarch.tar --arch x86_64,aarch64

annotations:
name: annotations
runs-on: ubuntu-latest
Expand Down
20 changes: 20 additions & 0 deletions examples/alpine-multiarch-keys.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Regression test for #1944: multi-arch builds with Alpine signing keys
# This config triggered a bug where Alpine Linux returns the same ETag
# for different architecture-specific signing keys, causing cache collisions.
contents:
repositories:
- https://dl-cdn.alpinelinux.org/alpine/v3.22/main
- https://dl-cdn.alpinelinux.org/alpine/v3.22/community
packages:
- alpine-baselayout
- ca-certificates-bundle
- alpine-keys
- busybox

archs: [x86_64, aarch64]

environment:
PATH: /usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin

entrypoint:
command: /bin/sh
10 changes: 9 additions & 1 deletion pkg/apk/apk/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package apk

import (
"context"
"crypto/sha256"
"encoding/base32"
"fmt"
"io"
Expand Down Expand Up @@ -381,7 +382,14 @@ func cacheFileFromEtag(cacheFile, etag string) (string, error) {
ext = ".tar.gz"
}

absPath, err := filepath.Abs(filepath.Join(cacheDir, etag+ext))
// Create a unique cache key by combining the etag with a hash of the URL.
// This prevents collisions when different URLs return the same ETag
// (e.g., Alpine Linux keys all have ETag "639a4604-320").
// The URL hash ensures each unique file gets its own cache entry.
urlHash := sha256.Sum256([]byte(cacheFile))
cacheKey := fmt.Sprintf("%s-%x", etag, urlHash[:4])

absPath, err := filepath.Abs(filepath.Join(cacheDir, cacheKey+ext))
if err != nil {
return "", err
}
Expand Down
Loading
Loading