From c7f80f7d9e1e7fd9d1d3f5fa9688a5f2cabe5722 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Tue, 4 Feb 2025 01:34:30 +0800 Subject: [PATCH] feat: kmip client backend setup --- backend/src/@types/fastify.d.ts | 2 + backend/src/@types/knex.d.ts | 4 + .../db/migrations/20250203141127_add-kmip.ts | 24 +++ backend/src/db/schemas/index.ts | 1 + backend/src/db/schemas/kmip-clients.ts | 20 ++ backend/src/db/schemas/models.ts | 3 +- backend/src/ee/routes/v1/index.ts | 2 + backend/src/ee/routes/v1/kmip-router.ts | 183 ++++++++++++++++++ .../ee/services/audit-log/audit-log-types.ts | 46 ++++- .../src/ee/services/kmip/kmip-client-dal.ts | 11 ++ backend/src/ee/services/kmip/kmip-enum.ts | 6 + backend/src/ee/services/kmip/kmip-service.ts | 127 ++++++++++++ backend/src/ee/services/kmip/kmip-types.ts | 24 +++ .../services/permission/project-permission.ts | 22 ++- backend/src/server/routes/index.ts | 11 +- 15 files changed, 481 insertions(+), 5 deletions(-) create mode 100644 backend/src/db/migrations/20250203141127_add-kmip.ts create mode 100644 backend/src/db/schemas/kmip-clients.ts create mode 100644 backend/src/ee/routes/v1/kmip-router.ts create mode 100644 backend/src/ee/services/kmip/kmip-client-dal.ts create mode 100644 backend/src/ee/services/kmip/kmip-enum.ts create mode 100644 backend/src/ee/services/kmip/kmip-service.ts create mode 100644 backend/src/ee/services/kmip/kmip-types.ts diff --git a/backend/src/@types/fastify.d.ts b/backend/src/@types/fastify.d.ts index f3298625e..d56c13431 100644 --- a/backend/src/@types/fastify.d.ts +++ b/backend/src/@types/fastify.d.ts @@ -16,6 +16,7 @@ import { TExternalKmsServiceFactory } from "@app/ee/services/external-kms/extern import { TGroupServiceFactory } from "@app/ee/services/group/group-service"; import { TIdentityProjectAdditionalPrivilegeServiceFactory } from "@app/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-service"; import { TIdentityProjectAdditionalPrivilegeV2ServiceFactory } from "@app/ee/services/identity-project-additional-privilege-v2/identity-project-additional-privilege-v2-service"; +import { TKmipServiceFactory } from "@app/ee/services/kmip/kmip-service"; import { TLdapConfigServiceFactory } from "@app/ee/services/ldap-config/ldap-config-service"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { TOidcConfigServiceFactory } from "@app/ee/services/oidc/oidc-config-service"; @@ -212,6 +213,7 @@ declare module "fastify" { totp: TTotpServiceFactory; appConnection: TAppConnectionServiceFactory; secretSync: TSecretSyncServiceFactory; + kmip: TKmipServiceFactory; }; // this is exclusive use for middlewares in which we need to inject data // everywhere else access using service layer diff --git a/backend/src/@types/knex.d.ts b/backend/src/@types/knex.d.ts index 2dad77392..8b3c8b0ed 100644 --- a/backend/src/@types/knex.d.ts +++ b/backend/src/@types/knex.d.ts @@ -143,6 +143,9 @@ import { TInternalKms, TInternalKmsInsert, TInternalKmsUpdate, + TKmipClients, + TKmipClientsInsert, + TKmipClientsUpdate, TKmsKeys, TKmsKeysInsert, TKmsKeysUpdate, @@ -902,5 +905,6 @@ declare module "knex/types/tables" { TAppConnectionsUpdate >; [TableName.SecretSync]: KnexOriginal.CompositeTableType; + [TableName.KmipClient]: KnexOriginal.CompositeTableType; } } diff --git a/backend/src/db/migrations/20250203141127_add-kmip.ts b/backend/src/db/migrations/20250203141127_add-kmip.ts new file mode 100644 index 000000000..c80059b9d --- /dev/null +++ b/backend/src/db/migrations/20250203141127_add-kmip.ts @@ -0,0 +1,24 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; + +export async function up(knex: Knex): Promise { + const hasKmipClientTable = await knex.schema.hasTable(TableName.KmipClient); + if (!hasKmipClientTable) { + await knex.schema.createTable(TableName.KmipClient, (t) => { + t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); + t.string("name").notNullable(); + t.specificType("permissions", "text[]"); + t.string("description"); + t.string("projectId").notNullable(); + t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE"); + }); + } +} + +export async function down(knex: Knex): Promise { + const hasKmipClientTable = await knex.schema.hasTable(TableName.KmipClient); + if (hasKmipClientTable) { + await knex.schema.dropTable(TableName.KmipClient); + } +} diff --git a/backend/src/db/schemas/index.ts b/backend/src/db/schemas/index.ts index 9bcfdd49f..f3e687676 100644 --- a/backend/src/db/schemas/index.ts +++ b/backend/src/db/schemas/index.ts @@ -45,6 +45,7 @@ export * from "./incident-contacts"; export * from "./integration-auths"; export * from "./integrations"; export * from "./internal-kms"; +export * from "./kmip-clients"; export * from "./kms-key-versions"; export * from "./kms-keys"; export * from "./kms-root-config"; diff --git a/backend/src/db/schemas/kmip-clients.ts b/backend/src/db/schemas/kmip-clients.ts new file mode 100644 index 000000000..eb8f31bfb --- /dev/null +++ b/backend/src/db/schemas/kmip-clients.ts @@ -0,0 +1,20 @@ +// Code generated by automation script, DO NOT EDIT. +// Automated by pulling database and generating zod schema +// To update. Just run npm run generate:schema +// Written by akhilmhdh. + +import { z } from "zod"; + +import { TImmutableDBKeys } from "./models"; + +export const KmipClientsSchema = z.object({ + id: z.string().uuid(), + name: z.string(), + permissions: z.string().array().nullable().optional(), + description: z.string().nullable().optional(), + projectId: z.string() +}); + +export type TKmipClients = z.infer; +export type TKmipClientsInsert = Omit, TImmutableDBKeys>; +export type TKmipClientsUpdate = Partial, TImmutableDBKeys>>; diff --git a/backend/src/db/schemas/models.ts b/backend/src/db/schemas/models.ts index 3ead85530..fdaad428b 100644 --- a/backend/src/db/schemas/models.ts +++ b/backend/src/db/schemas/models.ts @@ -132,7 +132,8 @@ export enum TableName { SlackIntegrations = "slack_integrations", ProjectSlackConfigs = "project_slack_configs", AppConnection = "app_connections", - SecretSync = "secret_syncs" + SecretSync = "secret_syncs", + KmipClient = "kmip_clients" } export type TImmutableDBKeys = "id" | "createdAt" | "updatedAt"; diff --git a/backend/src/ee/routes/v1/index.ts b/backend/src/ee/routes/v1/index.ts index 5f931440c..cb2e7e0da 100644 --- a/backend/src/ee/routes/v1/index.ts +++ b/backend/src/ee/routes/v1/index.ts @@ -9,6 +9,7 @@ import { registerDynamicSecretRouter } from "./dynamic-secret-router"; import { registerExternalKmsRouter } from "./external-kms-router"; import { registerGroupRouter } from "./group-router"; import { registerIdentityProjectAdditionalPrivilegeRouter } from "./identity-project-additional-privilege-router"; +import { registerKmipRouter } from "./kmip-router"; import { registerLdapRouter } from "./ldap-router"; import { registerLicenseRouter } from "./license-router"; import { registerOidcRouter } from "./oidc-router"; @@ -110,4 +111,5 @@ export const registerV1EERoutes = async (server: FastifyZodProvider) => { }); await server.register(registerProjectTemplateRouter, { prefix: "/project-templates" }); + await server.register(registerKmipRouter, { prefix: "/kmip" }); }; diff --git a/backend/src/ee/routes/v1/kmip-router.ts b/backend/src/ee/routes/v1/kmip-router.ts new file mode 100644 index 000000000..66d3e7e28 --- /dev/null +++ b/backend/src/ee/routes/v1/kmip-router.ts @@ -0,0 +1,183 @@ +import { z } from "zod"; + +import { KmipClientsSchema } from "@app/db/schemas"; +import { EventType } from "@app/ee/services/audit-log/audit-log-types"; +import { KmipPermission } from "@app/ee/services/kmip/kmip-enum"; +import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; +import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; +import { AuthMode } from "@app/services/auth/auth-type"; + +const KmipClientResponseSchema = KmipClientsSchema.pick({ + projectId: true, + name: true, + id: true, + description: true, + permissions: true +}); + +export const registerKmipRouter = async (server: FastifyZodProvider) => { + server.route({ + method: "POST", + url: "/clients", + config: { + rateLimit: writeLimit + }, + schema: { + body: z.object({ + projectId: z.string(), + name: z.string().trim().min(1), + description: z.string().optional(), + permissions: z.nativeEnum(KmipPermission).array() + }), + response: { + 200: KmipClientResponseSchema + } + }, + onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), + handler: async (req) => { + const kmipClient = await server.services.kmip.createKmipClient({ + actor: req.permission.type, + actorId: req.permission.id, + actorAuthMethod: req.permission.authMethod, + actorOrgId: req.permission.orgId, + ...req.body + }); + + await server.services.auditLog.createAuditLog({ + ...req.auditLogInfo, + orgId: req.permission.orgId, + projectId: kmipClient.projectId, + event: { + type: EventType.CREATE_KMIP_CLIENT, + metadata: { + id: kmipClient.id, + name: kmipClient.name, + permissions: (kmipClient.permissions ?? []) as KmipPermission[] + } + } + }); + } + }); + + server.route({ + method: "PATCH", + url: "/clients/:id", + config: { + rateLimit: writeLimit + }, + schema: { + params: z.object({ + id: z.string() + }), + body: z.object({ + name: z.string().trim().min(1), + description: z.string().optional(), + permissions: z.nativeEnum(KmipPermission).array() + }), + response: { + 200: KmipClientResponseSchema + } + }, + onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), + handler: async (req) => { + const kmipClient = await server.services.kmip.updateKmipClient({ + actor: req.permission.type, + actorId: req.permission.id, + actorAuthMethod: req.permission.authMethod, + actorOrgId: req.permission.orgId, + ...req.params, + ...req.body + }); + + await server.services.auditLog.createAuditLog({ + ...req.auditLogInfo, + orgId: req.permission.orgId, + projectId: kmipClient.projectId, + event: { + type: EventType.UPDATE_KMIP_CLIENT, + metadata: { + id: kmipClient.id, + name: kmipClient.name, + permissions: (kmipClient.permissions ?? []) as KmipPermission[] + } + } + }); + } + }); + + server.route({ + method: "DELETE", + url: "/clients/:id", + config: { + rateLimit: writeLimit + }, + schema: { + params: z.object({ + id: z.string() + }), + response: { + 200: KmipClientResponseSchema + } + }, + onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), + handler: async (req) => { + const kmipClient = await server.services.kmip.deleteKmipClient({ + actor: req.permission.type, + actorId: req.permission.id, + actorAuthMethod: req.permission.authMethod, + actorOrgId: req.permission.orgId, + ...req.params + }); + + await server.services.auditLog.createAuditLog({ + ...req.auditLogInfo, + orgId: req.permission.orgId, + projectId: kmipClient.projectId, + event: { + type: EventType.DELETE_KMIP_CLIENT, + metadata: { + id: kmipClient.id + } + } + }); + } + }); + + server.route({ + method: "GET", + url: "/clients/:id", + config: { + rateLimit: readLimit + }, + schema: { + params: z.object({ + id: z.string() + }), + response: { + 200: KmipClientResponseSchema + } + }, + onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), + handler: async (req) => { + const kmipClient = await server.services.kmip.getKmipClient({ + actor: req.permission.type, + actorId: req.permission.id, + actorAuthMethod: req.permission.authMethod, + actorOrgId: req.permission.orgId, + ...req.params + }); + + await server.services.auditLog.createAuditLog({ + ...req.auditLogInfo, + orgId: req.permission.orgId, + projectId: kmipClient.projectId, + event: { + type: EventType.GET_KMIP_CLIENT, + metadata: { + id: kmipClient.id + } + } + }); + } + }); +}; diff --git a/backend/src/ee/services/audit-log/audit-log-types.ts b/backend/src/ee/services/audit-log/audit-log-types.ts index ffabb3cc4..fca2975be 100644 --- a/backend/src/ee/services/audit-log/audit-log-types.ts +++ b/backend/src/ee/services/audit-log/audit-log-types.ts @@ -21,6 +21,8 @@ import { TUpdateSecretSyncDTO } from "@app/services/secret-sync/secret-sync-types"; +import { KmipPermission } from "../kmip/kmip-enum"; + export type TListProjectAuditLogDTO = { filter: { userAgentType?: UserAgentType; @@ -251,7 +253,11 @@ export enum EventType { SECRET_SYNC_IMPORT_SECRETS = "secret-sync-import-secrets", SECRET_SYNC_REMOVE_SECRETS = "secret-sync-remove-secrets", OIDC_GROUP_MEMBERSHIP_MAPPING_ASSIGN_USER = "oidc-group-membership-mapping-assign-user", - OIDC_GROUP_MEMBERSHIP_MAPPING_REMOVE_USER = "oidc-group-membership-mapping-remove-user" + OIDC_GROUP_MEMBERSHIP_MAPPING_REMOVE_USER = "oidc-group-membership-mapping-remove-user", + CREATE_KMIP_CLIENT = "create-kmip-client", + UPDATE_KMIP_CLIENT = "update-kmip-client", + DELETE_KMIP_CLIENT = "delete-kmip-client", + GET_KMIP_CLIENT = "get-kmip-client" } interface UserActorMetadata { @@ -2066,6 +2072,38 @@ interface OidcGroupMembershipMappingRemoveUserEvent { }; } +interface CreateKmipClientEvent { + type: EventType.CREATE_KMIP_CLIENT; + metadata: { + name: string; + id: string; + permissions: KmipPermission[]; + }; +} + +interface UpdateKmipClientEvent { + type: EventType.UPDATE_KMIP_CLIENT; + metadata: { + name: string; + id: string; + permissions: KmipPermission[]; + }; +} + +interface DeleteKmipClientEvent { + type: EventType.DELETE_KMIP_CLIENT; + metadata: { + id: string; + }; +} + +interface GetKmipClientEvent { + type: EventType.GET_KMIP_CLIENT; + metadata: { + id: string; + }; +} + export type Event = | GetSecretsEvent | GetSecretEvent @@ -2256,4 +2294,8 @@ export type Event = | SecretSyncImportSecretsEvent | SecretSyncRemoveSecretsEvent | OidcGroupMembershipMappingAssignUserEvent - | OidcGroupMembershipMappingRemoveUserEvent; + | OidcGroupMembershipMappingRemoveUserEvent + | CreateKmipClientEvent + | UpdateKmipClientEvent + | DeleteKmipClientEvent + | GetKmipClientEvent; diff --git a/backend/src/ee/services/kmip/kmip-client-dal.ts b/backend/src/ee/services/kmip/kmip-client-dal.ts new file mode 100644 index 000000000..e4f1d3408 --- /dev/null +++ b/backend/src/ee/services/kmip/kmip-client-dal.ts @@ -0,0 +1,11 @@ +import { TDbClient } from "@app/db"; +import { TableName } from "@app/db/schemas"; +import { ormify } from "@app/lib/knex"; + +export type TKmipClientDALFactory = ReturnType; + +export const kmipClientDALFactory = (db: TDbClient) => { + const kmipClient = ormify(db, TableName.KmipClient); + + return kmipClient; +}; diff --git a/backend/src/ee/services/kmip/kmip-enum.ts b/backend/src/ee/services/kmip/kmip-enum.ts new file mode 100644 index 000000000..aca3421bb --- /dev/null +++ b/backend/src/ee/services/kmip/kmip-enum.ts @@ -0,0 +1,6 @@ +export enum KmipPermission { + Create = "create", + Locate = "locate", + Check = "check", + Get = "get" +} diff --git a/backend/src/ee/services/kmip/kmip-service.ts b/backend/src/ee/services/kmip/kmip-service.ts new file mode 100644 index 000000000..59390b4cc --- /dev/null +++ b/backend/src/ee/services/kmip/kmip-service.ts @@ -0,0 +1,127 @@ +import { ForbiddenError } from "@casl/ability"; + +import { ActionProjectType } from "@app/db/schemas"; + +import { TPermissionServiceFactory } from "../permission/permission-service"; +import { ProjectPermissionKmipActions, ProjectPermissionSub } from "../permission/project-permission"; +import { TKmipClientDALFactory } from "./kmip-client-dal"; +import { TCreateKmipClientDTO, TDeleteKmipClientDTO, TGetKmipClientDTO, TUpdateKmipClientDTO } from "./kmip-types"; + +type TKmipServiceFactoryDep = { + kmipClientDAL: TKmipClientDALFactory; + permissionService: Pick; +}; + +export type TKmipServiceFactory = ReturnType; + +export const kmipServiceFactory = ({ kmipClientDAL, permissionService }: TKmipServiceFactoryDep) => { + const createKmipClient = async ({ + actor, + actorId, + actorOrgId, + actorAuthMethod, + projectId, + name, + description, + permissions + }: TCreateKmipClientDTO) => { + const { permission } = await permissionService.getProjectPermission({ + actor, + actorId, + projectId, + actorAuthMethod, + actorOrgId, + actionProjectType: ActionProjectType.KMS + }); + + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionKmipActions.CreateClients, + ProjectPermissionSub.Kmip + ); + + const kmipClient = await kmipClientDAL.create({ + projectId, + name, + description, + permissions + }); + + return kmipClient; + }; + + const updateKmipClient = async ({ + actor, + actorId, + actorOrgId, + actorAuthMethod, + name, + description, + permissions, + id + }: TUpdateKmipClientDTO) => { + const kmipClient = await kmipClientDAL.findById(id); + + const { permission } = await permissionService.getProjectPermission({ + actor, + actorId, + projectId: kmipClient.projectId, + actorAuthMethod, + actorOrgId, + actionProjectType: ActionProjectType.KMS + }); + + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionKmipActions.UpdateClients, + ProjectPermissionSub.Kmip + ); + + const updatedKmipClient = await kmipClientDAL.updateById(id, { + name, + description, + permissions + }); + + return updatedKmipClient; + }; + + const deleteKmipClient = async ({ actor, actorId, actorOrgId, actorAuthMethod, id }: TDeleteKmipClientDTO) => { + const kmipClient = await kmipClientDAL.findById(id); + + const { permission } = await permissionService.getProjectPermission({ + actor, + actorId, + projectId: kmipClient.projectId, + actorAuthMethod, + actorOrgId, + actionProjectType: ActionProjectType.KMS + }); + + ForbiddenError.from(permission).throwUnlessCan( + ProjectPermissionKmipActions.DeleteClients, + ProjectPermissionSub.Kmip + ); + + const deletedKmipClient = await kmipClientDAL.deleteById(id); + + return deletedKmipClient; + }; + + const getKmipClient = async ({ actor, actorId, actorOrgId, actorAuthMethod, id }: TGetKmipClientDTO) => { + const kmipClient = await kmipClientDAL.findById(id); + + const { permission } = await permissionService.getProjectPermission({ + actor, + actorId, + projectId: kmipClient.projectId, + actorAuthMethod, + actorOrgId, + actionProjectType: ActionProjectType.KMS + }); + + ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionKmipActions.ReadClients, ProjectPermissionSub.Kmip); + + return kmipClient; + }; + + return { createKmipClient, updateKmipClient, deleteKmipClient, getKmipClient }; +}; diff --git a/backend/src/ee/services/kmip/kmip-types.ts b/backend/src/ee/services/kmip/kmip-types.ts new file mode 100644 index 000000000..4b43abf14 --- /dev/null +++ b/backend/src/ee/services/kmip/kmip-types.ts @@ -0,0 +1,24 @@ +import { TProjectPermission } from "@app/lib/types"; + +import { KmipPermission } from "./kmip-enum"; + +export type TCreateKmipClientDTO = { + name: string; + description?: string; + permissions: KmipPermission[]; +} & TProjectPermission; + +export type TUpdateKmipClientDTO = { + id: string; + name?: string; + description?: string; + permissions?: KmipPermission[]; +} & Omit; + +export type TDeleteKmipClientDTO = { + id: string; +} & Omit; + +export type TGetKmipClientDTO = { + id: string; +} & Omit; diff --git a/backend/src/ee/services/permission/project-permission.ts b/backend/src/ee/services/permission/project-permission.ts index e9ba49127..ef7ef34ae 100644 --- a/backend/src/ee/services/permission/project-permission.ts +++ b/backend/src/ee/services/permission/project-permission.ts @@ -44,6 +44,13 @@ export enum ProjectPermissionSecretSyncActions { RemoveSecrets = "remove-secrets" } +export enum ProjectPermissionKmipActions { + CreateClients = "create-clients", + UpdateClients = "update-clients", + DeleteClients = "delete-clients", + ReadClients = "read-clients" +} + export enum ProjectPermissionSub { Role = "role", Member = "member", @@ -75,7 +82,8 @@ export enum ProjectPermissionSub { PkiCollections = "pki-collections", Kms = "kms", Cmek = "cmek", - SecretSyncs = "secret-syncs" + SecretSyncs = "secret-syncs", + Kmip = "kmip" } export type SecretSubjectFields = { @@ -156,6 +164,7 @@ export type ProjectPermissionSet = | [ProjectPermissionActions, ProjectPermissionSub.PkiAlerts] | [ProjectPermissionActions, ProjectPermissionSub.PkiCollections] | [ProjectPermissionSecretSyncActions, ProjectPermissionSub.SecretSyncs] + | [ProjectPermissionKmipActions, ProjectPermissionSub.Kmip] | [ProjectPermissionCmekActions, ProjectPermissionSub.Cmek] | [ProjectPermissionActions.Delete, ProjectPermissionSub.Project] | [ProjectPermissionActions.Edit, ProjectPermissionSub.Project] @@ -575,6 +584,17 @@ const buildAdminPermissionRules = () => { ], ProjectPermissionSub.SecretSyncs ); + + can( + [ + ProjectPermissionKmipActions.CreateClients, + ProjectPermissionKmipActions.UpdateClients, + ProjectPermissionKmipActions.DeleteClients, + ProjectPermissionKmipActions.ReadClients + ], + ProjectPermissionSub.Kmip + ); + return rules; }; diff --git a/backend/src/server/routes/index.ts b/backend/src/server/routes/index.ts index 3e5947956..eabbb8e0a 100644 --- a/backend/src/server/routes/index.ts +++ b/backend/src/server/routes/index.ts @@ -35,6 +35,8 @@ import { HsmModule } from "@app/ee/services/hsm/hsm-types"; import { identityProjectAdditionalPrivilegeDALFactory } from "@app/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-dal"; import { identityProjectAdditionalPrivilegeServiceFactory } from "@app/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-service"; import { identityProjectAdditionalPrivilegeV2ServiceFactory } from "@app/ee/services/identity-project-additional-privilege-v2/identity-project-additional-privilege-v2-service"; +import { kmipClientDALFactory } from "@app/ee/services/kmip/kmip-client-dal"; +import { kmipServiceFactory } from "@app/ee/services/kmip/kmip-service"; import { ldapConfigDALFactory } from "@app/ee/services/ldap-config/ldap-config-dal"; import { ldapConfigServiceFactory } from "@app/ee/services/ldap-config/ldap-config-service"; import { ldapGroupMapDALFactory } from "@app/ee/services/ldap-config/ldap-group-map-dal"; @@ -380,6 +382,7 @@ export const registerRoutes = async ( const projectTemplateDAL = projectTemplateDALFactory(db); const resourceMetadataDAL = resourceMetadataDALFactory(db); + const kmipClientDAL = kmipClientDALFactory(db); const permissionService = permissionServiceFactory({ permissionDAL, @@ -1418,6 +1421,11 @@ export const registerRoutes = async ( keyStore }); + const kmipService = kmipServiceFactory({ + kmipClientDAL, + permissionService + }); + await superAdminService.initServerCfg(); // setup the communication with license key server @@ -1516,7 +1524,8 @@ export const registerRoutes = async ( projectTemplate: projectTemplateService, totp: totpService, appConnection: appConnectionService, - secretSync: secretSyncService + secretSync: secretSyncService, + kmip: kmipService }); const cronJobs: CronJob[] = [];