Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8767951fa2 | ||
|
|
f18b5877d3 | ||
|
|
93fd9daeb9 | ||
|
|
5df79de1c7 | ||
|
|
5b5e43b07a | ||
|
|
4c5135eb1b | ||
|
|
0133423f0d | ||
|
|
501b9b442d | ||
|
|
d84ed4821c | ||
|
|
c9e2ddd448 | ||
|
|
165241de42 | ||
|
|
c7d17faf05 | ||
|
|
58021646e3 | ||
|
|
3e7a85e9b8 | ||
|
|
bb7a9a257e | ||
|
|
c690d1090c | ||
|
|
1d1c258f9c | ||
|
|
5d096e226f | ||
|
|
7fc7ceaba0 | ||
|
|
78ec0b7666 | ||
|
|
053f764b8f | ||
|
|
ad3b8b9e49 |
@@ -1,2 +1,5 @@
|
|||||||
ignore:
|
ignore:
|
||||||
- "internal/test"
|
- "internal/test"
|
||||||
|
coverage:
|
||||||
|
status:
|
||||||
|
patch: false
|
||||||
|
|||||||
23
go.mod
23
go.mod
@@ -13,7 +13,7 @@ require (
|
|||||||
github.com/google/go-containerregistry v0.20.1
|
github.com/google/go-containerregistry v0.20.1
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2
|
github.com/hashicorp/go-cleanhttp v0.5.2
|
||||||
github.com/in-toto/in-toto-golang v0.9.0
|
github.com/in-toto/in-toto-golang v0.9.0
|
||||||
github.com/open-policy-agent/opa v0.67.0
|
github.com/open-policy-agent/opa v0.67.1
|
||||||
github.com/opencontainers/image-spec v1.1.0
|
github.com/opencontainers/image-spec v1.1.0
|
||||||
github.com/package-url/packageurl-go v0.1.3
|
github.com/package-url/packageurl-go v0.1.3
|
||||||
github.com/secure-systems-lab/go-securesystemslib v0.8.0
|
github.com/secure-systems-lab/go-securesystemslib v0.8.0
|
||||||
@@ -24,7 +24,7 @@ require (
|
|||||||
github.com/stretchr/testify v1.9.0
|
github.com/stretchr/testify v1.9.0
|
||||||
github.com/testcontainers/testcontainers-go/modules/registry v0.32.0
|
github.com/testcontainers/testcontainers-go/modules/registry v0.32.0
|
||||||
github.com/theupdateframework/go-tuf/v2 v2.0.0
|
github.com/theupdateframework/go-tuf/v2 v2.0.0
|
||||||
google.golang.org/api v0.189.0
|
google.golang.org/api v0.190.0
|
||||||
sigs.k8s.io/yaml v1.4.0
|
sigs.k8s.io/yaml v1.4.0
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -33,12 +33,12 @@ replace github.com/google/go-containerregistry => github.com/kipz/go-containerre
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go v0.115.0 // indirect
|
cloud.google.com/go v0.115.0 // indirect
|
||||||
cloud.google.com/go/auth v0.7.2 // indirect
|
cloud.google.com/go/auth v0.7.3 // indirect
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.3 // indirect
|
cloud.google.com/go/auth/oauth2adapt v0.2.3 // indirect
|
||||||
cloud.google.com/go/compute/metadata v0.5.0 // indirect
|
cloud.google.com/go/compute/metadata v0.5.0 // indirect
|
||||||
cloud.google.com/go/iam v1.1.10 // indirect
|
cloud.google.com/go/iam v1.1.12 // indirect
|
||||||
cloud.google.com/go/kms v1.18.2 // indirect
|
cloud.google.com/go/kms v1.18.4 // indirect
|
||||||
cloud.google.com/go/longrunning v0.5.9 // indirect
|
cloud.google.com/go/longrunning v0.5.11 // indirect
|
||||||
dario.cat/mergo v1.0.0 // indirect
|
dario.cat/mergo v1.0.0 // indirect
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
|
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
|
||||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||||
@@ -101,13 +101,12 @@ require (
|
|||||||
github.com/gobwas/glob v0.2.3 // indirect
|
github.com/gobwas/glob v0.2.3 // indirect
|
||||||
github.com/gogo/protobuf v1.3.2 // indirect
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||||
github.com/golang/protobuf v1.5.4 // indirect
|
|
||||||
github.com/golang/snappy v0.0.4 // indirect
|
github.com/golang/snappy v0.0.4 // indirect
|
||||||
github.com/google/certificate-transparency-go v1.2.1 // indirect
|
github.com/google/certificate-transparency-go v1.2.1 // indirect
|
||||||
github.com/google/s2a-go v0.1.7 // indirect
|
github.com/google/s2a-go v0.1.8 // indirect
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
|
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
|
||||||
github.com/googleapis/gax-go/v2 v2.12.5 // indirect
|
github.com/googleapis/gax-go/v2 v2.13.0 // indirect
|
||||||
github.com/gorilla/mux v1.8.1 // indirect
|
github.com/gorilla/mux v1.8.1 // indirect
|
||||||
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
|
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
|
||||||
github.com/hashicorp/hcl v1.0.1-vault-5 // indirect
|
github.com/hashicorp/hcl v1.0.1-vault-5 // indirect
|
||||||
@@ -192,9 +191,9 @@ require (
|
|||||||
golang.org/x/term v0.22.0 // indirect
|
golang.org/x/term v0.22.0 // indirect
|
||||||
golang.org/x/text v0.16.0 // indirect
|
golang.org/x/text v0.16.0 // indirect
|
||||||
golang.org/x/time v0.5.0 // indirect
|
golang.org/x/time v0.5.0 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20240722135656-d784300faade // indirect
|
google.golang.org/genproto v0.0.0-20240730163845-b1a4ccb954bf // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20240725223205-93522f1f2a9f // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240722135656-d784300faade // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf // indirect
|
||||||
google.golang.org/grpc v1.65.0 // indirect
|
google.golang.org/grpc v1.65.0 // indirect
|
||||||
google.golang.org/protobuf v1.34.2 // indirect
|
google.golang.org/protobuf v1.34.2 // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
|
|||||||
44
go.sum
44
go.sum
@@ -1,18 +1,18 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14=
|
cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14=
|
||||||
cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU=
|
cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU=
|
||||||
cloud.google.com/go/auth v0.7.2 h1:uiha352VrCDMXg+yoBtaD0tUF4Kv9vrtrWPYXwutnDE=
|
cloud.google.com/go/auth v0.7.3 h1:98Vr+5jMaCZ5NZk6e/uBgf60phTk/XN84r8QEWB9yjY=
|
||||||
cloud.google.com/go/auth v0.7.2/go.mod h1:VEc4p5NNxycWQTMQEDQF0bd6aTMb6VgYDXEwiJJQAbs=
|
cloud.google.com/go/auth v0.7.3/go.mod h1:HJtWUx1P5eqjy/f6Iq5KeytNpbAcGolPhOgyop2LlzA=
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.3 h1:MlxF+Pd3OmSudg/b1yZ5lJwoXCEaeedAguodky1PcKI=
|
cloud.google.com/go/auth/oauth2adapt v0.2.3 h1:MlxF+Pd3OmSudg/b1yZ5lJwoXCEaeedAguodky1PcKI=
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX5cuhwU+ffUuXRJE8I=
|
cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX5cuhwU+ffUuXRJE8I=
|
||||||
cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY=
|
cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY=
|
||||||
cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY=
|
cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY=
|
||||||
cloud.google.com/go/iam v1.1.10 h1:ZSAr64oEhQSClwBL670MsJAW5/RLiC6kfw3Bqmd5ZDI=
|
cloud.google.com/go/iam v1.1.12 h1:JixGLimRrNGcxvJEQ8+clfLxPlbeZA6MuRJ+qJNQ5Xw=
|
||||||
cloud.google.com/go/iam v1.1.10/go.mod h1:iEgMq62sg8zx446GCaijmA2Miwg5o3UbO+nI47WHJps=
|
cloud.google.com/go/iam v1.1.12/go.mod h1:9LDX8J7dN5YRyzVHxwQzrQs9opFFqn0Mxs9nAeB+Hhg=
|
||||||
cloud.google.com/go/kms v1.18.2 h1:EGgD0B9k9tOOkbPhYW1PHo2W0teamAUYMOUIcDRMfPk=
|
cloud.google.com/go/kms v1.18.4 h1:dYN3OCsQ6wJLLtOnI8DGUwQ5shMusXsWCCC+s09ATsk=
|
||||||
cloud.google.com/go/kms v1.18.2/go.mod h1:YFz1LYrnGsXARuRePL729oINmN5J/5e7nYijgvfiIeY=
|
cloud.google.com/go/kms v1.18.4/go.mod h1:SG1bgQ3UWW6/KdPo9uuJnzELXY5YTTMJtDYvajiQ22g=
|
||||||
cloud.google.com/go/longrunning v0.5.9 h1:haH9pAuXdPAMqHvzX0zlWQigXT7B0+CL4/2nXXdBo5k=
|
cloud.google.com/go/longrunning v0.5.11 h1:Havn1kGjz3whCfoD8dxMLP73Ph5w+ODyZB9RUsDxtGk=
|
||||||
cloud.google.com/go/longrunning v0.5.9/go.mod h1:HD+0l9/OOW0za6UWdKJtXoFAX/BGg/3Wj8p10NeWF7c=
|
cloud.google.com/go/longrunning v0.5.11/go.mod h1:rDn7//lmlfWV1Dx6IB4RatCPenTwwmqXuiP0/RgoEO4=
|
||||||
cuelabs.dev/go/oci/ociregistry v0.0.0-20240404174027-a39bec0462d2 h1:BnG6pr9TTr6CYlrJznYUDj6V7xldD1W+1iXPum0wT/w=
|
cuelabs.dev/go/oci/ociregistry v0.0.0-20240404174027-a39bec0462d2 h1:BnG6pr9TTr6CYlrJznYUDj6V7xldD1W+1iXPum0wT/w=
|
||||||
cuelabs.dev/go/oci/ociregistry v0.0.0-20240404174027-a39bec0462d2/go.mod h1:pK23AUVXuNzzTpfMCA06sxZGeVQ/75FdVtW249de9Uo=
|
cuelabs.dev/go/oci/ociregistry v0.0.0-20240404174027-a39bec0462d2/go.mod h1:pK23AUVXuNzzTpfMCA06sxZGeVQ/75FdVtW249de9Uo=
|
||||||
cuelang.org/go v0.9.2 h1:pfNiry2PdRBr02G/aKm5k2vhzmqbAOoaB4WurmEbWvs=
|
cuelang.org/go v0.9.2 h1:pfNiry2PdRBr02G/aKm5k2vhzmqbAOoaB4WurmEbWvs=
|
||||||
@@ -353,8 +353,8 @@ github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17
|
|||||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||||
github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o=
|
github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM=
|
||||||
github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
|
github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA=
|
||||||
github.com/google/tink/go v1.7.0 h1:6Eox8zONGebBFcCBqkVmt60LaWZa6xg1cl/DwAh/J1w=
|
github.com/google/tink/go v1.7.0 h1:6Eox8zONGebBFcCBqkVmt60LaWZa6xg1cl/DwAh/J1w=
|
||||||
github.com/google/tink/go v1.7.0/go.mod h1:GAUOd+QE3pgj9q8VKIGTCP33c/B7eb4NhxLcgTJZStM=
|
github.com/google/tink/go v1.7.0/go.mod h1:GAUOd+QE3pgj9q8VKIGTCP33c/B7eb4NhxLcgTJZStM=
|
||||||
github.com/google/trillian v1.6.0 h1:jMBeDBIkINFvS2n6oV5maDqfRlxREAc6CW9QYWQ0qT4=
|
github.com/google/trillian v1.6.0 h1:jMBeDBIkINFvS2n6oV5maDqfRlxREAc6CW9QYWQ0qT4=
|
||||||
@@ -364,8 +364,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
|||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs=
|
github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs=
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
|
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
|
||||||
github.com/googleapis/gax-go/v2 v2.12.5 h1:8gw9KZK8TiVKB6q3zHY3SBzLnrGp6HQjyfYBYGmXdxA=
|
github.com/googleapis/gax-go/v2 v2.13.0 h1:yitjD5f7jQHhyDsnhKEBU52NdvvdSeGzlAnDPT0hH1s=
|
||||||
github.com/googleapis/gax-go/v2 v2.12.5/go.mod h1:BUDKcWo+RaKq5SC9vVYL0wLADa3VcfswbOMMRmB9H3E=
|
github.com/googleapis/gax-go/v2 v2.13.0/go.mod h1:Z/fvTZXF8/uw7Xu5GuslPw+bplx6SS338j1Is2S+B7A=
|
||||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
||||||
@@ -493,8 +493,8 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
|
|||||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||||
github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw=
|
github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw=
|
||||||
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
|
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
|
||||||
github.com/open-policy-agent/opa v0.67.0 h1:FOdsO9yNhfmrh+72oVK7ImWmzruG+VSpfbr5IBqEWVs=
|
github.com/open-policy-agent/opa v0.67.1 h1:rzy26J6g1X+CKknAcx0Vfbt41KqjuSzx4E0A8DAZf3E=
|
||||||
github.com/open-policy-agent/opa v0.67.0/go.mod h1:aqKlHc8E2VAAylYE9x09zJYr/fYzGX+JKne89UGqFzk=
|
github.com/open-policy-agent/opa v0.67.1/go.mod h1:aqKlHc8E2VAAylYE9x09zJYr/fYzGX+JKne89UGqFzk=
|
||||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||||
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
|
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
|
||||||
@@ -805,19 +805,19 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T
|
|||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/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=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||||
google.golang.org/api v0.189.0 h1:equMo30LypAkdkLMBqfeIqtyAnlyig1JSZArl4XPwdI=
|
google.golang.org/api v0.190.0 h1:ASM+IhLY1zljNdLu19W1jTmU6A+gMk6M46Wlur61s+Q=
|
||||||
google.golang.org/api v0.189.0/go.mod h1:FLWGJKb0hb+pU2j+rJqwbnsF+ym+fQs73rbJ+KAUgy8=
|
google.golang.org/api v0.190.0/go.mod h1:QIr6I9iedBLnfqoD6L6Vze1UvS5Hzj5r2aUBOaZnLHo=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
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/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-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-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||||
google.golang.org/genproto v0.0.0-20240722135656-d784300faade h1:lKFsS7wpngDgSCeFn7MoLy+wBDQZ1UQIJD4UNM1Qvkg=
|
google.golang.org/genproto v0.0.0-20240730163845-b1a4ccb954bf h1:OqdXDEakZCVtDiZTjcxfwbHPCT11ycCEsTKesBVKvyY=
|
||||||
google.golang.org/genproto v0.0.0-20240722135656-d784300faade/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY=
|
google.golang.org/genproto v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:mCr1K1c8kX+1iSBREvU3Juo11CB+QOEWxbRS01wWl5M=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0=
|
google.golang.org/genproto/googleapis/api v0.0.0-20240725223205-93522f1f2a9f h1:b1Ln/PG8orm0SsBbHZWke8dDp2lrCD4jSmfglFpTZbk=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094/go.mod h1:fJ/e3If/Q67Mj99hin0hMhiNyCRmt6BQ2aWIJshUSJw=
|
google.golang.org/genproto/googleapis/api v0.0.0-20240725223205-93522f1f2a9f/go.mod h1:AHT0dDg3SoMOgZGnZk29b5xTbPHMoEC8qthmBLJCpys=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240722135656-d784300faade h1:oCRSWfwGXQsqlVdErcyTt4A93Y8fo0/9D4b1gnI++qo=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf h1:liao9UHurZLtiEwBgT9LMOnKYsHze6eA6w1KQCMVN2Q=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240722135656-d784300faade/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -45,6 +46,14 @@ func CreateTempDir(t *testing.T, dir, pattern string) string {
|
|||||||
return tempDir
|
return tempDir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetMockSigner(_ context.Context) (dsse.SignerVerifier, error) {
|
||||||
|
priv, err := os.ReadFile(filepath.Join("..", "..", "test", "testdata", "test-signing-key.pem"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return signerverifier.LoadKeyPair(priv)
|
||||||
|
}
|
||||||
|
|
||||||
func Setup(t *testing.T) (context.Context, dsse.SignerVerifier) {
|
func Setup(t *testing.T) (context.Context, dsse.SignerVerifier) {
|
||||||
var tl tlog.TL
|
var tl tlog.TL
|
||||||
if UseMockTL {
|
if UseMockTL {
|
||||||
|
|||||||
@@ -15,9 +15,6 @@ import (
|
|||||||
"github.com/docker/attest/pkg/policy"
|
"github.com/docker/attest/pkg/policy"
|
||||||
"github.com/google/go-containerregistry/pkg/registry"
|
"github.com/google/go-containerregistry/pkg/registry"
|
||||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||||
"github.com/google/go-containerregistry/pkg/v1/empty"
|
|
||||||
"github.com/google/go-containerregistry/pkg/v1/layout"
|
|
||||||
"github.com/google/go-containerregistry/pkg/v1/mutate"
|
|
||||||
"github.com/google/go-containerregistry/pkg/v1/static"
|
"github.com/google/go-containerregistry/pkg/v1/static"
|
||||||
"github.com/google/go-containerregistry/pkg/v1/types"
|
"github.com/google/go-containerregistry/pkg/v1/types"
|
||||||
intoto "github.com/in-toto/in-toto-golang/in_toto"
|
intoto "github.com/in-toto/in-toto-golang/in_toto"
|
||||||
@@ -66,21 +63,11 @@ func TestSignVerifyOCILayout(t *testing.T) {
|
|||||||
signedIndex := attIdx.Index
|
signedIndex := attIdx.Index
|
||||||
signedIndex, err = attestation.UpdateIndexImages(signedIndex, signedManifests, attestation.WithReplacedLayers(tc.replace))
|
signedIndex, err = attestation.UpdateIndexImages(signedIndex, signedManifests, attestation.WithReplacedLayers(tc.replace))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
// output signed attestations
|
spec, err := oci.ParseImageSpec(oci.LocalPrefix + outputLayout)
|
||||||
idx := v1.ImageIndex(empty.Index)
|
|
||||||
idx = mutate.AppendManifests(idx, mutate.IndexAddendum{
|
|
||||||
Add: signedIndex,
|
|
||||||
Descriptor: v1.Descriptor{
|
|
||||||
Annotations: map[string]string{
|
|
||||||
oci.OCIReferenceTarget: attIdx.Name,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
_, err = layout.Write(outputLayout, idx)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
src, err := oci.ParseImageSpec("oci://" + outputLayout)
|
err = mirror.SaveIndex([]*oci.ImageSpec{spec}, signedIndex, attIdx.Name)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
policy, err := Verify(ctx, src, policyOpts)
|
policy, err := Verify(ctx, spec, policyOpts)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equalf(t, OutcomeSuccess, policy.Outcome, "Policy should have been found")
|
assert.Equalf(t, OutcomeSuccess, policy.Outcome, "Policy should have been found")
|
||||||
|
|
||||||
|
|||||||
@@ -10,12 +10,10 @@ import (
|
|||||||
|
|
||||||
"github.com/docker/attest/internal/test"
|
"github.com/docker/attest/internal/test"
|
||||||
"github.com/docker/attest/pkg/attestation"
|
"github.com/docker/attest/pkg/attestation"
|
||||||
|
"github.com/docker/attest/pkg/config"
|
||||||
|
"github.com/docker/attest/pkg/mirror"
|
||||||
"github.com/docker/attest/pkg/oci"
|
"github.com/docker/attest/pkg/oci"
|
||||||
"github.com/docker/attest/pkg/policy"
|
"github.com/docker/attest/pkg/policy"
|
||||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
|
||||||
"github.com/google/go-containerregistry/pkg/v1/empty"
|
|
||||||
"github.com/google/go-containerregistry/pkg/v1/layout"
|
|
||||||
"github.com/google/go-containerregistry/pkg/v1/mutate"
|
|
||||||
intoto "github.com/in-toto/in-toto-golang/in_toto"
|
intoto "github.com/in-toto/in-toto-golang/in_toto"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
@@ -34,7 +32,7 @@ func TestVerifyAttestations(t *testing.T) {
|
|||||||
env := new(attestation.Envelope)
|
env := new(attestation.Envelope)
|
||||||
err = json.Unmarshal(ex, env)
|
err = json.Unmarshal(ex, env)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
resolver := &test.MockResolver{
|
resolver := &oci.MockResolver{
|
||||||
Envs: []*attestation.Envelope{env},
|
Envs: []*attestation.Envelope{env},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,25 +82,17 @@ func TestVSA(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// output signed attestations
|
// output signed attestations
|
||||||
idx := v1.ImageIndex(empty.Index)
|
spec, err := oci.ParseImageSpec(oci.LocalPrefix+outputLayout, oci.WithPlatform(LinuxAMD64))
|
||||||
idx = mutate.AppendManifests(idx, mutate.IndexAddendum{
|
require.NoError(t, err)
|
||||||
Add: signedIndex,
|
err = mirror.SaveIndex([]*oci.ImageSpec{spec}, signedIndex, attIdx.Name)
|
||||||
Descriptor: v1.Descriptor{
|
|
||||||
Annotations: map[string]string{
|
|
||||||
oci.OCIReferenceTarget: attIdx.Name,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
_, err = layout.Write(outputLayout, idx)
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// mocked vsa query should pass
|
// mocked vsa query should pass
|
||||||
policyOpts := &policy.Options{
|
policyOpts := &policy.Options{
|
||||||
LocalPolicyDir: PassPolicyDir,
|
LocalPolicyDir: PassPolicyDir,
|
||||||
|
AttestationStyle: config.AttestationStyleAttached,
|
||||||
}
|
}
|
||||||
src, err := oci.ParseImageSpec("oci://"+outputLayout, oci.WithPlatform(LinuxAMD64))
|
results, err := Verify(ctx, spec, policyOpts)
|
||||||
require.NoError(t, err)
|
|
||||||
results, err := Verify(ctx, src, policyOpts)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, OutcomeSuccess, results.Outcome)
|
assert.Equal(t, OutcomeSuccess, results.Outcome)
|
||||||
assert.Empty(t, results.Violations)
|
assert.Empty(t, results.Violations)
|
||||||
@@ -142,25 +132,17 @@ func TestVerificationFailure(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// output signed attestations
|
// output signed attestations
|
||||||
idx := v1.ImageIndex(empty.Index)
|
spec, err := oci.ParseImageSpec(oci.LocalPrefix+outputLayout, oci.WithPlatform(LinuxAMD64))
|
||||||
idx = mutate.AppendManifests(idx, mutate.IndexAddendum{
|
require.NoError(t, err)
|
||||||
Add: signedIndex,
|
err = mirror.SaveIndex([]*oci.ImageSpec{spec}, signedIndex, attIdx.Name)
|
||||||
Descriptor: v1.Descriptor{
|
|
||||||
Annotations: map[string]string{
|
|
||||||
oci.OCIReferenceTarget: attIdx.Name,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
_, err = layout.Write(outputLayout, idx)
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// mocked vsa query should fail
|
// mocked vsa query should fail
|
||||||
policyOpts := &policy.Options{
|
policyOpts := &policy.Options{
|
||||||
LocalPolicyDir: FailPolicyDir,
|
LocalPolicyDir: FailPolicyDir,
|
||||||
|
AttestationStyle: config.AttestationStyleAttached,
|
||||||
}
|
}
|
||||||
src, err := oci.ParseImageSpec("oci://"+outputLayout, oci.WithPlatform(LinuxAMD64))
|
results, err := Verify(ctx, spec, policyOpts)
|
||||||
require.NoError(t, err)
|
|
||||||
results, err := Verify(ctx, src, policyOpts)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, OutcomeFailure, results.Outcome)
|
assert.Equal(t, OutcomeFailure, results.Outcome)
|
||||||
assert.Len(t, results.Violations, 1)
|
assert.Len(t, results.Violations, 1)
|
||||||
@@ -224,24 +206,15 @@ func TestSignVerify(t *testing.T) {
|
|||||||
imageName = attIdx.Name
|
imageName = attIdx.Name
|
||||||
}
|
}
|
||||||
// output signed attestations
|
// output signed attestations
|
||||||
idx := v1.ImageIndex(empty.Index)
|
spec, err := oci.ParseImageSpec(oci.LocalPrefix+outputLayout, oci.WithPlatform(LinuxAMD64))
|
||||||
idx = mutate.AppendManifests(idx, mutate.IndexAddendum{
|
require.NoError(t, err)
|
||||||
Add: signedIndex,
|
err = mirror.SaveIndex([]*oci.ImageSpec{spec}, signedIndex, imageName)
|
||||||
Descriptor: v1.Descriptor{
|
require.NoError(t, err)
|
||||||
Annotations: map[string]string{
|
|
||||||
oci.OCIReferenceTarget: imageName,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
_, err = layout.Write(outputLayout, idx)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
policyOpts := &policy.Options{
|
policyOpts := &policy.Options{
|
||||||
LocalPolicyDir: tc.policyDir,
|
LocalPolicyDir: tc.policyDir,
|
||||||
}
|
}
|
||||||
src, err := oci.ParseImageSpec("oci://"+outputLayout, oci.WithPlatform(LinuxAMD64))
|
results, err := Verify(ctx, spec, policyOpts)
|
||||||
require.NoError(t, err)
|
|
||||||
results, err := Verify(ctx, src, policyOpts)
|
|
||||||
if tc.expectError {
|
if tc.expectError {
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ type Manifest struct {
|
|||||||
|
|
||||||
// accumulated during signing
|
// accumulated during signing
|
||||||
SignedLayers []*Layer
|
SignedLayers []*Layer
|
||||||
// details of subect image
|
// details of subject image
|
||||||
SubjectName string
|
SubjectName string
|
||||||
SubjectDescriptor *v1.Descriptor
|
SubjectDescriptor *v1.Descriptor
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ func SaveImage(output *oci.ImageSpec, image v1.Image, imageName string) error {
|
|||||||
|
|
||||||
func SaveReferrers(manifest *attestation.Manifest, outputs []*oci.ImageSpec) error {
|
func SaveReferrers(manifest *attestation.Manifest, outputs []*oci.ImageSpec) error {
|
||||||
for _, output := range outputs {
|
for _, output := range outputs {
|
||||||
|
// OCI layout output for referrers not supported
|
||||||
if output.Type == oci.OCI {
|
if output.Type == oci.OCI {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -147,10 +148,10 @@ func SaveReferrers(manifest *attestation.Manifest, outputs []*oci.ImageSpec) err
|
|||||||
return fmt.Errorf("failed to build image: %w", err)
|
return fmt.Errorf("failed to build image: %w", err)
|
||||||
}
|
}
|
||||||
for _, image := range images {
|
for _, image := range images {
|
||||||
err = SaveImage(attOut, image, "")
|
err := PushImageToRegistry(image, attOut.Identifier)
|
||||||
}
|
if err != nil {
|
||||||
if err != nil {
|
return fmt.Errorf("failed to push image: %w", err)
|
||||||
return fmt.Errorf("failed to push image: %w", err)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ func TestSavingIndex(t *testing.T) {
|
|||||||
err = SaveIndex(output, attIdx.Index, indexName)
|
err = SaveIndex(output, attIdx.Index, indexName)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
ociOutput, err := oci.ParseImageSpecs("oci://" + outputLayout)
|
ociOutput, err := oci.ParseImageSpecs(oci.LocalPrefix + outputLayout)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
err = SaveIndex(ociOutput, attIdx.Index, indexName)
|
err = SaveIndex(ociOutput, attIdx.Index, indexName)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -59,7 +59,7 @@ func TestSavingImage(t *testing.T) {
|
|||||||
err = SaveImage(output, img, indexName)
|
err = SaveImage(output, img, indexName)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
ociOutput, err := oci.ParseImageSpec("oci://" + outputLayout)
|
ociOutput, err := oci.ParseImageSpec(oci.LocalPrefix + outputLayout)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
err = SaveImage(ociOutput, img, indexName)
|
err = SaveImage(ociOutput, img, indexName)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -96,9 +96,9 @@ func TestSavingReferrers(t *testing.T) {
|
|||||||
err = SaveReferrers(manifest, output)
|
err = SaveReferrers(manifest, output)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
reg := &test.MockRegistryResolver{
|
reg := &oci.MockRegistryResolver{
|
||||||
Subject: subject,
|
Subject: subject,
|
||||||
MockResolver: &test.MockResolver{},
|
MockResolver: &oci.MockResolver{},
|
||||||
ImageNameStr: indexName,
|
ImageNameStr: indexName,
|
||||||
}
|
}
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|||||||
@@ -95,7 +95,6 @@ func attestationManifestFromOCILayout(path string, platform *v1.Platform) (*atte
|
|||||||
}
|
}
|
||||||
|
|
||||||
idxDescriptor := idxm.Manifests[0]
|
idxDescriptor := idxm.Manifests[0]
|
||||||
name := idxDescriptor.Annotations["org.opencontainers.image.ref.name"]
|
|
||||||
idxDigest := idxDescriptor.Digest
|
idxDigest := idxDescriptor.Digest
|
||||||
|
|
||||||
mfs, err := idx.ImageIndex(idxDigest)
|
mfs, err := idx.ImageIndex(idxDigest)
|
||||||
@@ -109,11 +108,16 @@ func attestationManifestFromOCILayout(path string, platform *v1.Platform) (*atte
|
|||||||
var subjectDescriptor *v1.Descriptor
|
var subjectDescriptor *v1.Descriptor
|
||||||
for i := range mfs2.Manifests {
|
for i := range mfs2.Manifests {
|
||||||
manifest := &mfs2.Manifests[i]
|
manifest := &mfs2.Manifests[i]
|
||||||
if manifest.Platform.Equals(*platform) {
|
if manifest.Platform != nil {
|
||||||
subjectDescriptor = manifest
|
if manifest.Platform.Equals(*platform) {
|
||||||
break
|
subjectDescriptor = manifest
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if subjectDescriptor == nil {
|
||||||
|
return nil, fmt.Errorf("platform not found in index")
|
||||||
|
}
|
||||||
for i := range mfs2.Manifests {
|
for i := range mfs2.Manifests {
|
||||||
mf := &mfs2.Manifests[i]
|
mf := &mfs2.Manifests[i]
|
||||||
if mf.Annotations[att.DockerReferenceType] != attestation.AttestationManifestType {
|
if mf.Annotations[att.DockerReferenceType] != attestation.AttestationManifestType {
|
||||||
@@ -135,7 +139,7 @@ func attestationManifestFromOCILayout(path string, platform *v1.Platform) (*atte
|
|||||||
attest := &attestation.Manifest{
|
attest := &attestation.Manifest{
|
||||||
OriginalLayers: layers,
|
OriginalLayers: layers,
|
||||||
OriginalDescriptor: mf,
|
OriginalDescriptor: mf,
|
||||||
SubjectName: name,
|
SubjectName: idxDescriptor.Annotations["org.opencontainers.image.ref.name"],
|
||||||
SubjectDescriptor: subjectDescriptor,
|
SubjectDescriptor: subjectDescriptor,
|
||||||
}
|
}
|
||||||
return attest, nil
|
return attest, nil
|
||||||
|
|||||||
69
pkg/oci/layout_test.go
Normal file
69
pkg/oci/layout_test.go
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
package oci_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/docker/attest/internal/test"
|
||||||
|
"github.com/docker/attest/pkg/attest"
|
||||||
|
"github.com/docker/attest/pkg/attestation"
|
||||||
|
"github.com/docker/attest/pkg/mirror"
|
||||||
|
"github.com/docker/attest/pkg/oci"
|
||||||
|
"github.com/docker/attest/pkg/policy"
|
||||||
|
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAttestationFromOCILayout(t *testing.T) {
|
||||||
|
ctx, signer := test.Setup(t)
|
||||||
|
outputLayout := test.CreateTempDir(t, "", "attest-oci-layout")
|
||||||
|
|
||||||
|
invalidPlatform := &v1.Platform{
|
||||||
|
Architecture: "invalid",
|
||||||
|
OS: "invalid",
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := &attestation.SigningOptions{}
|
||||||
|
attIdx, err := oci.IndexFromPath(oci.UnsignedTestImage)
|
||||||
|
require.NoError(t, err)
|
||||||
|
signedManifests, err := attest.SignStatements(ctx, attIdx.Index, signer, opts)
|
||||||
|
require.NoError(t, err)
|
||||||
|
signedIndex := attIdx.Index
|
||||||
|
signedIndex, err = attestation.UpdateIndexImages(signedIndex, signedManifests)
|
||||||
|
require.NoError(t, err)
|
||||||
|
spec, err := oci.ParseImageSpec(oci.LocalPrefix + outputLayout)
|
||||||
|
require.NoError(t, err)
|
||||||
|
err = mirror.SaveIndex([]*oci.ImageSpec{spec}, signedIndex, outputLayout)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
platform *v1.Platform
|
||||||
|
errorStr string
|
||||||
|
}{
|
||||||
|
{name: "nominal", platform: spec.Platform},
|
||||||
|
{name: "invalid platform", platform: invalidPlatform, errorStr: "platform not found in index"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
spec := &oci.ImageSpec{
|
||||||
|
Type: oci.OCI,
|
||||||
|
Identifier: outputLayout,
|
||||||
|
Platform: tc.platform,
|
||||||
|
}
|
||||||
|
resolver, err := policy.CreateImageDetailsResolver(spec)
|
||||||
|
if tc.errorStr != "" {
|
||||||
|
require.Error(t, err)
|
||||||
|
assert.Contains(t, err.Error(), tc.errorStr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
require.NoError(t, err)
|
||||||
|
desc, err := resolver.ImageDescriptor(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
digest := desc.Digest.String()
|
||||||
|
assert.True(t, strings.Contains(digest, "sha256:"))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,15 +1,10 @@
|
|||||||
package test
|
package oci
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/docker/attest/pkg/attestation"
|
"github.com/docker/attest/pkg/attestation"
|
||||||
"github.com/docker/attest/pkg/oci"
|
|
||||||
"github.com/docker/attest/pkg/signerverifier"
|
|
||||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||||
"github.com/secure-systems-lab/go-securesystemslib/dsse"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type MockResolver struct {
|
type MockResolver struct {
|
||||||
@@ -37,7 +32,7 @@ func (r MockResolver) ImageDescriptor(_ context.Context) (*v1.Descriptor, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r MockResolver) ImagePlatform(_ context.Context) (*v1.Platform, error) {
|
func (r MockResolver) ImagePlatform(_ context.Context) (*v1.Platform, error) {
|
||||||
return oci.ParsePlatform("linux/amd64")
|
return ParsePlatform("linux/amd64")
|
||||||
}
|
}
|
||||||
|
|
||||||
type MockRegistryResolver struct {
|
type MockRegistryResolver struct {
|
||||||
@@ -53,11 +48,3 @@ func (r *MockRegistryResolver) ImageDescriptor(_ context.Context) (*v1.Descripto
|
|||||||
func (r *MockRegistryResolver) ImageName(_ context.Context) (string, error) {
|
func (r *MockRegistryResolver) ImageName(_ context.Context) (string, error) {
|
||||||
return r.ImageNameStr, nil
|
return r.ImageNameStr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetMockSigner(_ context.Context) (dsse.SignerVerifier, error) {
|
|
||||||
priv, err := os.ReadFile(filepath.Join("..", "..", "test", "testdata", "test-signing-key.pem"))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return signerverifier.LoadKeyPair(priv)
|
|
||||||
}
|
|
||||||
@@ -95,10 +95,10 @@ func TestWithoutTag(t *testing.T) {
|
|||||||
{name: "image:tag", expected: "index.docker.io/library/image"},
|
{name: "image:tag", expected: "index.docker.io/library/image"},
|
||||||
{name: "image", expected: "index.docker.io/library/image"},
|
{name: "image", expected: "index.docker.io/library/image"},
|
||||||
{name: "image:sha256-digest.att", expected: "index.docker.io/library/image"},
|
{name: "image:sha256-digest.att", expected: "index.docker.io/library/image"},
|
||||||
{name: "docker://image:tag", expected: "docker://index.docker.io/library/image"},
|
{name: RegistryPrefix + "image:tag", expected: RegistryPrefix + "index.docker.io/library/image"},
|
||||||
{name: "image@sha256:166710df254975d4a6c4c407c315951c22753dcaa829e020a3fd5d18fff70dd2", expected: "index.docker.io/library/image"},
|
{name: "image@sha256:166710df254975d4a6c4c407c315951c22753dcaa829e020a3fd5d18fff70dd2", expected: "index.docker.io/library/image"},
|
||||||
{name: "docker://image@sha256:166710df254975d4a6c4c407c315951c22753dcaa829e020a3fd5d18fff70dd2", expected: "docker://index.docker.io/library/image"},
|
{name: RegistryPrefix + "image@sha256:166710df254975d4a6c4c407c315951c22753dcaa829e020a3fd5d18fff70dd2", expected: RegistryPrefix + "index.docker.io/library/image"},
|
||||||
{name: "docker://127.0.0.1:36555/repo:latest", expected: "docker://127.0.0.1:36555/repo"},
|
{name: RegistryPrefix + "127.0.0.1:36555/repo:latest", expected: RegistryPrefix + "127.0.0.1:36555/repo"},
|
||||||
}
|
}
|
||||||
for _, c := range tc {
|
for _, c := range tc {
|
||||||
t.Run(c.name, func(t *testing.T) {
|
t.Run(c.name, func(t *testing.T) {
|
||||||
@@ -116,11 +116,11 @@ func TestReplaceTag(t *testing.T) {
|
|||||||
{name: "image:tag", expected: "index.docker.io/library/image:sha256-digest.att"},
|
{name: "image:tag", expected: "index.docker.io/library/image:sha256-digest.att"},
|
||||||
{name: "image", expected: "index.docker.io/library/image:sha256-digest.att"},
|
{name: "image", expected: "index.docker.io/library/image:sha256-digest.att"},
|
||||||
{name: "image:sha256-digest.att", expected: "index.docker.io/library/image:sha256-digest.att"},
|
{name: "image:sha256-digest.att", expected: "index.docker.io/library/image:sha256-digest.att"},
|
||||||
{name: "docker://image:tag", expected: "docker://index.docker.io/library/image:sha256-digest.att"},
|
{name: RegistryPrefix + "image:tag", expected: RegistryPrefix + "index.docker.io/library/image:sha256-digest.att"},
|
||||||
{name: "image@sha256:166710df254975d4a6c4c407c315951c22753dcaa829e020a3fd5d18fff70dd2", expected: "index.docker.io/library/image:sha256-digest.att"},
|
{name: "image@sha256:166710df254975d4a6c4c407c315951c22753dcaa829e020a3fd5d18fff70dd2", expected: "index.docker.io/library/image:sha256-digest.att"},
|
||||||
{name: "oci://foobar", expected: "oci://foobar"},
|
{name: LocalPrefix + "foobar", expected: LocalPrefix + "foobar"},
|
||||||
{name: "docker://image@sha256:166710df254975d4a6c4c407c315951c22753dcaa829e020a3fd5d18fff70dd2", expected: "docker://index.docker.io/library/image:sha256-digest.att"},
|
{name: RegistryPrefix + "image@sha256:166710df254975d4a6c4c407c315951c22753dcaa829e020a3fd5d18fff70dd2", expected: RegistryPrefix + "index.docker.io/library/image:sha256-digest.att"},
|
||||||
{name: "docker://127.0.0.1:36555/repo:latest", expected: "docker://127.0.0.1:36555/repo:sha256-digest.att"},
|
{name: RegistryPrefix + "127.0.0.1:36555/repo:latest", expected: RegistryPrefix + "127.0.0.1:36555/repo:sha256-digest.att"},
|
||||||
}
|
}
|
||||||
|
|
||||||
digest := v1.Hash{
|
digest := v1.Hash{
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package oci
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/attest/pkg/attestation"
|
"github.com/docker/attest/pkg/attestation"
|
||||||
att "github.com/docker/attest/pkg/attestation"
|
att "github.com/docker/attest/pkg/attestation"
|
||||||
@@ -58,7 +59,7 @@ func (r *ReferrersResolver) resolveAttestations(ctx context.Context, predicateTy
|
|||||||
}
|
}
|
||||||
var referrersSubjectRef name.Digest
|
var referrersSubjectRef name.Digest
|
||||||
if r.referrersRepo != "" {
|
if r.referrersRepo != "" {
|
||||||
referrersSubjectRef, err = name.NewDigest(fmt.Sprintf("%s@%s", r.referrersRepo, subjectDigest))
|
referrersSubjectRef, err = name.NewDigest(fmt.Sprintf("%s@%s", strings.TrimPrefix(r.referrersRepo, RegistryPrefix), subjectDigest))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create referrers reference: %w", err)
|
return nil, fmt.Errorf("failed to create referrers reference: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -219,19 +219,20 @@ func CreateImageDetailsResolver(imageSource *oci.ImageSpec) (oci.ImageDetailsRes
|
|||||||
}
|
}
|
||||||
|
|
||||||
func CreateAttestationResolver(resolver oci.ImageDetailsResolver, mapping *config.PolicyMapping) (oci.AttestationResolver, error) {
|
func CreateAttestationResolver(resolver oci.ImageDetailsResolver, mapping *config.PolicyMapping) (oci.AttestationResolver, error) {
|
||||||
switch resolver := resolver.(type) {
|
if mapping.Attestations != nil {
|
||||||
case *oci.RegistryImageDetailsResolver:
|
if mapping.Attestations.Style == config.AttestationStyleAttached {
|
||||||
if mapping.Attestations != nil && mapping.Attestations.Style == config.AttestationStyleAttached {
|
switch resolver := resolver.(type) {
|
||||||
return oci.NewRegistryAttestationResolver(resolver)
|
case *oci.RegistryImageDetailsResolver:
|
||||||
} else {
|
return oci.NewRegistryAttestationResolver(resolver)
|
||||||
if mapping.Attestations != nil && mapping.Attestations.Repo != "" {
|
case *oci.LayoutResolver:
|
||||||
return oci.NewReferrersAttestationResolver(resolver, oci.WithReferrersRepo(mapping.Attestations.Repo))
|
return resolver, nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unsupported image details resolver type: %T", resolver)
|
||||||
}
|
}
|
||||||
return oci.NewReferrersAttestationResolver(resolver)
|
|
||||||
}
|
}
|
||||||
case *oci.LayoutResolver:
|
if mapping.Attestations.Repo != "" {
|
||||||
return resolver, nil
|
return oci.NewReferrersAttestationResolver(resolver, oci.WithReferrersRepo(mapping.Attestations.Repo))
|
||||||
default:
|
}
|
||||||
return nil, fmt.Errorf("unsupported image details resolver type: %T", resolver)
|
|
||||||
}
|
}
|
||||||
|
return oci.NewReferrersAttestationResolver(resolver)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ func TestRegoEvaluator_Evaluate(t *testing.T) {
|
|||||||
|
|
||||||
re := policy.NewRegoEvaluator(true)
|
re := policy.NewRegoEvaluator(true)
|
||||||
|
|
||||||
defaultResolver := test.MockResolver{
|
defaultResolver := oci.MockResolver{
|
||||||
Envs: []*attestation.Envelope{loadAttestation(t, ExampleAttestation)},
|
Envs: []*attestation.Envelope{loadAttestation(t, ExampleAttestation)},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,3 +115,64 @@ func TestLoadingMappings(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCreateAttestationResolver(t *testing.T) {
|
||||||
|
mockResolver := oci.MockResolver{
|
||||||
|
Envs: []*attestation.Envelope{},
|
||||||
|
}
|
||||||
|
layoutResolver := &oci.LayoutResolver{}
|
||||||
|
registryResolver := &oci.RegistryImageDetailsResolver{}
|
||||||
|
|
||||||
|
nilRepoReferrers := &config.PolicyMapping{
|
||||||
|
Attestations: &config.AttestationConfig{
|
||||||
|
Style: config.AttestationStyleReferrers,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
referrers := &config.PolicyMapping{
|
||||||
|
Attestations: &config.AttestationConfig{
|
||||||
|
Repo: "localhost:5000/repo",
|
||||||
|
Style: config.AttestationStyleReferrers,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
attached := &config.PolicyMapping{
|
||||||
|
Attestations: &config.AttestationConfig{
|
||||||
|
Style: config.AttestationStyleAttached,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
resolver oci.ImageDetailsResolver
|
||||||
|
mapping *config.PolicyMapping
|
||||||
|
errorStr string
|
||||||
|
}{
|
||||||
|
{name: "referrers", resolver: layoutResolver, mapping: referrers},
|
||||||
|
{name: "referrers (no mapped repo)", resolver: layoutResolver, mapping: nilRepoReferrers},
|
||||||
|
{name: "referrers (no mapping)", resolver: layoutResolver, mapping: &config.PolicyMapping{Attestations: nil}},
|
||||||
|
{name: "attached (registry)", resolver: registryResolver, mapping: attached},
|
||||||
|
{name: "attached (layout)", resolver: layoutResolver, mapping: attached},
|
||||||
|
{name: "attached (unsupported)", resolver: mockResolver, mapping: attached, errorStr: "unsupported image details resolver type"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
resolver, err := policy.CreateAttestationResolver(tc.resolver, tc.mapping)
|
||||||
|
if tc.errorStr == "" {
|
||||||
|
require.NoError(t, err)
|
||||||
|
} else {
|
||||||
|
assert.Contains(t, err.Error(), tc.errorStr)
|
||||||
|
}
|
||||||
|
if tc.mapping.Attestations == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch resolver.(type) {
|
||||||
|
case *oci.ReferrersResolver:
|
||||||
|
assert.Equal(t, tc.mapping.Attestations.Style, config.AttestationStyleReferrers)
|
||||||
|
case *oci.RegistryResolver:
|
||||||
|
assert.Equal(t, tc.mapping.Attestations.Style, config.AttestationStyleAttached)
|
||||||
|
case *oci.LayoutResolver:
|
||||||
|
assert.Equal(t, tc.mapping.Attestations.Style, config.AttestationStyleAttached)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user