Repository: chainguard-dev/apko
Pull request #1312 (2024-09-20 18:55:25)

Drop a period from a command's help
The help for every other command does not end with a period so let's make them consistent.


Patch:
diff --git a/.github/workflows/build-samples.yml b/.github/workflows/build-samples.yml
index 14f627a..0a1f0a7 100644
--- a/.github/workflows/build-samples.yml
+++ b/.github/workflows/build-samples.yml
@@ -25,7 +25,7 @@ jobs:
       - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1
         with:
           egress-policy: audit
-      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+      - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
       - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v2.1.5
         with:
           go-version-file: 'go.mod'
@@ -62,7 +62,7 @@ jobs:
       - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1
         with:
           egress-policy: audit
-      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+      - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
       - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v2.1.5
         with:
           go-version-file: 'go.mod'
@@ -97,7 +97,7 @@ jobs:
       - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1
         with:
           egress-policy: audit
-      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+      - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
       - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v2.1.5
         with:
           go-version-file: 'go.mod'
@@ -127,7 +127,7 @@ jobs:
       - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1
         with:
           egress-policy: audit
-      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+      - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
       - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v2.1.5
         with:
           go-version-file: 'go.mod'
@@ -166,7 +166,7 @@ jobs:
       - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1
         with:
           egress-policy: audit
-      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+      - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
       - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v2.1.5
         with:
           go-version-file: 'go.mod'
@@ -205,7 +205,7 @@ jobs:
       - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1
         with:
           egress-policy: audit
-      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+      - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
       - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v2.1.5
         with:
           go-version-file: 'go.mod'
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index cf310da..51c1d10 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -19,7 +19,7 @@ jobs:
         with:
           egress-policy: audit
 
-      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+      - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
 
       - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v2.1.5
         with:
diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml
index 6aff57d..2fd042f 100644
--- a/.github/workflows/codeql.yaml
+++ b/.github/workflows/codeql.yaml
@@ -22,7 +22,7 @@ jobs:
       with:
         egress-policy: audit
 
-    - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+    - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
 
     - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v3.0.0
       with:
@@ -30,7 +30,7 @@ jobs:
         check-latest: true
 
     - name: Initialize CodeQL
-      uses: github/codeql-action/init@294a9d92911152fe08befb9ec03e240add280cb3
+      uses: github/codeql-action/init@e2b3eafc8d227b0241d48be5f425d47c2d750a13
       with:
         languages: go
 
@@ -38,4 +38,4 @@ jobs:
       run: make apko
 
     - name: Perform CodeQL Analysis
-      uses: github/codeql-action/analyze@294a9d92911152fe08befb9ec03e240add280cb3
+      uses: github/codeql-action/analyze@e2b3eafc8d227b0241d48be5f425d47c2d750a13
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index fcff897..fab5809 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -23,7 +23,7 @@ jobs:
     - uses: step-security/harden-runner@91182cccc01eb5e619899d80e4e971d6181294a7 # v2.10.1
       with:
         egress-policy: audit
-    - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+    - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
     - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v2.2.0
       with:
         go-version-file: 'go.mod'
diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml
index a8c198b..4253d52 100644
--- a/.github/workflows/verify.yaml
+++ b/.github/workflows/verify.yaml
@@ -15,7 +15,7 @@ jobs:
       contents: read
 
     steps:
-      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+      - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
       - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v2.2.0
         with:
           go-version-file: 'go.mod'
diff --git a/.goreleaser.yaml b/.goreleaser.yaml
index a47edec..d453575 100644
--- a/.goreleaser.yaml
+++ b/.goreleaser.yaml
@@ -58,5 +58,5 @@ changelog:
 
 release:
   draft: false
-  prerelease: true
+  prerelease: false
   name_template: "Release {{ .Tag }}"
diff --git a/go.mod b/go.mod
index ef90e8e..c16a01b 100644
--- a/go.mod
+++ b/go.mod
@@ -13,7 +13,7 @@ require (
 	github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
 	github.com/hashicorp/go-retryablehttp v0.7.7
 	github.com/invopop/jsonschema v0.12.0
-	github.com/klauspost/compress v1.17.9
+	github.com/klauspost/compress v1.17.10
 	github.com/klauspost/pgzip v1.2.6
 	github.com/package-url/packageurl-go v0.1.3
 	github.com/psanford/memfs v0.0.0-20230130182539-4dbf7e3e865e
@@ -26,12 +26,12 @@ require (
 	go.lsp.dev/uri v0.3.0
 	go.opentelemetry.io/otel v1.30.0
 	go.opentelemetry.io/otel/trace v1.30.0
-	go.step.sm/crypto v0.52.0
+	go.step.sm/crypto v0.53.0
 	golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa
 	golang.org/x/sync v0.8.0
 	golang.org/x/sys v0.25.0
 	golang.org/x/time v0.6.0
-	google.golang.org/api v0.198.0
+	google.golang.org/api v0.199.0
 	gopkg.in/ini.v1 v1.67.0
 	gopkg.in/yaml.v3 v3.0.1
 	k8s.io/apimachinery v0.31.1
@@ -40,9 +40,9 @@ require (
 
 require (
 	chainguard.dev/go-grpc-kit v0.17.6 // indirect
-	cloud.google.com/go/auth v0.9.4 // indirect
+	cloud.google.com/go/auth v0.9.5 // indirect
 	cloud.google.com/go/auth/oauth2adapt v0.2.4 // indirect
-	cloud.google.com/go/compute/metadata v0.5.1 // indirect
+	cloud.google.com/go/compute/metadata v0.5.2 // indirect
 	dario.cat/mergo v1.0.1 // indirect
 	filippo.io/edwards25519 v1.1.0 // indirect
 	github.com/Microsoft/go-winio v0.6.2 // indirect
@@ -157,9 +157,9 @@ require (
 	golang.org/x/oauth2 v0.23.0 // indirect
 	golang.org/x/term v0.24.0 // indirect
 	golang.org/x/text v0.18.0 // indirect
-	google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed // indirect
+	google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect
 	google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
-	google.golang.org/grpc v1.66.2 // indirect
+	google.golang.org/grpc v1.67.0 // indirect
 	google.golang.org/protobuf v1.34.2 // indirect
 	gopkg.in/warnings.v0 v0.1.2 // indirect
 	gotest.tools/v3 v3.5.1 // indirect
diff --git a/go.sum b/go.sum
index af9cdce..7f30c23 100644
--- a/go.sum
+++ b/go.sum
@@ -3,12 +3,12 @@ chainguard.dev/go-grpc-kit v0.17.6/go.mod h1:ZNaXn2KEO++2u2WveHs65krYiHmAEGjYLeE
 chainguard.dev/sdk v0.1.25 h1:C+FeoJCt4AeMMlWw6+vu5CIcNeYJgooPse6UMLcZzik=
 chainguard.dev/sdk v0.1.25/go.mod h1:k88fQlFggN176oyRjg7c1ICpEAbDJOlTcZe+BBHk+70=
 cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
-cloud.google.com/go/auth v0.9.4 h1:DxF7imbEbiFu9+zdKC6cKBko1e8XeJnipNqIbWZ+kDI=
-cloud.google.com/go/auth v0.9.4/go.mod h1:SHia8n6//Ya940F1rLimhJCjjx7KE17t0ctFEci3HkA=
+cloud.google.com/go/auth v0.9.5 h1:4CTn43Eynw40aFVr3GpPqsQponx2jv0BQpjvajsbbzw=
+cloud.google.com/go/auth v0.9.5/go.mod h1:Xo0n7n66eHyOWWCnitop6870Ilwo3PiZyodVkkH1xWM=
 cloud.google.com/go/auth/oauth2adapt v0.2.4 h1:0GWE/FUsXhf6C+jAkWgYm7X9tK8cuEIfy19DBn6B6bY=
 cloud.google.com/go/auth/oauth2adapt v0.2.4/go.mod h1:jC/jOpwFP6JBxhB3P5Rr0a9HLMC/Pe3eaL4NmdvqPtc=
-cloud.google.com/go/compute/metadata v0.5.1 h1:NM6oZeZNlYjiwYje+sYFjEpP0Q0zCan1bmQW/KmIrGs=
-cloud.google.com/go/compute/metadata v0.5.1/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k=
+cloud.google.com/go/compute/metadata v0.5.2 h1:UxK4uu/Tn+I3p2dYWTfiX4wva7aYlKixAHn3fyqngqo=
+cloud.google.com/go/compute/metadata v0.5.2/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k=
 dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
 dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
 filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
@@ -223,8 +223,8 @@ github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4
 github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
-github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
+github.com/klauspost/compress v1.17.10 h1:oXAz+Vh0PMUvJczoi+flxpnBEPxoER1IaAnU/NMPtT0=
+github.com/klauspost/compress v1.17.10/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
 github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
 github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -395,8 +395,8 @@ go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8d
 go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o=
 go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
 go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
-go.step.sm/crypto v0.52.0 h1:3blUzFm0S4tPrijcvcP47tvd7VmEEGJnvzblE+sg5LI=
-go.step.sm/crypto v0.52.0/go.mod h1:GcT4hMILsNiiN3dIXH/Df5fLVs/KIwGZva85faw7lYw=
+go.step.sm/crypto v0.53.0 h1:+1as1ogzuCzx15/468M4mEC5juogI5a0Fzbsyh1CuYY=
+go.step.sm/crypto v0.53.0/go.mod h1:AqLU78RqNUHepLzyOWZuNN/2++Lu7dZENdO9UzWOGSk=
 go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
 go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
 go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
@@ -523,16 +523,16 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/api v0.198.0 h1:OOH5fZatk57iN0A7tjJQzt6aPfYQ1JiWkt1yGseazks=
-google.golang.org/api v0.198.0/go.mod h1:/Lblzl3/Xqqk9hw/yS97TImKTUwnf1bv89v7+OagJzc=
+google.golang.org/api v0.199.0 h1:aWUXClp+VFJmqE0JPvpZOK3LDQMyFKYIow4etYd9qxs=
+google.golang.org/api v0.199.0/go.mod h1:ohG4qSztDJmZdjK/Ar6MhbAmb/Rpi4JHOqagsh90K28=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
 google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
-google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed h1:3RgNmBoI9MZhsj3QxC+AP/qQhNwpCLOvYDYYsFrhFt0=
-google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo=
+google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc=
+google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I=
 google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
 google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
 google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
@@ -542,8 +542,8 @@ google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQ
 google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
 google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
 google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
-google.golang.org/grpc v1.66.2 h1:3QdXkuq3Bkh7w+ywLdLvM56cmGvQHUMZpiCzt6Rqaoo=
-google.golang.org/grpc v1.66.2/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
+google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw=
+google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
 google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
diff --git a/internal/cli/build.go b/internal/cli/build.go
index 0763314..51aed9d 100644
--- a/internal/cli/build.go
+++ b/internal/cli/build.go
@@ -301,7 +301,7 @@ func buildImageComponents(ctx context.Context, workDir string, archs []types.Arc
 	}
 
 	// generate the index
-	finalDigest, idx, err := oci.GenerateIndex(ctx, *ic, imgs)
+	finalDigest, idx, err := oci.GenerateIndex(ctx, *ic, imgs, multiArchBDE)
 	if err != nil {
 		return nil, nil, fmt.Errorf("failed to generate OCI index: %w", err)
 	}
diff --git a/internal/cli/dot.go b/internal/cli/dot.go
index 51924bd..9c5fbe7 100644
--- a/internal/cli/dot.go
+++ b/internal/cli/dot.go
@@ -51,8 +51,8 @@ func dotcmd() *cobra.Command {
 
 	cmd := &cobra.Command{
 		Use:   "dot",
-		Short: "Output a digraph showing the resolved dependencies of an apko config.",
-		Long: `Output a digraph showing the resolved dependencies of an apko config.
+		Short: "Output a digraph showing the resolved dependencies of an apko config",
+		Long: `Output a digraph showing the resolved dependencies of an apko config
 
 # Render an svg of example.yaml
 apko dot example.yaml | dot -Tvsg > graph.svg
diff --git a/pkg/apk/apk/apkindex.go b/pkg/apk/apk/apkindex.go
index dd3ac2d..2ae4019 100644
--- a/pkg/apk/apk/apkindex.go
+++ b/pkg/apk/apk/apkindex.go
@@ -119,8 +119,12 @@ func ParsePackageIndex(apkIndexUnpacked io.Reader) ([]*Package, error) {
 			continue
 		}
 
-		if len(line) > 1 && line[1:2] != ":" {
-			return nil, fmt.Errorf("cannot parse line %d: expected \":\" in not found", linenr)
+		if len(line) < 2 {
+			return nil, fmt.Errorf("cannot parse line %d: expected len >= 2, saw %q", linenr, line)
+		}
+
+		if line[1:2] != ":" {
+			return nil, fmt.Errorf("cannot parse line %d: expected \":\" not found", linenr)
 		}
 
 		token := line[:1]
diff --git a/pkg/apk/apk/implementation.go b/pkg/apk/apk/implementation.go
index 7d97f27..c9e2252 100644
--- a/pkg/apk/apk/implementation.go
+++ b/pkg/apk/apk/implementation.go
@@ -79,7 +79,7 @@ type APK struct {
 
 	// This is a map of arch to apk.APK for every arch in a mult-arch situation.
 	// It's stuffed here to avoid plumbing it across every method, but it's optional.
-	Others map[string]*APK
+	ByArch map[string]*APK
 }
 
 func New(options ...Option) (*APK, error) {
@@ -497,21 +497,16 @@ func (a *APK) ResolveWorld(ctx context.Context) (toInstall []*RepositoryPackage,
 	resolver := NewPkgResolver(ctx, indexes)
 
 	// For other architectures we're building (if any), we want to disqualify any packages not present in all archs.
-	others := map[string][]NamedIndex{}
-	for otherArch, otherAPK := range a.Others {
-		if otherArch == a.arch {
-			// No need to do this on ourselves.
-			continue
-		}
-
+	allArchs := map[string][]NamedIndex{}
+	for otherArch, otherAPK := range a.ByArch {
 		indexes, err := otherAPK.GetRepositoryIndexes(ctx, a.ignoreSignatures)
 		if err != nil {
 			return toInstall, conflicts, fmt.Errorf("getting indexes for %q sibling: %w", otherArch, err)
 		}
-		others[otherArch] = indexes
+		allArchs[otherArch] = indexes
 	}
 
-	toInstall, conflicts, err = resolver.GetPackagesWithDependencies(ctx, directPkgs, others)
+	toInstall, conflicts, err = resolver.GetPackagesWithDependencies(ctx, directPkgs, allArchs)
 	if err != nil {
 		return
 	}
diff --git a/pkg/apk/apk/index.go b/pkg/apk/apk/index.go
index f8fec84..05599a7 100644
--- a/pkg/apk/apk/index.go
+++ b/pkg/apk/apk/index.go
@@ -51,7 +51,7 @@ var globalIndexCache = &indexCache{
 }
 
 type indexResult struct {
-	idx *APKIndex
+	idx NamedIndex
 	err error
 }
 
@@ -67,19 +67,29 @@ type indexCache struct {
 	indexes sync.Map
 }
 
-func (i *indexCache) get(ctx context.Context, u string, keys map[string][]byte, arch string, opts *indexOpts) (*APKIndex, error) {
+func (i *indexCache) get(ctx context.Context, repoName, repoURL string, keys map[string][]byte, arch string, opts *indexOpts) (NamedIndex, error) {
+	u := IndexURL(repoURL, arch)
+
 	ctx, span := otel.Tracer("go-apk").Start(ctx, fmt.Sprintf("indexCache.get(%q)", u))
 	defer span.End()
 
+	repoBase := fmt.Sprintf("%s/%s", repoURL, arch)
+	repoRef := Repository{URI: repoBase}
+
 	if strings.HasPrefix(u, "https://") || strings.HasPrefix(u, "http://") {
 		// We don't want remote indexes to change while we're running.
 		once, _ := i.onces.LoadOrStore(u, &sync.Once{})
 		once.(*sync.Once).Do(func() {
 			idx, err := getRepositoryIndex(ctx, u, keys, arch, opts)
-			i.indexes.Store(u, indexResult{
-				idx: idx,
-				err: err,
-			})
+			if err != nil {
+				i.indexes.Store(u, indexResult{
+					err: err,
+				})
+			} else {
+				i.indexes.Store(u, indexResult{
+					idx: NewNamedRepositoryWithIndex(repoName, repoRef.WithIndex(idx)),
+				})
+			}
 		})
 	} else {
 		i.Lock()
@@ -96,10 +106,15 @@ func (i *indexCache) get(ctx context.Context, u string, keys map[string][]byte,
 		if !ok || mod.After(before) {
 			// If this is the first time or it has changed since the last time...
 			idx, err := getRepositoryIndex(ctx, u, keys, arch, opts)
-			i.indexes.Store(u, indexResult{
-				idx: idx,
-				err: err,
-			})
+			if err != nil {
+				i.indexes.Store(u, indexResult{
+					err: err,
+				})
+			} else {
+				i.indexes.Store(u, indexResult{
+					idx: NewNamedRepositoryWithIndex(repoName, repoRef.WithIndex(idx)),
+				})
+			}
 			i.modtimes[u] = mod
 		}
 	}
@@ -154,11 +169,9 @@ func GetRepositoryIndexes(ctx context.Context, repos []string, keys map[string][
 				repoURL = parts[1]
 			}
 
-			u := IndexURL(repoURL, arch)
-			repoBase := fmt.Sprintf("%s/%s", repoURL, arch)
-
-			index, err := globalIndexCache.get(ctx, u, keys, arch, opts)
+			index, err := globalIndexCache.get(ctx, repoName, repoURL, keys, arch, opts)
 			if err != nil {
+				u := IndexURL(repoURL, arch)
 				asURL, _ := url.Parse(u)
 				return fmt.Errorf("reading index %s: %w", asURL.Redacted(), err)
 			}
@@ -167,10 +180,7 @@ func GetRepositoryIndexes(ctx context.Context, repos []string, keys map[string][
 			if index == nil {
 				return nil
 			}
-
-			repoRef := Repository{URI: repoBase}
-
-			indexes[i] = NewNamedRepositoryWithIndex(repoName, repoRef.WithIndex(index))
+			indexes[i] = index
 			return nil
 		})
 	}
diff --git a/pkg/apk/apk/repo.go b/pkg/apk/apk/repo.go
index 823e340..8e34fa6 100644
--- a/pkg/apk/apk/repo.go
+++ b/pkg/apk/apk/repo.go
@@ -21,13 +21,13 @@ import (
 	"errors"
 	"fmt"
 	"io"
+	"maps"
 	"path/filepath"
+	"slices"
 	"strings"
 	"sync"
 
 	"go.opentelemetry.io/otel"
-	"golang.org/x/exp/maps"
-	"golang.org/x/exp/slices"
 
 	"github.com/chainguard-dev/clog"
 )
@@ -205,9 +205,22 @@ type PkgResolver struct {
 	installIfMap map[string][]*repositoryPackage // contains any package that should be installed if the named package is installed
 }
 
+// Clone returns a copy of PkgResolver.
+func (p *PkgResolver) Clone() *PkgResolver {
+	return &PkgResolver{
+		indexes:      p.indexes,
+		nameMap:      maps.Clone(p.nameMap),
+		installIfMap: maps.Clone(p.installIfMap),
+	}
+}
+
 // NewPkgResolver creates a new pkgResolver from a list of indexes.
 // The indexes are anything that implements NamedIndex.
 func NewPkgResolver(ctx context.Context, indexes []NamedIndex) *PkgResolver {
+	return globalResolverCache.Get(ctx, indexes)
+}
+
+func newPkgResolver(ctx context.Context, indexes []NamedIndex) *PkgResolver {
 	_, span := otel.Tracer("go-apk").Start(ctx, "NewPkgResolver")
 	defer span.End()
 
@@ -436,55 +449,14 @@ func (p *PkgResolver) constrain(constraints []string, dq map[*RepositoryPackage]
 	return nil
 }
 
-func (p *PkgResolver) disqualifyMissingArchs(otherArchs map[string][]NamedIndex, dq map[*RepositoryPackage]string) {
-	// arch -> name -> set[version]
-	allowablePackages := map[string]map[string]map[string]struct{}{}
-
-	// Build up a map per arch to quickly check existence of a package name+version.
-	for arch, indexes := range otherArchs {
-		allowed := map[string]map[string]struct{}{}
-		for _, index := range indexes {
-			for _, pkg := range index.Packages() {
-				versions, ok := allowed[pkg.Name]
-				if !ok {
-					versions = map[string]struct{}{}
-				}
-				versions[pkg.Version] = struct{}{}
-				allowed[pkg.Name] = versions
-			}
-		}
-		allowablePackages[arch] = allowed
-	}
-
-	// Check each package in this arch against every other arch, disqualifying any that are missing.
-	for _, pkgVersions := range p.nameMap {
-		for _, pkg := range pkgVersions {
-			for arch, allowed := range allowablePackages {
-				versions, ok := allowed[pkg.Name]
-				if !ok {
-					p.disqualify(dq, pkg.RepositoryPackage, fmt.Sprintf("package %q not available for arch %q", pkg.Filename(), arch))
-				}
-				if _, ok := versions[pkg.Version]; !ok {
-					p.disqualify(dq, pkg.RepositoryPackage, fmt.Sprintf("package %q not available for arch %q", pkg.Filename(), arch))
-				}
-			}
-		}
-	}
-}
-
 // GetPackagesWithDependencies get all of the dependencies for the given packages based on the
 // indexes. Does not filter for installed already or not.
-func (p *PkgResolver) GetPackagesWithDependencies(ctx context.Context, packages []string, otherArchs map[string][]NamedIndex) (toInstall []*RepositoryPackage, conflicts []string, err error) {
+func (p *PkgResolver) GetPackagesWithDependencies(ctx context.Context, packages []string, allArchs map[string][]NamedIndex) (toInstall []*RepositoryPackage, conflicts []string, err error) {
 	_, span := otel.Tracer("go-apk").Start(ctx, "GetPackageWithDependencies")
 	defer span.End()
 
 	// Tracks all the packages we have disqualified and the reason we disqualified them.
-	dq := map[*RepositoryPackage]string{}
-
-	// If we are solving in the context of other architectures, we want to disqualify any packages that aren't available in all architectures.
-	if len(otherArchs) != 0 {
-		p.disqualifyMissingArchs(otherArchs, dq)
-	}
+	dq := globalDisqualifyCache.Get(ctx, allArchs)
 
 	// We're going to mutate this as our set of input packages to install, so make a copy.
 	constraints := slices.Clone(packages)
@@ -780,7 +752,7 @@ func (p *PkgResolver) getPackageDependencies(pkg *RepositoryPackage, allowPin st
 			options[dep] = pkgs
 		}
 
-		constraints = maps.Keys(options)
+		constraints = slices.Collect(maps.Keys(options))
 		if len(constraints) == 0 {
 			// Nothing left to solve.
 			continue
@@ -1068,3 +1040,55 @@ func maybedqerror(constraint string, pkgs []*repositoryPackage, dq map[*Reposito
 
 	return fmt.Errorf("could not find constraint %q in indexes", constraint)
 }
+
+func disqualifyDifference(ctx context.Context, byArch map[string][]NamedIndex) map[*RepositoryPackage]string {
+	dq := map[*RepositoryPackage]string{}
+
+	if len(byArch) == 1 {
+		// There is no difference between archs if we have one arch.
+		return dq
+	}
+
+	// arch -> name -> set[version]
+	allowablePackages := map[string]map[string]map[string]struct{}{}
+
+	for arch, indexes := range byArch {
+		// Build up a map per arch to quickly check existence of a package name+version.
+		allowed := map[string]map[string]struct{}{}
+		for _, index := range indexes {
+			for _, pkg := range index.Packages() {
+				versions, ok := allowed[pkg.Name]
+				if !ok {
+					versions = map[string]struct{}{}
+				}
+				versions[pkg.Version] = struct{}{}
+				allowed[pkg.Name] = versions
+			}
+		}
+		allowablePackages[arch] = allowed
+	}
+
+	for arch := range allowablePackages {
+		p := newPkgResolver(ctx, byArch[arch])
+		for otherArch, allowed := range allowablePackages {
+			if otherArch == arch {
+				continue
+			}
+
+			for _, pkgVersions := range p.nameMap {
+				for _, pkg := range pkgVersions {
+					versions, ok := allowed[pkg.Name]
+					if !ok {
+						dq[pkg.RepositoryPackage] = fmt.Sprintf("package %q not available for arch %q", pkg.Filename(), otherArch)
+						continue
+					}
+					if _, ok := versions[pkg.Version]; !ok {
+						dq[pkg.RepositoryPackage] = fmt.Sprintf("package %q not available for arch %q", pkg.Filename(), otherArch)
+					}
+				}
+			}
+		}
+	}
+
+	return dq
+}
diff --git a/pkg/apk/apk/repository.go b/pkg/apk/apk/repository.go
index 0b7f7f5..4810cf0 100644
--- a/pkg/apk/apk/repository.go
+++ b/pkg/apk/apk/repository.go
@@ -19,10 +19,22 @@ func NewRepositoryFromComponents(baseURI, release, repo, arch string) Repository
 
 // WithIndex returns a RepositoryWithIndex object with the
 func (r *Repository) WithIndex(index *APKIndex) *RepositoryWithIndex {
-	return &RepositoryWithIndex{
+	rwi := &RepositoryWithIndex{
 		Repository: r,
 		index:      index,
 	}
+	pkgs := make([]*RepositoryPackage, 0, len(index.Packages))
+	for _, pkg := range index.Packages {
+		rp := &RepositoryPackage{
+			Package:    pkg,
+			repository: rwi,
+		}
+		pkgs = append(pkgs, rp)
+	}
+
+	rwi.pkgs = pkgs
+
+	return rwi
 }
 
 // IndexURI returns the uri of the APKINDEX for this repository
@@ -40,19 +52,12 @@ func (r *Repository) IsRemote() bool {
 type RepositoryWithIndex struct {
 	*Repository
 	index *APKIndex
+	pkgs  []*RepositoryPackage
 }
 
 // Packages returns a list of RepositoryPackage in this repository
-func (r *RepositoryWithIndex) Packages() (pkgs []*RepositoryPackage) {
-	for _, pkg := range r.index.Packages {
-		rp := &RepositoryPackage{
-			Package:    pkg,
-			repository: r,
-		}
-		pkgs = append(pkgs, rp)
-	}
-
-	return
+func (r *RepositoryWithIndex) Packages() []*RepositoryPackage {
+	return r.pkgs
 }
 
 // Count returns the amout of packages that are available in this repository
diff --git a/pkg/apk/apk/shameful_global_caches.go b/pkg/apk/apk/shameful_global_caches.go
new file mode 100644
index 0000000..2e0843f
--- /dev/null
+++ b/pkg/apk/apk/shameful_global_caches.go
@@ -0,0 +1,149 @@
+// Copyright 2023 Chainguard, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package apk
+
+import (
+	"context"
+	"maps"
+	"slices"
+	"strings"
+	"sync"
+)
+
+// It is expensive to parse every version in the APKINDEX and grow a bunch of maps.
+// This caches a PkgResolver based on the input []NamedIndex.
+var globalResolverCache = &resolverCache{}
+
+type resolverCache struct {
+	sync.Mutex
+	children map[NamedIndex]*resolverCache
+	pr       *PkgResolver
+}
+
+func (r *resolverCache) find(indexes []NamedIndex) *PkgResolver {
+	if len(indexes) == 0 {
+		return r.pr
+	}
+
+	if r.children == nil {
+		return nil
+	}
+
+	child, ok := r.children[indexes[0]]
+	if !ok {
+		return nil
+	}
+
+	return child.find(indexes[1:])
+}
+
+func (r *resolverCache) fill(indexes []NamedIndex, pr *PkgResolver) {
+	if len(indexes) == 0 {
+		r.pr = pr
+		return
+	}
+
+	if r.children == nil {
+		r.children = make(map[NamedIndex]*resolverCache)
+	}
+
+	child, ok := r.children[indexes[0]]
+	if !ok {
+		child = &resolverCache{}
+		r.children[indexes[0]] = child
+	}
+
+	child.fill(indexes[1:], pr)
+}
+
+func (r *resolverCache) Get(ctx context.Context, indexes []NamedIndex) *PkgResolver {
+	r.Lock()
+	defer r.Unlock()
+
+	if pr := r.find(indexes); pr != nil {
+		return pr.Clone()
+	}
+
+	pr := newPkgResolver(ctx, indexes)
+	r.fill(indexes, pr)
+
+	return pr.Clone()
+}
+
+// It is expensive to compute the complement
+// This a PkgResolver based on the input []NamedIndex.
+var globalDisqualifyCache = &disqualifyCache{}
+
+type disqualifyCache struct {
+	sync.Mutex
+	children map[NamedIndex]*disqualifyCache
+	dq       map[*RepositoryPackage]string
+}
+
+func (r *disqualifyCache) find(indexes []NamedIndex) map[*RepositoryPackage]string {
+	if len(indexes) == 0 {
+		return r.dq
+	}
+
+	if r.children == nil {
+		return nil
+	}
+
+	child, ok := r.children[indexes[0]]
+	if !ok {
+		return nil
+	}
+
+	return child.find(indexes[1:])
+}
+
+func (r *disqualifyCache) fill(indexes []NamedIndex, dq map[*RepositoryPackage]string) {
+	if len(indexes) == 0 {
+		r.dq = dq
+		return
+	}
+
+	if r.children == nil {
+		r.children = make(map[NamedIndex]*disqualifyCache)
+	}
+
+	child, ok := r.children[indexes[0]]
+	if !ok {
+		child = &disqualifyCache{}
+		r.children[indexes[0]] = child
+	}
+
+	child.fill(indexes[1:], dq)
+}
+
+// It is expensive to compute the difference between every architecture.
+// This caches that difference based on the input []NamedIndex for every architecture.
+func (r *disqualifyCache) Get(ctx context.Context, byArch map[string][]NamedIndex) map[*RepositoryPackage]string {
+	r.Lock()
+	defer r.Unlock()
+
+	indexes := slices.Concat(slices.Collect(maps.Values(byArch))...)
+	slices.SortFunc(indexes, func(a, b NamedIndex) int {
+		return strings.Compare(a.Name(), b.Name())
+	})
+	if dq := r.find(indexes); dq != nil {
+		return maps.Clone(dq)
+	}
+
+	dq := disqualifyDifference(ctx, byArch)
+	r.fill(indexes, dq)
+
+	return maps.Clone(dq)
+}
diff --git a/pkg/apk/auth/auth.go b/pkg/apk/auth/auth.go
index 62a100a..b2af1e2 100644
--- a/pkg/apk/auth/auth.go
+++ b/pkg/apk/auth/auth.go
@@ -17,9 +17,9 @@ var DefaultAuthenticators Authenticator = multiAuthenticator{
 	// First, we'll try to use the HTTP_AUTH environment variable if it's set.
 	EnvAuth{},
 	// If both of these envs are set, we'll try to use the k8s token first.
-	NewK8sAuth(os.Getenv("K8S_TOKEN_PATH"), os.Getenv("CHAINGUARD_IDENTITY"), "https://issuer.enforce.dev", "https://apk.cgr.dev"),
+	NewK8sAuth(os.Getenv("K8S_TOKEN_PATH"), os.Getenv("CHAINGUARD_IDENTITY"), "https://issuer.enforce.dev", "apk.cgr.dev"),
 	// If only the identity env is set, and k8s auth didn't work, we'll try to use exchanged GCP auth.
-	NewChainguardIdentityAuth(os.Getenv("CHAINGUARD_IDENTITY"), "https://issuer.enforce.dev", "https://apk.cgr.dev"),
+	NewChainguardIdentityAuth(os.Getenv("CHAINGUARD_IDENTITY"), "https://issuer.enforce.dev", "apk.cgr.dev"),
 	// If nothing has worked yet, we'll try to use chainctl.
 	CGRAuth{},
 }
diff --git a/pkg/apk/auth/chainguard.go b/pkg/apk/auth/chainguard.go
index 06785a8..6b94fcc 100644
--- a/pkg/apk/auth/chainguard.go
+++ b/pkg/apk/auth/chainguard.go
@@ -24,9 +24,10 @@ import (
 // Audience is usually https://apk.cgr.dev.
 func NewChainguardIdentityAuth(identity, issuer, audience string) Authenticator {
 	return &cgAuth{
-		id:  identity,
-		iss: issuer,
-		aud: audience,
+		id:        identity,
+		iss:       issuer,
+		aud:       audience,
+		sometimes: rate.Sometimes{Interval: 10 * time.Minute},
 	}
 }
 
diff --git a/pkg/build/multi.go b/pkg/build/multi.go
index 4029984..d33ea10 100644
--- a/pkg/build/multi.go
+++ b/pkg/build/multi.go
@@ -58,7 +58,7 @@ func NewMultiArch(ctx context.Context, archs []types.Architecture, opts ...Optio
 	}
 
 	for _, bc := range m.Contexts {
-		bc.apk.Others = apks
+		bc.apk.ByArch = apks
 	}
 
 	return m, nil
diff --git a/pkg/build/oci/image.go b/pkg/build/oci/image.go
index 92da7e5..1cfb08f 100644
--- a/pkg/build/oci/image.go
+++ b/pkg/build/oci/image.go
@@ -93,6 +93,7 @@ func BuildImageFromLayer(ctx context.Context, baseImage v1.Image, layer v1.Layer
 			annotations["org.opencontainers.image.revision"] = hash
 		}
 	}
+	annotations["org.opencontainers.image.created"] = created.Format(time.RFC3339)
 
 	if mediaType != ggcrtypes.DockerLayer && len(annotations) > 0 {
 		v1Image = mutate.Annotations(v1Image, annotations).(v1.Image)
diff --git a/pkg/build/oci/index.go b/pkg/build/oci/index.go
index 5399891..74802e6 100644
--- a/pkg/build/oci/index.go
+++ b/pkg/build/oci/index.go
@@ -23,6 +23,7 @@ import (
 	"os"
 	"sort"
 	"strings"
+	"time"
 
 	"github.com/google/go-containerregistry/pkg/name"
 	v1 "github.com/google/go-containerregistry/pkg/v1"
@@ -41,23 +42,23 @@ import (
 // GenerateIndex generates an OCI image index from the given imgs. The index type
 // will be "application/vnd.oci.image.index.v1+json".
 // The index is stored in memory.
-func GenerateIndex(ctx context.Context, ic types.ImageConfiguration, imgs map[types.Architecture]oci.SignedImage) (name.Digest, oci.SignedImageIndex, error) {
+func GenerateIndex(ctx context.Context, ic types.ImageConfiguration, imgs map[types.Architecture]oci.SignedImage, created time.Time) (name.Digest, oci.SignedImageIndex, error) {
 	_, span := otel.Tracer("apko").Start(ctx, "GenerateIndex")
 	defer span.End()
 
-	return generateIndexWithMediaType(ggcrtypes.OCIImageIndex, ic, imgs)
+	return generateIndexWithMediaType(ggcrtypes.OCIImageIndex, ic, imgs, created)
 }
 
 // GenerateDockerIndex generates a docker multi-arch manifest from the given imgs. The index type
 // will be "application/vnd.docker.distribution.manifest.list.v2+json".
 // The index is stored in memory.
-func GenerateDockerIndex(ctx context.Context, ic types.ImageConfiguration, imgs map[types.Architecture]oci.SignedImage) (name.Digest, oci.SignedImageIndex, error) {
-	return generateIndexWithMediaType(ggcrtypes.DockerManifestList, ic, imgs)
+func GenerateDockerIndex(ctx context.Context, ic types.ImageConfiguration, imgs map[types.Architecture]oci.SignedImage, created time.Time) (name.Digest, oci.SignedImageIndex, error) {
+	return generateIndexWithMediaType(ggcrtypes.DockerManifestList, ic, imgs, created)
 }
 
 // generateIndexWithMediaType generates an index or docker manifest list from the given imgs. The index type
 // is provided by the `mediaType` parameter.
-func generateIndexWithMediaType(mediaType ggcrtypes.MediaType, ic types.ImageConfiguration, imgs map[types.Architecture]oci.SignedImage) (name.Digest, oci.SignedImageIndex, error) {
+func generateIndexWithMediaType(mediaType ggcrtypes.MediaType, ic types.ImageConfiguration, imgs map[types.Architecture]oci.SignedImage, created time.Time) (name.Digest, oci.SignedImageIndex, error) {
 	// If annotations are set and we're using the OCI mediaType, set annotations on the index.
 	annotations := map[string]string{}
 	if mediaType == ggcrtypes.OCIImageIndex {
@@ -72,6 +73,7 @@ func generateIndexWithMediaType(mediaType ggcrtypes.MediaType, ic types.ImageCon
 			}
 		}
 	}
+	annotations["org.opencontainers.image.created"] = created.Format(time.RFC3339)
 
 	idx := signed.ImageIndex(
 		mutate.IndexMediaType(


Test patch:
diff --git a/.github/workflows/go-tests.yaml b/.github/workflows/go-tests.yaml
index 41c9c6a..2fee581 100644
--- a/.github/workflows/go-tests.yaml
+++ b/.github/workflows/go-tests.yaml
@@ -19,7 +19,7 @@ jobs:
           egress-policy: audit
 
       - name: Checkout code
-        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+        uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
 
       - name: Install Go
         uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v3.0.0
diff --git a/internal/cli/build_test.go b/internal/cli/build_test.go
index b48566f..8bbfa5d 100644
--- a/internal/cli/build_test.go
+++ b/internal/cli/build_test.go
@@ -105,6 +105,8 @@ func TestBuild(t *testing.T) {
 }
 
 func TestBuildWithBase(t *testing.T) {
+	t.Skip("we can't easily update the golden image, so this test is disabled for now")
+
 	// TODO(sfc-gh-mhazy) Check sboms after base image support is reflected in them.
 
 	ctx := context.Background()
diff --git a/internal/cli/publish_test.go b/internal/cli/publish_test.go
index 0cb61c0..a117663 100644
--- a/internal/cli/publish_test.go
+++ b/internal/cli/publish_test.go
@@ -91,7 +91,7 @@ func TestPublish(t *testing.T) {
 
 	// This test will fail if we ever make a change in apko that changes the image.
 	// Sometimes, this is intentional, and we need to change this and bump the version.
-	want := "sha256:04fd170ec7fc5904638c1ebb09196f2329d06eae68c8b4dd9ac7fb1cf5fbb7cc"
+	want := "sha256:f09e60c2dabb44047225149ccc4a6cdffac23aabf50352931ddd618705e82f2d"
 	require.Equal(t, want, digest.String())
 
 	sdst := fmt.Sprintf("%s:%s.sbom", dst, strings.ReplaceAll(want, ":", "-"))
@@ -109,7 +109,7 @@ func TestPublish(t *testing.T) {
 
 	// This test will fail if we ever make a change in apko that changes the SBOM.
 	// Sometimes, this is intentional, and we need to change this and bump the version.
-	swant := "sha256:21e2b7e0f29f989a9da47b397048a6543bcd394931ecf3818e757aebdf8b0123"
+	swant := "sha256:194bbad4bd7a37e206126b24d63fd0146434b1abbad9afa567fab364c0d5e608"
 	require.Equal(t, swant, got)
 
 	im, err := idx.IndexManifest()
@@ -118,8 +118,8 @@ func TestPublish(t *testing.T) {
 	// We also want to check the children SBOMs because the index SBOM does not have
 	// references to the children SBOMs, just the children!
 	wantBoms := []string{
-		"sha256:c1e01ba7017c59abf15295bc031aecff632aa01ec855c08c5db037a030b17e86",
-		"sha256:432bb01194d2761ee239380bd8f1b281d45d7edb3389e797c3c8b9f477b2284c",
+		"sha256:3bb2af9d9909bc82e537ac17c5283c8e60589b77ada27ec0ad94964709c7d076",
+		"sha256:d3106b5778c36eed5a87d41b7d62234f598917846c3c8d3478a69d5c1f7d4199",
 	}
 
 	for i, m := range im.Manifests {
diff --git a/internal/cli/testdata/golden/blobs/sha256/e42af50bd66e8060653eb032153bc77d039807418ee4d80e0fbca5e3e5028926 b/internal/cli/testdata/golden/blobs/sha256/a87baa16c787394589606e2519134a8e23d9323f475cc3e1a6f63731e8579675
similarity index 53%
rename from internal/cli/testdata/golden/blobs/sha256/e42af50bd66e8060653eb032153bc77d039807418ee4d80e0fbca5e3e5028926
rename to internal/cli/testdata/golden/blobs/sha256/a87baa16c787394589606e2519134a8e23d9323f475cc3e1a6f63731e8579675
index 5f78ee1..98684a1 100644
--- a/internal/cli/testdata/golden/blobs/sha256/e42af50bd66e8060653eb032153bc77d039807418ee4d80e0fbca5e3e5028926
+++ b/internal/cli/testdata/golden/blobs/sha256/a87baa16c787394589606e2519134a8e23d9323f475cc3e1a6f63731e8579675
@@ -1,1 +1,1 @@
-{"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","config":{"mediaType":"application/vnd.oci.image.config.v1+json","size":524,"digest":"sha256:684cd13c05ce23fe0a4ce616b40aa4d027ee38ebc7e393a361ecd0f301ea55a8"},"layers":[{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","size":3100,"digest":"sha256:16e741f38ee9768330001d0b12b34006d5bdf90bc2dd72716bca4446e66b6ac6"}]}
\ No newline at end of file
+{"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","config":{"mediaType":"application/vnd.oci.image.config.v1+json","size":593,"digest":"sha256:bbaad1e21e057125420f82a99f24337b25e483d9332e6d6e2485a71562bd2900"},"layers":[{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","size":3100,"digest":"sha256:16e741f38ee9768330001d0b12b34006d5bdf90bc2dd72716bca4446e66b6ac6"}],"annotations":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z"}}
\ No newline at end of file
diff --git a/internal/cli/testdata/golden/blobs/sha256/a8c325d93bf7fede3a4fac598ea0d05b7a56d702efbed5cbcf1f40c3e7ad7076 b/internal/cli/testdata/golden/blobs/sha256/b12d8e8b08c2b824fa25d5d797d1aa95a424968f8136392f6a5476cc89577fbb
similarity index 86%
rename from internal/cli/testdata/golden/blobs/sha256/a8c325d93bf7fede3a4fac598ea0d05b7a56d702efbed5cbcf1f40c3e7ad7076
rename to internal/cli/testdata/golden/blobs/sha256/b12d8e8b08c2b824fa25d5d797d1aa95a424968f8136392f6a5476cc89577fbb
index 82e5513..6622935 100644
--- a/internal/cli/testdata/golden/blobs/sha256/a8c325d93bf7fede3a4fac598ea0d05b7a56d702efbed5cbcf1f40c3e7ad7076
+++ b/internal/cli/testdata/golden/blobs/sha256/b12d8e8b08c2b824fa25d5d797d1aa95a424968f8136392f6a5476cc89577fbb
@@ -1,1 +1,1 @@
-{"architecture":"arm64","author":"github.com/chainguard-dev/apko","created":"1970-01-01T00:00:00Z","history":[{"author":"apko","created":"1970-01-01T00:00:00Z","created_by":"apko","comment":"This is an apko single-layer image"}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:efe1fac5d8d6bcadf61026012fa98c321eb53299f22f02b1fe5ed4c22f2995cf"]},"config":{"Entrypoint":["/bin/sh","-l"],"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt"]}}
\ No newline at end of file
+{"architecture":"arm64","author":"github.com/chainguard-dev/apko","created":"1970-01-01T00:00:00Z","history":[{"author":"apko","created":"1970-01-01T00:00:00Z","created_by":"apko","comment":"This is an apko single-layer image"}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:efe1fac5d8d6bcadf61026012fa98c321eb53299f22f02b1fe5ed4c22f2995cf"]},"config":{"Entrypoint":["/bin/sh","-l"],"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt"],"Labels":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z"}}}
\ No newline at end of file
diff --git a/internal/cli/testdata/golden/blobs/sha256/684cd13c05ce23fe0a4ce616b40aa4d027ee38ebc7e393a361ecd0f301ea55a8 b/internal/cli/testdata/golden/blobs/sha256/bbaad1e21e057125420f82a99f24337b25e483d9332e6d6e2485a71562bd2900
similarity index 86%
rename from internal/cli/testdata/golden/blobs/sha256/684cd13c05ce23fe0a4ce616b40aa4d027ee38ebc7e393a361ecd0f301ea55a8
rename to internal/cli/testdata/golden/blobs/sha256/bbaad1e21e057125420f82a99f24337b25e483d9332e6d6e2485a71562bd2900
index 1dac546..6fbf690 100644
--- a/internal/cli/testdata/golden/blobs/sha256/684cd13c05ce23fe0a4ce616b40aa4d027ee38ebc7e393a361ecd0f301ea55a8
+++ b/internal/cli/testdata/golden/blobs/sha256/bbaad1e21e057125420f82a99f24337b25e483d9332e6d6e2485a71562bd2900
@@ -1,1 +1,1 @@
-{"architecture":"amd64","author":"github.com/chainguard-dev/apko","created":"1970-01-01T00:00:00Z","history":[{"author":"apko","created":"1970-01-01T00:00:00Z","created_by":"apko","comment":"This is an apko single-layer image"}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:ae315dbf6cdeac9bef1b14aed88fd75bbfbf5ed9671994241528c2da3fa6d785"]},"config":{"Entrypoint":["/bin/sh","-l"],"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt"]}}
\ No newline at end of file
+{"architecture":"amd64","author":"github.com/chainguard-dev/apko","created":"1970-01-01T00:00:00Z","history":[{"author":"apko","created":"1970-01-01T00:00:00Z","created_by":"apko","comment":"This is an apko single-layer image"}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:ae315dbf6cdeac9bef1b14aed88fd75bbfbf5ed9671994241528c2da3fa6d785"]},"config":{"Entrypoint":["/bin/sh","-l"],"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt"],"Labels":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z"}}}
\ No newline at end of file
diff --git a/internal/cli/testdata/golden/blobs/sha256/7e3a7384fe0243cc4b498cd54be2455fdcbb7aebd5eb94566926a5088868eef4 b/internal/cli/testdata/golden/blobs/sha256/f5e87ab7f4eba7d7a649cd3fcb969b4fcb9c72784c9cbe7ed3f0f60e84933972
similarity index 53%
rename from internal/cli/testdata/golden/blobs/sha256/7e3a7384fe0243cc4b498cd54be2455fdcbb7aebd5eb94566926a5088868eef4
rename to internal/cli/testdata/golden/blobs/sha256/f5e87ab7f4eba7d7a649cd3fcb969b4fcb9c72784c9cbe7ed3f0f60e84933972
index 597bf30..52805d8 100644
--- a/internal/cli/testdata/golden/blobs/sha256/7e3a7384fe0243cc4b498cd54be2455fdcbb7aebd5eb94566926a5088868eef4
+++ b/internal/cli/testdata/golden/blobs/sha256/f5e87ab7f4eba7d7a649cd3fcb969b4fcb9c72784c9cbe7ed3f0f60e84933972
@@ -1,1 +1,1 @@
-{"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","config":{"mediaType":"application/vnd.oci.image.config.v1+json","size":524,"digest":"sha256:a8c325d93bf7fede3a4fac598ea0d05b7a56d702efbed5cbcf1f40c3e7ad7076"},"layers":[{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","size":3110,"digest":"sha256:6e6ffbcf153baa74794a66c87760f8d393ad82b51770b2c3b6ae5211ee5d7b6d"}]}
\ No newline at end of file
+{"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","config":{"mediaType":"application/vnd.oci.image.config.v1+json","size":593,"digest":"sha256:b12d8e8b08c2b824fa25d5d797d1aa95a424968f8136392f6a5476cc89577fbb"},"layers":[{"mediaType":"application/vnd.oci.image.layer.v1.tar+gzip","size":3110,"digest":"sha256:6e6ffbcf153baa74794a66c87760f8d393ad82b51770b2c3b6ae5211ee5d7b6d"}],"annotations":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z"}}
\ No newline at end of file
diff --git a/internal/cli/testdata/golden/index.json b/internal/cli/testdata/golden/index.json
index 29b1801..44f1880 100755
--- a/internal/cli/testdata/golden/index.json
+++ b/internal/cli/testdata/golden/index.json
@@ -1,1 +1,1 @@
-{"schemaVersion":2,"mediaType":"application/vnd.oci.image.index.v1+json","manifests":[{"mediaType":"application/vnd.oci.image.manifest.v1+json","size":402,"digest":"sha256:e42af50bd66e8060653eb032153bc77d039807418ee4d80e0fbca5e3e5028926","platform":{"architecture":"amd64","os":"linux"}},{"mediaType":"application/vnd.oci.image.manifest.v1+json","size":402,"digest":"sha256:7e3a7384fe0243cc4b498cd54be2455fdcbb7aebd5eb94566926a5088868eef4","platform":{"architecture":"arm64","os":"linux"}}]}
\ No newline at end of file
+{"schemaVersion":2,"mediaType":"application/vnd.oci.image.index.v1+json","manifests":[{"mediaType":"application/vnd.oci.image.manifest.v1+json","size":476,"digest":"sha256:a87baa16c787394589606e2519134a8e23d9323f475cc3e1a6f63731e8579675","platform":{"architecture":"amd64","os":"linux"}},{"mediaType":"application/vnd.oci.image.manifest.v1+json","size":476,"digest":"sha256:f5e87ab7f4eba7d7a649cd3fcb969b4fcb9c72784c9cbe7ed3f0f60e84933972","platform":{"architecture":"arm64","os":"linux"}}],"annotations":{"org.opencontainers.image.created":"1970-01-01T00:00:00Z"}}
\ No newline at end of file
diff --git a/internal/cli/testdata/golden/sboms/sbom-aarch64.spdx.json b/internal/cli/testdata/golden/sboms/sbom-aarch64.spdx.json
index f687a4c..8349b75 100644
--- a/internal/cli/testdata/golden/sboms/sbom-aarch64.spdx.json
+++ b/internal/cli/testdata/golden/sboms/sbom-aarch64.spdx.json
@@ -13,13 +13,13 @@
   "dataLicense": "CC0-1.0",
   "documentNamespace": "https://spdx.org/spdxdocs/apko/",
   "documentDescribes": [
-    "SPDXRef-Package-sha256-7e3a7384fe0243cc4b498cd54be2455fdcbb7aebd5eb94566926a5088868eef4"
+    "SPDXRef-Package-sha256-f5e87ab7f4eba7d7a649cd3fcb969b4fcb9c72784c9cbe7ed3f0f60e84933972"
   ],
   "packages": [
     {
-      "SPDXID": "SPDXRef-Package-sha256-7e3a7384fe0243cc4b498cd54be2455fdcbb7aebd5eb94566926a5088868eef4",
-      "name": "sha256:7e3a7384fe0243cc4b498cd54be2455fdcbb7aebd5eb94566926a5088868eef4",
-      "versionInfo": "sha256:7e3a7384fe0243cc4b498cd54be2455fdcbb7aebd5eb94566926a5088868eef4",
+      "SPDXID": "SPDXRef-Package-sha256-f5e87ab7f4eba7d7a649cd3fcb969b4fcb9c72784c9cbe7ed3f0f60e84933972",
+      "name": "sha256:f5e87ab7f4eba7d7a649cd3fcb969b4fcb9c72784c9cbe7ed3f0f60e84933972",
+      "versionInfo": "sha256:f5e87ab7f4eba7d7a649cd3fcb969b4fcb9c72784c9cbe7ed3f0f60e84933972",
       "filesAnalyzed": false,
       "description": "apko container image",
       "downloadLocation": "NOASSERTION",
@@ -28,13 +28,13 @@
       "checksums": [
         {
           "algorithm": "SHA256",
-          "checksumValue": "7e3a7384fe0243cc4b498cd54be2455fdcbb7aebd5eb94566926a5088868eef4"
+          "checksumValue": "f5e87ab7f4eba7d7a649cd3fcb969b4fcb9c72784c9cbe7ed3f0f60e84933972"
         }
       ],
       "externalRefs": [
         {
           "referenceCategory": "PACKAGE-MANAGER",
-          "referenceLocator": "pkg:oci/golden@sha256%3A7e3a7384fe0243cc4b498cd54be2455fdcbb7aebd5eb94566926a5088868eef4?arch=arm64\u0026mediaType=application%2Fvnd.oci.image.manifest.v1%2Bjson\u0026os=linux",
+          "referenceLocator": "pkg:oci/golden@sha256%3Af5e87ab7f4eba7d7a649cd3fcb969b4fcb9c72784c9cbe7ed3f0f60e84933972?arch=arm64\u0026mediaType=application%2Fvnd.oci.image.manifest.v1%2Bjson\u0026os=linux",
           "referenceType": "purl"
         }
       ]
@@ -96,7 +96,7 @@
   ],
   "relationships": [
     {
-      "spdxElementId": "SPDXRef-Package-sha256-7e3a7384fe0243cc4b498cd54be2455fdcbb7aebd5eb94566926a5088868eef4",
+      "spdxElementId": "SPDXRef-Package-sha256-f5e87ab7f4eba7d7a649cd3fcb969b4fcb9c72784c9cbe7ed3f0f60e84933972",
       "relationshipType": "CONTAINS",
       "relatedSpdxElement": "SPDXRef-Package-sha256-6e6ffbcf153baa74794a66c87760f8d393ad82b51770b2c3b6ae5211ee5d7b6d"
     }
diff --git a/internal/cli/testdata/golden/sboms/sbom-index.spdx.json b/internal/cli/testdata/golden/sboms/sbom-index.spdx.json
index a39f6ef..6d78f05 100644
--- a/internal/cli/testdata/golden/sboms/sbom-index.spdx.json
+++ b/internal/cli/testdata/golden/sboms/sbom-index.spdx.json
@@ -1,6 +1,6 @@
 {
   "SPDXID": "SPDXRef-DOCUMENT",
-  "name": "sbom-sha256:685a8f5d66554057ea6e697be713d81bdaec276f4ef845243e60fc61df698168",
+  "name": "sbom-sha256:d558b9114f2eaf11b1a3d9720cdcff3b12f087e741377d04f93bd5dc53f36227",
   "spdxVersion": "SPDX-2.3",
   "creationInfo": {
     "created": "1970-01-01T00:00:00Z",
@@ -13,13 +13,13 @@
   "dataLicense": "CC0-1.0",
   "documentNamespace": "https://spdx.org/spdxdocs/apko/",
   "documentDescribes": [
-    "SPDXRef-Package-sha256-685a8f5d66554057ea6e697be713d81bdaec276f4ef845243e60fc61df698168"
+    "SPDXRef-Package-sha256-d558b9114f2eaf11b1a3d9720cdcff3b12f087e741377d04f93bd5dc53f36227"
   ],
   "packages": [
     {
-      "SPDXID": "SPDXRef-Package-sha256-685a8f5d66554057ea6e697be713d81bdaec276f4ef845243e60fc61df698168",
-      "name": "sha256:685a8f5d66554057ea6e697be713d81bdaec276f4ef845243e60fc61df698168",
-      "versionInfo": "sha256:685a8f5d66554057ea6e697be713d81bdaec276f4ef845243e60fc61df698168",
+      "SPDXID": "SPDXRef-Package-sha256-d558b9114f2eaf11b1a3d9720cdcff3b12f087e741377d04f93bd5dc53f36227",
+      "name": "sha256:d558b9114f2eaf11b1a3d9720cdcff3b12f087e741377d04f93bd5dc53f36227",
+      "versionInfo": "sha256:d558b9114f2eaf11b1a3d9720cdcff3b12f087e741377d04f93bd5dc53f36227",
       "filesAnalyzed": false,
       "description": "Multi-arch image index",
       "downloadLocation": "NOASSERTION",
@@ -29,21 +29,21 @@
       "checksums": [
         {
           "algorithm": "SHA256",
-          "checksumValue": "685a8f5d66554057ea6e697be713d81bdaec276f4ef845243e60fc61df698168"
+          "checksumValue": "d558b9114f2eaf11b1a3d9720cdcff3b12f087e741377d04f93bd5dc53f36227"
         }
       ],
       "externalRefs": [
         {
           "referenceCategory": "PACKAGE-MANAGER",
-          "referenceLocator": "pkg:oci/golden@sha256%3A685a8f5d66554057ea6e697be713d81bdaec276f4ef845243e60fc61df698168?mediaType=application%2Fvnd.oci.image.index.v1%2Bjson",
+          "referenceLocator": "pkg:oci/golden@sha256%3Ad558b9114f2eaf11b1a3d9720cdcff3b12f087e741377d04f93bd5dc53f36227?mediaType=application%2Fvnd.oci.image.index.v1%2Bjson",
           "referenceType": "purl"
         }
       ]
     },
     {
-      "SPDXID": "SPDXRef-Package-sha256-e42af50bd66e8060653eb032153bc77d039807418ee4d80e0fbca5e3e5028926",
-      "name": "sha256:e42af50bd66e8060653eb032153bc77d039807418ee4d80e0fbca5e3e5028926",
-      "versionInfo": "sha256:e42af50bd66e8060653eb032153bc77d039807418ee4d80e0fbca5e3e5028926",
+      "SPDXID": "SPDXRef-Package-sha256-a87baa16c787394589606e2519134a8e23d9323f475cc3e1a6f63731e8579675",
+      "name": "sha256:a87baa16c787394589606e2519134a8e23d9323f475cc3e1a6f63731e8579675",
+      "versionInfo": "sha256:a87baa16c787394589606e2519134a8e23d9323f475cc3e1a6f63731e8579675",
       "filesAnalyzed": false,
       "downloadLocation": "NOASSERTION",
       "supplier": "Organization: Chainguard, Inc.",
@@ -51,21 +51,21 @@
       "checksums": [
         {
           "algorithm": "SHA256",
-          "checksumValue": "e42af50bd66e8060653eb032153bc77d039807418ee4d80e0fbca5e3e5028926"
+          "checksumValue": "a87baa16c787394589606e2519134a8e23d9323f475cc3e1a6f63731e8579675"
         }
       ],
       "externalRefs": [
         {
           "referenceCategory": "PACKAGE-MANAGER",
-          "referenceLocator": "pkg:oci/golden@sha256%3Ae42af50bd66e8060653eb032153bc77d039807418ee4d80e0fbca5e3e5028926?arch=amd64\u0026mediaType=application%2Fvnd.oci.image.manifest.v1%2Bjson\u0026os=linux",
+          "referenceLocator": "pkg:oci/golden@sha256%3Aa87baa16c787394589606e2519134a8e23d9323f475cc3e1a6f63731e8579675?arch=amd64\u0026mediaType=application%2Fvnd.oci.image.manifest.v1%2Bjson\u0026os=linux",
           "referenceType": "purl"
         }
       ]
     },
     {
-      "SPDXID": "SPDXRef-Package-sha256-7e3a7384fe0243cc4b498cd54be2455fdcbb7aebd5eb94566926a5088868eef4",
-      "name": "sha256:7e3a7384fe0243cc4b498cd54be2455fdcbb7aebd5eb94566926a5088868eef4",
-      "versionInfo": "sha256:7e3a7384fe0243cc4b498cd54be2455fdcbb7aebd5eb94566926a5088868eef4",
+      "SPDXID": "SPDXRef-Package-sha256-f5e87ab7f4eba7d7a649cd3fcb969b4fcb9c72784c9cbe7ed3f0f60e84933972",
+      "name": "sha256:f5e87ab7f4eba7d7a649cd3fcb969b4fcb9c72784c9cbe7ed3f0f60e84933972",
+      "versionInfo": "sha256:f5e87ab7f4eba7d7a649cd3fcb969b4fcb9c72784c9cbe7ed3f0f60e84933972",
       "filesAnalyzed": false,
       "downloadLocation": "NOASSERTION",
       "supplier": "Organization: Chainguard, Inc.",
@@ -73,13 +73,13 @@
       "checksums": [
         {
           "algorithm": "SHA256",
-          "checksumValue": "7e3a7384fe0243cc4b498cd54be2455fdcbb7aebd5eb94566926a5088868eef4"
+          "checksumValue": "f5e87ab7f4eba7d7a649cd3fcb969b4fcb9c72784c9cbe7ed3f0f60e84933972"
         }
       ],
       "externalRefs": [
         {
           "referenceCategory": "PACKAGE-MANAGER",
-          "referenceLocator": "pkg:oci/golden@sha256%3A7e3a7384fe0243cc4b498cd54be2455fdcbb7aebd5eb94566926a5088868eef4?arch=arm64\u0026mediaType=application%2Fvnd.oci.image.manifest.v1%2Bjson\u0026os=linux",
+          "referenceLocator": "pkg:oci/golden@sha256%3Af5e87ab7f4eba7d7a649cd3fcb969b4fcb9c72784c9cbe7ed3f0f60e84933972?arch=arm64\u0026mediaType=application%2Fvnd.oci.image.manifest.v1%2Bjson\u0026os=linux",
           "referenceType": "purl"
         }
       ]
@@ -87,14 +87,14 @@
   ],
   "relationships": [
     {
-      "spdxElementId": "SPDXRef-Package-sha256-685a8f5d66554057ea6e697be713d81bdaec276f4ef845243e60fc61df698168",
+      "spdxElementId": "SPDXRef-Package-sha256-d558b9114f2eaf11b1a3d9720cdcff3b12f087e741377d04f93bd5dc53f36227",
       "relationshipType": "VARIANT_OF",
-      "relatedSpdxElement": "SPDXRef-Package-sha256-e42af50bd66e8060653eb032153bc77d039807418ee4d80e0fbca5e3e5028926"
+      "relatedSpdxElement": "SPDXRef-Package-sha256-a87baa16c787394589606e2519134a8e23d9323f475cc3e1a6f63731e8579675"
     },
     {
-      "spdxElementId": "SPDXRef-Package-sha256-685a8f5d66554057ea6e697be713d81bdaec276f4ef845243e60fc61df698168",
+      "spdxElementId": "SPDXRef-Package-sha256-d558b9114f2eaf11b1a3d9720cdcff3b12f087e741377d04f93bd5dc53f36227",
       "relationshipType": "VARIANT_OF",
-      "relatedSpdxElement": "SPDXRef-Package-sha256-7e3a7384fe0243cc4b498cd54be2455fdcbb7aebd5eb94566926a5088868eef4"
+      "relatedSpdxElement": "SPDXRef-Package-sha256-f5e87ab7f4eba7d7a649cd3fcb969b4fcb9c72784c9cbe7ed3f0f60e84933972"
     }
   ]
 }
diff --git a/internal/cli/testdata/golden/sboms/sbom-x86_64.spdx.json b/internal/cli/testdata/golden/sboms/sbom-x86_64.spdx.json
index 639f52f..14292a0 100644
--- a/internal/cli/testdata/golden/sboms/sbom-x86_64.spdx.json
+++ b/internal/cli/testdata/golden/sboms/sbom-x86_64.spdx.json
@@ -13,13 +13,13 @@
   "dataLicense": "CC0-1.0",
   "documentNamespace": "https://spdx.org/spdxdocs/apko/",
   "documentDescribes": [
-    "SPDXRef-Package-sha256-e42af50bd66e8060653eb032153bc77d039807418ee4d80e0fbca5e3e5028926"
+    "SPDXRef-Package-sha256-a87baa16c787394589606e2519134a8e23d9323f475cc3e1a6f63731e8579675"
   ],
   "packages": [
     {
-      "SPDXID": "SPDXRef-Package-sha256-e42af50bd66e8060653eb032153bc77d039807418ee4d80e0fbca5e3e5028926",
-      "name": "sha256:e42af50bd66e8060653eb032153bc77d039807418ee4d80e0fbca5e3e5028926",
-      "versionInfo": "sha256:e42af50bd66e8060653eb032153bc77d039807418ee4d80e0fbca5e3e5028926",
+      "SPDXID": "SPDXRef-Package-sha256-a87baa16c787394589606e2519134a8e23d9323f475cc3e1a6f63731e8579675",
+      "name": "sha256:a87baa16c787394589606e2519134a8e23d9323f475cc3e1a6f63731e8579675",
+      "versionInfo": "sha256:a87baa16c787394589606e2519134a8e23d9323f475cc3e1a6f63731e8579675",
       "filesAnalyzed": false,
       "description": "apko container image",
       "downloadLocation": "NOASSERTION",
@@ -28,13 +28,13 @@
       "checksums": [
         {
           "algorithm": "SHA256",
-          "checksumValue": "e42af50bd66e8060653eb032153bc77d039807418ee4d80e0fbca5e3e5028926"
+          "checksumValue": "a87baa16c787394589606e2519134a8e23d9323f475cc3e1a6f63731e8579675"
         }
       ],
       "externalRefs": [
         {
           "referenceCategory": "PACKAGE-MANAGER",
-          "referenceLocator": "pkg:oci/golden@sha256%3Ae42af50bd66e8060653eb032153bc77d039807418ee4d80e0fbca5e3e5028926?arch=amd64\u0026mediaType=application%2Fvnd.oci.image.manifest.v1%2Bjson\u0026os=linux",
+          "referenceLocator": "pkg:oci/golden@sha256%3Aa87baa16c787394589606e2519134a8e23d9323f475cc3e1a6f63731e8579675?arch=amd64\u0026mediaType=application%2Fvnd.oci.image.manifest.v1%2Bjson\u0026os=linux",
           "referenceType": "purl"
         }
       ]
@@ -96,7 +96,7 @@
   ],
   "relationships": [
     {
-      "spdxElementId": "SPDXRef-Package-sha256-e42af50bd66e8060653eb032153bc77d039807418ee4d80e0fbca5e3e5028926",
+      "spdxElementId": "SPDXRef-Package-sha256-a87baa16c787394589606e2519134a8e23d9323f475cc3e1a6f63731e8579675",
       "relationshipType": "CONTAINS",
       "relatedSpdxElement": "SPDXRef-Package-sha256-16e741f38ee9768330001d0b12b34006d5bdf90bc2dd72716bca4446e66b6ac6"
     }
diff --git a/pkg/apk/apk/repo_test.go b/pkg/apk/apk/repo_test.go
index 5e78387..27886ee 100644
--- a/pkg/apk/apk/repo_test.go
+++ b/pkg/apk/apk/repo_test.go
@@ -1039,10 +1039,6 @@ func TestDisqualifyingOtherArchitectures(t *testing.T) {
 	names := []string{"package1", "package2", "onlyinarm64"}
 	_, index := testGetPackagesAndIndex()
 
-	others := map[string][]NamedIndex{
-		"x86_64": testNamedRepositoryFromIndexes(index),
-	}
-
 	arm64 := slices.Clone(index)
 	repo := Repository{}
 	repoWithIndex := repo.WithIndex(&APKIndex{
@@ -1050,7 +1046,14 @@ func TestDisqualifyingOtherArchitectures(t *testing.T) {
 	})
 	arm64 = append(arm64, repoWithIndex)
 
-	resolver := NewPkgResolver(context.Background(), testNamedRepositoryFromIndexes(arm64))
-	_, _, err := resolver.GetPackagesWithDependencies(context.Background(), names, others)
+	armIndex := testNamedRepositoryFromIndexes(arm64)
+
+	byArch := map[string][]NamedIndex{
+		"x86_64":  testNamedRepositoryFromIndexes(index),
+		"aarch64": armIndex,
+	}
+
+	resolver := NewPkgResolver(context.Background(), armIndex)
+	_, _, err := resolver.GetPackagesWithDependencies(context.Background(), names, byArch)
 	require.ErrorContains(t, err, "package \"onlyinarm64-1.0.0.apk\" not available for arch \"x86_64\"")
 }
diff --git a/pkg/build/oci/image_test.go b/pkg/build/oci/image_test.go
index a3d6ff0..eef3ce4 100644
--- a/pkg/build/oci/image_test.go
+++ b/pkg/build/oci/image_test.go
@@ -61,7 +61,9 @@ func TestBuildImageFromLayer(t *testing.T) {
 					"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
 					"SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt",
 				},
-				Labels: map[string]string{},
+				Labels: map[string]string{
+					"org.opencontainers.image.created": now.Format(time.RFC3339),
+				},
 			},
 		},
 	}, {
@@ -88,7 +90,9 @@ func TestBuildImageFromLayer(t *testing.T) {
 					"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
 					"SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt",
 				},
-				Labels: map[string]string{},
+				Labels: map[string]string{
+					"org.opencontainers.image.created": now.Format(time.RFC3339),
+				},
 			},
 		},
 	}, {
@@ -116,7 +120,9 @@ func TestBuildImageFromLayer(t *testing.T) {
 					"PATH=/something/else:/another/one:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
 					"SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt",
 				},
-				Labels: map[string]string{},
+				Labels: map[string]string{
+					"org.opencontainers.image.created": now.Format(time.RFC3339),
+				},
 			},
 		},
 	}, {
@@ -144,7 +150,9 @@ func TestBuildImageFromLayer(t *testing.T) {
 					"PATH=",
 					"SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt",
 				},
-				Labels: map[string]string{},
+				Labels: map[string]string{
+					"org.opencontainers.image.created": now.Format(time.RFC3339),
+				},
 			},
 		},
 	}} {
@@ -161,7 +169,3 @@ func TestBuildImageFromLayer(t *testing.T) {
 		})
 	}
 }
-
-func TestBuildImageTarballFromLayer(t *testing.T) {
-
-}