diff --git a/backend/src/services/pki-sync/aws-certificate-manager/aws-certificate-manager-pki-sync-fns.ts b/backend/src/services/pki-sync/aws-certificate-manager/aws-certificate-manager-pki-sync-fns.ts index ae4cdcf55..3e07420b5 100644 --- a/backend/src/services/pki-sync/aws-certificate-manager/aws-certificate-manager-pki-sync-fns.ts +++ b/backend/src/services/pki-sync/aws-certificate-manager/aws-certificate-manager-pki-sync-fns.ts @@ -3,6 +3,7 @@ import * as AWS from "aws-sdk"; import RE2 from "re2"; import { z } from "zod"; +import { TCertificateSyncs } from "@app/db/schemas"; import { BadRequestError, NotFoundError } from "@app/lib/errors"; import { logger } from "@app/lib/logger"; import { TAppConnectionDALFactory } from "@app/services/app-connection/app-connection-dal"; @@ -397,11 +398,10 @@ export const awsCertificateManagerPkiSyncFactory = ({ }); const existingSyncRecords = await certificateSyncDAL.findByPkiSyncId(pkiSync.id); - type SyncRecord = (typeof existingSyncRecords)[0]; - const syncRecordsByCertId = new Map(); - const syncRecordsByExternalId = new Map(); + const syncRecordsByCertId = new Map(); + const syncRecordsByExternalId = new Map(); - existingSyncRecords.forEach((record: SyncRecord) => { + existingSyncRecords.forEach((record: TCertificateSyncs) => { if (record.certificateId) { syncRecordsByCertId.set(record.certificateId, record); } diff --git a/backend/src/services/pki-sync/azure-key-vault/azure-key-vault-pki-sync-fns.ts b/backend/src/services/pki-sync/azure-key-vault/azure-key-vault-pki-sync-fns.ts index 0bd9e201d..765d0b8ba 100644 --- a/backend/src/services/pki-sync/azure-key-vault/azure-key-vault-pki-sync-fns.ts +++ b/backend/src/services/pki-sync/azure-key-vault/azure-key-vault-pki-sync-fns.ts @@ -2,6 +2,7 @@ import { AxiosError } from "axios"; import * as crypto from "crypto"; +import { TCertificateSyncs } from "@app/db/schemas"; import { request } from "@app/lib/config/request"; import { logger } from "@app/lib/logger"; import { TAppConnectionDALFactory } from "@app/services/app-connection/app-connection-dal"; @@ -346,11 +347,10 @@ export const azureKeyVaultPkiSyncFactory = ({ ); const existingSyncRecords = await certificateSyncDAL.findByPkiSyncId(pkiSync.id); - type SyncRecord = (typeof existingSyncRecords)[0]; - const syncRecordsByCertId = new Map(); - const syncRecordsByExternalId = new Map(); + const syncRecordsByCertId = new Map(); + const syncRecordsByExternalId = new Map(); - existingSyncRecords.forEach((record: SyncRecord) => { + existingSyncRecords.forEach((record: TCertificateSyncs) => { if (record.certificateId) { syncRecordsByCertId.set(record.certificateId, record); } @@ -368,10 +368,10 @@ export const azureKeyVaultPkiSyncFactory = ({ }[] = []; const syncOptions = pkiSync.syncOptions as - | { certificateNameSchema?: string; canRemoveCertificates?: boolean; preserveVersion?: boolean } + | { certificateNameSchema?: string; canRemoveCertificates?: boolean; enableVersioning?: boolean } | undefined; const canRemoveCertificates = syncOptions?.canRemoveCertificates ?? true; - const preserveVersion = syncOptions?.preserveVersion ?? true; + const enableVersioning = syncOptions?.enableVersioning ?? true; const activeExternalIdentifiers = new Set(); @@ -382,7 +382,7 @@ export const azureKeyVaultPkiSyncFactory = ({ continue; } - if (preserveVersion && typeof certificateId === "string") { + if (enableVersioning && typeof certificateId === "string") { const certificate = await certificateDAL.findById(certificateId); if (certificate?.renewedByCertificateId) { // eslint-disable-next-line no-continue @@ -399,7 +399,7 @@ export const azureKeyVaultPkiSyncFactory = ({ if (existingSyncRecord?.externalIdentifier) { const existingAzureCert = vaultCertificates[existingSyncRecord.externalIdentifier]; - if (existingAzureCert && preserveVersion) { + if (existingAzureCert && enableVersioning) { targetCertName = existingSyncRecord.externalIdentifier; activeExternalIdentifiers.add(targetCertName); @@ -409,7 +409,7 @@ export const azureKeyVaultPkiSyncFactory = ({ } } else if (!existingAzureCert) { shouldCreateNew = true; - } else if (!preserveVersion) { + } else if (!enableVersioning) { shouldCreateNew = true; } } else { @@ -544,7 +544,7 @@ export const azureKeyVaultPkiSyncFactory = ({ ]); } - if (preserveVersion) { + if (enableVersioning) { const currentCertificate = await certificateDAL.findById(certificateId); if (currentCertificate?.renewedFromCertificateId) { await certificateSyncDAL.removeCertificates(pkiSync.id, [currentCertificate.renewedFromCertificateId]); diff --git a/backend/src/services/pki-sync/azure-key-vault/azure-key-vault-pki-sync-schemas.ts b/backend/src/services/pki-sync/azure-key-vault/azure-key-vault-pki-sync-schemas.ts index b7fcbfb6d..90f4a119b 100644 --- a/backend/src/services/pki-sync/azure-key-vault/azure-key-vault-pki-sync-schemas.ts +++ b/backend/src/services/pki-sync/azure-key-vault/azure-key-vault-pki-sync-schemas.ts @@ -14,7 +14,7 @@ export const AzureKeyVaultPkiSyncConfigSchema = z.object({ const AzureKeyVaultPkiSyncOptionsSchema = z.object({ canImportCertificates: z.boolean().default(false), canRemoveCertificates: z.boolean().default(true), - preserveVersion: z.boolean().default(true), + enableVersioning: z.boolean().default(true), certificateNameSchema: z .string() .optional() diff --git a/backend/src/services/pki-sync/pki-sync-service.ts b/backend/src/services/pki-sync/pki-sync-service.ts index 0c385ce9c..02a76db2a 100644 --- a/backend/src/services/pki-sync/pki-sync-service.ts +++ b/backend/src/services/pki-sync/pki-sync-service.ts @@ -95,10 +95,17 @@ export const pkiSyncServiceFactory = ({ }); } - const invalidCertificates = certificates.filter((cert) => cert.projectId !== expectedProjectId); - if (invalidCertificates.length > 0) { + const invalidProjectCertificates = certificates.filter((cert) => cert.projectId !== expectedProjectId); + if (invalidProjectCertificates.length > 0) { throw new BadRequestError({ - message: `Certificates do not belong to the same project: ${invalidCertificates.map((cert) => cert.id).join(", ")}` + message: `Certificates do not belong to the same project: ${invalidProjectCertificates.map((cert) => cert.id).join(", ")}` + }); + } + + const invalidRenewedCertificates = certificates.filter((cert) => cert.renewedByCertificateId); + if (invalidRenewedCertificates.length > 0) { + throw new BadRequestError({ + message: `Cannot add renewed certificates to PKI sync: ${invalidRenewedCertificates.map((cert) => cert.id).join(", ")}` }); } }; diff --git a/frontend/src/components/pki-syncs/forms/PkiSyncConnectionField.tsx b/frontend/src/components/pki-syncs/forms/PkiSyncConnectionField.tsx index 90af04203..c8da83aac 100644 --- a/frontend/src/components/pki-syncs/forms/PkiSyncConnectionField.tsx +++ b/frontend/src/components/pki-syncs/forms/PkiSyncConnectionField.tsx @@ -69,7 +69,7 @@ export const PkiSyncConnectionField = ({ onChange: callback }: Props) => { ( { {currentDestination === PkiSync.AzureKeyVault && ( ( {

When enabled, Infisical will create a new version of the existing certificate in Azure Key Vault during certificate renewal syncs, - preserving the certificate name. + preserving the original certificate name.

This allows consuming services to continue using the same certificate name diff --git a/frontend/src/components/pki-syncs/forms/schemas/azure-key-vault-pki-sync-destination-schema.ts b/frontend/src/components/pki-syncs/forms/schemas/azure-key-vault-pki-sync-destination-schema.ts index c2f53191e..2a8f3ee53 100644 --- a/frontend/src/components/pki-syncs/forms/schemas/azure-key-vault-pki-sync-destination-schema.ts +++ b/frontend/src/components/pki-syncs/forms/schemas/azure-key-vault-pki-sync-destination-schema.ts @@ -7,7 +7,7 @@ import { BasePkiSyncSchema } from "./base-pki-sync-schema"; const AzureKeyVaultSyncOptionsSchema = z.object({ canImportCertificates: z.boolean().default(false), canRemoveCertificates: z.boolean().default(true), - preserveVersion: z.boolean().default(true), + enableVersioning: z.boolean().default(true), certificateNameSchema: z .string() .optional() diff --git a/frontend/src/pages/cert-manager/CertificatesPage/components/CertificatesTable.tsx b/frontend/src/pages/cert-manager/CertificatesPage/components/CertificatesTable.tsx index 115526f5a..369bfe7b3 100644 --- a/frontend/src/pages/cert-manager/CertificatesPage/components/CertificatesTable.tsx +++ b/frontend/src/pages/cert-manager/CertificatesPage/components/CertificatesTable.tsx @@ -458,31 +458,33 @@ export const CertificatesTable = ({ handlePopUpOpen }: Props) => { ); })()} - {/* PKI Sync management - only for active certificates */} - {certificate.status === CertStatus.ACTIVE && ( - - {(isAllowed) => ( - - handlePopUpOpen("managePkiSyncs", { - certificateId: certificate.id, - commonName: certificate.commonName - }) - } - disabled={!isAllowed} - icon={} - > - Manage PKI Syncs - - )} - - )} + {/* PKI Sync management - only for active certificates that are not renewed */} + {certificate.status === CertStatus.ACTIVE && + !certificate.renewedByCertificateId && ( + + {(isAllowed) => ( + + handlePopUpOpen("managePkiSyncs", { + certificateId: certificate.id, + commonName: certificate.commonName + }) + } + disabled={!isAllowed} + icon={} + > + Manage PKI Syncs + + )} + + )} {/* Only show revoke button if CA supports revocation */} {(() => { const caType = caCapabilityMap[certificate.caId];