package cli import ( "errors" "fmt" "os" "github.com/spf13/cobra" "gitea.mynodes.xyz/ilker/llmgw/internal/release" ) func newReleaseCmd() *cobra.Command { c := &cobra.Command{ Use: "release", Short: "Sign releases, and make the key they are signed with", } c.AddCommand(&cobra.Command{ Use: "keygen", Short: "Make a release signing key pair", Long: "Prints a public key and a private key. The private key goes into the CI\n" + "secret RELEASE_SIGNING_KEY and nowhere else; the public key into\n" + "internal/release/trusted.pub, which every build from then on carries\n" + "and checks releases against. Run once, on a machine you trust.", Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, _ []string) error { pub, priv, err := release.GenerateKey() if err != nil { return err } fmt.Fprintf(cmd.OutOrStdout(), "public: %s\nprivate: %s\n", pub, priv) fmt.Fprintln(cmd.ErrOrStderr(), "\nThe private key signs every release: put it in the CI secret "+ "RELEASE_SIGNING_KEY, then clear this terminal's scrollback.") return nil }, }) c.AddCommand(&cobra.Command{ Use: "sign FILE", Short: "Sign a release's checksums, writing FILE.sig", Long: "Reads the private key from RELEASE_SIGNING_KEY, never from an argument,\n" + "so it does not land in a shell history or a process list.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { key := os.Getenv("RELEASE_SIGNING_KEY") if key == "" { return errors.New("RELEASE_SIGNING_KEY is not set") } data, err := os.ReadFile(args[0]) if err != nil { return err } sig, err := release.Sign(key, data) if err != nil { return err } if pub := release.TrustedKey(); pub != "" { // Signed with a key this build would not accept is a release // every upgraded machine refuses: stopped here instead. if err := release.Verify(pub, data, sig); err != nil { return fmt.Errorf("the signing key does not match this build's trusted key: %w", err) } } return os.WriteFile(args[0]+".sig", []byte(sig+"\n"), 0o644) //nolint:gosec // public }, }) return c }