feat: kmip poc done

This commit is contained in:
Sheen Capadngan
2025-02-14 23:55:57 +08:00
parent b8a07979c3
commit af652f7e52
12 changed files with 631 additions and 14 deletions
@@ -269,7 +269,12 @@ export enum EventType {
CREATE_KMIP_CLIENT_CERTIFICATE = "create-kmip-client-certificate",
KMIP_OPERATION_CREATE = "kmip-operation-create",
KMIP_OPERATION_GET = "kmip-operation-get",
KMIP_OPERATION_DELETE = "kmip-operation-delete"
KMIP_OPERATION_DELETE = "kmip-operation-delete",
KMIP_OPERATION_GET_ATTRIBUTES = "kmip-operation-get-attributes",
KMIP_OPERATION_ACTIVATE = "kmip-operation-activate",
KMIP_OPERATION_REVOKE = "kmip-operation-revoke",
KMIP_OPERATION_LOCATE = "kmip-operation-locate",
KMIP_OPERATION_REGISTER = "kmip-operation-register"
}
interface UserActorMetadata {
@@ -2165,6 +2170,43 @@ interface KmipOperationCreateEvent {
};
}
interface KmipOperationGetAttributesEvent {
type: EventType.KMIP_OPERATION_GET_ATTRIBUTES;
metadata: {
id: string;
};
}
interface KmipOperationActivateEvent {
type: EventType.KMIP_OPERATION_ACTIVATE;
metadata: {
id: string;
};
}
interface KmipOperationRevokeEvent {
type: EventType.KMIP_OPERATION_REVOKE;
metadata: {
id: string;
};
}
interface KmipOperationLocateEvent {
type: EventType.KMIP_OPERATION_LOCATE;
metadata: {
ids: string[];
};
}
interface KmipOperationRegisterEvent {
type: EventType.KMIP_OPERATION_REGISTER;
metadata: {
id: string;
algorithm: string;
name: string;
};
}
export type Event =
| GetSecretsEvent
| GetSecretEvent
@@ -2364,4 +2406,9 @@ export type Event =
| CreateKmipClientCertificateEvent
| KmipOperationGetEvent
| KmipOperationDeleteEvent
| KmipOperationCreateEvent;
| KmipOperationCreateEvent
| KmipOperationGetAttributesEvent
| KmipOperationActivateEvent
| KmipOperationRevokeEvent
| KmipOperationLocateEvent
| KmipOperationRegisterEvent;
+5 -1
View File
@@ -3,5 +3,9 @@ export enum KmipPermission {
Locate = "locate",
Check = "check",
Get = "get",
Delete = "delete"
GetAttributes = "get-attributes",
Activate = "activate",
Revoke = "revoke",
Delete = "delete",
Register = "register"
}
@@ -6,7 +6,15 @@ import { TProjectDALFactory } from "@app/services/project/project-dal";
import { TKmipClientDALFactory } from "./kmip-client-dal";
import { KmipPermission } from "./kmip-enum";
import { TKmipCreateDTO, TKmipDeleteDTO, TKmipGetDTO } from "./kmip-types";
import {
TKmipCreateDTO,
TKmipDeleteDTO,
TKmipGetAttributesDTO,
TKmipGetDTO,
TKmipLocateDTO,
TKmipRegisterDTO,
TKmipRevokeDTO
} from "./kmip-types";
type TKmipOperationServiceFactoryDep = {
kmsService: TKmsServiceFactory;
@@ -143,13 +151,211 @@ export const kmipOperationServiceFactory = ({
return {
id: key.id,
value: kmsKey.toString("base64"),
algorithm: completeKeyDetails.internalKms.encryptionAlgorithm
algorithm: completeKeyDetails.internalKms.encryptionAlgorithm,
isActive: !key.isDisabled,
createdAt: key.createdAt,
updatedAt: key.updatedAt
};
};
const activate = async ({ projectId: preSplitProjectId, id, clientId }: TKmipGetDTO) => {
let projectId = preSplitProjectId;
const cmekProjectFromSplit = await projectDAL.getProjectFromSplitId(projectId, ProjectType.KMS);
if (cmekProjectFromSplit) {
projectId = cmekProjectFromSplit.id;
}
const kmipClient = await kmipClientDAL.findOne({
id: clientId,
projectId
});
if (!kmipClient.permissions?.includes(KmipPermission.Activate)) {
throw new ForbiddenRequestError({
message: "Client does not have sufficient permission to perform KMIP activate"
});
}
const key = await kmsDAL.findOne({
id,
projectId
});
if (!key) {
throw new NotFoundError({ message: `Key with ID ${id} not found` });
}
return {
id: key.id,
isActive: !key.isDisabled
};
};
const revoke = async ({ projectId: preSplitProjectId, id, clientId }: TKmipRevokeDTO) => {
let projectId = preSplitProjectId;
const cmekProjectFromSplit = await projectDAL.getProjectFromSplitId(projectId, ProjectType.KMS);
if (cmekProjectFromSplit) {
projectId = cmekProjectFromSplit.id;
}
const kmipClient = await kmipClientDAL.findOne({
id: clientId,
projectId
});
if (!kmipClient.permissions?.includes(KmipPermission.Revoke)) {
throw new ForbiddenRequestError({
message: "Client does not have sufficient permission to perform KMIP revoke"
});
}
const key = await kmsDAL.findOne({
id,
projectId
});
if (!key) {
throw new NotFoundError({ message: `Key with ID ${id} not found` });
}
if (key.isReserved) {
throw new BadRequestError({ message: "Cannot revoke reserved keys" });
}
const completeKeyDetails = await kmsDAL.findByIdWithAssociatedKms(id);
if (!completeKeyDetails.internalKms) {
throw new BadRequestError({
message: "Cannot revoke external keys"
});
}
const revokedKey = await kmsDAL.updateById(key.id, {
isDisabled: true
});
return {
id: key.id,
updatedAt: revokedKey.updatedAt
};
};
const getAttributes = async ({ projectId: preSplitProjectId, id, clientId }: TKmipGetAttributesDTO) => {
let projectId = preSplitProjectId;
const cmekProjectFromSplit = await projectDAL.getProjectFromSplitId(projectId, ProjectType.KMS);
if (cmekProjectFromSplit) {
projectId = cmekProjectFromSplit.id;
}
const kmipClient = await kmipClientDAL.findOne({
id: clientId,
projectId
});
if (!kmipClient.permissions?.includes(KmipPermission.GetAttributes)) {
throw new ForbiddenRequestError({
message: "Client does not have sufficient permission to perform KMIP get attributes"
});
}
const key = await kmsDAL.findOne({
id,
projectId
});
if (!key) {
throw new NotFoundError({ message: `Key with ID ${id} not found` });
}
if (key.isReserved) {
throw new BadRequestError({ message: "Cannot get reserved keys" });
}
const completeKeyDetails = await kmsDAL.findByIdWithAssociatedKms(id);
if (!completeKeyDetails.internalKms) {
throw new BadRequestError({
message: "Cannot get external keys"
});
}
return {
id: key.id,
algorithm: completeKeyDetails.internalKms.encryptionAlgorithm,
isActive: !key.isDisabled,
createdAt: key.createdAt,
updatedAt: key.updatedAt
};
};
const locate = async ({ projectId: preSplitProjectId, clientId }: TKmipLocateDTO) => {
let projectId = preSplitProjectId;
const cmekProjectFromSplit = await projectDAL.getProjectFromSplitId(projectId, ProjectType.KMS);
if (cmekProjectFromSplit) {
projectId = cmekProjectFromSplit.id;
}
const kmipClient = await kmipClientDAL.findOne({
id: clientId,
projectId
});
if (!kmipClient.permissions?.includes(KmipPermission.Locate)) {
throw new ForbiddenRequestError({
message: "Client does not have sufficient permission to perform KMIP locate"
});
}
const keys = await kmsDAL.findProjectCmeks(projectId);
return keys;
};
const register = async ({ projectId: preSplitProjectId, clientId, key, algorithm, name }: TKmipRegisterDTO) => {
let projectId = preSplitProjectId;
const cmekProjectFromSplit = await projectDAL.getProjectFromSplitId(projectId, ProjectType.KMS);
if (cmekProjectFromSplit) {
projectId = cmekProjectFromSplit.id;
}
const kmipClient = await kmipClientDAL.findOne({
id: clientId,
projectId
});
if (!kmipClient.permissions?.includes(KmipPermission.Register)) {
throw new ForbiddenRequestError({
message: "Client does not have sufficient permission to perform KMIP register"
});
}
const project = await projectDAL.findById(projectId);
const kmsKey = await kmsService.importKeyMaterial({
name,
key: Buffer.from(key, "base64"),
algorithm,
isReserved: false,
projectId,
orgId: project.orgId
});
return kmsKey;
};
return {
create,
get,
deleteOp
activate,
getAttributes,
deleteOp,
revoke,
locate,
register
};
};
@@ -56,6 +56,26 @@ export type TKmipGetDTO = {
id: string;
} & KmipOperationBaseDTO;
export type TKmipGetAttributesDTO = {
id: string;
} & KmipOperationBaseDTO;
export type TKmipDeleteDTO = {
id: string;
} & KmipOperationBaseDTO;
export type TKmipActivateDTO = {
id: string;
} & KmipOperationBaseDTO;
export type TKmipRevokeDTO = {
id: string;
} & KmipOperationBaseDTO;
export type TKmipLocateDTO = KmipOperationBaseDTO;
export type TKmipRegisterDTO = {
name: string;
key: string;
algorithm: SymmetricEncryption;
} & KmipOperationBaseDTO;