mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat: HSM support
This commit is contained in:
@@ -525,3 +525,40 @@ func CallUpdateRawSecretsV3(httpClient *resty.Client, request UpdateRawSecretByN
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func CallExportKmsRootEncryptionKey(httpClient *resty.Client) (ExportKmsRootKeyResponse, error) {
|
||||
var exportKmsKeyResponse ExportKmsRootKeyResponse
|
||||
response, err := httpClient.
|
||||
R().
|
||||
SetResult(&exportKmsKeyResponse).
|
||||
SetHeader("User-Agent", USER_AGENT).
|
||||
Post(fmt.Sprintf("%v/v1/admin/kms-export", config.INFISICAL_URL))
|
||||
|
||||
if err != nil {
|
||||
return ExportKmsRootKeyResponse{}, fmt.Errorf("CallSuperAdminExportKmsKey: Unable to complete api request [err=%w]", err)
|
||||
}
|
||||
|
||||
if response.IsError() {
|
||||
return ExportKmsRootKeyResponse{}, fmt.Errorf("CallSuperAdminExportKmsKey: Unsuccessful response [%v %v] [status-code=%v] [response=%v]", response.Request.Method, response.Request.URL, response.StatusCode(), response.String())
|
||||
}
|
||||
|
||||
return exportKmsKeyResponse, nil
|
||||
}
|
||||
|
||||
func CallImportKmsRootEncryptionKey(httpClient *resty.Client, request ImportKmsRootKeyRequest) error {
|
||||
response, err := httpClient.
|
||||
R().
|
||||
SetHeader("User-Agent", USER_AGENT).
|
||||
SetBody(request).
|
||||
Post(fmt.Sprintf("%v/v1/admin/kms-import", config.INFISICAL_URL))
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("CallSuperAdminImportKmsKey: Unable to complete api request [err=%w]", err)
|
||||
}
|
||||
|
||||
if response.IsError() {
|
||||
return fmt.Errorf("CallSuperAdminImportKmsKey: Unsuccessful response [%v %v] [status-code=%v] [response=%v]", response.Request.Method, response.Request.URL, response.StatusCode(), response.String())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -136,8 +136,8 @@ type GetOrganizationsResponse struct {
|
||||
}
|
||||
|
||||
type SelectOrganizationResponse struct {
|
||||
Token string `json:"token"`
|
||||
MfaEnabled bool `json:"isMfaEnabled"`
|
||||
Token string `json:"token"`
|
||||
MfaEnabled bool `json:"isMfaEnabled"`
|
||||
}
|
||||
|
||||
type SelectOrganizationRequest struct {
|
||||
@@ -617,3 +617,11 @@ type GetRawSecretV3ByNameResponse struct {
|
||||
} `json:"secret"`
|
||||
ETag string
|
||||
}
|
||||
|
||||
type ExportKmsRootKeyResponse struct {
|
||||
SecretParts []string `json:"secretParts"`
|
||||
}
|
||||
|
||||
type ImportKmsRootKeyRequest struct {
|
||||
SecretParts []string `json:"secretParts"`
|
||||
}
|
||||
|
||||
128
cli/packages/cmd/kms.go
Normal file
128
cli/packages/cmd/kms.go
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
Copyright (c) 2023 Infisical Inc.
|
||||
*/
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Infisical/infisical-merge/packages/api"
|
||||
"github.com/Infisical/infisical-merge/packages/util"
|
||||
"github.com/fatih/color"
|
||||
"github.com/go-resty/resty/v2"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var kmsCmd = &cobra.Command{
|
||||
Use: "kms",
|
||||
Short: "Manage your Infisical KMS encryption keys",
|
||||
DisableFlagsInUseLine: true,
|
||||
Example: "infisical kms",
|
||||
Args: cobra.ExactArgs(0),
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
util.RequireLogin()
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
},
|
||||
}
|
||||
|
||||
// exportCmd represents the export command
|
||||
var exportKeyCmd = &cobra.Command{
|
||||
Use: "export",
|
||||
Short: "Used to export your Infisical root encryption key parts, to be used for recovery (infisical import-key [...parts])",
|
||||
DisableFlagsInUseLine: true,
|
||||
Example: "infisical kms export",
|
||||
Args: cobra.NoArgs,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
loggedInDetails, err := util.GetCurrentLoggedInUserDetails()
|
||||
|
||||
if err != nil {
|
||||
util.HandleError(err)
|
||||
}
|
||||
|
||||
if !loggedInDetails.IsUserLoggedIn || loggedInDetails.LoginExpired {
|
||||
util.HandleError(fmt.Errorf("You must be logged in to run this command"))
|
||||
}
|
||||
|
||||
httpClient := resty.New()
|
||||
httpClient.SetAuthToken(loggedInDetails.UserCredentials.JTWToken).
|
||||
SetHeader("Accept", "application/json")
|
||||
|
||||
res, err := api.CallExportKmsRootEncryptionKey(httpClient)
|
||||
|
||||
if err != nil {
|
||||
|
||||
if strings.Contains(err.Error(), "configuration already exported") {
|
||||
util.HandleError(fmt.Errorf("This KMS encryption key has already been exported. You can only export the decryption key once."))
|
||||
} else {
|
||||
util.HandleError(err)
|
||||
}
|
||||
}
|
||||
|
||||
boldGreen := color.New(color.FgGreen).Add(color.Bold)
|
||||
time.Sleep(time.Second * 1)
|
||||
boldGreen.Printf(">>>> Successfully exported KMS encryption key\n\n")
|
||||
|
||||
plainBold := color.New(color.Bold)
|
||||
|
||||
for i, part := range res.SecretParts {
|
||||
plainBold.Printf("Part %d: %v\n", i+1, part)
|
||||
}
|
||||
|
||||
boldYellow := color.New(color.FgYellow).Add(color.Bold)
|
||||
boldYellow.Printf("\nPlease store these parts in a secure location. You will need them to recover your KMS encryption key.\nYou will not be able to export these credentials again in the future.\n\n")
|
||||
},
|
||||
}
|
||||
|
||||
var importKeyCmd = &cobra.Command{
|
||||
Use: "import",
|
||||
Short: "Used to import your Infisical root encryption key parts, to be used for recovery (infisical import-key [...parts])",
|
||||
DisableFlagsInUseLine: true,
|
||||
Example: "infisical kms import",
|
||||
Args: cobra.MinimumNArgs(6),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
loggedInDetails, err := util.GetCurrentLoggedInUserDetails()
|
||||
|
||||
if err != nil {
|
||||
util.HandleError(err)
|
||||
}
|
||||
|
||||
if !loggedInDetails.IsUserLoggedIn || loggedInDetails.LoginExpired {
|
||||
util.HandleError(fmt.Errorf("You must be logged in to run this command"))
|
||||
}
|
||||
|
||||
httpClient := resty.New()
|
||||
httpClient.SetAuthToken(loggedInDetails.UserCredentials.JTWToken).
|
||||
SetHeader("Accept", "application/json")
|
||||
|
||||
err = api.CallImportKmsRootEncryptionKey(httpClient, api.ImportKmsRootKeyRequest{
|
||||
SecretParts: args,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "configuration was never exported") {
|
||||
util.HandleError(fmt.Errorf("This KMS encryption key has not been exported yet. You must export the key first before you can import it."))
|
||||
} else {
|
||||
util.HandleError(err)
|
||||
}
|
||||
}
|
||||
|
||||
boldGreen := color.New(color.FgGreen).Add(color.Bold)
|
||||
time.Sleep(time.Second * 1)
|
||||
boldGreen.Printf(">>>> Successfully imported KMS encryption key\n\n")
|
||||
|
||||
boldYellow := color.New(color.FgYellow).Add(color.Bold)
|
||||
boldYellow.Printf("Important: Make sure to set the `ROOT_KEY_ENCRYPTION_STRATEGY` environment variable to `BASIC` on your Infisical instance.\nNot doing this will likely result in having to re-import the key on the next instance restart.\n\n")
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
kmsCmd.AddCommand(exportKeyCmd)
|
||||
kmsCmd.AddCommand(importKeyCmd)
|
||||
|
||||
rootCmd.AddCommand(kmsCmd)
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user