onboard: make encryption opt-in via --enc flag
Encryption (passphrase prompt + SSH key generation) is now only triggered when the user passes --enc to 'picoclaw onboard'. Without the flag, onboard skips the credential-encryption setup and writes a plain config + workspace templates directly. - Add --enc BoolFlag in NewOnboardCommand() - Pass encrypt bool into onboard() - Guard passphrase prompt, SSH key generation, and related env-var setup behind the encrypt branch - Adjust 'Next steps' output so the passphrase reminder only appears when --enc was used
This commit is contained in:
parent
71fbf6db9d
commit
e29ee04a18
3 changed files with 54 additions and 37 deletions
|
|
@ -11,14 +11,19 @@ import (
|
||||||
var embeddedFiles embed.FS
|
var embeddedFiles embed.FS
|
||||||
|
|
||||||
func NewOnboardCommand() *cobra.Command {
|
func NewOnboardCommand() *cobra.Command {
|
||||||
|
var encrypt bool
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "onboard",
|
Use: "onboard",
|
||||||
Aliases: []string{"o"},
|
Aliases: []string{"o"},
|
||||||
Short: "Initialize picoclaw configuration and workspace",
|
Short: "Initialize picoclaw configuration and workspace",
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
onboard()
|
onboard(encrypt)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmd.Flags().BoolVar(&encrypt, "enc", false,
|
||||||
|
"Enable credential encryption (generates SSH key and prompts for passphrase)")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,9 @@ func TestNewOnboardCommand(t *testing.T) {
|
||||||
assert.Nil(t, cmd.PersistentPreRun)
|
assert.Nil(t, cmd.PersistentPreRun)
|
||||||
assert.Nil(t, cmd.PersistentPostRun)
|
assert.Nil(t, cmd.PersistentPostRun)
|
||||||
|
|
||||||
assert.False(t, cmd.HasFlags())
|
assert.True(t, cmd.HasFlags())
|
||||||
|
encFlag := cmd.Flags().Lookup("enc")
|
||||||
|
require.NotNil(t, encFlag, "expected --enc flag to be registered")
|
||||||
|
assert.Equal(t, "false", encFlag.DefValue, "--enc should default to false")
|
||||||
assert.False(t, cmd.HasSubCommands())
|
assert.False(t, cmd.HasSubCommands())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,13 @@ import (
|
||||||
"github.com/sipeed/picoclaw/pkg/credential"
|
"github.com/sipeed/picoclaw/pkg/credential"
|
||||||
)
|
)
|
||||||
|
|
||||||
func onboard() {
|
func onboard(encrypt bool) {
|
||||||
configPath := internal.GetConfigPath()
|
configPath := internal.GetConfigPath()
|
||||||
|
|
||||||
configExists := false
|
configExists := false
|
||||||
if _, err := os.Stat(configPath); err == nil {
|
if _, err := os.Stat(configPath); err == nil {
|
||||||
configExists = true
|
configExists = true
|
||||||
|
if encrypt {
|
||||||
// Only ask for confirmation when *both* config and SSH key already exist,
|
// Only ask for confirmation when *both* config and SSH key already exist,
|
||||||
// indicating a full re-onboard that would reset the config to defaults.
|
// indicating a full re-onboard that would reset the config to defaults.
|
||||||
sshKeyPath, _ := credential.DefaultSSHKeyPath()
|
sshKeyPath, _ := credential.DefaultSSHKeyPath()
|
||||||
|
|
@ -36,12 +37,15 @@ func onboard() {
|
||||||
}
|
}
|
||||||
// Config exists but SSH key is missing — keep existing config, only add SSH key.
|
// Config exists but SSH key is missing — keep existing config, only add SSH key.
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
if encrypt {
|
||||||
fmt.Println("\nSet up credential encryption")
|
fmt.Println("\nSet up credential encryption")
|
||||||
fmt.Println("-----------------------------")
|
fmt.Println("-----------------------------")
|
||||||
passphrase, err := promptPassphrase()
|
passphrase, pErr := promptPassphrase()
|
||||||
if err != nil {
|
if pErr != nil {
|
||||||
fmt.Printf("Error: %v\n", err)
|
fmt.Printf("Error: %v\n", pErr)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
// Expose the passphrase to credential.PassphraseProvider (which calls
|
// Expose the passphrase to credential.PassphraseProvider (which calls
|
||||||
|
|
@ -54,6 +58,7 @@ func onboard() {
|
||||||
fmt.Printf("Error generating SSH key: %v\n", err)
|
fmt.Printf("Error generating SSH key: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var cfg *config.Config
|
var cfg *config.Config
|
||||||
if configExists {
|
if configExists {
|
||||||
|
|
@ -76,11 +81,15 @@ func onboard() {
|
||||||
|
|
||||||
fmt.Printf("\n%s picoclaw is ready!\n", internal.Logo)
|
fmt.Printf("\n%s picoclaw is ready!\n", internal.Logo)
|
||||||
fmt.Println("\nNext steps:")
|
fmt.Println("\nNext steps:")
|
||||||
|
if encrypt {
|
||||||
fmt.Println(" 1. Set your encryption passphrase before starting picoclaw:")
|
fmt.Println(" 1. Set your encryption passphrase before starting picoclaw:")
|
||||||
fmt.Println(" export PICOCLAW_KEY_PASSPHRASE=<your-passphrase> # Linux/macOS")
|
fmt.Println(" export PICOCLAW_KEY_PASSPHRASE=<your-passphrase> # Linux/macOS")
|
||||||
fmt.Println(" set PICOCLAW_KEY_PASSPHRASE=<your-passphrase> # Windows cmd")
|
fmt.Println(" set PICOCLAW_KEY_PASSPHRASE=<your-passphrase> # Windows cmd")
|
||||||
fmt.Println("")
|
fmt.Println("")
|
||||||
fmt.Println(" 2. Add your API key to", configPath)
|
fmt.Println(" 2. Add your API key to", configPath)
|
||||||
|
} else {
|
||||||
|
fmt.Println(" 1. Add your API key to", configPath)
|
||||||
|
}
|
||||||
fmt.Println("")
|
fmt.Println("")
|
||||||
fmt.Println(" Recommended:")
|
fmt.Println(" Recommended:")
|
||||||
fmt.Println(" - OpenRouter: https://openrouter.ai/keys (access 100+ models)")
|
fmt.Println(" - OpenRouter: https://openrouter.ai/keys (access 100+ models)")
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue