Skip to content

Add cosign-based signing, attestation, and verification for modelkits#1023

Open
cr3ativ3cod3r wants to merge 6 commits intokitops-ml:mainfrom
cr3ativ3cod3r:Implement-cosign-based-signing
Open

Add cosign-based signing, attestation, and verification for modelkits#1023
cr3ativ3cod3r wants to merge 6 commits intokitops-ml:mainfrom
cr3ativ3cod3r:Implement-cosign-based-signing

Conversation

@cr3ativ3cod3r
Copy link
Copy Markdown

@cr3ativ3cod3r cr3ativ3cod3r commented Nov 18, 2025

Description

This PR adds support for signing, attesting, and verifying modelkits using the kit commands directly. These commands use cosign internally. The users doesn't have to switch between multiple tools. The verify command enables the user to run both verify and verify attestation using a single command.

Linked issues

closes #857

AI-Assisted Code

  • This PR contains AI-generated code that I have reviewed and tested
  • I take full responsibility for all code in this PR, regardless of how it was created

)

func RunSign(ctx context.Context, options *signOptions) error {
cmd := exec.CommandContext(ctx, "cosign", options.cosignArgs...)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Commands will panic with "executable file not found" when cosign binary is not installed on the system. This needs pre-flight checks before making these calls. Also is there a possibility to use cosign as a library instead of an external CLI ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Looked into use of cosign as a library. Found cosign(github.com/sigstore/cosign/v2/pkg/cosign). But it doesn't have a high level api to sign or attest. Actual signing happens in internal packages. Reviewed sigstore-go, which currently doesn't have attestation creation support.
I have added a check for cosign binary before execution of command.

"os/exec"
)

func RunAttest(context context.Context, options *attestOptions) any {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why does this return any and not error?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Changed it to error

return cmd
}

func runCommand(opts []verifyOptions) func(cmd *cobra.Command, args []string) error {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

While this code works due to reassignment of opts it's confusing. The function signature runCommand([]verifyOptions{})suggests it takes an initialized slice, but it's always called with an empty slice and immediately populated. Refactor to use local variable for opts

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Made opts local to runCommand instead of passing it as input.


err := cmd.Run()
if err != nil {
return fmt.Errorf("signing failed %s", err)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should use %w instead of %s

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Changed to %w.

func VerifyCommand() *cobra.Command {

cmd := &cobra.Command{
Use: "verify [FLAGS]",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

FLAGS -> flags


func AttestCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "attest [FLAGS]",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

FLAGS -> flags

return output.Fatalf("Failed to %s: %s", commands[i], err)
}
}
output.Infof("Modelkit signed")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks like a copy/paste error should be output.Infof("Modelkit verification successful")

Signed-off-by: Keerthan KK <tkthulasimandiram@gmail.com>
…cific flags

Signed-off-by: Keerthan KK <tkthulasimandiram@gmail.com>
Signed-off-by: Keerthan KK <tkthulasimandiram@gmail.com>
Signed-off-by: Keerthan KK <tkthulasimandiram@gmail.com>
Signed-off-by: Keerthan KK <tkthulasimandiram@gmail.com>
Signed-off-by: Keerthan KK <tkthulasimandiram@gmail.com>
@cr3ativ3cod3r cr3ativ3cod3r force-pushed the Implement-cosign-based-signing branch from bcca243 to 0848136 Compare December 28, 2025 14:26
@cr3ativ3cod3r cr3ativ3cod3r requested a review from gorkem December 28, 2025 15:01
Copy link
Copy Markdown
Contributor

@amisevsk amisevsk left a comment

Choose a reason for hiding this comment

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

High level, this PR appears to be a very thin wrapper on just calling the cosign CLI without any additional functionality. As it stands I don't think it's something worth adding to the project.

Additionally, I haven't built and tested it locally yet, but I have a feeling signing won't work as a user expects -- what happens if the ModelKit has not yet been pushed to a remote repository?

Lastly, a small nitpick, but adding 3 subcommands to the root command here in my opinion complicates the CLI more than is necessary. They could all be subcommands of one sign command to keep the main help page simpler.

Comment on lines +26 to +43
func RunAttest(context context.Context, options *attestOptions) error {
_, err := exec.LookPath("cosign")
if err != nil {
fmt.Println()
return fmt.Errorf("cosign not found, please install cosign")
}
cmd := exec.CommandContext(context, "cosign", options.cosignArgs...)

cmd.Stdin = os.Stdin
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout

err = cmd.Run()
if err != nil {
return fmt.Errorf("attestation failed: %w", err)
}
return nil
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The implementations for RunAttest, RunSign, and RunVerify appear to be identical.

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.

Sign the Vibes

3 participants