From 8f00bab61c8c6553e9a81f0a891d7eb6b6b8a012 Mon Sep 17 00:00:00 2001 From: Daniel Hougaard Date: Tue, 26 Aug 2025 19:55:52 +0200 Subject: [PATCH 1/2] fix(secrets-service): throw on invalid env / path --- .../secret-v2-bridge/secret-v2-bridge-fns.ts | 20 +++++++++++++++++++ .../secret-v2-bridge-service.ts | 12 ++++++++++- backend/src/services/secret/secret-service.ts | 10 ++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts b/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts index 7aee91273..807d2203d 100644 --- a/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts +++ b/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts @@ -22,6 +22,26 @@ const INTERPOLATION_TEST_REGEX = new RE2(INTERPOLATION_PATTERN_STRING); export const shouldUseSecretV2Bridge = (version: number) => version === 3; +export const validateSecretPath = async ( + data: { + projectId: string; + environment: string; + secretPath: string; + }, + folderDAL: Pick +) => { + const { projectId, environment, secretPath } = data; + + const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath); + + if (!folder) { + throw new NotFoundError({ + message: `Folder with path '${secretPath}' in environment '${environment}' was not found. Please ensure the environment slug and secret path is correct.`, + name: "SecretPathNotFound" + }); + } +}; + /** * Grabs and processes nested secret references from a string * diff --git a/backend/src/services/secret-v2-bridge/secret-v2-bridge-service.ts b/backend/src/services/secret-v2-bridge/secret-v2-bridge-service.ts index 101fd9b17..3b68f69f4 100644 --- a/backend/src/services/secret-v2-bridge/secret-v2-bridge-service.ts +++ b/backend/src/services/secret-v2-bridge/secret-v2-bridge-service.ts @@ -64,7 +64,8 @@ import { generatePaths, getAllSecretReferences, recursivelyGetSecretPaths, - reshapeBridgeSecret + reshapeBridgeSecret, + validateSecretPath } from "./secret-v2-bridge-fns"; import { SecretOperations, @@ -1040,6 +1041,15 @@ export const secretV2BridgeServiceFactory = ({ projectId }); + await validateSecretPath( + { + projectId, + environment, + secretPath: path + }, + folderDAL + ); + const encryptedCachedSecrets = await keyStore.getItem(cacheKey); if (encryptedCachedSecrets) { try { diff --git a/backend/src/services/secret/secret-service.ts b/backend/src/services/secret/secret-service.ts index f776b4527..922193c6c 100644 --- a/backend/src/services/secret/secret-service.ts +++ b/backend/src/services/secret/secret-service.ts @@ -97,6 +97,7 @@ import { } from "./secret-types"; import { TSecretVersionDALFactory } from "./secret-version-dal"; import { TSecretVersionTagDALFactory } from "./secret-version-tag-dal"; +import { validateSecretPath } from "../secret-v2-bridge/secret-v2-bridge-fns"; type TSecretServiceFactoryDep = { secretDAL: TSecretDALFactory; @@ -616,6 +617,15 @@ export const secretServiceFactory = ({ actionProjectType: ActionProjectType.SecretManager }); + await validateSecretPath( + { + projectId, + environment, + secretPath: path + }, + folderDAL + ); + let paths: { folderId: string; path: string }[] = []; if (recursive) { From 2f375d6b6581fd3df1f39d3323810fcdb89cbe8e Mon Sep 17 00:00:00 2001 From: Daniel Hougaard Date: Tue, 26 Aug 2025 20:25:41 +0200 Subject: [PATCH 2/2] requested changes --- .../secret-v2-bridge/secret-v2-bridge-fns.ts | 20 -------------- .../secret-v2-bridge-service.ts | 26 +++++++++---------- backend/src/services/secret/secret-service.ts | 24 ++++++++--------- 3 files changed, 25 insertions(+), 45 deletions(-) diff --git a/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts b/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts index 807d2203d..7aee91273 100644 --- a/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts +++ b/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts @@ -22,26 +22,6 @@ const INTERPOLATION_TEST_REGEX = new RE2(INTERPOLATION_PATTERN_STRING); export const shouldUseSecretV2Bridge = (version: number) => version === 3; -export const validateSecretPath = async ( - data: { - projectId: string; - environment: string; - secretPath: string; - }, - folderDAL: Pick -) => { - const { projectId, environment, secretPath } = data; - - const folder = await folderDAL.findBySecretPath(projectId, environment, secretPath); - - if (!folder) { - throw new NotFoundError({ - message: `Folder with path '${secretPath}' in environment '${environment}' was not found. Please ensure the environment slug and secret path is correct.`, - name: "SecretPathNotFound" - }); - } -}; - /** * Grabs and processes nested secret references from a string * diff --git a/backend/src/services/secret-v2-bridge/secret-v2-bridge-service.ts b/backend/src/services/secret-v2-bridge/secret-v2-bridge-service.ts index 3b68f69f4..b23cd0c56 100644 --- a/backend/src/services/secret-v2-bridge/secret-v2-bridge-service.ts +++ b/backend/src/services/secret-v2-bridge/secret-v2-bridge-service.ts @@ -64,8 +64,7 @@ import { generatePaths, getAllSecretReferences, recursivelyGetSecretPaths, - reshapeBridgeSecret, - validateSecretPath + reshapeBridgeSecret } from "./secret-v2-bridge-fns"; import { SecretOperations, @@ -1041,15 +1040,6 @@ export const secretV2BridgeServiceFactory = ({ projectId }); - await validateSecretPath( - { - projectId, - environment, - secretPath: path - }, - folderDAL - ); - const encryptedCachedSecrets = await keyStore.getItem(cacheKey); if (encryptedCachedSecrets) { try { @@ -1084,12 +1074,22 @@ export const secretV2BridgeServiceFactory = ({ currentPath: path }); - if (!deepPaths) return { secrets: [], imports: [] }; + if (!deepPaths?.length) { + throw new NotFoundError({ + message: `Folder with path '${path}' in environment '${environment}' was not found. Please ensure the environment slug and secret path is correct.`, + name: "SecretPathNotFound" + }); + } paths = deepPaths.map(({ folderId, path: p }) => ({ folderId, path: p })); } else { const folder = await folderDAL.findBySecretPath(projectId, environment, path); - if (!folder) return { secrets: [], imports: [] }; + if (!folder) { + throw new NotFoundError({ + message: `Folder with path '${path}' in environment '${environment}' was not found. Please ensure the environment slug and secret path is correct.`, + name: "SecretPathNotFound" + }); + } paths = [{ folderId: folder.id, path }]; } diff --git a/backend/src/services/secret/secret-service.ts b/backend/src/services/secret/secret-service.ts index 922193c6c..6bafa3ba6 100644 --- a/backend/src/services/secret/secret-service.ts +++ b/backend/src/services/secret/secret-service.ts @@ -97,7 +97,6 @@ import { } from "./secret-types"; import { TSecretVersionDALFactory } from "./secret-version-dal"; import { TSecretVersionTagDALFactory } from "./secret-version-tag-dal"; -import { validateSecretPath } from "../secret-v2-bridge/secret-v2-bridge-fns"; type TSecretServiceFactoryDep = { secretDAL: TSecretDALFactory; @@ -617,15 +616,6 @@ export const secretServiceFactory = ({ actionProjectType: ActionProjectType.SecretManager }); - await validateSecretPath( - { - projectId, - environment, - secretPath: path - }, - folderDAL - ); - let paths: { folderId: string; path: string }[] = []; if (recursive) { @@ -647,7 +637,12 @@ export const secretServiceFactory = ({ } }); - if (!deepPaths) return { secrets: [], imports: [] }; + if (!deepPaths?.length) { + throw new NotFoundError({ + message: `Folder with path '${path}' in environment '${environment}' was not found. Please ensure the environment slug and secret path is correct.`, + name: "SecretPathNotFound" + }); + } paths = deepPaths.map(({ folderId, path: p }) => ({ folderId, path: p })); } else { @@ -657,7 +652,12 @@ export const secretServiceFactory = ({ }); const folder = await folderDAL.findBySecretPath(projectId, environment, path); - if (!folder) return { secrets: [], imports: [] }; + if (!folder) { + throw new NotFoundError({ + message: `Folder with path '${path}' in environment '${environment}' was not found. Please ensure the environment slug and secret path is correct.`, + name: "SecretPathNotFound" + }); + } paths = [{ folderId: folder.id, path }]; }