17 Commits

Author SHA1 Message Date
Joel Kamp
79bbc9b55b Merge pull request #198 from docker/dependabot/go_modules/github.com/sigstore/sigstore/pkg/signature/kms/aws-1.8.10
feat(deps): bump github.com/sigstore/sigstore/pkg/signature/kms/aws from 1.8.9 to 1.8.10
2024-10-17 08:31:45 -05:00
Joel Kamp
47669993c6 Merge branch 'main' into dependabot/go_modules/github.com/sigstore/sigstore/pkg/signature/kms/aws-1.8.10 2024-10-17 08:25:14 -05:00
Joel Kamp
7414fb7339 Merge pull request #199 from docker/dependabot/go_modules/github.com/sigstore/sigstore/pkg/signature/kms/gcp-1.8.10
feat(deps): bump github.com/sigstore/sigstore/pkg/signature/kms/gcp from 1.8.9 to 1.8.10
2024-10-17 08:24:47 -05:00
dependabot[bot]
0e1005d0f7 feat(deps): bump github.com/sigstore/sigstore/pkg/signature/kms/aws
Bumps [github.com/sigstore/sigstore/pkg/signature/kms/aws](https://github.com/sigstore/sigstore) from 1.8.9 to 1.8.10.
- [Release notes](https://github.com/sigstore/sigstore/releases)
- [Commits](https://github.com/sigstore/sigstore/compare/v1.8.9...v1.8.10)

---
updated-dependencies:
- dependency-name: github.com/sigstore/sigstore/pkg/signature/kms/aws
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-17 13:18:42 +00:00
dependabot[bot]
94f69c75d2 feat(deps): bump github.com/sigstore/sigstore/pkg/signature/kms/gcp
Bumps [github.com/sigstore/sigstore/pkg/signature/kms/gcp](https://github.com/sigstore/sigstore) from 1.8.9 to 1.8.10.
- [Release notes](https://github.com/sigstore/sigstore/releases)
- [Commits](https://github.com/sigstore/sigstore/compare/v1.8.9...v1.8.10)

---
updated-dependencies:
- dependency-name: github.com/sigstore/sigstore/pkg/signature/kms/gcp
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-17 13:18:39 +00:00
Joel Kamp
b2e8166079 Merge pull request #200 from docker/dependabot/go_modules/github.com/sigstore/sigstore-1.8.10
feat(deps): bump github.com/sigstore/sigstore from 1.8.9 to 1.8.10
2024-10-17 08:16:22 -05:00
Joel Kamp
8c4ee60f50 Merge branch 'main' into dependabot/go_modules/github.com/sigstore/sigstore-1.8.10 2024-10-17 08:12:39 -05:00
mrjoelkamp
9b6234f0ae chore: go mod tidy 2024-10-17 08:12:10 -05:00
Joel Kamp
17b0978b44 Merge pull request #201 from docker/feat--add-verifier-version-to-vsa
feat: add verifier version to vsa
2024-10-17 08:09:17 -05:00
Joel Kamp
7ff20a9328 Merge branch 'main' into feat--add-verifier-version-to-vsa 2024-10-17 08:03:47 -05:00
James Carnegie
273b61ebd6 Merge branch 'main' into dependabot/go_modules/github.com/sigstore/sigstore-1.8.10 2024-10-17 09:36:58 +01:00
dependabot[bot]
eda0b23910 feat(deps): bump github.com/aws/aws-sdk-go-v2/config (#202)
Bumps [github.com/aws/aws-sdk-go-v2/config](https://github.com/aws/aws-sdk-go-v2) from 1.27.43 to 1.28.0.
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/config/v1.27.43...v1.28.0)

---
updated-dependencies:
- dependency-name: github.com/aws/aws-sdk-go-v2/config
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-17 09:36:43 +01:00
mrjoelkamp
4a82bb9981 feat: add version checker test 2024-10-16 15:18:34 -05:00
mrjoelkamp
84c0b116a7 feat: add verifier version to vsa 2024-10-16 12:01:31 -05:00
James Carnegie
16f65fefeb Merge branch 'main' into dependabot/go_modules/github.com/sigstore/sigstore-1.8.10 2024-10-16 10:13:44 +01:00
dependabot[bot]
e39a4ea9f3 feat(deps): bump google.golang.org/api from 0.200.0 to 0.201.0 (#197)
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.200.0 to 0.201.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.200.0...v0.201.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-16 10:13:11 +01:00
dependabot[bot]
2e4f8f79bd feat(deps): bump github.com/sigstore/sigstore from 1.8.9 to 1.8.10
Bumps [github.com/sigstore/sigstore](https://github.com/sigstore/sigstore) from 1.8.9 to 1.8.10.
- [Release notes](https://github.com/sigstore/sigstore/releases)
- [Commits](https://github.com/sigstore/sigstore/compare/v1.8.9...v1.8.10)

---
updated-dependencies:
- dependency-name: github.com/sigstore/sigstore
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-16 09:03:50 +00:00
9 changed files with 153 additions and 39 deletions

View File

@@ -3,6 +3,7 @@ package attestation
import (
"fmt"
"github.com/docker/attest/version"
intoto "github.com/in-toto/in-toto-golang/in_toto"
"github.com/package-url/packageurl-go"
)
@@ -22,9 +23,12 @@ type VSAPredicate struct {
}
type VSAVerifier struct {
ID string `json:"id"`
ID string `json:"id"`
Version VerifierVersion `json:"version"`
}
type VerifierVersion map[string]string
type VSAPolicy struct {
URI string `json:"uri,omitempty"`
Digest map[string]string `json:"digest"`
@@ -44,3 +48,16 @@ func ToVSAResourceURI(sub intoto.Subject) (string, error) {
purl.Qualifiers = packageurl.QualifiersFromMap(quals)
return purl.String(), nil
}
func GetVerifierVersion(fetcher version.Fetcher) (VerifierVersion, error) {
attestVersion, err := fetcher.Get()
if err != nil {
return nil, fmt.Errorf("failed to get attest version: %w", err)
}
if attestVersion == nil {
return nil, nil
}
return VerifierVersion{
version.ThisModulePath: attestVersion.String(),
}, nil
}

18
go.mod
View File

@@ -1,12 +1,10 @@
module github.com/docker/attest
go 1.22.7
toolchain go1.22.8
go 1.22.8
require (
github.com/Masterminds/semver/v3 v3.3.0
github.com/aws/aws-sdk-go-v2/config v1.27.43
github.com/aws/aws-sdk-go-v2/config v1.28.0
github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20231024185945-8841054dbdb8
github.com/containerd/containerd/v2 v2.0.0-rc.5
github.com/containerd/platforms v0.2.1
@@ -22,12 +20,12 @@ require (
github.com/secure-systems-lab/go-securesystemslib v0.8.0
github.com/sigstore/cosign/v2 v2.4.1
github.com/sigstore/rekor v1.3.6
github.com/sigstore/sigstore v1.8.9
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.9
github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.9
github.com/sigstore/sigstore v1.8.10
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.10
github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.10
github.com/stretchr/testify v1.9.0
github.com/theupdateframework/go-tuf/v2 v2.0.2
google.golang.org/api v0.200.0
google.golang.org/api v0.201.0
sigs.k8s.io/yaml v1.4.0
)
@@ -35,7 +33,7 @@ require (
replace github.com/google/go-containerregistry => github.com/docker/go-containerregistry v0.0.0-20240808132857-c8bfc44af7c8
require (
cloud.google.com/go v0.115.1 // indirect
cloud.google.com/go v0.116.0 // indirect
cloud.google.com/go/auth v0.9.8 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.4 // indirect
cloud.google.com/go/compute/metadata v0.5.2 // indirect
@@ -57,7 +55,7 @@ require (
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.24.1 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2 // indirect
github.com/aws/aws-sdk-go-v2/service/kms v1.35.7 // indirect
github.com/aws/aws-sdk-go-v2/service/kms v1.37.2 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.24.2 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.2 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.32.2 // indirect

28
go.sum
View File

@@ -1,6 +1,6 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.115.1 h1:Jo0SM9cQnSkYfp44+v+NQXHpcHqlnRJk2qxh6yvxxxQ=
cloud.google.com/go v0.115.1/go.mod h1:DuujITeaufu3gL68/lOFIirVNJwQeyf5UXyi+Wbgknc=
cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE=
cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U=
cloud.google.com/go/auth v0.9.8 h1:+CSJ0Gw9iVeSENVCKJoLHhdUykDgXSc4Qn+gu2BRtR8=
cloud.google.com/go/auth v0.9.8/go.mod h1:xxA5AqpDrvS+Gkmo9RqrGGRh6WSNKKOXhY3zNOr38tI=
cloud.google.com/go/auth/oauth2adapt v0.2.4 h1:0GWE/FUsXhf6C+jAkWgYm7X9tK8cuEIfy19DBn6B6bY=
@@ -101,8 +101,8 @@ github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU
github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
github.com/aws/aws-sdk-go-v2 v1.32.2 h1:AkNLZEyYMLnx/Q/mSKkcMqwNFXMAvFto9bNsHqcTduI=
github.com/aws/aws-sdk-go-v2 v1.32.2/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo=
github.com/aws/aws-sdk-go-v2/config v1.27.43 h1:p33fDDihFC390dhhuv8nOmX419wjOSDQRb+USt20RrU=
github.com/aws/aws-sdk-go-v2/config v1.27.43/go.mod h1:pYhbtvg1siOOg8h5an77rXle9tVG8T+BWLWAo7cOukc=
github.com/aws/aws-sdk-go-v2/config v1.28.0 h1:FosVYWcqEtWNxHn8gB/Vs6jOlNwSoyOCA/g/sxyySOQ=
github.com/aws/aws-sdk-go-v2/config v1.28.0/go.mod h1:pYhbtvg1siOOg8h5an77rXle9tVG8T+BWLWAo7cOukc=
github.com/aws/aws-sdk-go-v2/credentials v1.17.41 h1:7gXo+Axmp+R4Z+AK8YFQO0ZV3L0gizGINCOWxSLY9W8=
github.com/aws/aws-sdk-go-v2/credentials v1.17.41/go.mod h1:u4Eb8d3394YLubphT4jLEwN1rLNq2wFOlT6OuxFwPzU=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.17 h1:TMH3f/SCAWdNtXXVPPu5D6wrr4G5hI1rAxbcocKfC7Q=
@@ -121,8 +121,8 @@ github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 h1:TToQNkv
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0/go.mod h1:0jp+ltwkf+SwG2fm/PKo8t4y8pJSgOCO4D8Lz3k0aHQ=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2 h1:s7NA1SOw8q/5c0wr8477yOPp0z+uBaXBnLE0XYb0POA=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2/go.mod h1:fnjjWyAW/Pj5HYOxl9LJqWtEwS7W2qgcRLWP+uWbss0=
github.com/aws/aws-sdk-go-v2/service/kms v1.35.7 h1:v0D1LeMkA/X+JHAZWERrr+sUGOt8KrCZKnJA6KszkcE=
github.com/aws/aws-sdk-go-v2/service/kms v1.35.7/go.mod h1:K9lwD0Rsx9+NSaJKsdAdlDK4b2G4KKOEve9PzHxPoMI=
github.com/aws/aws-sdk-go-v2/service/kms v1.37.2 h1:tfBABi5R6aSZlhgTWHxL+opYUDOnIGoNcJLwVYv0jLM=
github.com/aws/aws-sdk-go-v2/service/kms v1.37.2/go.mod h1:dZYFcQwuoh+cLOlFnZItijZptmyDhRIkOKWFO1CfzV8=
github.com/aws/aws-sdk-go-v2/service/sso v1.24.2 h1:bSYXVyUzoTHoKalBmwaZxs97HU9DWWI3ehHSAMa7xOk=
github.com/aws/aws-sdk-go-v2/service/sso v1.24.2/go.mod h1:skMqY7JElusiOUjMJMOv1jJsP7YUg7DrhgqZZWuzu1U=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.2 h1:AhmO1fHINP9vFYUE0LHzCWg/LfUWUF+zFPEcY9QXb7o=
@@ -529,16 +529,16 @@ github.com/sigstore/protobuf-specs v0.3.2 h1:nCVARCN+fHjlNCk3ThNXwrZRqIommIeNKWw
github.com/sigstore/protobuf-specs v0.3.2/go.mod h1:RZ0uOdJR4OB3tLQeAyWoJFbNCBFrPQdcokntde4zRBA=
github.com/sigstore/rekor v1.3.6 h1:QvpMMJVWAp69a3CHzdrLelqEqpTM3ByQRt5B5Kspbi8=
github.com/sigstore/rekor v1.3.6/go.mod h1:JDTSNNMdQ/PxdsS49DJkJ+pRJCO/83nbR5p3aZQteXc=
github.com/sigstore/sigstore v1.8.9 h1:NiUZIVWywgYuVTxXmRoTT4O4QAGiTEKup4N1wdxFadk=
github.com/sigstore/sigstore v1.8.9/go.mod h1:d9ZAbNDs8JJfxJrYmulaTazU3Pwr8uLL9+mii4BNR3w=
github.com/sigstore/sigstore v1.8.10 h1:r4t+TYzJlG9JdFxMy+um9GZhZ2N1hBTyTex0AHEZxFs=
github.com/sigstore/sigstore v1.8.10/go.mod h1:BekjqxS5ZtHNJC4u3Q3Stvfx2eyisbW/lUZzmPU2u4A=
github.com/sigstore/sigstore-go v0.6.1 h1:tGkkv1oDIER+QYU5MrjqlttQOVDWfSkmYwMqkJhB/cg=
github.com/sigstore/sigstore-go v0.6.1/go.mod h1:Xe5GHmUeACRFbomUWzVkf/xYCn8xVifb9DgqJrV2dIw=
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.9 h1:tgpdvjyoEgYFeTBFe4MHvBKsG+J4E7NVtstChIExVT8=
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.9/go.mod h1:wCz6cAZKL/wFumDHX9l8VkVITS2GntrOfs2j/kwH4wo=
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.10 h1:e5GfVngPjGap/N3ODefayt7vKIPS1/v3hWLZ9+4MrN4=
github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.10/go.mod h1:HOr3AdFPKdND2FNl/sUD5ZifPl1OMJvrbf9xIaaWcus=
github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.8 h1:RKk4Z+qMaLORUdT7zntwMqKiYAej1VQlCswg0S7xNSY=
github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.8/go.mod h1:dMJdlBWKHMu2xf0wIKpbo7+QfG+RzVkBB3nHP8EMM5o=
github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.9 h1:liWcl12dfFeQXU0JemQVgdVQx02Fls9UPdrFzVrCWhs=
github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.9/go.mod h1:Ckx62auqPQvNJWRBAboY+/kHs77gy6L33b6UtB/FB5U=
github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.10 h1:Xre51HdjIIaVo5ox5zyL+6h0tkrx7Ke9Neh7fLmmZK0=
github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.10/go.mod h1:VNfdklQDbyGJog8S7apdxiEfmYmCkKyxrsCL9xprkTY=
github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.8 h1:Zte3Oogkd8m+nu2oK3yHtGmN++TZWh2Lm6q2iSprT1M=
github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.8/go.mod h1:j00crVw6ki4/WViXflw0zWgNALrAzZT+GbIK8v7Xlz4=
github.com/sigstore/timestamp-authority v1.2.2 h1:X4qyutnCQqJ0apMewFyx+3t7Tws00JQ/JonBiu3QvLE=
@@ -750,8 +750,8 @@ 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-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
google.golang.org/api v0.200.0 h1:0ytfNWn101is6e9VBoct2wrGDjOi5vn7jw5KtaQgDrU=
google.golang.org/api v0.200.0/go.mod h1:Tc5u9kcbjO7A8SwGlYj4IiVifJU01UqXtEgDMYmBmV8=
google.golang.org/api v0.201.0 h1:+7AD9JNM3tREtawRMu8sOjSbb8VYcYXJG/2eEOmfDu0=
google.golang.org/api v0.201.0/go.mod h1:HVY0FCHVs89xIW9fzf/pBvOEm+OolHa86G/txFezyq4=
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=

View File

@@ -33,13 +33,17 @@ func (e *InvalidVersionError) Error() string {
}
func NewDefaultVersionChecker() *DefaultVersionChecker {
return &DefaultVersionChecker{}
return &DefaultVersionChecker{
VersionFetcher: version.NewGoVersionFetcher(),
}
}
type DefaultVersionChecker struct{}
type DefaultVersionChecker struct {
VersionFetcher version.Fetcher
}
func (vc *DefaultVersionChecker) CheckVersion(client Downloader) error {
attestVersion, err := version.Get()
attestVersion, err := vc.VersionFetcher.Get()
if err != nil {
return fmt.Errorf("failed to get version: %w", err)
}

61
tuf/version_test.go Normal file
View File

@@ -0,0 +1,61 @@
package tuf
import (
"fmt"
"os"
"path/filepath"
"testing"
"github.com/Masterminds/semver/v3"
"github.com/docker/attest/internal/test"
"github.com/docker/attest/version"
"github.com/stretchr/testify/assert"
)
const (
invalidVersion = "0.0.1"
validVersion = "v1.0.0-0"
versionConstraint = ">=v1.0.0-0"
)
func TestDefaultVersionChecker(t *testing.T) {
testDir := test.CreateTempDir(t, "", "tuf_temp")
versionConstraintsPath := filepath.Join(testDir, "version-constraints")
err := os.WriteFile(versionConstraintsPath, []byte(versionConstraint), 0o600)
assert.NoError(t, err)
tufClient := NewMockTufClient(testDir)
expectedError := fmt.Sprintf("%s version %s does not satisfy constraints %s: %s is less than %s", version.ThisModulePath, invalidVersion, versionConstraint, invalidVersion, validVersion)
testCases := []struct {
name string
expectedError string
version string
}{
{name: "version is less than the minimum", expectedError: expectedError, version: "0.0.1"},
{name: "version is equal to the minimum", version: "1.0.0"},
{name: "version is greater than the minimum", version: "1.0.1"},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
checker := NewDefaultVersionChecker()
checker.VersionFetcher = &MockVersionFetcher{version: tc.version}
err := checker.CheckVersion(tufClient)
if tc.expectedError != "" {
assert.Error(t, err)
assert.Equal(t, tc.expectedError, err.Error())
return
}
assert.NoError(t, err)
})
}
}
type MockVersionFetcher struct {
version string
}
func (m *MockVersionFetcher) Get() (*semver.Version, error) {
return semver.NewVersion(m.version)
}

View File

@@ -19,10 +19,11 @@ func Set(ctx context.Context, userAgent string) context.Context {
// Get retrieves the HTTP user agent from the context.
func Get(ctx context.Context) string {
fetcher := version.NewGoVersionFetcher()
if ua, ok := ctx.Value(userAgentKey).(string); ok {
return ua
}
version, err := version.Get()
version, err := fetcher.Get()
if err != nil || version == nil {
return defaultUserAgent
}

View File

@@ -14,6 +14,7 @@ import (
"github.com/docker/attest/oci"
"github.com/docker/attest/policy"
"github.com/docker/attest/tuf"
"github.com/docker/attest/version"
intoto "github.com/in-toto/in-toto-golang/in_toto"
)
@@ -21,6 +22,7 @@ type ImageVerifier struct {
opts *policy.Options
tufClient tuf.Downloader
attestationVerifier attestation.Verifier
versionFetcher version.Fetcher
}
func NewImageVerifier(ctx context.Context, opts *policy.Options) (*ImageVerifier, error) {
@@ -46,6 +48,7 @@ func NewImageVerifier(ctx context.Context, opts *policy.Options) (*ImageVerifier
opts: opts,
tufClient: tufClient,
attestationVerifier: attestationVerifier,
versionFetcher: version.NewGoVersionFetcher(),
}, nil
}
@@ -93,7 +96,7 @@ func (verifier *ImageVerifier) Verify(ctx context.Context, src *oci.ImageSpec) (
return nil, fmt.Errorf("failed to create attestation resolver: %w", err)
}
evaluator := policy.NewRegoEvaluator(verifier.opts.Debug, verifier.attestationVerifier)
result, err = verifyAttestations(ctx, resolver, evaluator, resolvedPolicy, verifier.opts)
result, err = verifier.verifyAttestations(ctx, resolver, evaluator, resolvedPolicy)
if err != nil {
return nil, fmt.Errorf("failed to evaluate policy: %w", err)
}
@@ -141,7 +144,7 @@ func defaultLocalTargetsDir() (string, error) {
return filepath.Join(homeDir, ".docker", "tuf"), nil
}
func toVerificationResult(p *policy.Policy, input *policy.Input, result *policy.Result) (*VerificationResult, error) {
func toVerificationResult(p *policy.Policy, input *policy.Input, result *policy.Result, versionFetcher version.Fetcher) (*VerificationResult, error) {
dgst, err := oci.SplitDigest(input.Digest)
if err != nil {
return nil, fmt.Errorf("failed to split digest: %w", err)
@@ -168,6 +171,10 @@ func toVerificationResult(p *policy.Policy, input *policy.Input, result *policy.
}
vsaPolicy := attestation.VSAPolicy{URI: result.Summary.PolicyURI, DownloadLocation: p.URI, Digest: p.Digest}
attestVersion, err := attestation.GetVerifierVersion(versionFetcher)
if err != nil {
return nil, fmt.Errorf("failed to get verifier version: %w", err)
}
return &VerificationResult{
Policy: p,
@@ -182,7 +189,8 @@ func toVerificationResult(p *policy.Policy, input *policy.Input, result *policy.
},
Predicate: attestation.VSAPredicate{
Verifier: attestation.VSAVerifier{
ID: result.Summary.Verifier,
ID: result.Summary.Verifier,
Version: attestVersion,
},
TimeVerified: time.Now().UTC().Format(time.RFC3339),
ResourceURI: resourceURI,
@@ -195,7 +203,7 @@ func toVerificationResult(p *policy.Policy, input *policy.Input, result *policy.
}, nil
}
func verifyAttestations(ctx context.Context, resolver attestation.Resolver, evaluator policy.Evaluator, resolvedPolicy *policy.Policy, opts *policy.Options) (*VerificationResult, error) {
func (verifier *ImageVerifier) verifyAttestations(ctx context.Context, resolver attestation.Resolver, evaluator policy.Evaluator, resolvedPolicy *policy.Policy) (*VerificationResult, error) {
desc, err := resolver.ImageDescriptor(ctx)
if err != nil {
return nil, fmt.Errorf("failed to get image descriptor: %w", err)
@@ -247,7 +255,7 @@ func verifyAttestations(ctx context.Context, resolver attestation.Resolver, eval
Domain: reference.Domain(ref),
NormalizedName: reference.Path(ref),
FamiliarName: reference.FamiliarName(ref),
Parameters: opts.Parameters,
Parameters: verifier.opts.Parameters,
}
// rego has null strings
if tag != "" {
@@ -257,7 +265,7 @@ func verifyAttestations(ctx context.Context, resolver attestation.Resolver, eval
if err != nil {
return nil, fmt.Errorf("policy evaluation failed: %w", err)
}
verificationResult, err := toVerificationResult(resolvedPolicy, input, result)
verificationResult, err := toVerificationResult(resolvedPolicy, input, result, verifier.versionFetcher)
if err != nil {
return nil, fmt.Errorf("failed to convert to policy result: %w", err)
}

View File

@@ -9,6 +9,7 @@ import (
"testing"
"time"
"github.com/Masterminds/semver/v3"
"github.com/distribution/reference"
"github.com/docker/attest/attestation"
"github.com/docker/attest/internal/test"
@@ -17,6 +18,7 @@ import (
"github.com/docker/attest/policy"
"github.com/docker/attest/tlog"
"github.com/docker/attest/tuf"
"github.com/docker/attest/version"
intoto "github.com/in-toto/in-toto-golang/in_toto"
"github.com/secure-systems-lab/go-securesystemslib/dsse"
"github.com/stretchr/testify/assert"
@@ -32,9 +34,16 @@ var (
)
const (
LinuxAMD64 = "linux/amd64"
LinuxAMD64 = "linux/amd64"
TestVerifierVersion = "9.9.9"
)
type MockVersionFetcher struct{}
func (m *MockVersionFetcher) Get() (*semver.Version, error) {
return semver.NewVersion(TestVerifierVersion)
}
func TestVerifyAttestations(t *testing.T) {
ex, err := os.ReadFile(ExampleAttestation)
assert.NoError(t, err)
@@ -62,7 +71,9 @@ func TestVerifyAttestations(t *testing.T) {
return policy.AllowedResult(), tc.policyEvaluationError
},
}
_, err := verifyAttestations(ctx, resolver, &mockPE, &policy.Policy{ResolvedName: ""}, &policy.Options{})
verifier, err := NewImageVerifier(ctx, &policy.Options{})
require.NoError(t, err)
_, err = verifier.verifyAttestations(ctx, resolver, &mockPE, &policy.Policy{ResolvedName: ""})
if tc.expectedError != nil {
if assert.Error(t, err) {
assert.Equal(t, tc.expectedError.Error(), err.Error())
@@ -102,7 +113,10 @@ func TestVSA(t *testing.T) {
AttestationStyle: mapping.AttestationStyleAttached,
DisableTUF: true,
}
results, err := Verify(ctx, spec, policyOpts)
verifier, err := NewImageVerifier(ctx, policyOpts)
require.NoError(t, err)
verifier.versionFetcher = &MockVersionFetcher{}
results, err := verifier.Verify(ctx, spec)
require.NoError(t, err)
assert.Equal(t, OutcomeSuccess, results.Outcome)
assert.Empty(t, results.Violations)
@@ -135,6 +149,7 @@ func TestVSA(t *testing.T) {
assert.NotEmpty(t, digest)
assert.Contains(t, []string{"application/vnd.in-toto.provenance+dsse", "application/vnd.in-toto.spdx+dsse"}, input.MediaType)
}
assert.Equal(t, TestVerifierVersion, attestationPredicate.Verifier.Version[version.ThisModulePath])
}
func TestVerificationFailure(t *testing.T) {

View File

@@ -9,9 +9,19 @@ import (
const ThisModulePath = "github.com/docker/attest"
type Fetcher interface {
Get() (*semver.Version, error)
}
type GoModVersionFetcher struct{}
func NewGoVersionFetcher() *GoModVersionFetcher {
return &GoModVersionFetcher{}
}
// Get returns the version of the attest module.
// this can return nil if the version can't be determined (without an error).
func Get() (*semver.Version, error) {
func (*GoModVersionFetcher) Get() (*semver.Version, error) {
var attestMod *debug.Module
bi, ok := debug.ReadBuildInfo()
if !ok {