From 9d0020fa4e14148e7fa75710ec94bb163a2f0958 Mon Sep 17 00:00:00 2001
From: Scott Wilson
Date: Mon, 14 Apr 2025 10:50:45 -0700
Subject: [PATCH] improvement: rollback deprecate all secret rotation v1
create, update UI to only prevent pg/mssql
---
.../v1/secret-rotation-provider-router.ts | 3 +-
.../ee/routes/v1/secret-rotation-router.ts | 13 +++--
.../secret-rotation-service.ts | 7 +++
.../secret-rotation/templates/index.ts | 6 ++-
.../secret-rotation/templates/types.ts | 1 +
backend/src/services/project/project-types.ts | 4 +-
.../src/hooks/api/secretRotation/types.ts | 1 +
.../SecretRotationPage/SecretRotationPage.tsx | 53 ++++++++++++++++---
8 files changed, 73 insertions(+), 15 deletions(-)
diff --git a/backend/src/ee/routes/v1/secret-rotation-provider-router.ts b/backend/src/ee/routes/v1/secret-rotation-provider-router.ts
index 58419d3b7..e6a1ac72b 100644
--- a/backend/src/ee/routes/v1/secret-rotation-provider-router.ts
+++ b/backend/src/ee/routes/v1/secret-rotation-provider-router.ts
@@ -23,7 +23,8 @@ export const registerSecretRotationProviderRouter = async (server: FastifyZodPro
title: z.string(),
image: z.string().optional(),
description: z.string().optional(),
- template: z.any()
+ template: z.any(),
+ isDeprecated: z.boolean().optional()
})
.array()
})
diff --git a/backend/src/ee/routes/v1/secret-rotation-router.ts b/backend/src/ee/routes/v1/secret-rotation-router.ts
index 1efc2c8aa..936459fa1 100644
--- a/backend/src/ee/routes/v1/secret-rotation-router.ts
+++ b/backend/src/ee/routes/v1/secret-rotation-router.ts
@@ -1,7 +1,6 @@
import { z } from "zod";
import { SecretRotationOutputsSchema, SecretRotationsSchema } from "@app/db/schemas";
-import { BadRequestError } from "@app/lib/errors";
import { removeTrailingSlash } from "@app/lib/fn";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
@@ -41,10 +40,16 @@ export const registerSecretRotationRouter = async (server: FastifyZodProvider) =
}
},
onRequest: verifyAuth([AuthMode.JWT]),
- handler: async () => {
- throw new BadRequestError({
- message: `This version of Secret Rotations has been deprecated. Please see docs for new version.`
+ handler: async (req) => {
+ const secretRotation = await server.services.secretRotation.createRotation({
+ actor: req.permission.type,
+ actorAuthMethod: req.permission.authMethod,
+ actorId: req.permission.id,
+ actorOrgId: req.permission.orgId,
+ ...req.body,
+ projectId: req.body.workspaceId
});
+ return { secretRotation };
}
});
diff --git a/backend/src/ee/services/secret-rotation/secret-rotation-service.ts b/backend/src/ee/services/secret-rotation/secret-rotation-service.ts
index df7b86a0b..2364de79d 100644
--- a/backend/src/ee/services/secret-rotation/secret-rotation-service.ts
+++ b/backend/src/ee/services/secret-rotation/secret-rotation-service.ts
@@ -127,6 +127,13 @@ export const secretRotationServiceFactory = ({
});
if (selectedSecrets.length !== Object.values(outputs).length)
throw new NotFoundError({ message: `Secrets not found in folder with ID '${folder.id}'` });
+ const rotatedSecrets = selectedSecrets.filter(({ isRotatedSecret }) => isRotatedSecret);
+ if (rotatedSecrets.length)
+ throw new BadRequestError({
+ message: `Selected secrets are already used for rotation: ${rotatedSecrets
+ .map((secret) => secret.key)
+ .join(", ")}`
+ });
} else {
const selectedSecrets = await secretDAL.find({
folderId: folder.id,
diff --git a/backend/src/ee/services/secret-rotation/templates/index.ts b/backend/src/ee/services/secret-rotation/templates/index.ts
index 39774ae28..ce3ecd687 100644
--- a/backend/src/ee/services/secret-rotation/templates/index.ts
+++ b/backend/src/ee/services/secret-rotation/templates/index.ts
@@ -18,7 +18,8 @@ export const rotationTemplates: TSecretRotationProviderTemplate[] = [
title: "PostgreSQL",
image: "postgres.png",
description: "Rotate PostgreSQL/CockroachDB user credentials",
- template: POSTGRES_TEMPLATE
+ template: POSTGRES_TEMPLATE,
+ isDeprecated: true
},
{
name: "mysql",
@@ -32,7 +33,8 @@ export const rotationTemplates: TSecretRotationProviderTemplate[] = [
title: "Microsoft SQL Server",
image: "mssqlserver.png",
description: "Rotate Microsoft SQL server user credentials",
- template: MSSQL_TEMPLATE
+ template: MSSQL_TEMPLATE,
+ isDeprecated: true
},
{
name: "aws-iam",
diff --git a/backend/src/ee/services/secret-rotation/templates/types.ts b/backend/src/ee/services/secret-rotation/templates/types.ts
index 2adc40ba3..2ec998db7 100644
--- a/backend/src/ee/services/secret-rotation/templates/types.ts
+++ b/backend/src/ee/services/secret-rotation/templates/types.ts
@@ -50,6 +50,7 @@ export type TSecretRotationProviderTemplate = {
image?: string;
description?: string;
template: THttpProviderTemplate | TDbProviderTemplate | TAwsProviderTemplate;
+ isDeprecated?: boolean;
};
export type THttpProviderTemplate = {
diff --git a/backend/src/services/project/project-types.ts b/backend/src/services/project/project-types.ts
index 4195f3dfc..4346ae2c4 100644
--- a/backend/src/services/project/project-types.ts
+++ b/backend/src/services/project/project-types.ts
@@ -1,11 +1,11 @@
import { Knex } from "knex";
-import { ProjectType, TProjectKeys, SortDirection } from "@app/db/schemas";
+import { ProjectType, SortDirection, TProjectKeys } from "@app/db/schemas";
import { TSshCertificateAuthorityDALFactory } from "@app/ee/services/ssh/ssh-certificate-authority-dal";
import { TSshCertificateAuthoritySecretDALFactory } from "@app/ee/services/ssh/ssh-certificate-authority-secret-dal";
+import { OrgServiceActor, TProjectPermission } from "@app/lib/types";
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
import { TProjectSshConfigDALFactory } from "@app/services/project/project-ssh-config-dal";
-import { OrgServiceActor, TProjectPermission } from "@app/lib/types";
import { ActorAuthMethod, ActorType } from "../auth/auth-type";
diff --git a/frontend/src/hooks/api/secretRotation/types.ts b/frontend/src/hooks/api/secretRotation/types.ts
index 07a4c70df..19c4cdcdf 100644
--- a/frontend/src/hooks/api/secretRotation/types.ts
+++ b/frontend/src/hooks/api/secretRotation/types.ts
@@ -45,6 +45,7 @@ export type TSecretRotationProviderTemplate = {
image?: string;
description?: string;
template: THttpProviderTemplate | TDbProviderTemplate;
+ isDeprecated?: boolean;
};
export type THttpProviderTemplate = {
diff --git a/frontend/src/pages/secret-manager/SecretRotationPage/SecretRotationPage.tsx b/frontend/src/pages/secret-manager/SecretRotationPage/SecretRotationPage.tsx
index a9d9f0bf0..5d40a4126 100644
--- a/frontend/src/pages/secret-manager/SecretRotationPage/SecretRotationPage.tsx
+++ b/frontend/src/pages/secret-manager/SecretRotationPage/SecretRotationPage.tsx
@@ -38,7 +38,12 @@ import {
Tr
} from "@app/components/v2";
import { NoticeBannerV2 } from "@app/components/v2/NoticeBannerV2/NoticeBannerV2";
-import { ProjectPermissionSub, useWorkspace } from "@app/context";
+import {
+ ProjectPermissionSub,
+ useProjectPermission,
+ useSubscription,
+ useWorkspace
+} from "@app/context";
import { ProjectPermissionSecretRotationActions } from "@app/context/ProjectPermissionContext/types";
import { usePopUp } from "@app/hooks";
import {
@@ -47,20 +52,29 @@ import {
useGetSecretRotations,
useRestartSecretRotation
} from "@app/hooks/api";
+import { TSecretRotationProviderTemplate } from "@app/hooks/api/secretRotation/types";
import { ProjectType } from "@app/hooks/api/workspace/types";
+import { CreateRotationForm } from "@app/pages/secret-manager/SecretRotationPage/components/CreateRotationForm";
const Page = () => {
const { currentWorkspace } = useWorkspace();
+ const { permission } = useProjectPermission();
const navigate = useNavigate();
const { popUp, handlePopUpOpen, handlePopUpToggle, handlePopUpClose } = usePopUp([
+ "createRotation",
"activeBot",
"deleteRotation",
"upgradePlan",
"secretRotationV2"
] as const);
const workspaceId = currentWorkspace?.id || "";
+ const canCreateRotation = permission.can(
+ ProjectPermissionSecretRotationActions.Create,
+ ProjectPermissionSub.SecretRotation
+ );
+ const { subscription } = useSubscription();
const { data: secretRotationProviders, isPending: isRotationProviderLoading } =
useGetSecretRotationProviders({ workspaceId });
@@ -119,6 +133,18 @@ const Page = () => {
}
};
+ const handleCreateRotation = (provider: TSecretRotationProviderTemplate) => {
+ if (subscription && !subscription?.secretRotation) {
+ handlePopUpOpen("upgradePlan");
+ return;
+ }
+ if (!canCreateRotation) {
+ createNotification({ type: "error", text: "Access permission denied!!" });
+ return;
+ }
+ handlePopUpOpen("createRotation", provider);
+ };
+
return (
{
Infisical is revamping its Secret Rotation experience.
- Secret Rotations can now be created from the{" "}
+ PostgreSQL and Microsoft SQL Server Rotations can now be created from the{" "}
{
key={`infisical-rotation-provider-${provider.name}`}
tabIndex={0}
role="button"
- onKeyDown={() => {
- handlePopUpOpen("secretRotationV2", provider.title);
+ onKeyDown={(evt) => {
+ if (evt.key !== "Enter") return;
+ if (provider.isDeprecated) {
+ handlePopUpOpen("secretRotationV2", provider.title);
+ } else {
+ handleCreateRotation(provider);
+ }
}}
onClick={() => {
- handlePopUpOpen("secretRotationV2", provider.title);
+ if (provider.isDeprecated) {
+ handlePopUpOpen("secretRotationV2", provider.title);
+ } else {
+ handleCreateRotation(provider);
+ }
}}
>
{
+ handlePopUpToggle("createRotation", isOpen)}
+ provider={(popUp.createRotation.data as TSecretRotationProviderTemplate) || {}}
+ />
{
>
Secret Manager Dashboard
{" "}
- to create a Secret Rotation.
+ to create a {popUp.secretRotationV2.data} Rotation.
![]()