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

Observations whilst using Cosign as a Library #3102

Open
ChrisJBurns opened this issue Jul 8, 2023 · 2 comments
Open

Observations whilst using Cosign as a Library #3102

ChrisJBurns opened this issue Jul 8, 2023 · 2 comments
Labels
enhancement New feature or request

Comments

@ChrisJBurns
Copy link
Contributor

ChrisJBurns commented Jul 8, 2023

Cosign initially was created as a binary, and with it's use being quite wide and popular there's been more and more users that have expressed desire to use Cosign in their own coded custom workflows. This is also true of any third-party tooling that wants to integrate with Cosign and use it's functionality but does not want to include the calling of the binary itself. This is where the ability of being able to integrate Cosign as a library would come in handy. There has been previous threads about this, so I won't go any further with it. I just want to outline the current state of play when it comes to using Cosign as a library, so decisions can be made in future about how to make this more streamlined.

The primary observations were the following:

  • Due to a lot of functionality being in the cmd layer that cannot be bypassed, users have to create all of the config structs in-code with default values and pass them to the cmd layer. At the CLI level, this isn't required because Cosign is built with the cobra library which allows for the default setting of values - which isn't possible when using Cosign as a library, so we should probably allow this in future.
  • When specifying registry credentials, it wasn't obvious on how this could be done. With a couple of hours of sifting through older Cosign issues, I saw that there is some code that looks to a local docker creds store but if one wasn't present where the code was being run (in my case a container), you had a number of options through Keychains. We should probably make this easier instead of users having to write the following pieces of code, or at least document it in future for the cases where there are no .dockerconfig.json files:
// A keychain that is able to return the creds based on the registry url
type InMemoryKeyChain struct {  
	// An in-memory map of username/passwords
	credentials map[string]userCredentials
}
...
    keychain := &InMemoryKeyChain{
		credentials: map[string]userCredentials{
			req.Source.Cosign.Registry: {
				username: req.Source.Username,
				password: req.Source.Password,
			},
		},
	}
...
		Registry: options.RegistryOptions{
			AllowInsecure:      false,
			KubernetesKeychain: false,
			Keychain:           keychain,
		},
...
  • Providing signing key had to be done via an environment variable - which isn't the most secure. In containerised environments this isn't the end of the world as the environment variable could have been set in the code (in my case it was) and so it would not have been visible by any process other than the application itself and it's child-processes. But on longer running applications, where the variable is not set in code, this is probably not ideal. In more library compatible versions of a future Cosign, we should probably allow the option of users being able to just pass the key through as a parameter to the API sign function, how they get the key into code can be of their own concern. But allowing it to be as easy as possible without compriomising on security is probably a wise idea.

  • A similar story to the COSIGN_PASSWORD variable. Because it has to be entered by a user that runs the binary, or set as a variable, we should probably make this similar to the signing key point above where we allow it to be passed as a parameter to the function in future API friendly versions of the library.

All round, the experience actually wasn't that painful. The Keychain took longer than I'd like it to have took, but it still works, and the key and password variable setting isn't the end of the world, but can definitely be made easier and more secure. I think the painful process will be how strike a balance between the cmd and pkg/api layer so that we offer the same functionality across both whilst keeping the same user experience for the cmd layer and making the API layer easier. I suspect that we definitely want to allow users to set all of the same flags as I had to in the cmd version, but in order to cut the code down, perhaps we set defaults? (like we do in the cmd layer using cobra) so users don't have to provide all of them.

As a footnote, we have started to implement custom error types in the pkg layer that will be useful when using Cosign as a library so users can write error handling code on their end:

The reference PR for all of this can be found in the following PR where I implemented Cosign support for the registry-image-resource for Concourse: https://github.com/concourse/registry-image-resource/pull/341/files

@ChrisJBurns ChrisJBurns added the enhancement New feature or request label Jul 8, 2023
@znewman01
Copy link
Contributor

This is super helpful, thanks! I'll make sure the folks working on the new sigstore-go library hear about all this, as well as the clients special interest group in general.

@ChrisJBurns
Copy link
Contributor Author

ChrisJBurns commented Jul 9, 2023

@znewman01 Great! I found the Go library after I raised this issue, so I'll try and contribute to it if I can (permitting I have time from my other commitments) 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants