mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-10-31 18:48:08 +00:00 
			
		
		
		
	Fix transit byok tool, add docs, tests (#19373)
* Fix Vault Transit BYOK helper argument parsing This commit fixes the following issues with the importer: - More than two arguments were not supported, causing the CLI to error out and resulting in a failure to import RSA keys. - The @file notation support was not accepted for KEY, meaning unencrypted keys had to be manually specified on the CLI. - Parsing of additional argument data was done in a non-standard way. - Fix parsing of command line options and ensure only relevant options are included. Additionally, some error messages and help text was clarified. Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add missing documentation on Transit CLI to website Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add tests for Transit BYOK vault subcommand Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Add changelog Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> * Appease CI Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com> --------- Signed-off-by: Alexander Scheel <alex.scheel@hashicorp.com>
This commit is contained in:
		
							
								
								
									
										3
									
								
								changelog/19373.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								changelog/19373.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | ```release-note:bug | ||||||
|  | cli/transit: Fix import, import-version command invocation | ||||||
|  | ``` | ||||||
| @@ -8,6 +8,7 @@ import ( | |||||||
| 	"encoding/base64" | 	"encoding/base64" | ||||||
| 	"encoding/pem" | 	"encoding/pem" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"os" | ||||||
| 	"regexp" | 	"regexp" | ||||||
| 	"strings" | 	"strings" | ||||||
|  |  | ||||||
| @@ -38,17 +39,20 @@ func (c *TransitImportCommand) Help() string { | |||||||
| Usage: vault transit import PATH KEY [options...] | Usage: vault transit import PATH KEY [options...] | ||||||
|  |  | ||||||
|   Using the Transit or Transform key wrapping system, imports key material from |   Using the Transit or Transform key wrapping system, imports key material from | ||||||
|   the base64 encoded KEY, into a new key whose API path is PATH.  To import a new version |   the base64 encoded KEY (either directly on the CLI or via @path notation), | ||||||
|   into an existing key, use import_version.  The remaining options after KEY (key=value style) are passed |   into a new key whose API path is PATH.  To import a new version into an | ||||||
|   on to the transit/transform create key endpoint.  If your system or device natively supports |   existing key, use import_version.  The remaining options after KEY (key=value | ||||||
|   the RSA AES key wrap mechanism, you should use it directly rather than this command.  |   style) are passed on to the transit/transform create key endpoint.  If your | ||||||
|  |   system or device natively supports the RSA AES key wrap mechanism (such as | ||||||
|  |   the PKCS#11 mechanism CKM_RSA_AES_KEY_WRAP), you should use it directly | ||||||
|  |   rather than this command. | ||||||
| ` + c.Flags().Help() | ` + c.Flags().Help() | ||||||
|  |  | ||||||
| 	return strings.TrimSpace(helpText) | 	return strings.TrimSpace(helpText) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (c *TransitImportCommand) Flags() *FlagSets { | func (c *TransitImportCommand) Flags() *FlagSets { | ||||||
| 	return c.flagSet(FlagSetHTTP | FlagSetOutputField | FlagSetOutputFormat) | 	return c.flagSet(FlagSetHTTP) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (c *TransitImportCommand) AutocompleteArgs() complete.Predictor { | func (c *TransitImportCommand) AutocompleteArgs() complete.Predictor { | ||||||
| @@ -60,13 +64,20 @@ func (c *TransitImportCommand) AutocompleteFlags() complete.Flags { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (c *TransitImportCommand) Run(args []string) int { | func (c *TransitImportCommand) Run(args []string) int { | ||||||
| 	return importKey(c.BaseCommand, "import", args) | 	return importKey(c.BaseCommand, "import", c.Flags(), args) | ||||||
| } | } | ||||||
|  |  | ||||||
| // error codes: 1: user error, 2: internal computation error, 3: remote api call error | // error codes: 1: user error, 2: internal computation error, 3: remote api call error | ||||||
| func importKey(c *BaseCommand, operation string, args []string) int { | func importKey(c *BaseCommand, operation string, flags *FlagSets, args []string) int { | ||||||
| 	if len(args) != 2 { | 	// Parse and validate the arguments. | ||||||
| 		c.UI.Error(fmt.Sprintf("Incorrect argument count (expected 2, got %d)", len(args))) | 	if err := flags.Parse(args); err != nil { | ||||||
|  | 		c.UI.Error(err.Error()) | ||||||
|  | 		return 1 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	args = flags.Args() | ||||||
|  | 	if len(args) < 2 { | ||||||
|  | 		c.UI.Error(fmt.Sprintf("Incorrect argument count (expected 2+, got %d). Wanted PATH to import into and KEY material.", len(args))) | ||||||
| 		return 1 | 		return 1 | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -89,7 +100,18 @@ func importKey(c *BaseCommand, operation string, args []string) int { | |||||||
| 	path := parts[1] | 	path := parts[1] | ||||||
| 	keyName := parts[2] | 	keyName := parts[2] | ||||||
|  |  | ||||||
| 	key, err := base64.StdEncoding.DecodeString(args[1]) | 	keyMaterial := args[1] | ||||||
|  | 	if keyMaterial[0] == '@' { | ||||||
|  | 		keyMaterialBytes, err := os.ReadFile(keyMaterial[1:]) | ||||||
|  | 		if err != nil { | ||||||
|  | 			c.UI.Error(fmt.Sprintf("error reading key material file: %v", err)) | ||||||
|  | 			return 1 | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		keyMaterial = string(keyMaterialBytes) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	key, err := base64.StdEncoding.DecodeString(keyMaterial) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		c.UI.Error(fmt.Sprintf("error base64 decoding source key material: %v", err)) | 		c.UI.Error(fmt.Sprintf("error base64 decoding source key material: %v", err)) | ||||||
| 		return 1 | 		return 1 | ||||||
| @@ -126,15 +148,19 @@ func importKey(c *BaseCommand, operation string, args []string) int { | |||||||
| 	} | 	} | ||||||
| 	combinedCiphertext := append(wrappedAESKey, wrappedTargetKey...) | 	combinedCiphertext := append(wrappedAESKey, wrappedTargetKey...) | ||||||
| 	importCiphertext := base64.StdEncoding.EncodeToString(combinedCiphertext) | 	importCiphertext := base64.StdEncoding.EncodeToString(combinedCiphertext) | ||||||
|  |  | ||||||
| 	// Parse all the key options | 	// Parse all the key options | ||||||
| 	data := map[string]interface{}{ | 	data, err := parseArgsData(os.Stdin, args[2:]) | ||||||
| 		"ciphertext": importCiphertext, | 	if err != nil { | ||||||
|  | 		c.UI.Error(fmt.Sprintf("Failed to parse extra K=V data: %s", err)) | ||||||
|  | 		return 1 | ||||||
| 	} | 	} | ||||||
| 	for _, v := range args[2:] { | 	if data == nil { | ||||||
| 		parts := strings.Split(v, "=") | 		data = make(map[string]interface{}, 1) | ||||||
| 		data[parts[0]] = parts[1] |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	data["ciphertext"] = importCiphertext | ||||||
|  |  | ||||||
| 	c.UI.Output("Submitting wrapped key to Vault transit.") | 	c.UI.Output("Submitting wrapped key to Vault transit.") | ||||||
| 	// Finally, call import | 	// Finally, call import | ||||||
| 	_, err = client.Logical().Write(path+"/keys/"+keyName+"/"+operation, data) | 	_, err = client.Logical().Write(path+"/keys/"+keyName+"/"+operation, data) | ||||||
|   | |||||||
							
								
								
									
										186
									
								
								command/transit_import_key_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								command/transit_import_key_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,186 @@ | |||||||
|  | package command | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"crypto/rand" | ||||||
|  | 	"crypto/rsa" | ||||||
|  | 	"crypto/x509" | ||||||
|  | 	"encoding/base64" | ||||||
|  | 	"testing" | ||||||
|  |  | ||||||
|  | 	"github.com/hashicorp/vault/api" | ||||||
|  |  | ||||||
|  | 	"github.com/stretchr/testify/require" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Validate the `vault transit import` command works. | ||||||
|  | func TestTransitImport(t *testing.T) { | ||||||
|  | 	t.Parallel() | ||||||
|  |  | ||||||
|  | 	client, closer := testVaultServer(t) | ||||||
|  | 	defer closer() | ||||||
|  |  | ||||||
|  | 	if err := client.Sys().Mount("transit", &api.MountInput{ | ||||||
|  | 		Type: "transit", | ||||||
|  | 	}); err != nil { | ||||||
|  | 		t.Fatalf("transit mount error: %#v", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	rsa1, rsa2, aes128, aes256 := generateKeys(t) | ||||||
|  |  | ||||||
|  | 	type testCase struct { | ||||||
|  | 		variant    string | ||||||
|  | 		path       string | ||||||
|  | 		key        []byte | ||||||
|  | 		args       []string | ||||||
|  | 		shouldFail bool | ||||||
|  | 	} | ||||||
|  | 	tests := []testCase{ | ||||||
|  | 		{ | ||||||
|  | 			"import", | ||||||
|  | 			"transit/keys/rsa1", | ||||||
|  | 			rsa1, | ||||||
|  | 			[]string{"type=rsa-2048"}, | ||||||
|  | 			false, /* first import */ | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"import", | ||||||
|  | 			"transit/keys/rsa1", | ||||||
|  | 			rsa2, | ||||||
|  | 			[]string{"type=rsa-2048"}, | ||||||
|  | 			true, /* already exists */ | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"import-version", | ||||||
|  | 			"transit/keys/rsa1", | ||||||
|  | 			rsa2, | ||||||
|  | 			[]string{"type=rsa-2048"}, | ||||||
|  | 			false, /* new version */ | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"import", | ||||||
|  | 			"transit/keys/rsa2", | ||||||
|  | 			rsa2, | ||||||
|  | 			[]string{"type=rsa-4096"}, | ||||||
|  | 			true, /* wrong type */ | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"import", | ||||||
|  | 			"transit/keys/rsa2", | ||||||
|  | 			rsa2, | ||||||
|  | 			[]string{"type=rsa-2048"}, | ||||||
|  | 			false, /* new name */ | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"import", | ||||||
|  | 			"transit/keys/aes1", | ||||||
|  | 			aes128, | ||||||
|  | 			[]string{"type=aes128-gcm96"}, | ||||||
|  | 			false, /* first import */ | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"import", | ||||||
|  | 			"transit/keys/aes1", | ||||||
|  | 			aes256, | ||||||
|  | 			[]string{"type=aes256-gcm96"}, | ||||||
|  | 			true, /* already exists */ | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"import-version", | ||||||
|  | 			"transit/keys/aes1", | ||||||
|  | 			aes256, | ||||||
|  | 			[]string{"type=aes256-gcm96"}, | ||||||
|  | 			true, /* new version, different type */ | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"import-version", | ||||||
|  | 			"transit/keys/aes1", | ||||||
|  | 			aes128, | ||||||
|  | 			[]string{"type=aes128-gcm96"}, | ||||||
|  | 			false, /* new version */ | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"import", | ||||||
|  | 			"transit/keys/aes2", | ||||||
|  | 			aes256, | ||||||
|  | 			[]string{"type=aes128-gcm96"}, | ||||||
|  | 			true, /* wrong type */ | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"import", | ||||||
|  | 			"transit/keys/aes2", | ||||||
|  | 			aes256, | ||||||
|  | 			[]string{"type=aes256-gcm96"}, | ||||||
|  | 			false, /* new name */ | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for index, tc := range tests { | ||||||
|  | 		t.Logf("Running test case %d: %v", index, tc) | ||||||
|  | 		execTransitImport(t, client, tc.variant, tc.path, tc.key, tc.args, tc.shouldFail) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func execTransitImport(t *testing.T, client *api.Client, method string, path string, key []byte, data []string, expectFailure bool) { | ||||||
|  | 	t.Helper() | ||||||
|  |  | ||||||
|  | 	keyBase64 := base64.StdEncoding.EncodeToString(key) | ||||||
|  |  | ||||||
|  | 	var args []string | ||||||
|  | 	args = append(args, "transit") | ||||||
|  | 	args = append(args, method) | ||||||
|  | 	args = append(args, path) | ||||||
|  | 	args = append(args, keyBase64) | ||||||
|  | 	args = append(args, data...) | ||||||
|  |  | ||||||
|  | 	stdout := bytes.NewBuffer(nil) | ||||||
|  | 	stderr := bytes.NewBuffer(nil) | ||||||
|  | 	runOpts := &RunOptions{ | ||||||
|  | 		Stdout: stdout, | ||||||
|  | 		Stderr: stderr, | ||||||
|  | 		Client: client, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	code := RunCustom(args, runOpts) | ||||||
|  | 	combined := stdout.String() + stderr.String() | ||||||
|  |  | ||||||
|  | 	if code != 0 { | ||||||
|  | 		if !expectFailure { | ||||||
|  | 			t.Fatalf("Got unexpected failure from test (ret %d): %v", code, combined) | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		if expectFailure { | ||||||
|  | 			t.Fatalf("Expected failure, got success from test (ret %d): %v", code, combined) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func generateKeys(t *testing.T) (rsa1 []byte, rsa2 []byte, aes128 []byte, aes256 []byte) { | ||||||
|  | 	t.Helper() | ||||||
|  |  | ||||||
|  | 	priv1, err := rsa.GenerateKey(rand.Reader, 2048) | ||||||
|  | 	require.NotNil(t, priv1, "failed generating RSA 1 key") | ||||||
|  | 	require.NoError(t, err, "failed generating RSA 1 key") | ||||||
|  |  | ||||||
|  | 	rsa1, err = x509.MarshalPKCS8PrivateKey(priv1) | ||||||
|  | 	require.NotNil(t, rsa1, "failed marshaling RSA 1 key") | ||||||
|  | 	require.NoError(t, err, "failed marshaling RSA 1 key") | ||||||
|  |  | ||||||
|  | 	priv2, err := rsa.GenerateKey(rand.Reader, 2048) | ||||||
|  | 	require.NotNil(t, priv2, "failed generating RSA 2 key") | ||||||
|  | 	require.NoError(t, err, "failed generating RSA 2 key") | ||||||
|  |  | ||||||
|  | 	rsa2, err = x509.MarshalPKCS8PrivateKey(priv2) | ||||||
|  | 	require.NotNil(t, rsa2, "failed marshaling RSA 2 key") | ||||||
|  | 	require.NoError(t, err, "failed marshaling RSA 2 key") | ||||||
|  |  | ||||||
|  | 	aes128 = make([]byte, 128/8) | ||||||
|  | 	_, err = rand.Read(aes128) | ||||||
|  | 	require.NoError(t, err, "failed generating AES 128 key") | ||||||
|  |  | ||||||
|  | 	aes256 = make([]byte, 256/8) | ||||||
|  | 	_, err = rand.Read(aes256) | ||||||
|  | 	require.NoError(t, err, "failed generating AES 256 key") | ||||||
|  |  | ||||||
|  | 	return | ||||||
|  | } | ||||||
| @@ -22,21 +22,23 @@ func (c *TransitImportVersionCommand) Synopsis() string { | |||||||
|  |  | ||||||
| func (c *TransitImportVersionCommand) Help() string { | func (c *TransitImportVersionCommand) Help() string { | ||||||
| 	helpText := ` | 	helpText := ` | ||||||
| Usage: vault transit import-version PATH KEY | Usage: vault transit import-version PATH KEY [...] | ||||||
|  |  | ||||||
|   Using the Transit or Transform key wrapping system, imports key material from |   Using the Transit or Transform key wrapping system, imports key material from | ||||||
|   the base64 encoded KEY, into a new key whose API path is PATH.  To import a new transit/transform key, |   the base64 encoded KEY (either directly on the CLI or via @path notation), | ||||||
|   use import.  The remaining options after KEY (key=value style) are passed on to the transit/transform create key  |   into a new key whose API path is PATH.  To import a new transit/transform | ||||||
|   endpoint.  |   key, use the import command instead.  The remaining options after KEY | ||||||
|   If your system or device natively supports the RSA AES key wrap mechanism, you should use it directly  |   (key=value style) are passed on to the transit/transform create key endpoint. | ||||||
|   rather than this command. |   If your system or device natively supports the RSA AES key wrap mechanism | ||||||
|  |   (such as the PKCS#11 mechanism CKM_RSA_AES_KEY_WRAP), you should use it | ||||||
|  |   directly rather than this command. | ||||||
| ` + c.Flags().Help() | ` + c.Flags().Help() | ||||||
|  |  | ||||||
| 	return strings.TrimSpace(helpText) | 	return strings.TrimSpace(helpText) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (c *TransitImportVersionCommand) Flags() *FlagSets { | func (c *TransitImportVersionCommand) Flags() *FlagSets { | ||||||
| 	return c.flagSet(FlagSetHTTP | FlagSetOutputField | FlagSetOutputFormat) | 	return c.flagSet(FlagSetHTTP) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (c *TransitImportVersionCommand) AutocompleteArgs() complete.Predictor { | func (c *TransitImportVersionCommand) AutocompleteArgs() complete.Predictor { | ||||||
| @@ -48,5 +50,5 @@ func (c *TransitImportVersionCommand) AutocompleteFlags() complete.Flags { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (c *TransitImportVersionCommand) Run(args []string) int { | func (c *TransitImportVersionCommand) Run(args []string) int { | ||||||
| 	return importKey(c.BaseCommand, "import_version", args) | 	return importKey(c.BaseCommand, "import_version", c.Flags(), args) | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										62
									
								
								website/content/docs/commands/transit/import.mdx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								website/content/docs/commands/transit/import.mdx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | |||||||
|  | --- | ||||||
|  | layout: docs | ||||||
|  | page_title: transit import and transit import-version - Command | ||||||
|  | description: |- | ||||||
|  |   The "transit import" and "transit import-version" commands import the | ||||||
|  |   specified key into Transit, via the Transit BYOK mechanism. | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | # transit import and transit import-version | ||||||
|  |  | ||||||
|  | The `transit import` and `transit import-version` commands import the | ||||||
|  | specified key into Transit, via the [Transit BYOK | ||||||
|  | mechanism](/vault/docs/secrets/transit#bring-your-own-key-byok). The former | ||||||
|  | imports this key as a new key, failing if it already exists, whereas the | ||||||
|  | latter will only update an existing key in Transit to a new version of the | ||||||
|  | key material. | ||||||
|  |  | ||||||
|  | This needs access to read the transit mount's wrapping key (at | ||||||
|  | `transit/wrapping_key`) and the ability to write to either import | ||||||
|  | endpoints (either `transit/keys/:name/import` or | ||||||
|  | `transit/keys/:name/import_version`). | ||||||
|  |  | ||||||
|  | ## Examples | ||||||
|  |  | ||||||
|  | Imports a 2048-bit RSA key as a new key: | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | $ vault transit import transit/keys/test-key @test-key type=rsa-2048 | ||||||
|  | Retrieving transit wrapping key. | ||||||
|  | Wrapping source key with ephemeral key. | ||||||
|  | Encrypting ephemeral key with transit wrapping key. | ||||||
|  | Submitting wrapped key to Vault transit. | ||||||
|  | Success! | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Imports a new version of an existing key: | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | $ vault transit import-version transit/keys/test-key @test-key-updated | ||||||
|  | Retrieving transit wrapping key. | ||||||
|  | Wrapping source key with ephemeral key. | ||||||
|  | Encrypting ephemeral key with transit wrapping key. | ||||||
|  | Submitting wrapped key to Vault transit. | ||||||
|  | Success! | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## Usage | ||||||
|  |  | ||||||
|  | This command does not have any unique flags and respects core Vault CLI | ||||||
|  | commands. See `vault transit import -help` for more information. | ||||||
|  |  | ||||||
|  | This command requires two positional arguments: | ||||||
|  |  | ||||||
|  |  1. `PATH`, the path to the transit key to import in the format of | ||||||
|  |     `<mount>/keys/<key-name>`, where `<mount>` is the path to the mount | ||||||
|  |     (using `-namespace=<ns>` to specify any namespaces), and `<key-name>` | ||||||
|  |     is the desired name of the key. | ||||||
|  |  2. `KEY`, the key material to import in Standard Base64 encoding (either | ||||||
|  |     of a raw key in the case of symmetric keys such as AES, or of the DER | ||||||
|  |     encoded format for asymmetric keys such as RSA). If the value for `KEY` | ||||||
|  |     begins with an `@`, the CLI argument is assumed to be a path to a file | ||||||
|  |     on disk to be read. | ||||||
							
								
								
									
										32
									
								
								website/content/docs/commands/transit/index.mdx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								website/content/docs/commands/transit/index.mdx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | |||||||
|  | --- | ||||||
|  | layout: docs | ||||||
|  | page_title: transit - Command | ||||||
|  | description: |- | ||||||
|  |   The "transit" command groups subcommands for interacting with Vault's Transit | ||||||
|  |   secrets engine. | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | # transit | ||||||
|  |  | ||||||
|  | The `transit` command groups subcommands for interacting with Vault's | ||||||
|  | [Transit Secrets Engine](/vault/docs/secrets/transit). | ||||||
|  |  | ||||||
|  | ## Syntax | ||||||
|  |  | ||||||
|  | Option flags for a given subcommand are provided after the subcommand, but before the arguments. | ||||||
|  |  | ||||||
|  | ## Examples | ||||||
|  |  | ||||||
|  | To [import](/vault/docs/commands/transit/import) keys into a mount via the | ||||||
|  | [Transit BYOK](/vault/docs/secrets/transit#bring-your-own-key-byok) | ||||||
|  | mechanism, use the `vault transit import <path> <key>` or | ||||||
|  | `vault transit import-version <path> <key>` commands: | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | $ vault transit import transit/keys/test-key @test-key type=rsa-2048 | ||||||
|  | Retrieving transit wrapping key. | ||||||
|  | Wrapping source key with ephemeral key. | ||||||
|  | Encrypting ephemeral key with transit wrapping key. | ||||||
|  | Submitting wrapped key to Vault transit. | ||||||
|  | Success! | ||||||
|  | ``` | ||||||
| @@ -832,6 +832,19 @@ | |||||||
|           } |           } | ||||||
|         ] |         ] | ||||||
|       }, |       }, | ||||||
|  |       { | ||||||
|  |         "title": "<code>transit</code>", | ||||||
|  |         "routes": [ | ||||||
|  |           { | ||||||
|  |             "title": "Overview", | ||||||
|  |             "path": "commands/transit" | ||||||
|  |           }, | ||||||
|  |           { | ||||||
|  |             "title": "<code>import</code> and <code>import-version</code>", | ||||||
|  |             "path": "commands/transit/import" | ||||||
|  |           } | ||||||
|  |         ] | ||||||
|  |       }, | ||||||
|       { |       { | ||||||
|         "title": "<code>unwrap</code>", |         "title": "<code>unwrap</code>", | ||||||
|         "path": "commands/unwrap" |         "path": "commands/unwrap" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Alexander Scheel
					Alexander Scheel