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

fix: Keyring output #2784

Merged
merged 5 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion cli/keyring.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,21 @@ func MakeKeyringCommand() *cobra.Command {
Use: "keyring",
Short: "Manage DefraDB private keys",
Long: `Manage DefraDB private keys.
Generate, import, and export private keys.`,
Generate, import, and export private keys.

The following keys are loaded from the keyring on start:
peer-key: Ed25519 private key (required)
encryption-key: AES-128, AES-192, or AES-256 key (optional)

To randomly generate the required keys, run the following command:
defradb keyring generate

To import externally generated keys, run the following command:
defradb keyring import <name> <private-key-hex>

To learn more about the available options:
defradb keyring --help
`,
}
return cmd
}
32 changes: 23 additions & 9 deletions cli/keyring_generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
)

func MakeKeyringGenerateCommand() *cobra.Command {
var noEncryption bool
var noEncryptionKey bool
var noPeerKey bool
var cmd = &cobra.Command{
Use: "generate",
Short: "Generate private keys",
Long: `Generate private keys.
Randomly generate and store private keys in the keyring.
By default peer and encryption keys will be generated.
Copy link
Contributor

Choose a reason for hiding this comment

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

though: I wonder if we need to be more clear every time we mention encryption keys as there are different types of them for different context: encryption-at-rest, doc encryption, some ACP-related and so on. They grow like mushrooms these days.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it is well worth being very clear here - this is a destructive operation (information is overwritten), and the keys are accessible to users via the export command. I have a preference for us to list each key with it's keyring name, and a short description as to what it does.

Copy link
Member Author

Choose a reason for hiding this comment

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

There's a readme section dedicated to this already.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can we link to it from the cli? It is very handy if the CLI is self-explanatory, I find it annoying when I have to search for CLI documentation instead of just using --help

Copy link
Member Author

Choose a reason for hiding this comment

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

I've copied the key management section into the help for the base keyring command.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks Keenan :)


WARNING: This will overwrite existing keys in the keyring.

Expand All @@ -32,15 +34,17 @@
Example: with no encryption key
defradb keyring generate --no-encryption-key

Example: with no peer key
defradb keyring generate --no-peer-key

Example: with system keyring
defradb keyring generate --keyring-backend system`,
RunE: func(cmd *cobra.Command, args []string) error {
keyring, err := openKeyring(cmd)
if err != nil {
return err
}
if !noEncryption {
// generate optional encryption key
if !noEncryptionKey {
encryptionKey, err := crypto.GenerateAES256()
if err != nil {
return err
Expand All @@ -49,15 +53,25 @@
if err != nil {
return err
}
log.Info("generated encryption key")
}
peerKey, err := crypto.GenerateEd25519()
if err != nil {
return err
if !noPeerKey {
peerKey, err := crypto.GenerateEd25519()
if err != nil {
return err

Check warning on line 61 in cli/keyring_generate.go

View check run for this annotation

Codecov / codecov/patch

cli/keyring_generate.go#L61

Added line #L61 was not covered by tests
}
err = keyring.Set(peerKeyName, peerKey)
if err != nil {
return err

Check warning on line 65 in cli/keyring_generate.go

View check run for this annotation

Codecov / codecov/patch

cli/keyring_generate.go#L65

Added line #L65 was not covered by tests
}
log.Info("generated peer key")
}
return keyring.Set(peerKeyName, peerKey)
return nil
},
}
cmd.Flags().BoolVar(&noEncryption, "no-encryption-key", false,
"Skip generating an encryption. Encryption at rest will be disabled")
cmd.Flags().BoolVar(&noEncryptionKey, "no-encryption-key", false,
"Skip generating an encryption key. Encryption at rest will be disabled")
cmd.Flags().BoolVar(&noPeerKey, "no-peer-key", false,
"Skip generating a peer key.")
return cmd
}
16 changes: 16 additions & 0 deletions cli/keyring_generate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,19 @@ func TestKeyringGenerateNoEncryptionKey(t *testing.T) {
assert.NoFileExists(t, filepath.Join(rootdir, "keys", encryptionKeyName))
assert.FileExists(t, filepath.Join(rootdir, "keys", peerKeyName))
}

func TestKeyringGenerateNoPeerKey(t *testing.T) {
rootdir := t.TempDir()
readPassword = func(_ *cobra.Command, _ string) ([]byte, error) {
return []byte("secret"), nil
}

cmd := NewDefraCommand()
cmd.SetArgs([]string{"keyring", "generate", "--no-peer-key", "--rootdir", rootdir})

err := cmd.Execute()
require.NoError(t, err)

assert.FileExists(t, filepath.Join(rootdir, "keys", encryptionKeyName))
assert.NoFileExists(t, filepath.Join(rootdir, "keys", peerKeyName))
}
6 changes: 5 additions & 1 deletion cli/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,13 @@
// openKeyring opens the keyring for the current environment.
func openKeyring(cmd *cobra.Command) (keyring.Keyring, error) {
cfg := mustGetContextConfig(cmd)
if cfg.Get("keyring.backend") == "system" {
backend := cfg.Get("keyring.backend")
if backend == "system" {
return keyring.OpenSystemKeyring(cfg.GetString("keyring.namespace")), nil
}
if backend != "file" {
log.Info("keyring defaulted to file backend")

Check warning on line 189 in cli/utils.go

View check run for this annotation

Codecov / codecov/patch

cli/utils.go#L189

Added line #L189 was not covered by tests
}
path := cfg.GetString("keyring.path")
if err := os.MkdirAll(path, 0755); err != nil {
return nil, err
Expand Down
14 changes: 14 additions & 0 deletions docs/website/references/cli/defradb_keyring.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@ Manage DefraDB private keys
Manage DefraDB private keys.
Generate, import, and export private keys.

The following keys are loaded from the keyring on start:
peer-key: Ed25519 private key (required)
encryption-key: AES-128, AES-192, or AES-256 key (optional)

To randomly generate the required keys, run the following command:
defradb keyring generate

To import externally generated keys, run the following command:
defradb keyring import <name> <private-key-hex>

To learn more about the available options:
defradb keyring --help


### Options

```
Expand Down
7 changes: 6 additions & 1 deletion docs/website/references/cli/defradb_keyring_generate.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Generate private keys

Generate private keys.
Randomly generate and store private keys in the keyring.
By default peer and encryption keys will be generated.

WARNING: This will overwrite existing keys in the keyring.

Expand All @@ -15,6 +16,9 @@ Example:
Example: with no encryption key
defradb keyring generate --no-encryption-key

Example: with no peer key
defradb keyring generate --no-peer-key

Example: with system keyring
defradb keyring generate --keyring-backend system

Expand All @@ -26,7 +30,8 @@ defradb keyring generate [flags]

```
-h, --help help for generate
--no-encryption-key Skip generating an encryption. Encryption at rest will be disabled
--no-encryption-key Skip generating an encryption key. Encryption at rest will be disabled
--no-peer-key Skip generating a peer key.
```

### Options inherited from parent commands
Expand Down
Loading