config: automatically upload new Azure SNP versions to API + sign version with release key (#1854)

* sign version with release key and remove version from fetcher interface
* extend azure-reporter GH action to upload updated version values to the Attestation API
This commit is contained in:
Adrian Stobbe 2023-06-02 12:10:22 +02:00 committed by GitHub
parent 18da9b8128
commit a813760f96
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 214 additions and 76 deletions

View file

@ -9,7 +9,7 @@ go_library(
deps = [
"//internal/api/attestationconfig",
"//internal/api/fetcher",
"//internal/api/versions",
"//internal/constants",
"//internal/sigstore",
],
)
@ -20,8 +20,6 @@ go_test(
embed = [":fetcher"],
deps = [
"//internal/api/attestationconfig",
"//internal/api/versions",
"@com_github_stretchr_testify//assert",
"@com_github_stretchr_testify//require",
],
)

View file

@ -16,15 +16,17 @@ import (
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfig"
"github.com/edgelesssys/constellation/v2/internal/api/fetcher"
versionsapi "github.com/edgelesssys/constellation/v2/internal/api/versions"
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/sigstore"
)
const cosignPublicKey = constants.CosignPublicKeyReleases
// AttestationConfigAPIFetcher fetches config API resources without authentication.
type AttestationConfigAPIFetcher interface {
FetchAzureSEVSNPVersion(ctx context.Context, azureVersion attestationconfig.AzureSEVSNPVersionGet, version versionsapi.Version) (attestationconfig.AzureSEVSNPVersionGet, error)
FetchAzureSEVSNPVersion(ctx context.Context, azureVersion attestationconfig.AzureSEVSNPVersionGet) (attestationconfig.AzureSEVSNPVersionGet, error)
FetchAzureSEVSNPVersionList(ctx context.Context, attestation attestationconfig.AzureSEVSNPVersionList) (attestationconfig.AzureSEVSNPVersionList, error)
FetchAzureSEVSNPVersionLatest(ctx context.Context, version versionsapi.Version) (attestationconfig.AzureSEVSNPVersionGet, error)
FetchAzureSEVSNPVersionLatest(ctx context.Context) (attestationconfig.AzureSEVSNPVersionGet, error)
}
// Fetcher fetches AttestationCfg API resources without authentication.
@ -48,16 +50,12 @@ func (f *Fetcher) FetchAzureSEVSNPVersionList(ctx context.Context, attestation a
}
// FetchAzureSEVSNPVersion fetches the version information from the config API.
func (f *Fetcher) FetchAzureSEVSNPVersion(ctx context.Context, attestation attestationconfig.AzureSEVSNPVersionGet, version versionsapi.Version) (attestationconfig.AzureSEVSNPVersionGet, error) {
cosignPublicKey, err := sigstore.CosignPublicKeyForVersion(version)
func (f *Fetcher) FetchAzureSEVSNPVersion(ctx context.Context, azureVersion attestationconfig.AzureSEVSNPVersionGet) (attestationconfig.AzureSEVSNPVersionGet, error) {
urlString, err := azureVersion.URL()
if err != nil {
return attestationconfig.AzureSEVSNPVersionGet{}, fmt.Errorf("get public key for config: %w", err)
return azureVersion, err
}
urlString, err := attestation.URL()
if err != nil {
return attestationconfig.AzureSEVSNPVersionGet{}, err
}
fetchedVersion, err := fetcher.Fetch(ctx, f.HTTPClient, attestation)
fetchedVersion, err := fetcher.Fetch(ctx, f.HTTPClient, azureVersion)
if err != nil {
return fetchedVersion, fmt.Errorf("fetch version %s: %w", fetchedVersion.Version, err)
}
@ -71,7 +69,7 @@ func (f *Fetcher) FetchAzureSEVSNPVersion(ctx context.Context, attestation attes
return fetchedVersion, fmt.Errorf("fetch version %s signature: %w", fetchedVersion.Version, err)
}
err = sigstore.CosignVerifier{}.VerifySignature(versionBytes, signature, cosignPublicKey)
err = sigstore.CosignVerifier{}.VerifySignature(versionBytes, signature, []byte(cosignPublicKey))
if err != nil {
return fetchedVersion, fmt.Errorf("verify version %s signature: %w", fetchedVersion.Version, err)
}
@ -79,14 +77,14 @@ func (f *Fetcher) FetchAzureSEVSNPVersion(ctx context.Context, attestation attes
}
// FetchAzureSEVSNPVersionLatest returns the latest versions of the given type.
func (f *Fetcher) FetchAzureSEVSNPVersionLatest(ctx context.Context, version versionsapi.Version) (res attestationconfig.AzureSEVSNPVersionGet, err error) {
func (f *Fetcher) FetchAzureSEVSNPVersionLatest(ctx context.Context) (res attestationconfig.AzureSEVSNPVersionGet, err error) {
var list attestationconfig.AzureSEVSNPVersionList
list, err = f.FetchAzureSEVSNPVersionList(ctx, list)
if err != nil {
return res, fmt.Errorf("fetching versions list: %w", err)
}
get := attestationconfig.AzureSEVSNPVersionGet{Version: list[0]} // get latest version (as sorted reversely alphanumerically)
get, err = f.FetchAzureSEVSNPVersion(ctx, get, version)
get, err = f.FetchAzureSEVSNPVersion(ctx, get)
if err != nil {
return res, fmt.Errorf("failed fetching version: %w", err)
}

View file

@ -15,9 +15,7 @@ import (
"testing"
configapi "github.com/edgelesssys/constellation/v2/internal/api/attestationconfig"
versionsapi "github.com/edgelesssys/constellation/v2/internal/api/versions"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
var testCfg = configapi.AzureSEVSNPVersionGet{
@ -36,7 +34,7 @@ func TestFetchLatestAzureSEVSNPVersion(t *testing.T) {
want configapi.AzureSEVSNPVersionGet
}{
"get version with valid signature": {
signature: []byte("MEUCIQDNn6wiSh9Nz9mtU9RvxvfkH3fNDFGeqopjTIRoBNkyrAIgSsKgdYNQXvPevaLWmmpnj/9WcgrltAQ+KfI+bQfklAo="),
signature: []byte("MEQCIBPEbYg89MIQuaGStLhKGLGMKvKFoYCaAniDLwoIwulqAiB+rj7KMaMOMGxmUsjI7KheCXSNM8NzN+tuDw6AywI75A=="), // signed with release key
want: testCfg,
},
"fail with invalid signature": {
@ -51,13 +49,10 @@ func TestFetchLatestAzureSEVSNPVersion(t *testing.T) {
signature: tc.signature,
},
}
require := require.New(t)
version, err := versionsapi.NewVersionFromShortPath("stream/debug/v9.9.9", versionsapi.VersionKindImage)
require.NoError(err)
fetcher := NewWithClient(client)
res, err := fetcher.FetchAzureSEVSNPVersionLatest(context.Background())
assert := assert.New(t)
res, err := fetcher.FetchAzureSEVSNPVersionLatest(context.Background(), version)
if tc.wantErr {
assert.Error(err)
} else {