You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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 urltypeInMemoryKeyChainstruct {
// An in-memory map of username/passwordscredentialsmap[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:
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.
@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) 👍
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:
cmd
layer that cannot be bypassed, users have to create all of the config structs in-code with default values and pass them to thecmd
layer. At the CLI level, this isn't required because Cosign is built with thecobra
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..dockerconfig.json
files: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
andpkg
/api
layer so that we offer the same functionality across both whilst keeping the same user experience for thecmd
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 thecmd
version, but in order to cut the code down, perhaps we set defaults? (like we do in thecmd
layer usingcobra
) 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/filescosign
as a library #666The text was updated successfully, but these errors were encountered: