From a3ec1a27dedc17b47b5fb9d2d87fe37158ff4442 Mon Sep 17 00:00:00 2001 From: Daniel Hougaard Date: Sun, 3 Nov 2024 22:13:45 +0400 Subject: [PATCH] fix: removed recovery --- backend/package-lock.json | 7 - backend/package.json | 1 - .../src/ee/services/license/license-fns.ts | 1 + .../src/ee/services/license/license-types.ts | 1 + backend/src/lib/crypto/index.ts | 1 - backend/src/lib/crypto/shamirs.ts | 38 ------ backend/src/server/routes/v1/admin-router.ts | 51 +------ backend/src/services/kms/kms-service.ts | 31 +---- .../super-admin/super-admin-service.ts | 51 ++----- cli/packages/api/api.go | 37 ----- cli/packages/api/model.go | 8 -- cli/packages/cmd/kms.go | 128 ------------------ frontend/src/hooks/api/admin/index.ts | 2 - frontend/src/hooks/api/admin/mutation.ts | 21 --- frontend/src/hooks/api/admin/types.ts | 1 - frontend/src/hooks/api/subscriptions/types.ts | 1 + .../admin/DashboardPage/EncryptionPanel.tsx | 94 +++---------- .../ExportRootKmsKeyModalContent.tsx | 53 -------- .../RestoreRootKmsKeyModalContent.tsx | 98 -------------- 19 files changed, 34 insertions(+), 591 deletions(-) delete mode 100644 backend/src/lib/crypto/shamirs.ts delete mode 100644 cli/packages/cmd/kms.go delete mode 100644 frontend/src/views/admin/DashboardPage/components/ExportRootKmsKeyModalContent.tsx delete mode 100644 frontend/src/views/admin/DashboardPage/components/RestoreRootKmsKeyModalContent.tsx diff --git a/backend/package-lock.json b/backend/package-lock.json index 52fc81f832..ef9f4e0d33 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -90,7 +90,6 @@ "safe-regex": "^2.1.1", "scim-patch": "^0.8.3", "scim2-parse-filter": "^0.2.10", - "secrets.js-grempe": "^2.0.0", "sjcl": "^1.0.8", "smee-client": "^2.0.0", "snowflake-sdk": "^1.14.0", @@ -18366,12 +18365,6 @@ "resolved": "https://registry.npmjs.org/scim2-parse-filter/-/scim2-parse-filter-0.2.10.tgz", "integrity": "sha512-k5TgGSuQEbR4jXRgw/GPAYVL9fMp1pWA2abLF5z3q9IGWSuZTqbrZBOSUezvc+rtViXr+czSZjg3eAN4QSTvxQ==" }, - "node_modules/secrets.js-grempe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/secrets.js-grempe/-/secrets.js-grempe-2.0.0.tgz", - "integrity": "sha512-4xkOIaDAg998dTFXZUJTOoVbdLHfB818SMeLJ69ABccgGEKokxsoRFupAFfAImloUSKv4QUGNMgKVbKMf6z0Ug==", - "license": "MIT" - }, "node_modules/secure-json-parse": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", diff --git a/backend/package.json b/backend/package.json index d063550e0f..0278689d33 100644 --- a/backend/package.json +++ b/backend/package.json @@ -195,7 +195,6 @@ "safe-regex": "^2.1.1", "scim-patch": "^0.8.3", "scim2-parse-filter": "^0.2.10", - "secrets.js-grempe": "^2.0.0", "sjcl": "^1.0.8", "smee-client": "^2.0.0", "snowflake-sdk": "^1.14.0", diff --git a/backend/src/ee/services/license/license-fns.ts b/backend/src/ee/services/license/license-fns.ts index 0864ab33cb..8e86851a0f 100644 --- a/backend/src/ee/services/license/license-fns.ts +++ b/backend/src/ee/services/license/license-fns.ts @@ -29,6 +29,7 @@ export const getDefaultOnPremFeatures = (): TFeatureSet => ({ auditLogStreams: false, auditLogStreamLimit: 3, samlSSO: false, + hsm: true, oidcSSO: false, scim: false, ldap: false, diff --git a/backend/src/ee/services/license/license-types.ts b/backend/src/ee/services/license/license-types.ts index 0ba54afc31..622b0e06b0 100644 --- a/backend/src/ee/services/license/license-types.ts +++ b/backend/src/ee/services/license/license-types.ts @@ -46,6 +46,7 @@ export type TFeatureSet = { auditLogStreams: false; auditLogStreamLimit: 3; samlSSO: false; + hsm: false; oidcSSO: false; scim: false; ldap: false; diff --git a/backend/src/lib/crypto/index.ts b/backend/src/lib/crypto/index.ts index 5ec76a6a2b..cc6acfb805 100644 --- a/backend/src/lib/crypto/index.ts +++ b/backend/src/lib/crypto/index.ts @@ -18,6 +18,5 @@ export { decryptSecrets, decryptSecretVersions } from "./secret-encryption"; -export { shamirsService } from "./shamirs"; export { verifyOfflineLicense } from "./signing"; export { generateSrpServerKey, srpCheckClientProof } from "./srp"; diff --git a/backend/src/lib/crypto/shamirs.ts b/backend/src/lib/crypto/shamirs.ts deleted file mode 100644 index 121c146b24..0000000000 --- a/backend/src/lib/crypto/shamirs.ts +++ /dev/null @@ -1,38 +0,0 @@ -import shamirs from "secrets.js-grempe"; - -import { getConfig } from "../config/env"; -import { symmetricCipherService, SymmetricEncryption } from "./cipher"; - -export const shamirsService = () => { - const $generateBasicEncryptionKey = () => { - const appCfg = getConfig(); - - const encryptionKey = appCfg.ENCRYPTION_KEY || appCfg.ROOT_ENCRYPTION_KEY; - const isBase64 = !appCfg.ENCRYPTION_KEY; - if (!encryptionKey) - throw new Error( - "Root encryption key not found for KMS service. Did you set the ENCRYPTION_KEY or ROOT_ENCRYPTION_KEY environment variables?" - ); - - return Buffer.from(encryptionKey, isBase64 ? "base64" : "utf8"); - }; - - const share = (secretBuffer: Buffer, partsCount: number, thresholdCount: number) => { - const cipher = symmetricCipherService(SymmetricEncryption.AES_GCM_256); - const hexSecret = Buffer.from(cipher.encrypt(secretBuffer, $generateBasicEncryptionKey())).toString("hex"); - - const secretParts = shamirs.share(hexSecret, partsCount, thresholdCount); - return secretParts; - }; - - const combine = (parts: string[]) => { - const encryptedSecret = shamirs.combine(parts); - - const cipher = symmetricCipherService(SymmetricEncryption.AES_GCM_256); - const decryptedSecret = cipher.decrypt(Buffer.from(encryptedSecret, "hex"), $generateBasicEncryptionKey()); - - return decryptedSecret; - }; - - return { share, combine }; -}; diff --git a/backend/src/server/routes/v1/admin-router.ts b/backend/src/server/routes/v1/admin-router.ts index 1136db3083..f3c1212330 100644 --- a/backend/src/server/routes/v1/admin-router.ts +++ b/backend/src/server/routes/v1/admin-router.ts @@ -196,54 +196,6 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => { } }); - server.route({ - method: "POST", - url: "/kms-export", - config: { - rateLimit: writeLimit - }, - schema: { - response: { - 200: z.object({ - secretParts: z.array(z.string()) - }) - } - }, - onRequest: (req, res, done) => { - verifyAuth([AuthMode.JWT])(req, res, () => { - verifySuperAdmin(req, res, done); - }); - }, - handler: async () => { - const keyParts = await server.services.superAdmin.exportPlainKmsKey(); - - return { - secretParts: keyParts - }; - } - }); - - server.route({ - method: "POST", - url: "/kms-import", - config: { - rateLimit: writeLimit - }, - schema: { - body: z.object({ - secretParts: z.array(z.string()) - }) - }, - onRequest: (req, res, done) => { - verifyAuth([AuthMode.JWT])(req, res, () => { - verifySuperAdmin(req, res, done); - }); - }, - handler: async (req) => { - await server.services.superAdmin.importPlainKmsKey(req.body.secretParts); - } - }); - server.route({ method: "GET", url: "/root-kms-config", @@ -259,8 +211,7 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => { name: z.string(), enabled: z.boolean() }) - .array(), - keyExported: z.boolean() + .array() }) } }, diff --git a/backend/src/services/kms/kms-service.ts b/backend/src/services/kms/kms-service.ts index c7f20dd722..df6f4692b0 100644 --- a/backend/src/services/kms/kms-service.ts +++ b/backend/src/services/kms/kms-service.ts @@ -11,7 +11,7 @@ import { } from "@app/ee/services/external-kms/providers/model"; import { KeyStorePrefixes, TKeyStoreFactory } from "@app/keystore/keystore"; import { getConfig } from "@app/lib/config/env"; -import { randomSecureBytes, shamirsService } from "@app/lib/crypto"; +import { randomSecureBytes } from "@app/lib/crypto"; import { symmetricCipherService, SymmetricEncryption } from "@app/lib/crypto/cipher"; import { generateHash } from "@app/lib/crypto/encryption"; import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors"; @@ -667,31 +667,6 @@ export const kmsServiceFactory = ({ throw new Error(`Invalid root key encryption strategy: ${strategy}`); }; - const exportRootEncryptionKeyParts = () => { - if (!ROOT_ENCRYPTION_KEY) { - throw new Error("Root encryption key not set"); - } - - const parts = shamirsService().share(ROOT_ENCRYPTION_KEY, 8, 4); - - return parts; - }; - - const importRootEncryptionKey = async (parts: string[]) => { - const decryptedRootKey = shamirsService().combine(parts); - - const encryptedRootKey = symmetricCipherService(SymmetricEncryption.AES_GCM_256).encrypt( - decryptedRootKey, - $getBasicEncryptionKey() - ); - - await kmsRootConfigDAL.updateById(KMS_ROOT_CONFIG_UUID, { - encryptedRootKey, - encryptionStrategy: RootKeyEncryptionStrategy.Basic - }); - ROOT_ENCRYPTION_KEY = decryptedRootKey; - }; - // by keeping the decrypted data key in inner scope // none of the entities outside can interact directly or expose the data key // NOTICE: If changing here update migrations/utils/kms @@ -972,8 +947,6 @@ export const kmsServiceFactory = ({ getProjectKeyBackup, loadProjectKeyBackup, getKmsById, - createCipherPairWithDataKey, - exportRootEncryptionKeyParts, - importRootEncryptionKey + createCipherPairWithDataKey }; }; diff --git a/backend/src/services/super-admin/super-admin-service.ts b/backend/src/services/super-admin/super-admin-service.ts index 315b30b169..97f314db80 100644 --- a/backend/src/services/super-admin/super-admin-service.ts +++ b/backend/src/services/super-admin/super-admin-service.ts @@ -23,14 +23,7 @@ type TSuperAdminServiceFactoryDep = { serverCfgDAL: TSuperAdminDALFactory; userDAL: TUserDALFactory; authService: Pick; - kmsService: Pick< - TKmsServiceFactory, - | "encryptWithRootKey" - | "decryptWithRootKey" - | "exportRootEncryptionKeyParts" - | "importRootEncryptionKey" - | "updateEncryptionStrategy" - >; + kmsService: Pick; kmsRootConfigDAL: TKmsRootConfigDALFactory; orgService: Pick; keyStore: Pick; @@ -162,35 +155,6 @@ export const superAdminServiceFactory = ({ return updatedServerCfg; }; - const exportPlainKmsKey = async () => { - const kmsRootConfig = await kmsRootConfigDAL.findById(KMS_ROOT_CONFIG_UUID); - - if (!kmsRootConfig) { - throw new NotFoundError({ name: "KmsRootConfig", message: "KMS root configuration not found" }); - } - - if (kmsRootConfig.exported) { - throw new BadRequestError({ name: "KmsRootConfig", message: "KMS root configuration already exported" }); - } - - await kmsRootConfigDAL.updateById(KMS_ROOT_CONFIG_UUID, { exported: true }); - return kmsService.exportRootEncryptionKeyParts(); - }; - - const importPlainKmsKey = async (secretParts: string[]) => { - const kmsRootConfig = await kmsRootConfigDAL.findById(KMS_ROOT_CONFIG_UUID); - - if (!kmsRootConfig) { - throw new NotFoundError({ name: "KmsRootConfig", message: "KMS root configuration not found" }); - } - - if (!kmsRootConfig.exported) { - throw new BadRequestError({ name: "KmsRootConfig", message: "KMS root configuration was never exported" }); - } - - await kmsService.importRootEncryptionKey(secretParts); - }; - const adminSignUp = async ({ lastName, firstName, @@ -361,12 +325,17 @@ export const superAdminServiceFactory = ({ } return { - strategies: enabledStrategies, - keyExported: kmsRootCfg.exported + strategies: enabledStrategies }; }; const updateRootEncryptionStrategy = async (strategy: RootKeyEncryptionStrategy) => { + if (!licenseService.onPremFeatures.hsm) { + throw new BadRequestError({ + message: "Failed to update encryption strategy due to plan restriction. Upgrade to Infisical's Enterprise plan." + }); + } + const configuredStrategies = await getConfiguredEncryptionStrategies(); const foundStrategy = configuredStrategies.strategies.find((s) => s.strategy === strategy); @@ -390,8 +359,6 @@ export const superAdminServiceFactory = ({ deleteUser, getAdminSlackConfig, updateRootEncryptionStrategy, - getConfiguredEncryptionStrategies, - exportPlainKmsKey, - importPlainKmsKey + getConfiguredEncryptionStrategies }; }; diff --git a/cli/packages/api/api.go b/cli/packages/api/api.go index d8d8849cbf..35767cd3f1 100644 --- a/cli/packages/api/api.go +++ b/cli/packages/api/api.go @@ -525,40 +525,3 @@ 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 -} diff --git a/cli/packages/api/model.go b/cli/packages/api/model.go index faf0db5979..adf7a814d3 100644 --- a/cli/packages/api/model.go +++ b/cli/packages/api/model.go @@ -617,11 +617,3 @@ type GetRawSecretV3ByNameResponse struct { } `json:"secret"` ETag string } - -type ExportKmsRootKeyResponse struct { - SecretParts []string `json:"secretParts"` -} - -type ImportKmsRootKeyRequest struct { - SecretParts []string `json:"secretParts"` -} diff --git a/cli/packages/cmd/kms.go b/cli/packages/cmd/kms.go deleted file mode 100644 index 6808c35b9e..0000000000 --- a/cli/packages/cmd/kms.go +++ /dev/null @@ -1,128 +0,0 @@ -/* -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) - -} diff --git a/frontend/src/hooks/api/admin/index.ts b/frontend/src/hooks/api/admin/index.ts index d3b3d17eb6..5405878c7c 100644 --- a/frontend/src/hooks/api/admin/index.ts +++ b/frontend/src/hooks/api/admin/index.ts @@ -1,8 +1,6 @@ export { useAdminDeleteUser, useCreateAdminUser, - useExportServerDecryptionKey, - useImportServerDecryptionKey, useUpdateAdminSlackConfig, useUpdateServerConfig, useUpdateServerEncryptionStrategy diff --git a/frontend/src/hooks/api/admin/mutation.ts b/frontend/src/hooks/api/admin/mutation.ts index b2e6b96071..30fffca3b2 100644 --- a/frontend/src/hooks/api/admin/mutation.ts +++ b/frontend/src/hooks/api/admin/mutation.ts @@ -98,24 +98,3 @@ export const useUpdateServerEncryptionStrategy = () => { } }); }; - -export const useExportServerDecryptionKey = () => { - return useMutation({ - mutationFn: async () => { - const { data } = await apiRequest.post<{ secretParts: string[] }>("/api/v1/admin/kms-export"); - return data.secretParts; - } - }); -}; - -export const useImportServerDecryptionKey = () => { - const queryClient = useQueryClient(); - return useMutation({ - mutationFn: async (secretParts: string[]) => { - await apiRequest.post("/api/v1/admin/kms-import", { secretParts }); - }, - onSuccess: () => { - queryClient.invalidateQueries(adminQueryKeys.serverConfig()); - } - }); -}; diff --git a/frontend/src/hooks/api/admin/types.ts b/frontend/src/hooks/api/admin/types.ts index 056391f85c..0fa6d23ef1 100644 --- a/frontend/src/hooks/api/admin/types.ts +++ b/frontend/src/hooks/api/admin/types.ts @@ -61,7 +61,6 @@ export type TGetServerRootKmsEncryptionDetails = { enabled: boolean; name: string; }[]; - keyExported: boolean; }; export enum RootKeyEncryptionStrategy { diff --git a/frontend/src/hooks/api/subscriptions/types.ts b/frontend/src/hooks/api/subscriptions/types.ts index 1ab01ef05b..b1c4e224d2 100644 --- a/frontend/src/hooks/api/subscriptions/types.ts +++ b/frontend/src/hooks/api/subscriptions/types.ts @@ -23,6 +23,7 @@ export type SubscriptionPlan = { workspacesUsed: number; environmentLimit: number; samlSSO: boolean; + hsm: boolean; oidcSSO: boolean; scim: boolean; ldap: boolean; diff --git a/frontend/src/views/admin/DashboardPage/EncryptionPanel.tsx b/frontend/src/views/admin/DashboardPage/EncryptionPanel.tsx index 7a7794db74..ad32df9982 100644 --- a/frontend/src/views/admin/DashboardPage/EncryptionPanel.tsx +++ b/frontend/src/views/admin/DashboardPage/EncryptionPanel.tsx @@ -1,12 +1,11 @@ import { useCallback } from "react"; import { Controller, useForm } from "react-hook-form"; -import { faExclamationCircle } from "@fortawesome/free-solid-svg-icons"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; import { createNotification } from "@app/components/notifications"; -import { Button, FormControl, Modal, Select, SelectItem, Tooltip } from "@app/components/v2"; +import { Button, FormControl, Select, SelectItem, UpgradePlanModal } from "@app/components/v2"; +import { useSubscription } from "@app/context"; import { usePopUp } from "@app/hooks"; import { useUpdateServerEncryptionStrategy } from "@app/hooks/api"; import { @@ -14,9 +13,6 @@ import { TGetServerRootKmsEncryptionDetails } from "@app/hooks/api/admin/types"; -import { ExportRootKmsKeyModalContent } from "./components/ExportRootKmsKeyModalContent"; -import { RestoreRootKmsKeyModalContent } from "./components/RestoreRootKmsKeyModalContent"; - const formSchema = z.object({ encryptionStrategy: z.nativeEnum(RootKeyEncryptionStrategy) }); @@ -29,10 +25,9 @@ type Props = { export const EncryptionPanel = ({ rootKmsDetails }: Props) => { const { mutateAsync: updateEncryptionStrategy } = useUpdateServerEncryptionStrategy(); - const { handlePopUpToggle, handlePopUpOpen, popUp } = usePopUp([ - "exportKey", - "restoreKey" - ] as const); + const { subscription } = useSubscription(); + + const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp(["upgradePlan"] as const); const { control, @@ -48,16 +43,18 @@ export const EncryptionPanel = ({ rootKmsDetails }: Props) => { }); const onSubmit = useCallback(async (formData: TForm) => { + if (!subscription) return; + + if (!subscription.hsm) { + handlePopUpOpen("upgradePlan", { + description: "Hardware Security Module's (HSM's), are only available on Enterprise plans." + }); + return; + } + try { await updateEncryptionStrategy(formData.encryptionStrategy); - if ( - !rootKmsDetails.keyExported && - formData.encryptionStrategy !== RootKeyEncryptionStrategy.Basic - ) { - handlePopUpOpen("exportKey"); - } - createNotification({ type: "success", text: "Encryption strategy updated successfully" @@ -81,50 +78,6 @@ export const EncryptionPanel = ({ rootKmsDetails }: Props) => {
KMS Encryption Strategy
- - {!rootKmsDetails.keyExported && ( -
- - You have not exported the KMS root encryption key. Switch to HSM encryption or - run the{" "} - - - infisical kms export - - {" "} - CLI command to export the key parts. -
- )} -
- If you experience issues with accessing projects while not using Regular - Encryption (default), you can restore the KMS root encryption key by using your - exported key parts. -

- If you do not have the exported key parts, you can export them by using the CLI - command -
- - - infisical kms export - - - .
-
- - Please keep in mind that you can only export the key parts once. - - - } - > - -
Select which type of encryption strategy you want to use for your KMS root key. HSM is @@ -163,20 +116,11 @@ export const EncryptionPanel = ({ rootKmsDetails }: Props) => { Save - - handlePopUpToggle("exportKey", state)} - > - - - - handlePopUpToggle("restoreKey", state)} - > - - + handlePopUpToggle("upgradePlan", isOpen)} + text={(popUp.upgradePlan?.data as { description: string })?.description} + /> ); }; diff --git a/frontend/src/views/admin/DashboardPage/components/ExportRootKmsKeyModalContent.tsx b/frontend/src/views/admin/DashboardPage/components/ExportRootKmsKeyModalContent.tsx deleted file mode 100644 index f59a8ac416..0000000000 --- a/frontend/src/views/admin/DashboardPage/components/ExportRootKmsKeyModalContent.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { useCallback, useState } from "react"; - -import { Button, ModalContent } from "@app/components/v2"; -import { useExportServerDecryptionKey } from "@app/hooks/api"; -import { useFileDownload } from "@app/hooks/useFileDownload"; -import { UsePopUpState } from "@app/hooks/usePopUp"; - -type Props = { - handlePopUpToggle: (popUpName: keyof UsePopUpState<["exportKey"]>, state?: boolean) => void; -}; - -export const ExportRootKmsKeyModalContent = ({ handlePopUpToggle }: Props) => { - const { mutateAsync: exportKey, isLoading } = useExportServerDecryptionKey(); - const downloadFile = useFileDownload(); - const [downloaded, setDownloaded] = useState(false); - - const onExport = useCallback(async () => { - const keyParts = await exportKey(); - downloadFile(keyParts.join("\n\n"), "infisical-encryption-key-parts.txt"); - setDownloaded(true); - }, []); - - return ( - -
- {!downloaded ? ( - <> - - - - - ) : ( -
- The key parts have been downloaded. Please store them in a safe place. You will need - these keys incase you need to recovery the KMS root encryption key. Please consult our - documentation for further instructions. -
- )} -
-
- ); -}; diff --git a/frontend/src/views/admin/DashboardPage/components/RestoreRootKmsKeyModalContent.tsx b/frontend/src/views/admin/DashboardPage/components/RestoreRootKmsKeyModalContent.tsx deleted file mode 100644 index 8122c44e33..0000000000 --- a/frontend/src/views/admin/DashboardPage/components/RestoreRootKmsKeyModalContent.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import { useMemo } from "react"; -import { Controller, useForm } from "react-hook-form"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { z } from "zod"; - -import { createNotification } from "@app/components/notifications"; -import { Button, FormControl, Input, ModalContent } from "@app/components/v2"; -import { useImportServerDecryptionKey } from "@app/hooks/api"; -import { UsePopUpState } from "@app/hooks/usePopUp"; - -type Props = { - handlePopUpToggle: (popUpName: keyof UsePopUpState<["restoreKey"]>, state?: boolean) => void; -}; - -const formSchema = z.object({ - keyParts: z - .array(z.string()) - .refine((data) => data.length === 4 && data.every((part) => part.length > 0), { - message: "Enter at least 4 key parts in order to restore the KMS root decryption key." - }) -}); -type TForm = z.infer; - -export const RestoreRootKmsKeyModalContent = ({ handlePopUpToggle }: Props) => { - const { mutateAsync: importKmsRootKey } = useImportServerDecryptionKey(); - - const { - control, - handleSubmit, - watch, - formState: { isSubmitting, errors, isLoading, isValid } - } = useForm({ - resolver: zodResolver(formSchema), - values: { - keyParts: ["", "", "", ""] - } - }); - - const keyParts = useMemo(() => watch("keyParts"), []); - - return ( - - - -
- } - > -
-
- {keyParts.map((_, index) => ( - ( -
- - - -
- )} - /> - ))} - {errors.keyParts && ( -
{errors.keyParts.message}
- )} -
-
- - ); -};