From d00b34663e1fd0b770d8efd6eb684935814dc034 Mon Sep 17 00:00:00 2001 From: Scott Wilson Date: Fri, 11 Apr 2025 19:34:33 -0700 Subject: [PATCH] improvement: native integration legacy details and sync redirects --- .../routes/v1/integration-auth-router.ts | 1 + .../integration-auth/integration-list.ts | 1 + .../cloud/aws-parameter-store.mdx | 4 + .../integrations/cloud/aws-secret-manager.mdx | 4 + .../cloud/azure-app-configuration.mdx | 4 + docs/integrations/cloud/azure-key-vault.mdx | 4 + docs/integrations/cloud/databricks.mdx | 4 + .../integrations/cloud/gcp-secret-manager.mdx | 4 + docs/integrations/cloud/terraform-cloud.mdx | 4 + docs/integrations/cloud/vercel.mdx | 5 + .../secret-syncs/CreateSecretSyncModal.tsx | 11 +- frontend/src/hooks/api/integrations/types.ts | 1 + .../IntegrationsListPage.tsx | 69 ++++---- .../CloudIntegrationSection.tsx | 166 +++++++++++------- .../SecretSyncsTab/SecretSyncsTab.tsx | 23 +++ .../IntegrationsListPage/route.tsx | 4 +- 16 files changed, 204 insertions(+), 105 deletions(-) diff --git a/backend/src/server/routes/v1/integration-auth-router.ts b/backend/src/server/routes/v1/integration-auth-router.ts index 185738de6..bca11cbf3 100644 --- a/backend/src/server/routes/v1/integration-auth-router.ts +++ b/backend/src/server/routes/v1/integration-auth-router.ts @@ -31,6 +31,7 @@ export const registerIntegrationAuthRouter = async (server: FastifyZodProvider) .object({ name: z.string(), slug: z.string(), + syncSlug: z.string().optional(), clientSlug: z.string().optional(), image: z.string(), isAvailable: z.boolean().optional(), diff --git a/backend/src/services/integration-auth/integration-list.ts b/backend/src/services/integration-auth/integration-list.ts index 7bd33d86b..e8ef72f7a 100644 --- a/backend/src/services/integration-auth/integration-list.ts +++ b/backend/src/services/integration-auth/integration-list.ts @@ -195,6 +195,7 @@ export const getIntegrationOptions = async () => { { name: "AWS Secrets Manager", slug: "aws-secret-manager", + syncSlug: "aws-secrets-manager", image: "Amazon Web Services.png", isAvailable: true, type: "custom", diff --git a/docs/integrations/cloud/aws-parameter-store.mdx b/docs/integrations/cloud/aws-parameter-store.mdx index 80b35b8fc..0d582d360 100644 --- a/docs/integrations/cloud/aws-parameter-store.mdx +++ b/docs/integrations/cloud/aws-parameter-store.mdx @@ -3,6 +3,10 @@ title: "AWS Parameter Store" description: "Learn how to sync secrets from Infisical to AWS Parameter Store." --- + + The AWS Parameter Store Native Integration will be deprecated in 2026. Please migrate to our new [AWS Parameter Store Sync](../secret-syncs/aws-parameter-store). + + Infisical will assume the provided role in your AWS account securely, without the need to share any credentials. diff --git a/docs/integrations/cloud/aws-secret-manager.mdx b/docs/integrations/cloud/aws-secret-manager.mdx index 1f3a0da1f..1f88a5775 100644 --- a/docs/integrations/cloud/aws-secret-manager.mdx +++ b/docs/integrations/cloud/aws-secret-manager.mdx @@ -3,6 +3,10 @@ title: "AWS Secrets Manager" description: "Learn how to sync secrets from Infisical to AWS Secrets Manager." --- + + The AWS Secrets Manager Native Integration will be deprecated in 2026. Please migrate to our new [AWS Secrets Manager Sync](../secret-syncs/aws-secrets-manager). + + Infisical will assume the provided role in your AWS account securely, without the need to share any credentials. diff --git a/docs/integrations/cloud/azure-app-configuration.mdx b/docs/integrations/cloud/azure-app-configuration.mdx index a96bec7b2..c11c367d8 100644 --- a/docs/integrations/cloud/azure-app-configuration.mdx +++ b/docs/integrations/cloud/azure-app-configuration.mdx @@ -3,6 +3,10 @@ title: "Azure App Configuration" description: "How to sync secrets from Infisical to Azure App Configuration" --- + + The Azure App Configuration Native Integration will be deprecated in 2026. Please migrate to our new [Azure App Configuration Sync](../secret-syncs/azure-app-configuration). + + **Prerequisites:** diff --git a/docs/integrations/cloud/azure-key-vault.mdx b/docs/integrations/cloud/azure-key-vault.mdx index ae04fda88..2de2b2582 100644 --- a/docs/integrations/cloud/azure-key-vault.mdx +++ b/docs/integrations/cloud/azure-key-vault.mdx @@ -3,6 +3,10 @@ title: "Azure Key Vault" description: "How to sync secrets from Infisical to Azure Key Vault" --- + + The Azure Key Vault Native Integration will be deprecated in 2026. Please migrate to our new [Azure Key Vault Sync](../secret-syncs/azure-key-vault). + + Prerequisites: diff --git a/docs/integrations/cloud/databricks.mdx b/docs/integrations/cloud/databricks.mdx index 1971190de..d58218840 100644 --- a/docs/integrations/cloud/databricks.mdx +++ b/docs/integrations/cloud/databricks.mdx @@ -3,6 +3,10 @@ title: "Databricks" description: "Learn how to sync secrets from Infisical to Databricks." --- + + The Databricks Native Integration will be deprecated in 2026. Please migrate to our new [Databricks Sync](../secret-syncs/databricks). + + Prerequisites: - Set up and add secrets to [Infisical Cloud](https://app.infisical.com) diff --git a/docs/integrations/cloud/gcp-secret-manager.mdx b/docs/integrations/cloud/gcp-secret-manager.mdx index e57a976f0..021cc076e 100644 --- a/docs/integrations/cloud/gcp-secret-manager.mdx +++ b/docs/integrations/cloud/gcp-secret-manager.mdx @@ -3,6 +3,10 @@ title: "GCP Secret Manager" description: "How to sync secrets from Infisical to GCP Secret Manager" --- + + The GCP Secret Manager Native Integration will be deprecated in 2026. Please migrate to our new [GCP Secret Manager Sync](../secret-syncs/gcp-secret-manager). + + diff --git a/docs/integrations/cloud/terraform-cloud.mdx b/docs/integrations/cloud/terraform-cloud.mdx index d68e8a14f..0bcd72f4d 100644 --- a/docs/integrations/cloud/terraform-cloud.mdx +++ b/docs/integrations/cloud/terraform-cloud.mdx @@ -3,6 +3,10 @@ title: "Terraform Cloud" description: "How to sync secrets from Infisical to Terraform Cloud" --- + + The Terraform Cloud Native Integration will be deprecated in 2026. Please migrate to our new [Terraform Cloud Sync](../secret-syncs/terraform-cloud). + + Prerequisites: - Set up and add envars to [Infisical Cloud](https://app.infisical.com) diff --git a/docs/integrations/cloud/vercel.mdx b/docs/integrations/cloud/vercel.mdx index 1cb1c06c3..9aa5686ac 100644 --- a/docs/integrations/cloud/vercel.mdx +++ b/docs/integrations/cloud/vercel.mdx @@ -3,6 +3,11 @@ title: "Vercel" description: "How to sync secrets from Infisical to Vercel" --- + + The Vercel Native Integration will be deprecated in 2026. Please migrate to our new [Vercel Sync](../secret-syncs/vercel). + + + Prerequisites: diff --git a/frontend/src/components/secret-syncs/CreateSecretSyncModal.tsx b/frontend/src/components/secret-syncs/CreateSecretSyncModal.tsx index 3e232765c..a7c211bff 100644 --- a/frontend/src/components/secret-syncs/CreateSecretSyncModal.tsx +++ b/frontend/src/components/secret-syncs/CreateSecretSyncModal.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useEffect, useState } from "react"; import { Modal, ModalContent } from "@app/components/v2"; import { SecretSync, TSecretSync } from "@app/hooks/api/secretSyncs"; @@ -10,6 +10,7 @@ import { SecretSyncSelect } from "./SecretSyncSelect"; type Props = { isOpen: boolean; onOpenChange: (isOpen: boolean) => void; + selectSync?: SecretSync | null; }; type ContentProps = { @@ -32,8 +33,12 @@ const Content = ({ onComplete, setSelectedSync, selectedSync }: ContentProps) => return ; }; -export const CreateSecretSyncModal = ({ onOpenChange, ...props }: Props) => { - const [selectedSync, setSelectedSync] = useState(null); +export const CreateSecretSyncModal = ({ onOpenChange, selectSync = null, ...props }: Props) => { + const [selectedSync, setSelectedSync] = useState(selectSync); + + useEffect(() => { + setSelectedSync(selectSync); + }, [selectSync]); return ( { title="Integrations" description="Manage integrations with third-party services." /> -
-
- - Integrations Update -
-

- Infisical is excited to announce{" "} - - Secret Syncs - - , a new way to sync your secrets to third-party services using{" "} - - App Connections - - , offering deeper customization and re-configurability. -

-

- Existing integrations (now called Native Integrations) will continue to be supported - as we build out our Secret Sync library. -

-
- - Secret Syncs - - New - + Secret Syncs + + Native Integrations + +
+ + Legacy + +
+
- Native Integrations Framework Integrations @@ -108,6 +81,26 @@ export const IntegrationsListPage = () => { +
+
+ + Native Integrations Transitioning to Legacy Status +
+

+ Native integrations are now a legacy feature and will begin deprecation in 2026. + We recommend migrating to our new{" "} + + Secret Syncs + {" "} + feature which offers the same functionality as Native Integrations with improved + stability, insights, re-configurability, and customization. +

+
SECRET_SYNCS.includes(type); + export const CloudIntegrationSection = ({ isLoading, cloudIntegrations = [], @@ -54,6 +62,7 @@ export const CloudIntegrationSection = ({ ] as const); const { permission } = useProjectPermission(); const { currentWorkspace } = useWorkspace(); + const navigate = useNavigate(); const isEmpty = !isLoading && !cloudIntegrations?.length; @@ -111,73 +120,104 @@ export const CloudIntegrationSection = ({ ))} {!isLoading && filteredIntegrations.length ? ( - filteredIntegrations.map((cloudIntegration) => ( -
null} - role="button" - tabIndex={0} - className={`group relative ${ - cloudIntegration.isAvailable - ? "cursor-pointer duration-200 hover:bg-mineshaft-700" - : "opacity-50" - } flex h-32 flex-col items-center justify-center rounded-md border border-mineshaft-600 bg-mineshaft-800 p-4`} - onClick={() => { - if (!cloudIntegration.isAvailable) return; - if ( - permission.cannot( - ProjectPermissionActions.Create, - ProjectPermissionSub.Integrations - ) - ) { - createNotification({ - type: "error", - text: "You do not have permission to create an integration" - }); - return; - } - onIntegrationStart(cloudIntegration.slug); - }} - key={cloudIntegration.slug} - > - integration logo -
- {cloudIntegration.name} -
- {cloudIntegration.isAvailable && - Boolean(integrationAuths?.[cloudIntegration.slug]) && ( -
-
-
- - Authorized -
- -
null} - role="button" - tabIndex={0} - onClick={async (event) => { - event.stopPropagation(); - handlePopUpOpen("deleteConfirmation", { - provider: cloudIntegration.slug - }); - }} - className="absolute right-0 top-0 flex h-0 w-12 cursor-pointer items-center justify-center overflow-hidden rounded-r-md bg-red text-xs opacity-50 transition-all duration-300 hover:opacity-100 group-hover:h-full" - > - + filteredIntegrations.map((cloudIntegration) => { + const syncSlug = cloudIntegration.syncSlug ?? cloudIntegration.slug; + const isSyncAvailable = isSecretSyncAvailable(syncSlug); + + return ( +
null} + role="button" + tabIndex={0} + className={`group relative ${ + cloudIntegration.isAvailable + ? "cursor-pointer duration-200 hover:bg-mineshaft-700" + : "opacity-50" + } flex h-36 flex-col items-center justify-center rounded-md border border-mineshaft-600 bg-mineshaft-800 p-3`} + onClick={() => { + if (isSyncAvailable) { + navigate({ + to: ROUTE_PATHS.SecretManager.IntegrationsListPage.path, + params: { + projectId: currentWorkspace.id + }, + search: { + selectedTab: IntegrationsListPageTabs.SecretSyncs, + addSync: syncSlug as SecretSync + } + }); + return; + } + if (!cloudIntegration.isAvailable) return; + if ( + permission.cannot( + ProjectPermissionActions.Create, + ProjectPermissionSub.Integrations + ) + ) { + createNotification({ + type: "error", + text: "You do not have permission to create an integration" + }); + return; + } + onIntegrationStart(cloudIntegration.slug); + }} + key={cloudIntegration.slug} + > +
+ integration logo +
+ {cloudIntegration.name} +
+
+ {cloudIntegration.isAvailable && + Boolean(integrationAuths?.[cloudIntegration.slug]) && ( +
+
+
+ + Authorized
- + +
null} + role="button" + tabIndex={0} + onClick={async (event) => { + event.stopPropagation(); + handlePopUpOpen("deleteConfirmation", { + provider: cloudIntegration.slug + }); + }} + className="absolute right-0 top-0 flex h-0 w-12 cursor-pointer items-center justify-center overflow-hidden rounded-r-md bg-red text-xs opacity-50 transition-all duration-300 hover:opacity-100 group-hover:h-full" + > + +
+
+
+
+ )} + {isSyncAvailable && ( +
+
+
+ Secret Sync Available +
)} -
- )) +
+ ); + }) ) : ( { const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp(["addSync"] as const); + const { addSync, ...search } = useSearch({ + from: ROUTE_PATHS.SecretManager.IntegrationsListPage.id + }); + + const navigate = useNavigate(); + const { currentWorkspace } = useWorkspace(); + useEffect(() => { + if (!addSync) return; + + handlePopUpOpen("addSync", addSync); + navigate({ + to: ROUTE_PATHS.SecretManager.IntegrationsListPage.path, + params: { + projectId: currentWorkspace.id + }, + search + }); + }, [addSync]); + const { data: secretSyncs = [], isPending: isSecretSyncsPending } = useListSecretSyncs( currentWorkspace.id, { @@ -76,6 +98,7 @@ export const SecretSyncsTab = () => {
handlePopUpToggle("addSync", isOpen)} /> diff --git a/frontend/src/pages/secret-manager/IntegrationsListPage/route.tsx b/frontend/src/pages/secret-manager/IntegrationsListPage/route.tsx index 7a5f70622..c31773546 100644 --- a/frontend/src/pages/secret-manager/IntegrationsListPage/route.tsx +++ b/frontend/src/pages/secret-manager/IntegrationsListPage/route.tsx @@ -6,6 +6,7 @@ import { workspaceKeys } from "@app/hooks/api"; import { TIntegration } from "@app/hooks/api/integrations/types"; import { fetchSecretSyncsByProjectId, + SecretSync, secretSyncKeys, TSecretSync } from "@app/hooks/api/secretSyncs"; @@ -15,7 +16,8 @@ import { IntegrationsListPageTabs } from "@app/types/integrations"; import { IntegrationsListPage } from "./IntegrationsListPage"; const IntegrationsListPageQuerySchema = z.object({ - selectedTab: z.nativeEnum(IntegrationsListPageTabs).optional() + selectedTab: z.nativeEnum(IntegrationsListPageTabs).optional(), + addSync: z.nativeEnum(SecretSync).optional() }); export const Route = createFileRoute(