diff --git a/backend/src/server/routes/v3/external-migration-router.ts b/backend/src/server/routes/v3/external-migration-router.ts index 0681a8bc9e..89621811dc 100644 --- a/backend/src/server/routes/v3/external-migration-router.ts +++ b/backend/src/server/routes/v3/external-migration-router.ts @@ -64,7 +64,7 @@ export const registerExternalMigrationRouter = async (server: FastifyZodProvider schema: { body: z.object({ vaultAccessToken: z.string(), - vaultNamespace: z.string(), + vaultNamespace: z.string().trim().optional(), vaultUrl: z.string(), mappingType: z.nativeEnum(VaultMappingType) }) diff --git a/backend/src/services/external-migration/external-migration-fns/vault.ts b/backend/src/services/external-migration/external-migration-fns/vault.ts index a61b2e703a..197102f820 100644 --- a/backend/src/services/external-migration/external-migration-fns/vault.ts +++ b/backend/src/services/external-migration/external-migration-fns/vault.ts @@ -1,6 +1,10 @@ import axios, { AxiosInstance } from "axios"; import { v4 as uuidv4 } from "uuid"; +import { BadRequestError } from "@app/lib/errors"; +import { logger } from "@app/lib/logger"; +import { blockLocalAndPrivateIpAddresses } from "@app/lib/validator"; + import { InfisicalImportData, VaultMappingType } from "../external-migration-types"; type VaultData = { @@ -12,18 +16,25 @@ type VaultData = { const vaultFactory = () => { const getMounts = async (request: AxiosInstance) => { - const response = await request.get< - Record< - string, - { - accessor: string; - options: { - version?: string; - } | null; - type: string; + const response = await request + .get< + Record< + string, + { + accessor: string; + options: { + version?: string; + } | null; + type: string; + } + > + >("/v1/sys/mounts") + .catch((err) => { + if (axios.isAxiosError(err)) { + logger.error(err.response?.data, "External migration: Failed to get Vault mounts"); } - > - >("/v1/sys/mounts"); + throw err; + }); return response.data; }; @@ -42,8 +53,11 @@ const vaultFactory = () => { return response.data.data.keys; } catch (err) { - if (axios.isAxiosError(err) && err.response?.status === 404) { - return null; + if (axios.isAxiosError(err)) { + logger.error(err.response?.data, "External migration: Failed to get Vault paths"); + if (err.response?.status === 404) { + return null; + } } throw err; } @@ -54,17 +68,24 @@ const vaultFactory = () => { { mountPath, secretPath }: { mountPath: string; secretPath: string } ) => { // For KV v2: /v1/{mount}/data/{path} - const response = await request.get<{ - data: { - data: Record; // KV v2 has nested data structure - metadata: { - created_time: string; - deletion_time: string; - destroyed: boolean; - version: number; + const response = await request + .get<{ + data: { + data: Record; // KV v2 has nested data structure + metadata: { + created_time: string; + deletion_time: string; + destroyed: boolean; + version: number; + }; }; - }; - }>(`/v1/${mountPath}/data/${secretPath}`); + }>(`/v1/${mountPath}/data/${secretPath}`) + .catch((err) => { + if (axios.isAxiosError(err)) { + logger.error(err.response?.data, "External migration: Failed to get Vault secret"); + } + throw err; + }); return response.data.data.data; }; @@ -110,14 +131,14 @@ const vaultFactory = () => { accessToken }: { baseUrl: string; - namespace: string; + namespace?: string; accessToken: string; }): Promise { const request = axios.create({ baseURL: baseUrl, headers: { - "X-Vault-Namespace": namespace, - "X-Vault-Token": accessToken + "X-Vault-Token": accessToken, + ...(namespace ? { "X-Vault-Namespace": namespace } : {}) } }); @@ -152,7 +173,7 @@ const vaultFactory = () => { }); allData.push({ - namespace, + namespace: namespace || "", mount: mountPath.replace(/\/$/, ""), path: secretPath.replace(`${cleanMountPath}/`, ""), secretData @@ -190,7 +211,7 @@ export const transformToInfisicalFormatNamespaceToProjects = ( for (const data of vaultData) { const { namespace, mount, path, secretData } = data; - if (mappingType === "namespace") { + if (mappingType === VaultMappingType.Namespace) { // create project (namespace) if (!projectMap.has(namespace)) { const projectId = uuidv4(); @@ -214,7 +235,7 @@ export const transformToInfisicalFormatNamespaceToProjects = ( }); } environmentId = environmentMap.get(envKey)!; - } else if (mappingType === "key-vault") { + } else if (mappingType === VaultMappingType.KeyVault) { if (!projectMap.has(mount)) { const projectId = uuidv4(); projectMap.set(mount, projectId); @@ -294,10 +315,18 @@ export const importVaultDataFn = async ({ mappingType }: { vaultAccessToken: string; - vaultNamespace: string; + vaultNamespace?: string; vaultUrl: string; mappingType: VaultMappingType; }) => { + await blockLocalAndPrivateIpAddresses(vaultUrl); + + if (mappingType === VaultMappingType.Namespace && !vaultNamespace) { + throw new BadRequestError({ + message: "Vault namespace is required when project mapping type is set to namespace." + }); + } + const vaultApi = vaultFactory(); const vaultData = await vaultApi.collectVaultData({ diff --git a/backend/src/services/external-migration/external-migration-types.ts b/backend/src/services/external-migration/external-migration-types.ts index f3431b5c93..89589d674c 100644 --- a/backend/src/services/external-migration/external-migration-types.ts +++ b/backend/src/services/external-migration/external-migration-types.ts @@ -33,7 +33,7 @@ export type TImportEnvKeyDataDTO = { export type TImportVaultDataDTO = { vaultAccessToken: string; - vaultNamespace: string; + vaultNamespace?: string; mappingType: VaultMappingType; vaultUrl: string; } & Omit; diff --git a/docs/docs.json b/docs/docs.json index 13ec5367e4..e0d7a20318 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -198,6 +198,21 @@ "documentation/platform/workflow-integrations/microsoft-teams-integration" ] }, + { + "group": "External Migrations", + "pages": [ + "documentation/platform/external-migrations/overview", + "documentation/platform/external-migrations/envkey", + "documentation/platform/external-migrations/vault" + ] + }, + { + "group": "External Migrations", + "pages": [ + "documentation/platform/workflow-integrations/slack-integration", + "documentation/platform/workflow-integrations/microsoft-teams-integration" + ] + }, { "group": "Admin Consoles", "pages": [ diff --git a/docs/documentation/guides/migrating-from-envkey.mdx b/docs/documentation/guides/migrating-from-envkey.mdx deleted file mode 100644 index e1d75bab07..0000000000 --- a/docs/documentation/guides/migrating-from-envkey.mdx +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: "Migrating from EnvKey to Infisical" -sidebarTitle: "Migration" -description: "Learn how to migrate from EnvKey to Infisical in the easiest way possible." ---- - -## What is Infisical? - -[Infisical](https://infisical.com) is an open-source all-in-one secret management platform that helps developers manage secrets (e.g., API-keys, DB access tokens, [certificates](https://infisical.com/docs/documentation/platform/pki/overview)) across their infrastructure. In addition, Infisical provides [secret sharing](https://infisical.com/docs/documentation/platform/secret-sharing) functionality, ability to [prevent secret leaks](https://infisical.com/docs/cli/scanning-overview), and more. - -Infisical is used by 10,000+ organizations across all industries including First American Financial Corporation, Delivery Hero, and [Hugging Face](https://infisical.com/customers/hugging-face). - -## Migrating from EnvKey - - - -Open the EnvKey dashboard and go to My Org. -![EnvKey Dashboard](../../images/guides/import-envkey/envkey-dashboard.png) - - -Go to Import/Export on the top right corner, Click on Export Org and save the exported file. -![Export organization](../../images/guides/import-envkey/envkey-export.png) - - -Click on copy to copy the encryption key and save it. -![Copy encryption key](../../images/guides/import-envkey/copy-encryption-key.png) - - -Open the Infisical dashboard and go to Organization Settings > Import. -![Infisical Organization settings](../../images/guides/import-envkey/infisical-import-dashboard.png) - - -Upload the exported file from EnvKey, paste the encryption key and click Import. -![Infisical Import EnvKey](../../images/guides/import-envkey/infisical-import-envkey.png) - - - - -## Talk to our team - -To make the migration process even more seamless, you can [schedule a meeting with our team](https://infisical.cal.com/vlad/migration-from-envkey-to-infisical) to learn more about how Infisical compares to EnvKey and discuss unique needs of your organization. You are also welcome to email us at [support@infisical.com](mailto:support@infisical.com) to ask any questions or get any technical help. diff --git a/docs/documentation/platform/external-migrations/envkey.mdx b/docs/documentation/platform/external-migrations/envkey.mdx new file mode 100644 index 0000000000..46051cd49b --- /dev/null +++ b/docs/documentation/platform/external-migrations/envkey.mdx @@ -0,0 +1,44 @@ +--- +title: "Migrating from EnvKey to Infisical" +sidebarTitle: "EnvKey" +description: "Learn how to migrate secrets from EnvKey to Infisical." +--- + +## Migrating from EnvKey + + + + ![EnvKey Dashboard](/images/platform/external-migrations/envkey-dashboard.png) + + + Go to Import/Export on the top right corner, Click on Export Org and save the exported file. + ![Export organization](/images/platform/external-migrations/envkey-export.png) + + + Click on copy to copy the encryption key and save it. + ![Copy encryption key](/images/platform/external-migrations/envkey-copy-encryption-key.png) + + + Open the Infisical dashboard and go to Organization Settings > External Migrations. + ![Infisical Organization settings](/images/platform/external-migrations/infisical-external-migration-dashboard.png) + + + + Select the EnvKey platform and click on Next. + ![Select EnvKey platform](/images/platform/external-migrations/infisical-import-envkey-modal.png) + + + + Upload the exported file from EnvKey, paste the encryption key and click Import data. + ![Infisical Import EnvKey](/images/platform/external-migrations/infisical-import-envkey.png) + + + + + It may take several minutes to complete the migration. You will receive an email when the migration is complete, or if there were any errors during the migration process. + + + +## Talk to our team + +To make the migration process even more seamless, you can [schedule a meeting with our team](https://infisical.cal.com/vlad/migration-from-envkey-to-infisical) to learn more about how Infisical compares to EnvKey and discuss unique needs of your organization. You are also welcome to email us at [support@infisical.com](mailto:support@infisical.com) to ask any questions or get any technical help. diff --git a/docs/documentation/platform/external-migrations/overview.mdx b/docs/documentation/platform/external-migrations/overview.mdx new file mode 100644 index 0000000000..cf6c5e5a14 --- /dev/null +++ b/docs/documentation/platform/external-migrations/overview.mdx @@ -0,0 +1,16 @@ +--- +title: "External Migrations" +sidebarTitle: "Overview" +description: "Learn how to migrate secrets from third-party secrets management platforms to Infisical." +--- + +## Overview + +Infisical supports migrating secrets from third-party secrets management platforms to Infisical. This is useful if you're looking to easily switch to Infisical and wish to move over your existing secrets from a different platform. + +## Supported Platforms + +- [EnvKey](./envkey) +- [Vault](./vault) + +We're always looking to add more migration paths for other providers. If we're missing a platform, please open an issue on our [GitHub repository](https://github.com/infisical/infisical/issues). \ No newline at end of file diff --git a/docs/documentation/platform/external-migrations/vault.mdx b/docs/documentation/platform/external-migrations/vault.mdx new file mode 100644 index 0000000000..ef139e8e4a --- /dev/null +++ b/docs/documentation/platform/external-migrations/vault.mdx @@ -0,0 +1,127 @@ +--- +title: "Migrating from Vault to Infisical" +sidebarTitle: "Vault" +description: "Learn how to migrate secrets from Vault to Infisical." +--- + +## Migrating from Vault + +Migrating from Vault Self-Hosted or Dedicated Vault is a straight forward process with our inbuilt migration option. In order to migrate from Vault, you'll need to provide Infisical an access token to your Vault instance. + +Currently the Vault migration only supports migrating secrets from the KV v2 secrets engine. If you're using a different secrets engine, please open an issue on our [GitHub repository](https://github.com/infisical/infisical/issues). + + +### Prerequisites + +- A Vault instance with the KV v2 secrets engine enabled. +- An access token to your Vault instance. + + +### Project Mapping + +When migrating from Vault, you'll need to choose how you want to map your Vault resources to Infisical projects. + +There are two options for project mapping: + +- `Namespace`: This will map your selected Vault namespace to a single Infisical project. When you select this option, each KV secret engine within the namespace will be mapped to a single Infisical project. Each KV secret engine will be mapped to a Infisical environment within the project. This means if you have 3 KV secret engines, you'll have 3 environments inside the same project, where the name of the environments correspond to the name of the KV secret engines. +- `Key Vault`: This will map all the KV secret engines within your Vault instance to a Infisical project. Each KV engine will be created as a Infisical project. This means if you have 3 KV secret engines, you'll have 3 Infisical projects. For each of the created projects, a single default environment will be created called `Production`, which will contain all your secrets from the corresponding KV secret engine. + + + + + + + In order to migrate from Vault, you'll need to create a Vault policy that allows Infisical to read the secrets and metadata from the KV v2 secrets engines within your Vault instance. + + + ```python + # Allow listing secret engines/mounts + path "sys/mounts" { + capabilities = ["read", "list"] + } + + # For KV v2 engines - access to both data and metadata + path "*/data/*" { + capabilities = ["read", "list"] + } + + path "*/metadata/*" { + capabilities = ["read", "list"] + } + + # If using Vault Enterprise - allow listing namespaces + path "sys/namespaces" { + capabilities = ["list", "read"] + } + + # Cross-namespace access (Enterprise only) + path "+/*" { + capabilities = ["read", "list"] + } + + path "+/sys/mounts" { + capabilities = ["read", "list"] + } + ``` + + Save this policy with the name `infisical-migration`. + + + + + You can use the Vault CLI to easily generate an access token for the new `infisical-migration` policy that you created in the previous step. + + ```bash + vault token create --policy="infisical-migration" + ``` + + After generating the token, you should see the following output: + + ```t + $ vault token create --policy="infisical-migration" + + Key Value + --- ----- + token + token_accessor p6kJDiBSzYYdabJUIpGCsCBm + token_duration 768h + token_renewable true + token_policies ["default" "infisical-migration"] + identity_policies [] + policies ["default" "infisical-migration"] + ``` + + Copy the `token` field and save it for later, as you'll need this when configuring the migration to Infisical. + + + + Open the Infisical dashboard and go to Organization Settings > External Migrations. + + ![Infisical Organization settings](/images/platform/external-migrations/infisical-external-migration-dashboard.png) + + + + Select the Vault platform and click on Next. + + ![Select Vault platform](/images/platform/external-migrations/infisical-import-vault-modal.png) + + + + Enter the Vault access token that you generated in the previous step and click Import data. + + ![Configure Vault migration](/images/platform/external-migrations/infisical-import-vault.png) + + - `Vault URL`: The URL of your Vault instance. + - `Vault Namespace`: The namespace of your Vault instance. This is optional, and can be left blank if you're not using namespaces for your Vault instance. + - `Vault Access Token`: The access token that you generated in the previous step. + + - `Project Mapping`: Choose how you want to map your Vault resources to Infisical projects. You can review the mapping options in the [Project Mapping](#project-mapping) section. + + Click on Import data to start the migration. + + + + + + It may take several minutes to complete the migration. You will receive an email when the migration is complete, or if there were any errors during the migration process. + \ No newline at end of file diff --git a/docs/images/guides/import-envkey/infisical-import-dashboard.png b/docs/images/guides/import-envkey/infisical-import-dashboard.png deleted file mode 100644 index ab197f1263..0000000000 Binary files a/docs/images/guides/import-envkey/infisical-import-dashboard.png and /dev/null differ diff --git a/docs/images/guides/import-envkey/infisical-import-envkey.png b/docs/images/guides/import-envkey/infisical-import-envkey.png deleted file mode 100644 index c504c98243..0000000000 Binary files a/docs/images/guides/import-envkey/infisical-import-envkey.png and /dev/null differ diff --git a/docs/images/guides/import-envkey/copy-encryption-key.png b/docs/images/platform/external-migrations/envkey-copy-encryption-key.png similarity index 100% rename from docs/images/guides/import-envkey/copy-encryption-key.png rename to docs/images/platform/external-migrations/envkey-copy-encryption-key.png diff --git a/docs/images/guides/import-envkey/envkey-dashboard.png b/docs/images/platform/external-migrations/envkey-dashboard.png similarity index 100% rename from docs/images/guides/import-envkey/envkey-dashboard.png rename to docs/images/platform/external-migrations/envkey-dashboard.png diff --git a/docs/images/guides/import-envkey/envkey-export.png b/docs/images/platform/external-migrations/envkey-export.png similarity index 100% rename from docs/images/guides/import-envkey/envkey-export.png rename to docs/images/platform/external-migrations/envkey-export.png diff --git a/docs/images/platform/external-migrations/infisical-external-migration-dashboard.png b/docs/images/platform/external-migrations/infisical-external-migration-dashboard.png new file mode 100644 index 0000000000..f978719f4f Binary files /dev/null and b/docs/images/platform/external-migrations/infisical-external-migration-dashboard.png differ diff --git a/docs/images/platform/external-migrations/infisical-import-envkey-modal.png b/docs/images/platform/external-migrations/infisical-import-envkey-modal.png new file mode 100644 index 0000000000..9abe26fc84 Binary files /dev/null and b/docs/images/platform/external-migrations/infisical-import-envkey-modal.png differ diff --git a/docs/images/platform/external-migrations/infisical-import-envkey.png b/docs/images/platform/external-migrations/infisical-import-envkey.png new file mode 100644 index 0000000000..0d73bc5a03 Binary files /dev/null and b/docs/images/platform/external-migrations/infisical-import-envkey.png differ diff --git a/docs/images/platform/external-migrations/infisical-import-vault-modal.png b/docs/images/platform/external-migrations/infisical-import-vault-modal.png new file mode 100644 index 0000000000..c5c4a90634 Binary files /dev/null and b/docs/images/platform/external-migrations/infisical-import-vault-modal.png differ diff --git a/docs/images/platform/external-migrations/infisical-import-vault.png b/docs/images/platform/external-migrations/infisical-import-vault.png new file mode 100644 index 0000000000..399e0100d9 Binary files /dev/null and b/docs/images/platform/external-migrations/infisical-import-vault.png differ diff --git a/frontend/src/hooks/api/migration/mutations.tsx b/frontend/src/hooks/api/migration/mutations.tsx index 86ab2377c6..529d5c4630 100644 --- a/frontend/src/hooks/api/migration/mutations.tsx +++ b/frontend/src/hooks/api/migration/mutations.tsx @@ -49,7 +49,7 @@ export const useImportVault = () => { mappingType }: { vaultAccessToken: string; - vaultNamespace: string; + vaultNamespace?: string; vaultUrl: string; mappingType: string; }) => { diff --git a/frontend/src/pages/organization/SettingsPage/components/ImportTab/ImportTab.tsx b/frontend/src/pages/organization/SettingsPage/components/ExternalMigrationsTab/ExternalMigrationsTab.tsx similarity index 98% rename from frontend/src/pages/organization/SettingsPage/components/ImportTab/ImportTab.tsx rename to frontend/src/pages/organization/SettingsPage/components/ExternalMigrationsTab/ExternalMigrationsTab.tsx index 596cef9f4d..a83fcf8811 100644 --- a/frontend/src/pages/organization/SettingsPage/components/ImportTab/ImportTab.tsx +++ b/frontend/src/pages/organization/SettingsPage/components/ExternalMigrationsTab/ExternalMigrationsTab.tsx @@ -9,7 +9,7 @@ import { ProjectMembershipRole } from "@app/hooks/api/roles/types"; import { SelectImportFromPlatformModal } from "./components/SelectImportFromPlatformModal"; -export const ImportTab = () => { +export const ExternalMigrationsTab = () => { const { membership } = useOrgPermission(); const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp(["selectImportPlatform"] as const); diff --git a/frontend/src/pages/organization/SettingsPage/components/ImportTab/components/EnvKeyPlatformModal.tsx b/frontend/src/pages/organization/SettingsPage/components/ExternalMigrationsTab/components/EnvKeyPlatformModal.tsx similarity index 100% rename from frontend/src/pages/organization/SettingsPage/components/ImportTab/components/EnvKeyPlatformModal.tsx rename to frontend/src/pages/organization/SettingsPage/components/ExternalMigrationsTab/components/EnvKeyPlatformModal.tsx diff --git a/frontend/src/pages/organization/SettingsPage/components/ImportTab/components/GenericDropzone.tsx b/frontend/src/pages/organization/SettingsPage/components/ExternalMigrationsTab/components/GenericDropzone.tsx similarity index 100% rename from frontend/src/pages/organization/SettingsPage/components/ImportTab/components/GenericDropzone.tsx rename to frontend/src/pages/organization/SettingsPage/components/ExternalMigrationsTab/components/GenericDropzone.tsx diff --git a/frontend/src/pages/organization/SettingsPage/components/ImportTab/components/SelectImportFromPlatformModal.tsx b/frontend/src/pages/organization/SettingsPage/components/ExternalMigrationsTab/components/SelectImportFromPlatformModal.tsx similarity index 100% rename from frontend/src/pages/organization/SettingsPage/components/ImportTab/components/SelectImportFromPlatformModal.tsx rename to frontend/src/pages/organization/SettingsPage/components/ExternalMigrationsTab/components/SelectImportFromPlatformModal.tsx diff --git a/frontend/src/pages/organization/SettingsPage/components/ImportTab/components/VaultPlatformModal.tsx b/frontend/src/pages/organization/SettingsPage/components/ExternalMigrationsTab/components/VaultPlatformModal.tsx similarity index 98% rename from frontend/src/pages/organization/SettingsPage/components/ImportTab/components/VaultPlatformModal.tsx rename to frontend/src/pages/organization/SettingsPage/components/ExternalMigrationsTab/components/VaultPlatformModal.tsx index eddeade312..f4507da4c2 100644 --- a/frontend/src/pages/organization/SettingsPage/components/ImportTab/components/VaultPlatformModal.tsx +++ b/frontend/src/pages/organization/SettingsPage/components/ExternalMigrationsTab/components/VaultPlatformModal.tsx @@ -62,7 +62,7 @@ const MAPPING_TYPE_MENU_ITEMS = [ export const VaultPlatformModal = ({ onClose }: Props) => { const formSchema = z.object({ vaultUrl: z.string().min(1), - vaultNamespace: z.string().min(1), + vaultNamespace: z.string().trim().optional(), vaultAccessToken: z.string().min(1), mappingType: z.nativeEnum(VaultMappingType).default(VaultMappingType.KeyVault) }); @@ -122,7 +122,7 @@ export const VaultPlatformModal = ({ onClose }: Props) => { errorText={error?.message} isError={Boolean(error)} > - + )} /> @@ -132,7 +132,6 @@ export const VaultPlatformModal = ({ onClose }: Props) => { render={({ field, fieldState: { error } }) => ( diff --git a/frontend/src/pages/organization/SettingsPage/components/ExternalMigrationsTab/index.tsx b/frontend/src/pages/organization/SettingsPage/components/ExternalMigrationsTab/index.tsx new file mode 100644 index 0000000000..fea504547b --- /dev/null +++ b/frontend/src/pages/organization/SettingsPage/components/ExternalMigrationsTab/index.tsx @@ -0,0 +1 @@ +export { ExternalMigrationsTab } from "./ExternalMigrationsTab"; diff --git a/frontend/src/pages/organization/SettingsPage/components/ImportTab/index.tsx b/frontend/src/pages/organization/SettingsPage/components/ImportTab/index.tsx deleted file mode 100644 index ec2b6ead60..0000000000 --- a/frontend/src/pages/organization/SettingsPage/components/ImportTab/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { ImportTab } from "./ImportTab"; diff --git a/frontend/src/pages/organization/SettingsPage/components/OrgTabGroup/OrgTabGroup.tsx b/frontend/src/pages/organization/SettingsPage/components/OrgTabGroup/OrgTabGroup.tsx index a71ee7692b..42a8e58395 100644 --- a/frontend/src/pages/organization/SettingsPage/components/OrgTabGroup/OrgTabGroup.tsx +++ b/frontend/src/pages/organization/SettingsPage/components/OrgTabGroup/OrgTabGroup.tsx @@ -5,7 +5,7 @@ import { Tab, TabList, TabPanel, Tabs } from "@app/components/v2"; import { ROUTE_PATHS } from "@app/const/routes"; import { AuditLogStreamsTab } from "../AuditLogStreamTab"; -import { ImportTab } from "../ImportTab"; +import { ExternalMigrationsTab } from "../ExternalMigrationsTab"; import { KmipTab } from "../KmipTab/OrgKmipTab"; import { OrgEncryptionTab } from "../OrgEncryptionTab"; import { OrgGeneralTab } from "../OrgGeneralTab"; @@ -39,7 +39,11 @@ export const OrgTabGroup = () => { component: OrgWorkflowIntegrationTab }, { name: "Audit Log Streams", key: "tag-audit-log-streams", component: AuditLogStreamsTab }, - { name: "Import", key: "tab-import", component: ImportTab }, + { + name: "External Migrations", + key: "tab-external-migrations", + component: ExternalMigrationsTab + }, { name: "Project Templates", key: "project-templates",