Improvements to cert-syncs

This commit is contained in:
Carlos Monastyrski
2025-09-22 11:45:45 -03:00
parent 27dbe5b013
commit 3587fbf98b
26 changed files with 180 additions and 190 deletions
@@ -309,7 +309,7 @@ export const registerSyncPkiEndpoints = ({
server.route({ server.route({
method: "POST", method: "POST",
url: "/:pkiSyncId/remove", url: "/:pkiSyncId/remove-certificates",
config: { config: {
rateLimit: writeLimit rateLimit: writeLimit
}, },
@@ -23,7 +23,9 @@ import {
} from "@app/services/certificate/certificate-types"; } from "@app/services/certificate/certificate-types";
import { TKmsServiceFactory } from "@app/services/kms/kms-service"; import { TKmsServiceFactory } from "@app/services/kms/kms-service";
import { TPkiSubscriberDALFactory } from "@app/services/pki-subscriber/pki-subscriber-dal"; import { TPkiSubscriberDALFactory } from "@app/services/pki-subscriber/pki-subscriber-dal";
import { triggerAutoSyncForSubscriber } from "@app/services/pki-sync/pki-sync-fns"; import { TPkiSyncDALFactory } from "@app/services/pki-sync/pki-sync-dal";
import { triggerAutoSyncForSubscriber } from "@app/services/pki-sync/pki-sync-utils";
import { TPkiSyncQueueFactory } from "@app/services/pki-sync/pki-sync-queue";
import { TProjectDALFactory } from "@app/services/project/project-dal"; import { TProjectDALFactory } from "@app/services/project/project-dal";
import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns"; import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns";
@@ -57,12 +59,8 @@ type TAcmeCertificateAuthorityFnsDeps = {
"encryptWithKmsKey" | "generateKmsKey" | "createCipherPairWithDataKey" | "decryptWithKmsKey" "encryptWithKmsKey" | "generateKmsKey" | "createCipherPairWithDataKey" | "decryptWithKmsKey"
>; >;
pkiSubscriberDAL: Pick<TPkiSubscriberDALFactory, "findById">; pkiSubscriberDAL: Pick<TPkiSubscriberDALFactory, "findById">;
pkiSyncDAL: { pkiSyncDAL: Pick<TPkiSyncDALFactory, "find">;
find: (filter: { subscriberId: string; isAutoSyncEnabled: boolean }) => Promise<Array<{ id: string }>>; pkiSyncQueue: Pick<TPkiSyncQueueFactory, "queuePkiSyncSyncCertificatesById">;
};
pkiSyncQueue: {
queuePkiSyncSyncCertificatesById: (params: { syncId: string }) => Promise<void>;
};
projectDAL: Pick<TProjectDALFactory, "findById" | "findOne" | "updateById" | "transaction">; projectDAL: Pick<TProjectDALFactory, "findById" | "findOne" | "updateById" | "transaction">;
}; };
@@ -26,7 +26,9 @@ import {
import { TKmsServiceFactory } from "@app/services/kms/kms-service"; import { TKmsServiceFactory } from "@app/services/kms/kms-service";
import { TPkiSubscriberDALFactory } from "@app/services/pki-subscriber/pki-subscriber-dal"; import { TPkiSubscriberDALFactory } from "@app/services/pki-subscriber/pki-subscriber-dal";
import { TPkiSubscriberProperties } from "@app/services/pki-subscriber/pki-subscriber-types"; import { TPkiSubscriberProperties } from "@app/services/pki-subscriber/pki-subscriber-types";
import { triggerAutoSyncForSubscriber } from "@app/services/pki-sync/pki-sync-fns"; import { TPkiSyncDALFactory } from "@app/services/pki-sync/pki-sync-dal";
import { triggerAutoSyncForSubscriber } from "@app/services/pki-sync/pki-sync-utils";
import { TPkiSyncQueueFactory } from "@app/services/pki-sync/pki-sync-queue";
import { TProjectDALFactory } from "@app/services/project/project-dal"; import { TProjectDALFactory } from "@app/services/project/project-dal";
import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns"; import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns";
@@ -56,12 +58,8 @@ type TAzureAdCsCertificateAuthorityFnsDeps = {
"encryptWithKmsKey" | "generateKmsKey" | "createCipherPairWithDataKey" | "decryptWithKmsKey" "encryptWithKmsKey" | "generateKmsKey" | "createCipherPairWithDataKey" | "decryptWithKmsKey"
>; >;
pkiSubscriberDAL: Pick<TPkiSubscriberDALFactory, "findById">; pkiSubscriberDAL: Pick<TPkiSubscriberDALFactory, "findById">;
pkiSyncDAL: { pkiSyncDAL: Pick<TPkiSyncDALFactory, "find">;
find: (filter: { subscriberId: string; isAutoSyncEnabled: boolean }) => Promise<Array<{ id: string }>>; pkiSyncQueue: Pick<TPkiSyncQueueFactory, "queuePkiSyncSyncCertificatesById">;
};
pkiSyncQueue: {
queuePkiSyncSyncCertificatesById: (params: { syncId: string }) => Promise<void>;
};
projectDAL: Pick<TProjectDALFactory, "findById" | "findOne" | "updateById" | "transaction">; projectDAL: Pick<TProjectDALFactory, "findById" | "findOne" | "updateById" | "transaction">;
}; };
@@ -20,6 +20,8 @@ import { TCertificateBodyDALFactory } from "../certificate/certificate-body-dal"
import { TCertificateSecretDALFactory } from "../certificate/certificate-secret-dal"; import { TCertificateSecretDALFactory } from "../certificate/certificate-secret-dal";
import { TPkiSubscriberDALFactory } from "../pki-subscriber/pki-subscriber-dal"; import { TPkiSubscriberDALFactory } from "../pki-subscriber/pki-subscriber-dal";
import { SubscriberOperationStatus } from "../pki-subscriber/pki-subscriber-types"; import { SubscriberOperationStatus } from "../pki-subscriber/pki-subscriber-types";
import { TPkiSyncDALFactory } from "../pki-sync/pki-sync-dal";
import { TPkiSyncQueueFactory } from "../pki-sync/pki-sync-queue";
import { AcmeCertificateAuthorityFns } from "./acme/acme-certificate-authority-fns"; import { AcmeCertificateAuthorityFns } from "./acme/acme-certificate-authority-fns";
import { AzureAdCsCertificateAuthorityFns } from "./azure-ad-cs/azure-ad-cs-certificate-authority-fns"; import { AzureAdCsCertificateAuthorityFns } from "./azure-ad-cs/azure-ad-cs-certificate-authority-fns";
import { TCertificateAuthorityDALFactory } from "./certificate-authority-dal"; import { TCertificateAuthorityDALFactory } from "./certificate-authority-dal";
@@ -50,12 +52,8 @@ type TCertificateAuthorityQueueFactoryDep = {
certificateSecretDAL: Pick<TCertificateSecretDALFactory, "create">; certificateSecretDAL: Pick<TCertificateSecretDALFactory, "create">;
queueService: TQueueServiceFactory; queueService: TQueueServiceFactory;
pkiSubscriberDAL: Pick<TPkiSubscriberDALFactory, "findById" | "updateById">; pkiSubscriberDAL: Pick<TPkiSubscriberDALFactory, "findById" | "updateById">;
pkiSyncDAL: { pkiSyncDAL: Pick<TPkiSyncDALFactory, "find">;
find: (filter: { subscriberId: string; isAutoSyncEnabled: boolean }) => Promise<Array<{ id: string }>>; pkiSyncQueue: Pick<TPkiSyncQueueFactory, "queuePkiSyncSyncCertificatesById">;
};
pkiSyncQueue: {
queuePkiSyncSyncCertificatesById: (params: { syncId: string }) => Promise<void>;
};
}; };
export type TCertificateAuthorityQueueFactory = ReturnType<typeof certificateAuthorityQueueFactory>; export type TCertificateAuthorityQueueFactory = ReturnType<typeof certificateAuthorityQueueFactory>;
@@ -13,6 +13,8 @@ import { TCertificateDALFactory } from "../certificate/certificate-dal";
import { TCertificateSecretDALFactory } from "../certificate/certificate-secret-dal"; import { TCertificateSecretDALFactory } from "../certificate/certificate-secret-dal";
import { TKmsServiceFactory } from "../kms/kms-service"; import { TKmsServiceFactory } from "../kms/kms-service";
import { TPkiSubscriberDALFactory } from "../pki-subscriber/pki-subscriber-dal"; import { TPkiSubscriberDALFactory } from "../pki-subscriber/pki-subscriber-dal";
import { TPkiSyncDALFactory } from "../pki-sync/pki-sync-dal";
import { TPkiSyncQueueFactory } from "../pki-sync/pki-sync-queue";
import { TProjectDALFactory } from "../project/project-dal"; import { TProjectDALFactory } from "../project/project-dal";
import { import {
AcmeCertificateAuthorityFns, AcmeCertificateAuthorityFns,
@@ -68,12 +70,8 @@ type TCertificateAuthorityServiceFactoryDep = {
"encryptWithKmsKey" | "generateKmsKey" | "createCipherPairWithDataKey" | "decryptWithKmsKey" "encryptWithKmsKey" | "generateKmsKey" | "createCipherPairWithDataKey" | "decryptWithKmsKey"
>; >;
pkiSubscriberDAL: Pick<TPkiSubscriberDALFactory, "findById">; pkiSubscriberDAL: Pick<TPkiSubscriberDALFactory, "findById">;
pkiSyncDAL: { pkiSyncDAL: Pick<TPkiSyncDALFactory, "find">;
find: (filter: { subscriberId: string; isAutoSyncEnabled: boolean }) => Promise<Array<{ id: string }>>; pkiSyncQueue: Pick<TPkiSyncQueueFactory, "queuePkiSyncSyncCertificatesById">;
};
pkiSyncQueue: {
queuePkiSyncSyncCertificatesById: (params: { syncId: string }) => Promise<void>;
};
}; };
export type TCertificateAuthorityServiceFactory = ReturnType<typeof certificateAuthorityServiceFactory>; export type TCertificateAuthorityServiceFactory = ReturnType<typeof certificateAuthorityServiceFactory>;
@@ -19,7 +19,9 @@ import {
TAltNameMapping TAltNameMapping
} from "@app/services/certificate/certificate-types"; } from "@app/services/certificate/certificate-types";
import { TKmsServiceFactory } from "@app/services/kms/kms-service"; import { TKmsServiceFactory } from "@app/services/kms/kms-service";
import { triggerAutoSyncForSubscriber } from "@app/services/pki-sync/pki-sync-fns"; import { TPkiSyncDALFactory } from "@app/services/pki-sync/pki-sync-dal";
import { triggerAutoSyncForSubscriber } from "@app/services/pki-sync/pki-sync-utils";
import { TPkiSyncQueueFactory } from "@app/services/pki-sync/pki-sync-queue";
import { TProjectDALFactory } from "@app/services/project/project-dal"; import { TProjectDALFactory } from "@app/services/project/project-dal";
import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns"; import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns";
@@ -52,12 +54,8 @@ type TInternalCertificateAuthorityFnsDeps = {
certificateDAL: Pick<TCertificateDALFactory, "create" | "transaction">; certificateDAL: Pick<TCertificateDALFactory, "create" | "transaction">;
certificateBodyDAL: Pick<TCertificateBodyDALFactory, "create">; certificateBodyDAL: Pick<TCertificateBodyDALFactory, "create">;
certificateSecretDAL: Pick<TCertificateSecretDALFactory, "create">; certificateSecretDAL: Pick<TCertificateSecretDALFactory, "create">;
pkiSyncDAL: { pkiSyncDAL: Pick<TPkiSyncDALFactory, "find">;
find: (filter: { subscriberId: string; isAutoSyncEnabled: boolean }) => Promise<Array<{ id: string }>>; pkiSyncQueue: Pick<TPkiSyncQueueFactory, "queuePkiSyncSyncCertificatesById">;
};
pkiSyncQueue: {
queuePkiSyncSyncCertificatesById: (params: { syncId: string }) => Promise<void>;
};
}; };
export const InternalCertificateAuthorityFns = ({ export const InternalCertificateAuthorityFns = ({
@@ -22,7 +22,7 @@ import { TKmsServiceFactory } from "@app/services/kms/kms-service";
import { TPkiCollectionDALFactory } from "@app/services/pki-collection/pki-collection-dal"; import { TPkiCollectionDALFactory } from "@app/services/pki-collection/pki-collection-dal";
import { TPkiCollectionItemDALFactory } from "@app/services/pki-collection/pki-collection-item-dal"; import { TPkiCollectionItemDALFactory } from "@app/services/pki-collection/pki-collection-item-dal";
import { TPkiSyncDALFactory } from "@app/services/pki-sync/pki-sync-dal"; import { TPkiSyncDALFactory } from "@app/services/pki-sync/pki-sync-dal";
import { triggerAutoSyncForSubscriber } from "@app/services/pki-sync/pki-sync-fns"; import { triggerAutoSyncForSubscriber } from "@app/services/pki-sync/pki-sync-utils";
import { TPkiSyncQueueFactory } from "@app/services/pki-sync/pki-sync-queue"; import { TPkiSyncQueueFactory } from "@app/services/pki-sync/pki-sync-queue";
import { TProjectDALFactory } from "@app/services/project/project-dal"; import { TProjectDALFactory } from "@app/services/project/project-dal";
import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns"; import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns";
@@ -38,7 +38,7 @@ import { TCertificateAuthoritySecretDALFactory } from "@app/services/certificate
import { TKmsServiceFactory } from "@app/services/kms/kms-service"; import { TKmsServiceFactory } from "@app/services/kms/kms-service";
import { TPkiSubscriberDALFactory } from "@app/services/pki-subscriber/pki-subscriber-dal"; import { TPkiSubscriberDALFactory } from "@app/services/pki-subscriber/pki-subscriber-dal";
import { TPkiSyncDALFactory } from "@app/services/pki-sync/pki-sync-dal"; import { TPkiSyncDALFactory } from "@app/services/pki-sync/pki-sync-dal";
import { triggerAutoSyncForSubscriber } from "@app/services/pki-sync/pki-sync-fns"; import { triggerAutoSyncForSubscriber } from "@app/services/pki-sync/pki-sync-utils";
import { TPkiSyncQueueFactory } from "@app/services/pki-sync/pki-sync-queue"; import { TPkiSyncQueueFactory } from "@app/services/pki-sync/pki-sync-queue";
import { TProjectDALFactory } from "@app/services/project/project-dal"; import { TProjectDALFactory } from "@app/services/project/project-dal";
import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns"; import { getProjectKmsCertificateKeyId } from "@app/services/project/project-fns";
@@ -0,0 +1,52 @@
import RE2 from "re2";
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
import { PkiSync } from "@app/services/pki-sync/pki-sync-enums";
/**
* Azure Key Vault naming constraints for certificates
*/
export const AZURE_KEY_VAULT_CERTIFICATE_NAMING = {
/**
* Regular expression pattern for valid Azure Key Vault certificate names
* Must contain only alphanumeric characters and hyphens (a-z, A-Z, 0-9, -)
* Must be 1-127 characters long
*/
NAME_PATTERN: new RE2("^[a-zA-Z0-9-]{1,127}$"),
/**
* String of characters that are forbidden in Azure Key Vault certificate names
*/
FORBIDDEN_CHARACTERS: "!@#$%^&*()+=[]{}|\\:;\"'<>,.?/~` _",
/**
* Maximum length for certificate names in Azure Key Vault
*/
MAX_NAME_LENGTH: 127,
/**
* Minimum length for certificate names in Azure Key Vault
*/
MIN_NAME_LENGTH: 1,
/**
* String representation of the allowed character pattern (for UI display)
*/
ALLOWED_CHARACTER_PATTERN: "^[a-zA-Z0-9-]{1,127}$"
} as const;
/**
* Azure Key Vault PKI Sync list option configuration
*/
export const AZURE_KEY_VAULT_PKI_SYNC_LIST_OPTION = {
name: "Azure Key Vault" as const,
connection: AppConnection.AzureKeyVault,
destination: PkiSync.AzureKeyVault,
canImportCertificates: false,
canRemoveCertificates: true,
defaultCertificateNameSchema: "Infisical-PKI-Sync-{{certificateId}}",
forbiddenCharacters: AZURE_KEY_VAULT_CERTIFICATE_NAMING.FORBIDDEN_CHARACTERS,
allowedCharacterPattern: AZURE_KEY_VAULT_CERTIFICATE_NAMING.ALLOWED_CHARACTER_PATTERN,
maxCertificateNameLength: AZURE_KEY_VAULT_CERTIFICATE_NAMING.MAX_NAME_LENGTH,
minCertificateNameLength: AZURE_KEY_VAULT_CERTIFICATE_NAMING.MIN_NAME_LENGTH
} as const;
@@ -5,14 +5,12 @@ import * as crypto from "crypto";
import { request } from "@app/lib/config/request"; import { request } from "@app/lib/config/request";
import { logger } from "@app/lib/logger"; import { logger } from "@app/lib/logger";
import { TAppConnectionDALFactory } from "@app/services/app-connection/app-connection-dal"; import { TAppConnectionDALFactory } from "@app/services/app-connection/app-connection-dal";
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
import { getAzureConnectionAccessToken } from "@app/services/app-connection/azure-key-vault"; import { getAzureConnectionAccessToken } from "@app/services/app-connection/azure-key-vault";
import { createConnectionQueue, RateLimitConfig } from "@app/services/connection-queue"; import { createConnectionQueue, RateLimitConfig } from "@app/services/connection-queue";
import { TKmsServiceFactory } from "@app/services/kms/kms-service"; import { TKmsServiceFactory } from "@app/services/kms/kms-service";
import { matchesCertificateNameSchema } from "@app/services/pki-sync/pki-sync-fns"; import { matchesCertificateNameSchema } from "@app/services/pki-sync/pki-sync-fns";
import { TCertificateMap } from "@app/services/pki-sync/pki-sync-types"; import { TCertificateMap } from "@app/services/pki-sync/pki-sync-types";
import { PkiSync } from "../pki-sync-enums";
import { PkiSyncError } from "../pki-sync-errors"; import { PkiSyncError } from "../pki-sync-errors";
import { TPkiSyncWithCredentials } from "../pki-sync-types"; import { TPkiSyncWithCredentials } from "../pki-sync-types";
import { GetAzureKeyVaultCertificate, TAzureKeyVaultPkiSyncConfig } from "./azure-key-vault-pki-sync-types"; import { GetAzureKeyVaultCertificate, TAzureKeyVaultPkiSyncConfig } from "./azure-key-vault-pki-sync-types";
@@ -45,19 +43,6 @@ const isInfisicalManagedCertificate = (certificateName: string, pkiSync: TPkiSyn
return certificateName.startsWith("Infisical-PKI-Sync-"); return certificateName.startsWith("Infisical-PKI-Sync-");
}; };
export const AZURE_KEY_VAULT_PKI_SYNC_LIST_OPTION = {
name: "Azure Key Vault" as const,
connection: AppConnection.AzureKeyVault,
destination: PkiSync.AzureKeyVault,
canImportCertificates: false,
canRemoveCertificates: true,
defaultCertificateNameSchema: "Infisical-PKI-Sync-{{certificateId}}",
forbiddenCharacters: "!@#$%^&*()+=[]{}|\\:;\"'<>,.?/~` _",
allowedCharacterPattern: "^[a-zA-Z0-9-]{1,127}$",
maxCertificateNameLength: 127,
minCertificateNameLength: 1
};
type TAzureKeyVaultPkiSyncFactoryDeps = { type TAzureKeyVaultPkiSyncFactoryDeps = {
appConnectionDAL: Pick<TAppConnectionDALFactory, "findById" | "updateById">; appConnectionDAL: Pick<TAppConnectionDALFactory, "findById" | "updateById">;
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">; kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">;
@@ -5,6 +5,8 @@ import { AppConnection } from "@app/services/app-connection/app-connection-enums
import { PkiSync } from "@app/services/pki-sync/pki-sync-enums"; import { PkiSync } from "@app/services/pki-sync/pki-sync-enums";
import { PkiSyncSchema } from "@app/services/pki-sync/pki-sync-schemas"; import { PkiSyncSchema } from "@app/services/pki-sync/pki-sync-schemas";
import { AZURE_KEY_VAULT_CERTIFICATE_NAMING } from "./azure-key-vault-pki-sync-constants";
export const AzureKeyVaultPkiSyncConfigSchema = z.object({ export const AzureKeyVaultPkiSyncConfigSchema = z.object({
vaultBaseUrl: z.string().url() vaultBaseUrl: z.string().url()
}); });
@@ -22,12 +24,12 @@ const AzureKeyVaultPkiSyncOptionsSchema = z.object({
const testName = schema const testName = schema
.replace(new RE2("\\{\\{certificateId\\}\\}", "g"), "") .replace(new RE2("\\{\\{certificateId\\}\\}", "g"), "")
.replace(new RE2("\\{\\{environment\\}\\}", "g"), ""); .replace(new RE2("\\{\\{environment\\}\\}", "g"), "");
const azureNamePattern = new RE2("^[a-zA-Z0-9-]{1,127}$");
const forbiddenChars = "!@#$%^&*()+=[]{}|\\:;\"'<>,.?/~` _"; const hasForbiddenChars = AZURE_KEY_VAULT_CERTIFICATE_NAMING.FORBIDDEN_CHARACTERS.split("").some((char) =>
const hasForbiddenChars = forbiddenChars.split("").some((char) => testName.includes(char)); testName.includes(char)
);
return azureNamePattern.test(testName) && !hasForbiddenChars; return AZURE_KEY_VAULT_CERTIFICATE_NAMING.NAME_PATTERN.test(testName) && !hasForbiddenChars;
}, },
{ {
message: message:
@@ -1,3 +1,4 @@
export * from "./azure-key-vault-pki-sync-constants";
export * from "./azure-key-vault-pki-sync-fns"; export * from "./azure-key-vault-pki-sync-fns";
export * from "./azure-key-vault-pki-sync-schemas"; export * from "./azure-key-vault-pki-sync-schemas";
export * from "./azure-key-vault-pki-sync-types"; export * from "./azure-key-vault-pki-sync-types";
+2 -35
View File
@@ -3,14 +3,11 @@ import { z, ZodSchema } from "zod";
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
import { BadRequestError } from "@app/lib/errors"; import { BadRequestError } from "@app/lib/errors";
import { logger } from "@app/lib/logger";
import { TAppConnectionDALFactory } from "@app/services/app-connection/app-connection-dal"; import { TAppConnectionDALFactory } from "@app/services/app-connection/app-connection-dal";
import { TKmsServiceFactory } from "@app/services/kms/kms-service"; import { TKmsServiceFactory } from "@app/services/kms/kms-service";
import { import { AZURE_KEY_VAULT_PKI_SYNC_LIST_OPTION } from "./azure-key-vault/azure-key-vault-pki-sync-constants";
AZURE_KEY_VAULT_PKI_SYNC_LIST_OPTION, import { azureKeyVaultPkiSyncFactory } from "./azure-key-vault/azure-key-vault-pki-sync-fns";
azureKeyVaultPkiSyncFactory
} from "./azure-key-vault/azure-key-vault-pki-sync-fns";
import { PkiSync } from "./pki-sync-enums"; import { PkiSync } from "./pki-sync-enums";
import { TCertificateMap, TPkiSyncWithCredentials } from "./pki-sync-types"; import { TCertificateMap, TPkiSyncWithCredentials } from "./pki-sync-types";
@@ -151,36 +148,6 @@ const isAzureKeyVaultPkiSync = (pkiSync: TPkiSyncWithCredentials): boolean => {
return pkiSync.destination === PkiSync.AzureKeyVault; return pkiSync.destination === PkiSync.AzureKeyVault;
}; };
/**
* Trigger auto sync for PKI syncs connected to a PKI subscriber when certificates are issued/revoked/deleted
*/
export const triggerAutoSyncForSubscriber = async (
subscriberId: string,
dependencies: {
pkiSyncDAL: {
find: (filter: { subscriberId: string; isAutoSyncEnabled: boolean }) => Promise<Array<{ id: string }>>;
};
pkiSyncQueue: {
queuePkiSyncSyncCertificatesById: (params: { syncId: string }) => Promise<void>;
};
}
) => {
try {
const pkiSyncs = await dependencies.pkiSyncDAL.find({
subscriberId,
isAutoSyncEnabled: true
});
// Queue sync jobs for each auto sync enabled PKI sync
const syncPromises = pkiSyncs.map((pkiSync) =>
dependencies.pkiSyncQueue.queuePkiSyncSyncCertificatesById({ syncId: pkiSync.id })
);
await Promise.all(syncPromises);
} catch (error) {
logger.error(error, `Failed to trigger auto sync for subscriber ${subscriberId}:`);
}
};
export const PkiSyncFns = { export const PkiSyncFns = {
getCertificates: async ( getCertificates: async (
pkiSync: TPkiSyncWithCredentials, pkiSync: TPkiSyncWithCredentials,
@@ -14,10 +14,8 @@ export const PkiSyncOptionsSchema = z.object({
(val) => { (val) => {
if (!val) return true; if (!val) return true;
const allowedOptionalPlaceholders = ["{{environment}}"]; const allowedPlaceholdersRegexPart = ["{{certificateId}}"]
.map((p) => p.replace(new RE2(/[-/\\^$*+?.()|[\]{}]/g), "\\$&")) // Escape regex special characters
const allowedPlaceholdersRegexPart = ["{{certificateId}}", ...allowedOptionalPlaceholders]
.map((p) => p.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&")) // Escape regex special characters
.join("|"); .join("|");
const allowedContentRegex = new RE2(`^([a-zA-Z0-9_\\-/]|${allowedPlaceholdersRegexPart})*$`); const allowedContentRegex = new RE2(`^([a-zA-Z0-9_\\-/]|${allowedPlaceholdersRegexPart})*$`);
@@ -33,7 +31,7 @@ export const PkiSyncOptionsSchema = z.object({
}, },
{ {
message: message:
"Certificate name schema must include exactly one {{certificateId}} placeholder. It can also include {{environment}} placeholders. Only alphanumeric characters (a-z, A-Z, 0-9), dashes (-), underscores (_), and slashes (/) are allowed besides the placeholders." "Certificate name schema must include exactly one {{certificateId}} placeholder. Only alphanumeric characters (a-z, A-Z, 0-9), dashes (-), underscores (_), and slashes (/) are allowed besides the placeholders."
} }
) )
}); });
@@ -153,8 +153,8 @@ export const pkiSyncServiceFactory = ({
}: Omit<TUpdatePkiSyncDTO, "auditLogInfo" | "projectId">, }: Omit<TUpdatePkiSyncDTO, "auditLogInfo" | "projectId">,
actor: OrgServiceActor actor: OrgServiceActor
): Promise<TPkiSync> => { ): Promise<TPkiSync> => {
const existingSync = await pkiSyncDAL.findById(id); const pkiSync = await pkiSyncDAL.findById(id);
if (!existingSync) throw new NotFoundError({ message: "PKI sync not found" }); if (!pkiSync) throw new NotFoundError({ message: "PKI sync not found" });
const { permission } = await permissionService.getProjectPermission({ const { permission } = await permissionService.getProjectPermission({
actor: actor.type, actor: actor.type,
@@ -162,12 +162,9 @@ export const pkiSyncServiceFactory = ({
actorAuthMethod: actor.authMethod, actorAuthMethod: actor.authMethod,
actorOrgId: actor.orgId, actorOrgId: actor.orgId,
actionProjectType: ActionProjectType.CertificateManager, actionProjectType: ActionProjectType.CertificateManager,
projectId: existingSync.projectId projectId: pkiSync.projectId
}); });
const pkiSync = await pkiSyncDAL.findByIdAndProjectId(id, existingSync.projectId);
if (!pkiSync) throw new NotFoundError({ message: "PKI sync not found" });
let currentSubscriber; let currentSubscriber;
if (pkiSync.subscriberId) { if (pkiSync.subscriberId) {
currentSubscriber = await pkiSubscriberDAL.findById(pkiSync.subscriberId); currentSubscriber = await pkiSubscriberDAL.findById(pkiSync.subscriberId);
@@ -181,7 +178,7 @@ export const pkiSyncServiceFactory = ({
); );
if (name && name !== pkiSync.name) { if (name && name !== pkiSync.name) {
const existingPkiSync = await pkiSyncDAL.findByNameAndProjectId(name, existingSync.projectId); const existingPkiSync = await pkiSyncDAL.findByNameAndProjectId(name, pkiSync.projectId);
if (existingPkiSync) { if (existingPkiSync) {
throw new BadRequestError({ message: "PKI sync with this name already exists" }); throw new BadRequestError({ message: "PKI sync with this name already exists" });
} }
@@ -189,7 +186,7 @@ export const pkiSyncServiceFactory = ({
if (subscriberId) { if (subscriberId) {
const subscriber = await pkiSubscriberDAL.findById(subscriberId); const subscriber = await pkiSubscriberDAL.findById(subscriberId);
if (!subscriber || subscriber.projectId !== existingSync.projectId) { if (!subscriber || subscriber.projectId !== pkiSync.projectId) {
throw new NotFoundError({ message: "PKI subscriber not found" }); throw new NotFoundError({ message: "PKI subscriber not found" });
} }
} }
@@ -209,9 +206,9 @@ export const pkiSyncServiceFactory = ({
}); });
} }
if (syncOptions.canRemoveCertificates === false && providerCapabilities.canRemoveCertificates) { if (syncOptions.canRemoveCertificates && !providerCapabilities.canRemoveCertificates) {
throw new BadRequestError({ throw new BadRequestError({
message: `Certificate removal cannot be disabled for ${PKI_SYNC_NAME_MAP[pkiSync.destination]} PKI sync destination` message: `Certificate removal cannot be enabled for ${PKI_SYNC_NAME_MAP[pkiSync.destination]} PKI sync destination`
}); });
} }
@@ -237,9 +234,9 @@ export const pkiSyncServiceFactory = ({
const deletePkiSync = async ( const deletePkiSync = async (
{ id }: Omit<TDeletePkiSyncDTO, "auditLogInfo" | "projectId">, { id }: Omit<TDeletePkiSyncDTO, "auditLogInfo" | "projectId">,
actor: OrgServiceActor actor: OrgServiceActor
): Promise<TPkiSync> => { ) => {
const existingSync = await pkiSyncDAL.findById(id); const pkiSync = await pkiSyncDAL.findById(id);
if (!existingSync) throw new NotFoundError({ message: "PKI sync not found" }); if (!pkiSync) throw new NotFoundError({ message: "PKI sync not found" });
const { permission } = await permissionService.getProjectPermission({ const { permission } = await permissionService.getProjectPermission({
actor: actor.type, actor: actor.type,
@@ -247,12 +244,9 @@ export const pkiSyncServiceFactory = ({
actorAuthMethod: actor.authMethod, actorAuthMethod: actor.authMethod,
actorOrgId: actor.orgId, actorOrgId: actor.orgId,
actionProjectType: ActionProjectType.CertificateManager, actionProjectType: ActionProjectType.CertificateManager,
projectId: existingSync.projectId projectId: pkiSync.projectId
}); });
const pkiSync = await pkiSyncDAL.findByIdAndProjectId(id, existingSync.projectId);
if (!pkiSync) throw new NotFoundError({ message: "PKI sync not found" });
let pkiSyncSubscriber; let pkiSyncSubscriber;
if (pkiSync.subscriberId) { if (pkiSync.subscriberId) {
pkiSyncSubscriber = await pkiSubscriberDAL.findById(pkiSync.subscriberId); pkiSyncSubscriber = await pkiSubscriberDAL.findById(pkiSync.subscriberId);
@@ -265,31 +259,7 @@ export const pkiSyncServiceFactory = ({
: ProjectPermissionSub.PkiSyncs : ProjectPermissionSub.PkiSyncs
); );
await pkiSyncDAL.deleteById(id); return pkiSyncDAL.deleteById(id);
return {
...pkiSync,
description: pkiSync.description || undefined,
subscriberId: pkiSync.subscriberId || undefined,
syncStatus: pkiSync.syncStatus || undefined,
lastSyncedAt: pkiSync.lastSyncedAt || undefined,
lastSyncJobId: pkiSync.lastSyncJobId || undefined,
lastSyncMessage: pkiSync.lastSyncMessage || undefined,
importStatus: pkiSync.importStatus || undefined,
lastImportJobId: pkiSync.lastImportJobId || undefined,
lastImportMessage: pkiSync.lastImportMessage || undefined,
lastImportedAt: pkiSync.lastImportedAt || undefined,
removeStatus: pkiSync.removeStatus || undefined,
lastRemoveJobId: pkiSync.lastRemoveJobId || undefined,
lastRemoveMessage: pkiSync.lastRemoveMessage || undefined,
lastRemovedAt: pkiSync.lastRemovedAt || undefined,
connection: {
...pkiSync.connection,
description: pkiSync.connection.description || undefined,
gatewayId: pkiSync.connection.gatewayId || undefined,
projectId: pkiSync.connection.projectId || undefined,
isPlatformManagedCredentials: pkiSync.connection.isPlatformManagedCredentials || undefined
}
};
}; };
const listPkiSyncsByProjectId = async ({ projectId }: TListPkiSyncsByProjectId, actor: OrgServiceActor) => { const listPkiSyncsByProjectId = async ({ projectId }: TListPkiSyncsByProjectId, actor: OrgServiceActor) => {
@@ -310,15 +280,10 @@ export const pkiSyncServiceFactory = ({
const findPkiSyncById = async ({ id, projectId }: TFindPkiSyncByIdDTO, actor: OrgServiceActor) => { const findPkiSyncById = async ({ id, projectId }: TFindPkiSyncByIdDTO, actor: OrgServiceActor) => {
const pkiSync = await pkiSyncDAL.findById(id); const pkiSync = await pkiSyncDAL.findById(id);
if (!pkiSync) if (!pkiSync || (projectId && pkiSync.projectId !== projectId)) {
throw new NotFoundError({ throw new NotFoundError({
message: `Could not find PKI Sync with ID "${id}"` message: `Could not find PKI Sync with ID "${id}"`
}); });
if (projectId && pkiSync.projectId !== projectId) {
throw new NotFoundError({
message: `Could not find PKI Sync with ID "${id}" in project "${projectId}"`
});
} }
const { permission } = await permissionService.getProjectPermission({ const { permission } = await permissionService.getProjectPermission({
@@ -349,8 +314,8 @@ export const pkiSyncServiceFactory = ({
{ id }: Omit<TTriggerPkiSyncSyncCertificatesByIdDTO, "auditLogInfo" | "projectId">, { id }: Omit<TTriggerPkiSyncSyncCertificatesByIdDTO, "auditLogInfo" | "projectId">,
actor: OrgServiceActor actor: OrgServiceActor
) => { ) => {
const existingSync = await pkiSyncDAL.findById(id); const pkiSync = await pkiSyncDAL.findById(id);
if (!existingSync) throw new NotFoundError({ message: "PKI sync not found" }); if (!pkiSync) throw new NotFoundError({ message: "PKI sync not found" });
const { permission } = await permissionService.getProjectPermission({ const { permission } = await permissionService.getProjectPermission({
actor: actor.type, actor: actor.type,
@@ -358,12 +323,9 @@ export const pkiSyncServiceFactory = ({
actorAuthMethod: actor.authMethod, actorAuthMethod: actor.authMethod,
actorOrgId: actor.orgId, actorOrgId: actor.orgId,
actionProjectType: ActionProjectType.CertificateManager, actionProjectType: ActionProjectType.CertificateManager,
projectId: existingSync.projectId projectId: pkiSync.projectId
}); });
const pkiSync = await pkiSyncDAL.findByIdAndProjectId(id, existingSync.projectId);
if (!pkiSync) throw new NotFoundError({ message: "PKI sync not found" });
let syncSubscriber; let syncSubscriber;
if (pkiSync.subscriberId) { if (pkiSync.subscriberId) {
syncSubscriber = await pkiSubscriberDAL.findById(pkiSync.subscriberId); syncSubscriber = await pkiSubscriberDAL.findById(pkiSync.subscriberId);
@@ -385,8 +347,8 @@ export const pkiSyncServiceFactory = ({
{ id }: Omit<TTriggerPkiSyncImportCertificatesByIdDTO, "auditLogInfo" | "projectId">, { id }: Omit<TTriggerPkiSyncImportCertificatesByIdDTO, "auditLogInfo" | "projectId">,
actor: OrgServiceActor actor: OrgServiceActor
) => { ) => {
const existingSync = await pkiSyncDAL.findById(id); const pkiSync = await pkiSyncDAL.findById(id);
if (!existingSync) throw new NotFoundError({ message: "PKI sync not found" }); if (!pkiSync) throw new NotFoundError({ message: "PKI sync not found" });
const { permission } = await permissionService.getProjectPermission({ const { permission } = await permissionService.getProjectPermission({
actor: actor.type, actor: actor.type,
@@ -394,12 +356,9 @@ export const pkiSyncServiceFactory = ({
actorAuthMethod: actor.authMethod, actorAuthMethod: actor.authMethod,
actorOrgId: actor.orgId, actorOrgId: actor.orgId,
actionProjectType: ActionProjectType.CertificateManager, actionProjectType: ActionProjectType.CertificateManager,
projectId: existingSync.projectId projectId: pkiSync.projectId
}); });
const pkiSync = await pkiSyncDAL.findByIdAndProjectId(id, existingSync.projectId);
if (!pkiSync) throw new NotFoundError({ message: "PKI sync not found" });
// Check if the PKI sync destination supports importing certificates // Check if the PKI sync destination supports importing certificates
const syncOptions = listPkiSyncOptions().find((option) => option.destination === pkiSync.destination); const syncOptions = listPkiSyncOptions().find((option) => option.destination === pkiSync.destination);
if (!syncOptions?.canImportCertificates) { if (!syncOptions?.canImportCertificates) {
@@ -429,8 +388,8 @@ export const pkiSyncServiceFactory = ({
{ id }: Omit<TTriggerPkiSyncRemoveCertificatesByIdDTO, "auditLogInfo" | "projectId">, { id }: Omit<TTriggerPkiSyncRemoveCertificatesByIdDTO, "auditLogInfo" | "projectId">,
actor: OrgServiceActor actor: OrgServiceActor
) => { ) => {
const existingSync = await pkiSyncDAL.findById(id); const pkiSync = await pkiSyncDAL.findById(id);
if (!existingSync) throw new NotFoundError({ message: "PKI sync not found" }); if (!pkiSync) throw new NotFoundError({ message: "PKI sync not found" });
const { permission } = await permissionService.getProjectPermission({ const { permission } = await permissionService.getProjectPermission({
actor: actor.type, actor: actor.type,
@@ -438,12 +397,9 @@ export const pkiSyncServiceFactory = ({
actorAuthMethod: actor.authMethod, actorAuthMethod: actor.authMethod,
actorOrgId: actor.orgId, actorOrgId: actor.orgId,
actionProjectType: ActionProjectType.CertificateManager, actionProjectType: ActionProjectType.CertificateManager,
projectId: existingSync.projectId projectId: pkiSync.projectId
}); });
const pkiSync = await pkiSyncDAL.findByIdAndProjectId(id, existingSync.projectId);
if (!pkiSync) throw new NotFoundError({ message: "PKI sync not found" });
let removeSubscriber; let removeSubscriber;
if (pkiSync.subscriberId) { if (pkiSync.subscriberId) {
removeSubscriber = await pkiSubscriberDAL.findById(pkiSync.subscriberId); removeSubscriber = await pkiSubscriberDAL.findById(pkiSync.subscriberId);
@@ -0,0 +1,27 @@
import { logger } from "@app/lib/logger";
import { TPkiSyncDALFactory } from "./pki-sync-dal";
import { TPkiSyncQueueFactory } from "./pki-sync-queue";
export const triggerAutoSyncForSubscriber = async (
subscriberId: string,
dependencies: {
pkiSyncDAL: Pick<TPkiSyncDALFactory, "find">;
pkiSyncQueue: Pick<TPkiSyncQueueFactory, "queuePkiSyncSyncCertificatesById">;
}
) => {
try {
const pkiSyncs = await dependencies.pkiSyncDAL.find({
subscriberId,
isAutoSyncEnabled: true
});
// Queue sync jobs for each auto sync enabled PKI sync
const syncPromises = pkiSyncs.map((pkiSync) =>
dependencies.pkiSyncQueue.queuePkiSyncSyncCertificatesById({ syncId: pkiSync.id })
);
await Promise.all(syncPromises);
} catch (error) {
logger.error(error, `Failed to trigger auto sync for subscriber ${subscriberId}:`);
}
};
@@ -1,6 +1,6 @@
--- ---
title: "Remove Certificates from Azure Key Vault" title: "Remove Certificates from Azure Key Vault"
openapi: "POST /api/v1/pki/syncs/azure-key-vault/{pkiSyncId}/remove" openapi: "POST /api/v1/pki/syncs/azure-key-vault/{pkiSyncId}/remove-certificates"
--- ---
<Warning> <Warning>
@@ -29,7 +29,7 @@ This endpoint removes certificates from the specified Azure Key Vault that are n
<RequestExample> <RequestExample>
```bash cURL ```bash cURL
curl -X POST "https://app.infisical.com/api/v1/pki/syncs/azure-key-vault/ps_12345/remove" \ curl -X POST "https://app.infisical.com/api/v1/pki/syncs/azure-key-vault/ps_12345/remove-certificates" \
-H "Authorization: Bearer <your-api-key>" -H "Authorization: Bearer <your-api-key>"
``` ```
</RequestExample> </RequestExample>
@@ -10,7 +10,7 @@ This endpoint lists all available PKI sync destination options and their capabil
## Request ## Request
<ParamField query="projectId" type="string" optional> <ParamField query="projectId" type="string" optional>
Project ID (for authorization purposes, but the options are global) Project ID
</ParamField> </ParamField>
## Response ## Response
+2 -2
View File
@@ -2646,9 +2646,9 @@
"href": "https://infisical.com" "href": "https://infisical.com"
}, },
"api": { "api": {
"openapi": "https://api.infisical.com/api/docs/json", "openapi": "https://app.infisical.com/api/docs/json",
"mdx": { "mdx": {
"server": ["https://api.infisical.com"] "server": ["https://app.infisical.com"]
} }
}, },
"appearance": { "appearance": {
@@ -80,8 +80,7 @@ via the UI or API for the third-party service you intend to sync certificates to
- Certificate naming schema to control how certificate names are generated in the destination - Certificate naming schema to control how certificate names are generated in the destination
<Note> <Note>
Certificate Syncs manage certificates that are prefixed with "Infisical-" in the destination. Only Only certificates managed by Infisical will be affected during sync operations. Certificates not created or
certificates managed by Infisical will be affected during sync operations. Certificates not created or
managed by Infisical will remain untouched, and changes made to Infisical-managed certificates directly managed by Infisical will remain untouched, and changes made to Infisical-managed certificates directly
in the destination service may be overwritten by future syncs. in the destination service may be overwritten by future syncs.
</Note> </Note>
@@ -110,11 +109,9 @@ By default, certificates are named using the pattern `Infisical-{certificateId}`
You can customize certificate naming by providing a **Certificate Name Schema** when creating or updating a Certificate Sync. The schema supports the following placeholders: You can customize certificate naming by providing a **Certificate Name Schema** when creating or updating a Certificate Sync. The schema supports the following placeholders:
- `{{certificateId}}` - The unique certificate identifier (required) - `{{certificateId}}` - The unique certificate identifier (required)
- `{{environment}}` - The environment context (always "global" for PKI syncs)
**Examples:** **Examples:**
- `myapp-{{certificateId}}` → `myapp-abc123def456` - `myapp-{{certificateId}}` → `myapp-abc123def456`
- `{{environment}}-cert-{{certificateId}}` → `global-cert-abc123def456`
- `ssl/{{certificateId}}` → `ssl/abc123def456` - `ssl/{{certificateId}}` → `ssl/abc123def456`
**Rules:** **Rules:**
@@ -130,11 +130,10 @@ export const CreatePkiSyncForm = ({ destination, onComplete, onCancel }: Props)
Certificate Sync Behavior Certificate Sync Behavior
</div> </div>
<p className="mt-1 text-sm text-bunker-200"> <p className="mt-1 text-sm text-bunker-200">
Certificate Syncs manage certificates that are prefixed with &quot;Infisical-&quot; in Only certificates managed by Infisical will be affected during sync operations.
the destination. Only certificates managed by Infisical will be affected during sync Certificates not created or managed by Infisical will remain untouched, and changes made
operations. Certificates not created or managed by Infisical will remain untouched, and to Infisical-managed certificates directly in the destination service may be overwritten
changes made to Infisical-managed certificates directly in the destination service may by future syncs.
be overwritten by future syncs.
</p> </p>
</div> </div>
<div className="mt-4 flex gap-4"> <div className="mt-4 flex gap-4">
@@ -104,8 +104,8 @@ export const PkiSyncOptionsFields = ({ destination }: Props) => {
tooltipText={ tooltipText={
<div className="flex flex-col gap-3"> <div className="flex flex-col gap-3">
<span> <span>
When a certificate is synced, values will be injected into the certificate name When a certificate is synced, the certificate name schema will be applied before
schema before it reaches the destination. This is useful for organization. it reaches the destination.
</span> </span>
<div className="flex flex-col"> <div className="flex flex-col">
@@ -114,10 +114,6 @@ export const PkiSyncOptionsFields = ({ destination }: Props) => {
<li> <li>
<code>{"{{certificateId}}"}</code> - The unique ID of the certificate <code>{"{{certificateId}}"}</code> - The unique ID of the certificate
</li> </li>
<li>
<code>{"{{environment}}"}</code> - The environment which the certificate is in
(e.g. dev, staging, prod)
</li>
</ul> </ul>
</div> </div>
{syncOption?.forbiddenCharacters && syncOption.forbiddenCharacters.length > 0 && ( {syncOption?.forbiddenCharacters && syncOption.forbiddenCharacters.length > 0 && (
@@ -129,11 +125,6 @@ export const PkiSyncOptionsFields = ({ destination }: Props) => {
The following characters are not allowed:{" "} The following characters are not allowed:{" "}
{syncOption.forbiddenCharacters.split("").join(" ")} {syncOption.forbiddenCharacters.split("").join(" ")}
</div> </div>
{syncOption.allowedCharacterPattern && (
<div className="mt-1 text-xs text-bunker-300">
Only alphanumeric characters and hyphens are allowed (a-z, A-Z, 0-9, -)
</div>
)}
</div> </div>
)} )}
</div> </div>
@@ -142,7 +133,7 @@ export const PkiSyncOptionsFields = ({ destination }: Props) => {
isOptional isOptional
errorText={error?.message} errorText={error?.message}
label="Certificate Name Schema" label="Certificate Name Schema"
helperText="Infisical strongly advises setting a Certificate Name Schema to ensure that Infisical only manages the specific certificates you intend, keeping everything else untouched." helperText="Infisical strongly advises setting a Certificate Name Schema to ensure that Infisical only manages the specific certificates you intend to manage, keeping everything else untouched."
> >
<Input <Input
value={value || ""} value={value || ""}
@@ -97,7 +97,9 @@ export const useTriggerPkiSyncRemoveCertificates = () => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
return useMutation({ return useMutation({
mutationFn: async ({ syncId, destination }: TTriggerPkiSyncRemoveCertificatesDTO) => { mutationFn: async ({ syncId, destination }: TTriggerPkiSyncRemoveCertificatesDTO) => {
const { data } = await apiRequest.post(`/api/v1/pki/syncs/${destination}/${syncId}/remove`); const { data } = await apiRequest.post(
`/api/v1/pki/syncs/${destination}/${syncId}/remove-certificates`
);
return data; return data;
}, },
@@ -8,8 +8,7 @@ type Props = {
type: type:
| ProjectPermissionSub.SecretFolders | ProjectPermissionSub.SecretFolders
| ProjectPermissionSub.SecretImports | ProjectPermissionSub.SecretImports
| ProjectPermissionSub.SecretRotation | ProjectPermissionSub.SecretRotation;
| ProjectPermissionSub.PkiSyncs;
}; };
export const GeneralPermissionConditions = ({ position = 0, isDisabled, type }: Props) => { export const GeneralPermissionConditions = ({ position = 0, isDisabled, type }: Props) => {
@@ -0,0 +1,19 @@
import { ProjectPermissionSub } from "@app/context/ProjectPermissionContext/types";
import { ConditionsFields } from "./ConditionsFields";
type Props = {
position?: number;
isDisabled?: boolean;
};
export const PkiSyncPermissionConditions = ({ position = 0, isDisabled }: Props) => {
return (
<ConditionsFields
isDisabled={isDisabled}
subject={ProjectPermissionSub.PkiSyncs}
position={position}
selectOptions={[{ value: "subscriberName", label: "Subscriber Name" }]}
/>
);
};
@@ -23,6 +23,7 @@ import { GeneralPermissionPolicies } from "./GeneralPermissionPolicies";
import { IdentityManagementPermissionConditions } from "./IdentityManagementPermissionConditions"; import { IdentityManagementPermissionConditions } from "./IdentityManagementPermissionConditions";
import { PermissionEmptyState } from "./PermissionEmptyState"; import { PermissionEmptyState } from "./PermissionEmptyState";
import { PkiSubscriberPermissionConditions } from "./PkiSubscriberPermissionConditions"; import { PkiSubscriberPermissionConditions } from "./PkiSubscriberPermissionConditions";
import { PkiSyncPermissionConditions } from "./PkiSyncPermissionConditions";
import { PkiTemplatePermissionConditions } from "./PkiTemplatePermissionConditions"; import { PkiTemplatePermissionConditions } from "./PkiTemplatePermissionConditions";
import { import {
EXCLUDED_PERMISSION_SUBS, EXCLUDED_PERMISSION_SUBS,
@@ -74,6 +75,10 @@ export const renderConditionalComponents = (
return <SecretSyncPermissionConditions isDisabled={isDisabled} />; return <SecretSyncPermissionConditions isDisabled={isDisabled} />;
} }
if (subject === ProjectPermissionSub.PkiSyncs) {
return <PkiSyncPermissionConditions isDisabled={isDisabled} />;
}
if (subject === ProjectPermissionSub.SecretEvents) { if (subject === ProjectPermissionSub.SecretEvents) {
return <SecretEventPermissionConditions isDisabled={isDisabled} />; return <SecretEventPermissionConditions isDisabled={isDisabled} />;
} }