diff --git a/backend/src/server/routes/v1/secret-sync-routers/secret-sync-endpoints.ts b/backend/src/server/routes/v1/secret-sync-routers/secret-sync-endpoints.ts index e4de0fa51..6ab9b5939 100644 --- a/backend/src/server/routes/v1/secret-sync-routers/secret-sync-endpoints.ts +++ b/backend/src/server/routes/v1/secret-sync-routers/secret-sync-endpoints.ts @@ -367,17 +367,7 @@ export const registerSyncSecretsEndpoints = v === "true"), - stripSchema: z - .enum(["true", "false"]) - .optional() - .default("false") - .transform((v) => v === "true") + .describe(SecretSyncs.IMPORT_SECRETS(destination).importBehavior) }), response: { 200: z.object({ secretSync: responseSchema }) @@ -386,15 +376,13 @@ export const registerSyncSecretsEndpoints = { const { syncId } = req.params; - const { importBehavior, filterForSchema, stripSchema } = req.query; + const { importBehavior } = req.query; const secretSync = (await server.services.secretSync.triggerSecretSyncImportSecretsById( { syncId, destination, - importBehavior, - filterForSchema, - stripSchema + importBehavior }, req.permission )) as T; diff --git a/backend/src/services/secret-sync/aws-parameter-store/aws-parameter-store-sync-fns.ts b/backend/src/services/secret-sync/aws-parameter-store/aws-parameter-store-sync-fns.ts index abc4dcf82..a73bc81c9 100644 --- a/backend/src/services/secret-sync/aws-parameter-store/aws-parameter-store-sync-fns.ts +++ b/backend/src/services/secret-sync/aws-parameter-store/aws-parameter-store-sync-fns.ts @@ -2,6 +2,7 @@ import AWS, { AWSError } from "aws-sdk"; import { getAwsConnectionConfig } from "@app/services/app-connection/aws/aws-connection-fns"; import { SecretSyncError } from "@app/services/secret-sync/secret-sync-errors"; +import { matchesSchema } from "@app/services/secret-sync/secret-sync-fns"; import { TSecretMap } from "@app/services/secret-sync/secret-sync-types"; import { TAwsParameterStoreSyncWithCredentials } from "./aws-parameter-store-sync-types"; @@ -389,6 +390,9 @@ export const AwsParameterStoreSyncFns = { for (const entry of Object.entries(awsParameterStoreSecretsRecord)) { const [key, parameter] = entry; + // eslint-disable-next-line no-continue + if (!matchesSchema(key, syncOptions.keySchema)) continue; + if (!(key in secretMap) || !secretMap[key].value) { parametersToDelete.push(parameter); } diff --git a/backend/src/services/secret-sync/aws-secrets-manager/aws-secrets-manager-sync-fns.ts b/backend/src/services/secret-sync/aws-secrets-manager/aws-secrets-manager-sync-fns.ts index 7cea12d1b..cef1bee15 100644 --- a/backend/src/services/secret-sync/aws-secrets-manager/aws-secrets-manager-sync-fns.ts +++ b/backend/src/services/secret-sync/aws-secrets-manager/aws-secrets-manager-sync-fns.ts @@ -27,6 +27,7 @@ import { import { getAwsConnectionConfig } from "@app/services/app-connection/aws/aws-connection-fns"; import { AwsSecretsManagerSyncMappingBehavior } from "@app/services/secret-sync/aws-secrets-manager/aws-secrets-manager-sync-enums"; import { SecretSyncError } from "@app/services/secret-sync/secret-sync-errors"; +import { matchesSchema } from "@app/services/secret-sync/secret-sync-fns"; import { TSecretMap } from "@app/services/secret-sync/secret-sync-types"; import { TAwsSecretsManagerSyncWithCredentials } from "./aws-secrets-manager-sync-types"; @@ -399,6 +400,9 @@ export const AwsSecretsManagerSyncFns = { if (syncOptions.disableSecretDeletion) return; for await (const secretKey of Object.keys(awsSecretsRecord)) { + // eslint-disable-next-line no-continue + if (!matchesSchema(secretKey, syncOptions.keySchema)) continue; + if (!(secretKey in secretMap) || !secretMap[secretKey].value) { try { await deleteSecret(client, secretKey); diff --git a/backend/src/services/secret-sync/azure-app-configuration/azure-app-configuration-sync-fns.ts b/backend/src/services/secret-sync/azure-app-configuration/azure-app-configuration-sync-fns.ts index 64d82c125..dce509fac 100644 --- a/backend/src/services/secret-sync/azure-app-configuration/azure-app-configuration-sync-fns.ts +++ b/backend/src/services/secret-sync/azure-app-configuration/azure-app-configuration-sync-fns.ts @@ -7,6 +7,7 @@ import { TAppConnectionDALFactory } from "@app/services/app-connection/app-conne import { getAzureConnectionAccessToken } from "@app/services/app-connection/azure-key-vault"; import { isAzureKeyVaultReference } from "@app/services/integration-auth/integration-sync-secret-fns"; import { TKmsServiceFactory } from "@app/services/kms/kms-service"; +import { matchesSchema } from "@app/services/secret-sync/secret-sync-fns"; import { TSecretMap } from "@app/services/secret-sync/secret-sync-types"; import { TAzureAppConfigurationSyncWithCredentials } from "./azure-app-configuration-sync-types"; @@ -139,6 +140,9 @@ export const azureAppConfigurationSyncFactory = ({ if (secretSync.syncOptions.disableSecretDeletion) return; for await (const key of Object.keys(azureAppConfigSecrets)) { + // eslint-disable-next-line no-continue + if (!matchesSchema(key, secretSync.syncOptions.keySchema)) continue; + const azureSecret = azureAppConfigSecrets[key]; if ( !(key in secretMap) || diff --git a/backend/src/services/secret-sync/azure-key-vault/azure-key-vault-sync-fns.ts b/backend/src/services/secret-sync/azure-key-vault/azure-key-vault-sync-fns.ts index 12f1f2aff..fd1e2bd78 100644 --- a/backend/src/services/secret-sync/azure-key-vault/azure-key-vault-sync-fns.ts +++ b/backend/src/services/secret-sync/azure-key-vault/azure-key-vault-sync-fns.ts @@ -5,6 +5,7 @@ import { request } from "@app/lib/config/request"; import { TAppConnectionDALFactory } from "@app/services/app-connection/app-connection-dal"; import { getAzureConnectionAccessToken } from "@app/services/app-connection/azure-key-vault"; import { TKmsServiceFactory } from "@app/services/kms/kms-service"; +import { matchesSchema } from "@app/services/secret-sync/secret-sync-fns"; import { TSecretMap } from "@app/services/secret-sync/secret-sync-types"; import { SecretSyncError } from "../secret-sync-errors"; @@ -192,7 +193,9 @@ export const azureKeyVaultSyncFactory = ({ kmsService, appConnectionDAL }: TAzur if (secretSync.syncOptions.disableSecretDeletion) return; for await (const deleteSecretKey of deleteSecrets.filter( - (secret) => !setSecrets.find((setSecret) => setSecret.key === secret) + (secret) => + matchesSchema(secret, secretSync.syncOptions.keySchema) && + !setSecrets.find((setSecret) => setSecret.key === secret) )) { await request.delete(`${secretSync.destinationConfig.vaultBaseUrl}/secrets/${deleteSecretKey}?api-version=7.3`, { headers: { diff --git a/backend/src/services/secret-sync/camunda/camunda-sync-fns.ts b/backend/src/services/secret-sync/camunda/camunda-sync-fns.ts index 3a52a4939..256ae4644 100644 --- a/backend/src/services/secret-sync/camunda/camunda-sync-fns.ts +++ b/backend/src/services/secret-sync/camunda/camunda-sync-fns.ts @@ -12,6 +12,7 @@ import { TCamundaSyncWithCredentials } from "@app/services/secret-sync/camunda/camunda-sync-types"; import { SecretSyncError } from "@app/services/secret-sync/secret-sync-errors"; +import { matchesSchema } from "@app/services/secret-sync/secret-sync-fns"; import { TSecretMap } from "../secret-sync-types"; @@ -116,6 +117,9 @@ export const camundaSyncFactory = ({ kmsService, appConnectionDAL }: TCamundaSec if (secretSync.syncOptions.disableSecretDeletion) return; for await (const secret of Object.keys(camundaSecrets)) { + // eslint-disable-next-line no-continue + if (!matchesSchema(secret, secretSync.syncOptions.keySchema)) continue; + if (!(secret in secretMap) || !secretMap[secret].value) { try { await deleteCamundaSecret({ diff --git a/backend/src/services/secret-sync/databricks/databricks-sync-fns.ts b/backend/src/services/secret-sync/databricks/databricks-sync-fns.ts index 2ee7977a4..11143e24d 100644 --- a/backend/src/services/secret-sync/databricks/databricks-sync-fns.ts +++ b/backend/src/services/secret-sync/databricks/databricks-sync-fns.ts @@ -11,6 +11,7 @@ import { TDatabricksSyncWithCredentials } from "@app/services/secret-sync/databricks/databricks-sync-types"; import { SecretSyncError } from "@app/services/secret-sync/secret-sync-errors"; +import { matchesSchema } from "@app/services/secret-sync/secret-sync-fns"; import { SECRET_SYNC_NAME_MAP } from "@app/services/secret-sync/secret-sync-maps"; import { TSecretMap } from "../secret-sync-types"; @@ -115,6 +116,9 @@ export const databricksSyncFactory = ({ kmsService, appConnectionDAL }: TDatabri if (secretSync.syncOptions.disableSecretDeletion) return; for await (const secret of databricksSecretKeys) { + // eslint-disable-next-line no-continue + if (!matchesSchema(secret.key, secretSync.syncOptions.keySchema)) continue; + if (!(secret.key in secretMap)) { await deleteDatabricksSecrets({ key: secret.key, diff --git a/backend/src/services/secret-sync/gcp/gcp-sync-fns.ts b/backend/src/services/secret-sync/gcp/gcp-sync-fns.ts index a71e29ae4..97da66a48 100644 --- a/backend/src/services/secret-sync/gcp/gcp-sync-fns.ts +++ b/backend/src/services/secret-sync/gcp/gcp-sync-fns.ts @@ -4,6 +4,7 @@ import { request } from "@app/lib/config/request"; import { logger } from "@app/lib/logger"; import { getGcpConnectionAuthToken } from "@app/services/app-connection/gcp"; import { IntegrationUrls } from "@app/services/integration-auth/integration-list"; +import { matchesSchema } from "@app/services/secret-sync/secret-sync-fns"; import { SecretSyncError } from "../secret-sync-errors"; import { TSecretMap } from "../secret-sync-types"; @@ -153,6 +154,9 @@ export const GcpSyncFns = { } for await (const key of Object.keys(gcpSecrets)) { + // eslint-disable-next-line no-continue + if (!matchesSchema(key, secretSync.syncOptions.keySchema)) continue; + try { if (!(key in secretMap) || !secretMap[key].value) { // eslint-disable-next-line no-continue diff --git a/backend/src/services/secret-sync/github/github-sync-fns.ts b/backend/src/services/secret-sync/github/github-sync-fns.ts index 1fe922de5..952f4b512 100644 --- a/backend/src/services/secret-sync/github/github-sync-fns.ts +++ b/backend/src/services/secret-sync/github/github-sync-fns.ts @@ -4,6 +4,7 @@ import sodium from "libsodium-wrappers"; import { getGitHubClient } from "@app/services/app-connection/github"; import { GitHubSyncScope, GitHubSyncVisibility } from "@app/services/secret-sync/github/github-sync-enums"; import { SecretSyncError } from "@app/services/secret-sync/secret-sync-errors"; +import { matchesSchema } from "@app/services/secret-sync/secret-sync-fns"; import { SECRET_SYNC_NAME_MAP } from "@app/services/secret-sync/secret-sync-maps"; import { TSecretMap } from "@app/services/secret-sync/secret-sync-types"; @@ -222,6 +223,9 @@ export const GithubSyncFns = { if (secretSync.syncOptions.disableSecretDeletion) return; for await (const encryptedSecret of encryptedSecrets) { + // eslint-disable-next-line no-continue + if (!matchesSchema(encryptedSecret.name, secretSync.syncOptions.keySchema)) continue; + if (!(encryptedSecret.name in secretMap)) { await deleteSecret(client, secretSync, encryptedSecret); } diff --git a/backend/src/services/secret-sync/hc-vault/hc-vault-sync-fns.ts b/backend/src/services/secret-sync/hc-vault/hc-vault-sync-fns.ts index db35df292..6331cd91f 100644 --- a/backend/src/services/secret-sync/hc-vault/hc-vault-sync-fns.ts +++ b/backend/src/services/secret-sync/hc-vault/hc-vault-sync-fns.ts @@ -11,6 +11,7 @@ import { TPostHCVaultVariable } from "@app/services/secret-sync/hc-vault/hc-vault-sync-types"; import { SecretSyncError } from "@app/services/secret-sync/secret-sync-errors"; +import { matchesSchema } from "@app/services/secret-sync/secret-sync-fns"; import { TSecretMap } from "@app/services/secret-sync/secret-sync-types"; const listHCVaultVariables = async ({ instanceUrl, namespace, mount, accessToken, path }: THCVaultListVariables) => { @@ -68,7 +69,7 @@ export const HCVaultSyncFns = { const { connection, destinationConfig: { mount, path }, - syncOptions: { disableSecretDeletion } + syncOptions: { disableSecretDeletion, keySchema } } = secretSync; const { namespace } = connection.credentials; @@ -95,6 +96,9 @@ export const HCVaultSyncFns = { if (disableSecretDeletion) return; for await (const [key] of Object.entries(variables)) { + // eslint-disable-next-line no-continue + if (!matchesSchema(key, keySchema)) continue; + if (!(key in secretMap)) { delete variables[key]; tainted = true; diff --git a/backend/src/services/secret-sync/humanitec/humanitec-sync-fns.ts b/backend/src/services/secret-sync/humanitec/humanitec-sync-fns.ts index 5fa0a3d63..2fcf488aa 100644 --- a/backend/src/services/secret-sync/humanitec/humanitec-sync-fns.ts +++ b/backend/src/services/secret-sync/humanitec/humanitec-sync-fns.ts @@ -2,6 +2,7 @@ import { request } from "@app/lib/config/request"; import { logger } from "@app/lib/logger"; import { IntegrationUrls } from "@app/services/integration-auth/integration-list"; import { SecretSyncError } from "@app/services/secret-sync/secret-sync-errors"; +import { matchesSchema } from "@app/services/secret-sync/secret-sync-fns"; import { SECRET_SYNC_NAME_MAP } from "@app/services/secret-sync/secret-sync-maps"; import { TSecretMap } from "@app/services/secret-sync/secret-sync-types"; @@ -199,6 +200,9 @@ export const HumanitecSyncFns = { if (secretSync.syncOptions.disableSecretDeletion) return; for await (const humanitecSecret of humanitecSecrets) { + // eslint-disable-next-line no-continue + if (!matchesSchema(humanitecSecret.key, secretSync.syncOptions.keySchema)) continue; + if (!secretMap[humanitecSecret.key]) { await deleteSecret(secretSync, humanitecSecret); } diff --git a/backend/src/services/secret-sync/oci-vault/oci-vault-sync-fns.ts b/backend/src/services/secret-sync/oci-vault/oci-vault-sync-fns.ts index 95045e1e9..e270f2e02 100644 --- a/backend/src/services/secret-sync/oci-vault/oci-vault-sync-fns.ts +++ b/backend/src/services/secret-sync/oci-vault/oci-vault-sync-fns.ts @@ -11,6 +11,7 @@ import { TUpdateOCIVaultVariable } from "@app/services/secret-sync/oci-vault/oci-vault-sync-types"; import { SecretSyncError } from "@app/services/secret-sync/secret-sync-errors"; +import { matchesSchema } from "@app/services/secret-sync/secret-sync-fns"; import { TSecretMap } from "@app/services/secret-sync/secret-sync-types"; const listOCIVaultVariables = async ({ provider, compartmentId, vaultId, onlyActive }: TOCIVaultListVariables) => { @@ -211,6 +212,9 @@ export const OCIVaultSyncFns = { // Update and delete secrets for await (const [key, variable] of Object.entries(variables)) { + // eslint-disable-next-line no-continue + if (!matchesSchema(key, secretSync.syncOptions.keySchema)) continue; + // Only update / delete active secrets if (variable.lifecycleState === vault.models.SecretSummary.LifecycleState.Active) { if (key in secretMap && secretMap[key].value.length > 0) { diff --git a/backend/src/services/secret-sync/secret-sync-fns.ts b/backend/src/services/secret-sync/secret-sync-fns.ts index 87f187124..689d894ab 100644 --- a/backend/src/services/secret-sync/secret-sync-fns.ts +++ b/backend/src/services/secret-sync/secret-sync-fns.ts @@ -61,11 +61,6 @@ type TSyncSecretDeps = { kmsService: Pick; }; -interface TSyncSecretConfig { - filterForSchema?: boolean; - stripSchema?: boolean; -} - // Add schema to secret keys const addSchema = (unprocessedSecretMap: TSecretMap, schema?: string): TSecretMap => { if (!schema) return unprocessedSecretMap; @@ -101,17 +96,22 @@ const stripSchema = (unprocessedSecretMap: TSecretMap, schema?: string): TSecret return strippedMap; }; -// Filter only for secrets with keys that match the schema -const filterForSchema = (secretMap: TSecretMap, schema?: string): TSecretMap => { - if (!schema) return secretMap; +// Checks if a key matches a schema +export const matchesSchema = (key: string, schema?: string): boolean => { + if (!schema) return true; const [prefix, suffix] = schema.split("{{secretKey}}"); - if (prefix === undefined || suffix === undefined) return secretMap; + if (prefix === undefined || suffix === undefined) return true; + return key.startsWith(prefix) && key.endsWith(suffix); +}; + +// Filter only for secrets with keys that match the schema +const filterForSchema = (secretMap: TSecretMap, schema?: string): TSecretMap => { const filteredMap: TSecretMap = {}; for (const [key, value] of Object.entries(secretMap)) { - if (key.startsWith(prefix) && key.endsWith(suffix)) { + if (matchesSchema(key, schema)) { filteredMap[key] = value; } } @@ -178,8 +178,7 @@ export const SecretSyncFns = { }, getSecrets: async ( secretSync: TSecretSyncWithCredentials, - { kmsService, appConnectionDAL }: TSyncSecretDeps, - config?: TSyncSecretConfig + { kmsService, appConnectionDAL }: TSyncSecretDeps ): Promise => { let secretMap: TSecretMap; switch (secretSync.destination) { @@ -245,17 +244,7 @@ export const SecretSyncFns = { ); } - let processedSecretMap = secretMap; - - if (config?.filterForSchema) { - processedSecretMap = filterForSchema(processedSecretMap); - } - - if (config?.stripSchema) { - return stripSchema(processedSecretMap, secretSync.syncOptions.keySchema); - } - - return processedSecretMap; + return stripSchema(filterForSchema(secretMap), secretSync.syncOptions.keySchema); }, removeSecrets: ( secretSync: TSecretSyncWithCredentials, diff --git a/backend/src/services/secret-sync/secret-sync-queue.ts b/backend/src/services/secret-sync/secret-sync-queue.ts index 895afd45f..6255e259e 100644 --- a/backend/src/services/secret-sync/secret-sync-queue.ts +++ b/backend/src/services/secret-sync/secret-sync-queue.ts @@ -319,12 +319,9 @@ export const secretSyncQueueFactory = ({ ); }; - // TODO(andrey): Possibly add a "stripSchema" parameter for imports? const $importSecrets = async ( secretSync: TSecretSyncWithCredentials, - importBehavior: SecretSyncImportBehavior, - filterForSchema: boolean, - stripSchema: boolean + importBehavior: SecretSyncImportBehavior ): Promise => { const { projectId, environment, folder } = secretSync; @@ -333,17 +330,10 @@ export const secretSyncQueueFactory = ({ "Invalid Secret Sync source configuration: folder no longer exists. Please update source environment and secret path." ); - const importedSecrets = await SecretSyncFns.getSecrets( - secretSync, - { - appConnectionDAL, - kmsService - }, - { - filterForSchema, - stripSchema - } - ); + const importedSecrets = await SecretSyncFns.getSecrets(secretSync, { + appConnectionDAL, + kmsService + }); if (!Object.keys(importedSecrets).length) return {}; @@ -454,9 +444,7 @@ export const secretSyncQueueFactory = ({ secretSyncWithCredentials, initialSyncBehavior === SecretSyncInitialSyncBehavior.ImportPrioritizeSource ? SecretSyncImportBehavior.PrioritizeSource - : SecretSyncImportBehavior.PrioritizeDestination, - false, - false + : SecretSyncImportBehavior.PrioritizeDestination ); Object.entries(importedSecretMap).forEach(([key, secretData]) => { @@ -548,7 +536,7 @@ export const secretSyncQueueFactory = ({ const $handleImportSecretsJob = async (job: TSecretSyncImportSecretsDTO) => { const { - data: { syncId, auditLogInfo, importBehavior, filterForSchema, stripSchema } + data: { syncId, auditLogInfo, importBehavior } } = job; const secretSync = await secretSyncDAL.findById(syncId); @@ -586,9 +574,7 @@ export const secretSyncQueueFactory = ({ credentials } } as TSecretSyncWithCredentials, - importBehavior, - filterForSchema, - stripSchema + importBehavior ); isSuccess = true; diff --git a/backend/src/services/secret-sync/secret-sync-types.ts b/backend/src/services/secret-sync/secret-sync-types.ts index a25dfa3e0..64d027e18 100644 --- a/backend/src/services/secret-sync/secret-sync-types.ts +++ b/backend/src/services/secret-sync/secret-sync-types.ts @@ -231,8 +231,6 @@ export type TQueueSecretSyncImportSecretsByIdDTO = { syncId: string; importBehavior: SecretSyncImportBehavior; auditLogInfo?: AuditLogInfo; - filterForSchema: boolean; - stripSchema: boolean; }; export type TTriggerSecretSyncImportSecretsByIdDTO = { diff --git a/backend/src/services/secret-sync/teamcity/teamcity-sync-fns.ts b/backend/src/services/secret-sync/teamcity/teamcity-sync-fns.ts index 6dbd9bdd7..0afe29beb 100644 --- a/backend/src/services/secret-sync/teamcity/teamcity-sync-fns.ts +++ b/backend/src/services/secret-sync/teamcity/teamcity-sync-fns.ts @@ -1,6 +1,7 @@ import { request } from "@app/lib/config/request"; import { getTeamCityInstanceUrl } from "@app/services/app-connection/teamcity"; import { SecretSyncError } from "@app/services/secret-sync/secret-sync-errors"; +import { matchesSchema } from "@app/services/secret-sync/secret-sync-fns"; import { TSecretMap } from "@app/services/secret-sync/secret-sync-types"; import { TDeleteTeamCityVariable, @@ -125,6 +126,9 @@ export const TeamCitySyncFns = { const variables = await listTeamCityVariables({ instanceUrl, accessToken, project, buildConfig }); for await (const [key, variable] of Object.entries(variables)) { + // eslint-disable-next-line no-continue + if (!matchesSchema(key, secretSync.syncOptions.keySchema)) continue; + if (!(key in secretMap)) { try { await deleteTeamCityVariable({ diff --git a/backend/src/services/secret-sync/terraform-cloud/terraform-cloud-sync-fns.ts b/backend/src/services/secret-sync/terraform-cloud/terraform-cloud-sync-fns.ts index 4cfd7ec05..a58ec213c 100644 --- a/backend/src/services/secret-sync/terraform-cloud/terraform-cloud-sync-fns.ts +++ b/backend/src/services/secret-sync/terraform-cloud/terraform-cloud-sync-fns.ts @@ -4,6 +4,7 @@ import { AxiosResponse } from "axios"; import { request } from "@app/lib/config/request"; import { IntegrationUrls } from "@app/services/integration-auth/integration-list"; import { SecretSyncError } from "@app/services/secret-sync/secret-sync-errors"; +import { matchesSchema } from "@app/services/secret-sync/secret-sync-fns"; import { TSecretMap } from "@app/services/secret-sync/secret-sync-types"; import { SECRET_SYNC_NAME_MAP } from "../secret-sync-maps"; @@ -231,6 +232,9 @@ export const TerraformCloudSyncFns = { if (secretSync.syncOptions.disableSecretDeletion) return; for (const terraformCloudVariable of terraformCloudVariables) { + // eslint-disable-next-line no-continue + if (!matchesSchema(terraformCloudVariable.key, secretSync.syncOptions.keySchema)) continue; + if (!Object.prototype.hasOwnProperty.call(secretMap, terraformCloudVariable.key)) { await deleteVariable(secretSync, terraformCloudVariable); } diff --git a/backend/src/services/secret-sync/vercel/vercel-sync-fns.ts b/backend/src/services/secret-sync/vercel/vercel-sync-fns.ts index 713971283..90e9327e5 100644 --- a/backend/src/services/secret-sync/vercel/vercel-sync-fns.ts +++ b/backend/src/services/secret-sync/vercel/vercel-sync-fns.ts @@ -2,6 +2,7 @@ import { request } from "@app/lib/config/request"; import { IntegrationUrls } from "@app/services/integration-auth/integration-list"; import { SecretSyncError } from "@app/services/secret-sync/secret-sync-errors"; +import { matchesSchema } from "@app/services/secret-sync/secret-sync-fns"; import { TSecretMap } from "@app/services/secret-sync/secret-sync-types"; import { VercelEnvironmentType } from "./vercel-sync-enums"; @@ -290,6 +291,9 @@ export const VercelSyncFns = { if (secretSync.syncOptions.disableSecretDeletion) return; for await (const vercelSecret of vercelSecrets) { + // eslint-disable-next-line no-continue + if (!matchesSchema(vercelSecret.key, secretSync.syncOptions.keySchema)) continue; + if (!secretMap[vercelSecret.key]) { await deleteSecret(secretSync, vercelSecret); } diff --git a/backend/src/services/secret-sync/windmill/windmill-sync-fns.ts b/backend/src/services/secret-sync/windmill/windmill-sync-fns.ts index 2e2c36740..a09706581 100644 --- a/backend/src/services/secret-sync/windmill/windmill-sync-fns.ts +++ b/backend/src/services/secret-sync/windmill/windmill-sync-fns.ts @@ -1,6 +1,7 @@ import { request } from "@app/lib/config/request"; import { getWindmillInstanceUrl } from "@app/services/app-connection/windmill"; import { SecretSyncError } from "@app/services/secret-sync/secret-sync-errors"; +import { matchesSchema } from "@app/services/secret-sync/secret-sync-fns"; import { TDeleteWindmillVariable, TPostWindmillVariable, @@ -128,7 +129,7 @@ export const WindmillSyncFns = { const { connection, destinationConfig: { path }, - syncOptions: { disableSecretDeletion } + syncOptions: { disableSecretDeletion, keySchema } } = secretSync; // url needs to be lowercase @@ -169,6 +170,9 @@ export const WindmillSyncFns = { if (disableSecretDeletion) return; for await (const [key, variable] of Object.entries(variables)) { + // eslint-disable-next-line no-continue + if (!matchesSchema(key, keySchema)) continue; + if (!(key in secretMap)) { try { await deleteWindmillVariable({ diff --git a/frontend/src/components/secret-syncs/SecretSyncImportSecretsModal.tsx b/frontend/src/components/secret-syncs/SecretSyncImportSecretsModal.tsx index 87742c0f1..c1b21a771 100644 --- a/frontend/src/components/secret-syncs/SecretSyncImportSecretsModal.tsx +++ b/frontend/src/components/secret-syncs/SecretSyncImportSecretsModal.tsx @@ -10,8 +10,7 @@ import { ModalClose, ModalContent, Select, - SelectItem, - Switch + SelectItem } from "@app/components/v2"; import { SECRET_SYNC_IMPORT_BEHAVIOR_MAP, SECRET_SYNC_MAP } from "@app/helpers/secretSyncs"; import { @@ -32,20 +31,13 @@ type ContentProps = { }; const FormSchema = z.object({ - importBehavior: z.nativeEnum(SecretSyncImportBehavior), - filterForSchema: z.boolean(), - stripSchema: z.boolean() + importBehavior: z.nativeEnum(SecretSyncImportBehavior) }); type TFormData = z.infer; const Content = ({ secretSync, onComplete }: ContentProps) => { - const { - id: syncId, - destination, - projectId, - syncOptions: { keySchema } - } = secretSync; + const { id: syncId, destination, projectId } = secretSync; const destinationName = SECRET_SYNC_MAP[destination].name; const { @@ -53,28 +45,18 @@ const Content = ({ secretSync, onComplete }: ContentProps) => { control, formState: { isSubmitting, isDirty } } = useForm({ - resolver: zodResolver(FormSchema), - defaultValues: { - filterForSchema: false, - stripSchema: false - } + resolver: zodResolver(FormSchema) }); const triggerImportSecrets = useTriggerSecretSyncImportSecrets(); - const handleTriggerImportSecrets = async ({ - importBehavior, - filterForSchema, - stripSchema - }: TFormData) => { + const handleTriggerImportSecrets = async ({ importBehavior }: TFormData) => { try { await triggerImportSecrets.mutateAsync({ syncId, destination, importBehavior, - projectId, - filterForSchema, - stripSchema + projectId }); createNotification({ @@ -151,64 +133,6 @@ const Content = ({ secretSync, onComplete }: ContentProps) => { )} /> - {keySchema && ( - <> - ( - -

- If enabled, Infisical will only import destination secrets that match your key - schema: -

- {keySchema} - - } - label="Filter Keys for Schema" - isError={Boolean(error)} - errorText={error?.message} - > - - Only import destination secrets that match schema - -
- )} - /> - ( - - - Strip schema from imported secret keys - - - )} - /> - - )}