Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Signature discovery] Integrate signature discovery client into attestation agent. #343

Merged
merged 1 commit into from
Oct 3, 2023

Conversation

yawangwang
Copy link
Collaborator

@yawangwang yawangwang commented Aug 2, 2023

This PR includes the following changes:

  1. Added containerImageSignaturesFetcher to the attestation agent such that the agent can fetch any new container image signatures on refreshToken.
  2. Integrated the signature discovery client into signature fetcher and made corresponding changes to container_runner.
  3. Add specific tests that need root permission to run to ci.yaml.
  4. Integrate client experimental flag to gate the signed container feature.

@yawangwang yawangwang force-pushed the attestation-agent branch 3 times, most recently from 758515c to c78c5b1 Compare August 2, 2023 18:00
@yawangwang yawangwang marked this pull request as ready for review August 16, 2023 21:26
@yawangwang yawangwang requested review from alexmwu and jkl73 August 16, 2023 21:26
Copy link
Contributor

@alexmwu alexmwu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, this is the crucial bit of this feature and should go behind an experiment. Please do not submit until we have that functionality.

if err != nil {
logger.Printf("failed to retrieve auth token: %v, using empty auth for image pulling\n", err)
}
updatedSpec, err := spec.GetLaunchSpec(mdsClient)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need to update the spec? The launcher should only ever get the spec at startup. Refetching it can lead to weird states and potential security issues.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rational behind updating the spec is to enable operators don't have to restart VM when new docker repos added. Even though ADMC team is ok with restarting VM when new repos added, I feel it might be nice to have this feature. But if refetching it will lead to any potential security issues, we should definitely avoid that.

@@ -236,14 +266,38 @@ func NewRunner(ctx context.Context, cdClient *containerd.Client, token oauth2.To
return nil, fmt.Errorf("failed to create REST verifier client: %v", err)
}

// Fetch container image signatures by using signaturediscovery client.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you don't update the spec, this func should be unnecessary. Which is good because this is tough to follow.

@@ -79,6 +82,33 @@ const (
defaultRefreshJitter = 0.1
)

func fetchContainerImageSignatures(ctx context.Context, sdClient *signaturediscovery.Client, targetRepos []string, logger *log.Logger) []internal.Signature {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not required, but it would be nice to be able to cache signatures so we don't have to fetch every time. This complicates things, so maybe add a TODO with an issue.

@yawangwang
Copy link
Collaborator Author

IMO, this is the crucial bit of this feature and should go behind an experiment. Please do not submit until we have that functionality.

Agree, this PR should also go behind this PR for updating v1 SDK #305

@yawangwang yawangwang requested a review from alexmwu August 17, 2023 01:24
@yawangwang yawangwang force-pushed the attestation-agent branch 3 times, most recently from cc98bcd to 62d378c Compare August 23, 2023 19:13
@yawangwang yawangwang force-pushed the attestation-agent branch 5 times, most recently from 1652b48 to 042dc40 Compare September 19, 2023 19:32
@yawangwang
Copy link
Collaborator Author

IMO, this is the crucial bit of this feature and should go behind an experiment. Please do not submit until we have that functionality.

Agree, this PR should also go behind this PR for updating v1 SDK #305

Now since V1 SDK has been merged into master, this PR is now ready for review again with client experimental flag integration.

@@ -414,6 +417,71 @@ type idTokenResp struct {
Token string `json:"token"`
}

func TestFetchContainerImageSignatures(t *testing.T) {
ctx := namespaces.WithNamespace(context.Background(), "test")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should consider using something like https://pkg.go.dev/github.com/docker/docker/testutil/registry#V2 or the mock https://pkg.go.dev/github.com/docker/docker/testutil/registry#Mock instead of actually making a network call in our unit tests

},
},
{
name: "fetchContainerImageSignatures success with nil target repos",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a case for a nonexistent repo and one that exists but doesn't have signatures?

@@ -230,15 +259,29 @@ func NewRunner(ctx context.Context, cdClient *containerd.Client, token oauth2.To
return nil, fmt.Errorf("failed to create REST verifier client: %v", err)
}

// Fetch container image signatures with specific repositories.
containerSignaturesFetcher := func(targetRepos []string) []internal.Signature {
sdClient := getSignatureDiscoveryClient(cdClient, token, image.Target())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we getting a new signaturediscovery Client every time we call agent.Attest? Can we make this a closure to avoid this? Alternatively, we can pass the signature discovery client in the agent and use a fake for testing.

Comment on lines 100 to 109
if a.launchSpec.Experiments.EnableSignedContainerImage {
signatures := a.sigsFetcher(a.launchSpec.SignedImageRepos)
if len(signatures) > 0 {
req.ContainerImageSignatures = signatures
a.logger.Printf("Found container image signatures: %v\n", signatures)
}
}

resp, err := a.client.VerifyAttestation(ctx, req)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add unit test coverage here? The fake verifier client should expect to see signatures.

@yawangwang yawangwang force-pushed the attestation-agent branch 3 times, most recently from 2fcfaef to d6519ea Compare September 28, 2023 01:23
@yawangwang yawangwang requested a review from alexmwu September 28, 2023 01:32
t.Run(tc.name, func(t *testing.T) {
sdClient := signaturediscovery.NewFakeClient()
gotSigs := fetchContainerImageSignatures(ctx, sdClient, tc.targetRepos, log.Default())
if len(gotSigs) != tc.wantLen {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: For these test cases: why not len(gotSigs) != len(tc.WantBase64Sigs)? The only reason I can think of to have wantLen is in case we have a partial error. Which, if you can add a test case for, would be great to have! (e.g., add a repo with all invalid signatures and one with partial invalid signatures and have the fake verifier handle that).

@yawangwang yawangwang merged commit 7f60076 into google:master Oct 3, 2023
11 checks passed
alexmwu added a commit to alexmwu/go-tpm-tools that referenced this pull request Oct 27, 2023
New Features:
[launcher] Add experiment support google#352
[launcher] Integrate signature discovery client into attestation agent google#343

Bug Fixes:
Make launcher host tmp directory before experiment fetch google#363

Other Changes:
[launcher] Print kernel cmdline on builds google#268
Import latest version of go-tdx-guest google#373
[launcher] Print signature details instead of signature object google#374
[launcher] Add image tests for the experiments binary google#378
Update go-sev-guest to v0.9.3 google#381
@alexmwu alexmwu mentioned this pull request Oct 27, 2023
alexmwu added a commit that referenced this pull request Oct 27, 2023
New Features:
[launcher] Add experiment support #352
[launcher] Integrate signature discovery client into attestation agent #343

Bug Fixes:
Make launcher host tmp directory before experiment fetch #363

Other Changes:
[launcher] Print kernel cmdline on builds #268
Import latest version of go-tdx-guest #373
[launcher] Print signature details instead of signature object #374
[launcher] Add image tests for the experiments binary #378
Update go-sev-guest to v0.9.3 #381
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants