diff --git a/backend/src/ee/services/external-kms/external-kms-service.ts b/backend/src/ee/services/external-kms/external-kms-service.ts index 66712f715..506472363 100644 --- a/backend/src/ee/services/external-kms/external-kms-service.ts +++ b/backend/src/ee/services/external-kms/external-kms-service.ts @@ -54,7 +54,8 @@ export const externalKmsServiceFactory = ({ actorAuthMethod, actorOrgId ); - ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Settings); + + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Kms); const kmsSlug = slug ? slugify(slug) : slugify(alphaNumericNanoId(8).toLowerCase()); let sanitizedProviderInput = ""; @@ -125,7 +126,7 @@ export const externalKmsServiceFactory = ({ actorAuthMethod, actorOrgId ); - ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Settings); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Kms); const kmsSlug = slug ? slugify(slug) : undefined; const externalKmsDoc = await externalKmsDAL.findOne({ kmsKeyId: kmsDoc.id }); @@ -205,7 +206,7 @@ export const externalKmsServiceFactory = ({ actorAuthMethod, actorOrgId ); - ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Settings); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Kms); const externalKmsDoc = await externalKmsDAL.findOne({ kmsKeyId: kmsDoc.id }); if (!externalKmsDoc) throw new BadRequestError({ message: "External kms not found" }); @@ -226,7 +227,7 @@ export const externalKmsServiceFactory = ({ actorAuthMethod, actorOrgId ); - ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Settings); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Kms); const externalKmsDocs = await externalKmsDAL.find({ orgId: actorOrgId }); @@ -242,7 +243,8 @@ export const externalKmsServiceFactory = ({ actorAuthMethod, actorOrgId ); - ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Settings); + + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Kms); const externalKmsDoc = await externalKmsDAL.findOne({ kmsKeyId: kmsDoc.id }); if (!externalKmsDoc) throw new BadRequestError({ message: "External kms not found" }); @@ -282,7 +284,7 @@ export const externalKmsServiceFactory = ({ actorAuthMethod, actorOrgId ); - ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Settings); + ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Kms); const externalKmsDoc = await externalKmsDAL.findOne({ kmsKeyId: kmsDoc.id }); if (!externalKmsDoc) throw new BadRequestError({ message: "External kms not found" }); diff --git a/backend/src/ee/services/permission/org-permission.ts b/backend/src/ee/services/permission/org-permission.ts index 6b7b3b2b2..77eaacd3b 100644 --- a/backend/src/ee/services/permission/org-permission.ts +++ b/backend/src/ee/services/permission/org-permission.ts @@ -21,7 +21,8 @@ export enum OrgPermissionSubjects { Groups = "groups", Billing = "billing", SecretScanning = "secret-scanning", - Identity = "identity" + Identity = "identity", + Kms = "kms" } export type OrgPermissionSet = @@ -37,7 +38,8 @@ export type OrgPermissionSet = | [OrgPermissionActions, OrgPermissionSubjects.Groups] | [OrgPermissionActions, OrgPermissionSubjects.SecretScanning] | [OrgPermissionActions, OrgPermissionSubjects.Billing] - | [OrgPermissionActions, OrgPermissionSubjects.Identity]; + | [OrgPermissionActions, OrgPermissionSubjects.Identity] + | [OrgPermissionActions, OrgPermissionSubjects.Kms]; const buildAdminPermission = () => { const { can, build } = new AbilityBuilder>(createMongoAbility); @@ -100,6 +102,11 @@ const buildAdminPermission = () => { can(OrgPermissionActions.Edit, OrgPermissionSubjects.Identity); can(OrgPermissionActions.Delete, OrgPermissionSubjects.Identity); + can(OrgPermissionActions.Read, OrgPermissionSubjects.Kms); + can(OrgPermissionActions.Create, OrgPermissionSubjects.Kms); + can(OrgPermissionActions.Edit, OrgPermissionSubjects.Kms); + can(OrgPermissionActions.Delete, OrgPermissionSubjects.Kms); + return build({ conditionsMatcher }); }; diff --git a/frontend/src/context/OrgPermissionContext/types.ts b/frontend/src/context/OrgPermissionContext/types.ts index 95a9d00ac..36206873d 100644 --- a/frontend/src/context/OrgPermissionContext/types.ts +++ b/frontend/src/context/OrgPermissionContext/types.ts @@ -19,7 +19,8 @@ export enum OrgPermissionSubjects { Groups = "groups", Billing = "billing", SecretScanning = "secret-scanning", - Identity = "identity" + Identity = "identity", + Kms = "kms" } export type OrgPermissionSet = @@ -35,6 +36,7 @@ export type OrgPermissionSet = | [OrgPermissionActions, OrgPermissionSubjects.Groups] | [OrgPermissionActions, OrgPermissionSubjects.SecretScanning] | [OrgPermissionActions, OrgPermissionSubjects.Billing] - | [OrgPermissionActions, OrgPermissionSubjects.Identity]; + | [OrgPermissionActions, OrgPermissionSubjects.Identity] + | [OrgPermissionActions, OrgPermissionSubjects.Kms]; export type TOrgPermission = MongoAbility; diff --git a/frontend/src/views/Settings/OrgSettingsPage/components/OrgEncryptionTab/OrgEncryptionTab.tsx b/frontend/src/views/Settings/OrgSettingsPage/components/OrgEncryptionTab/OrgEncryptionTab.tsx index cbfb2c3e3..a41bb3ed9 100644 --- a/frontend/src/views/Settings/OrgSettingsPage/components/OrgEncryptionTab/OrgEncryptionTab.tsx +++ b/frontend/src/views/Settings/OrgSettingsPage/components/OrgEncryptionTab/OrgEncryptionTab.tsx @@ -1,8 +1,10 @@ import { faAws } from "@fortawesome/free-brands-svg-icons"; import { faEllipsis, faLock, faPlus } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { twMerge } from "tailwind-merge"; import { createNotification } from "@app/components/notifications"; +import { OrgPermissionCan } from "@app/components/permissions"; import { Button, DeleteActionModal, @@ -67,22 +69,27 @@ export const OrgEncryptionTab = withPermission(

Key Management System (KMS)

- + + {(isAllowed) => ( + + )} +

- Integrate with external KMS systems for encrypting your organization's data + Integrate with external KMS for encrypting your organization's data

@@ -119,28 +126,50 @@ export const OrgEncryptionTab = withPermission( - { - e.stopPropagation(); - handlePopUpOpen("editExternalKms", { - kmsId: kms.id - }); - }} + - Edit - - { - e.stopPropagation(); - handlePopUpOpen("removeExternalKms", { - slug: kms.slug, - kmsId: kms.id, - provider: kms.externalKms.provider - }); - }} + {(isAllowed) => ( + { + e.stopPropagation(); + handlePopUpOpen("editExternalKms", { + kmsId: kms.id + }); + }} + > + Edit + + )} + + - Delete - + {(isAllowed) => ( + { + e.stopPropagation(); + handlePopUpOpen("removeExternalKms", { + slug: kms.slug, + kmsId: kms.id, + provider: kms.externalKms.provider + }); + }} + > + Delete + + )} + @@ -175,5 +204,5 @@ export const OrgEncryptionTab = withPermission( ); }, - { action: OrgPermissionActions.Edit, subject: OrgPermissionSubjects.Settings } + { action: OrgPermissionActions.Read, subject: OrgPermissionSubjects.Kms } );