mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-15 10:35:17 +00:00
Merge pull request #2950 from Infisical/feat/secret-access-list
feat: secret access list
This commit is contained in:
@@ -11,6 +11,7 @@ import {
|
||||
SecretsSchema,
|
||||
SecretType
|
||||
} from "@app/db/schemas";
|
||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||
import { TSecretApprovalPolicyServiceFactory } from "@app/ee/services/secret-approval-policy/secret-approval-policy-service";
|
||||
@@ -69,6 +70,7 @@ import {
|
||||
TDeleteSecretRawDTO,
|
||||
TGetASecretDTO,
|
||||
TGetASecretRawDTO,
|
||||
TGetSecretAccessListDTO,
|
||||
TGetSecretsDTO,
|
||||
TGetSecretsRawDTO,
|
||||
TGetSecretVersionsDTO,
|
||||
@@ -94,7 +96,7 @@ type TSecretServiceFactoryDep = {
|
||||
>;
|
||||
secretV2BridgeService: TSecretV2BridgeServiceFactory;
|
||||
secretBlindIndexDAL: TSecretBlindIndexDALFactory;
|
||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission" | "getProjectPermissions">;
|
||||
snapshotService: Pick<TSecretSnapshotServiceFactory, "performSnapshot">;
|
||||
secretQueueService: Pick<
|
||||
TSecretQueueFactory,
|
||||
@@ -113,6 +115,7 @@ type TSecretServiceFactoryDep = {
|
||||
TSecretApprovalRequestSecretDALFactory,
|
||||
"insertMany" | "insertApprovalSecretTags"
|
||||
>;
|
||||
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
||||
};
|
||||
|
||||
export type TSecretServiceFactory = ReturnType<typeof secretServiceFactory>;
|
||||
@@ -134,7 +137,8 @@ export const secretServiceFactory = ({
|
||||
secretApprovalRequestDAL,
|
||||
secretApprovalRequestSecretDAL,
|
||||
secretV2BridgeService,
|
||||
secretApprovalRequestService
|
||||
secretApprovalRequestService,
|
||||
licenseService
|
||||
}: TSecretServiceFactoryDep) => {
|
||||
const getSecretReference = async (projectId: string) => {
|
||||
// if bot key missing means e2e still exist
|
||||
@@ -1153,6 +1157,71 @@ export const secretServiceFactory = ({
|
||||
return secretV2BridgeService.getSecretReferenceTree(dto);
|
||||
};
|
||||
|
||||
const getSecretAccessList = async (dto: TGetSecretAccessListDTO) => {
|
||||
const { environment, secretPath, secretName, projectId } = dto;
|
||||
const plan = await licenseService.getPlan(dto.actorOrgId);
|
||||
if (!plan.secretAccessInsights) {
|
||||
throw new BadRequestError({
|
||||
message: "Failed to fetch secret access list due to plan restriction. Upgrade your plan."
|
||||
});
|
||||
}
|
||||
|
||||
const secret = await secretV2BridgeService.getSecretByName({
|
||||
actor: dto.actor,
|
||||
actorId: dto.actorId,
|
||||
actorOrgId: dto.actorOrgId,
|
||||
actorAuthMethod: dto.actorAuthMethod,
|
||||
projectId,
|
||||
secretName,
|
||||
path: secretPath,
|
||||
environment,
|
||||
type: "shared"
|
||||
});
|
||||
|
||||
const { userPermissions, identityPermissions, groupPermissions } = await permissionService.getProjectPermissions(
|
||||
dto.projectId
|
||||
);
|
||||
|
||||
const attachAllowedActions = (
|
||||
entityPermission:
|
||||
| (typeof userPermissions)[number]
|
||||
| (typeof identityPermissions)[number]
|
||||
| (typeof groupPermissions)[number]
|
||||
) => {
|
||||
const allowedActions = [
|
||||
ProjectPermissionActions.Read,
|
||||
ProjectPermissionActions.Delete,
|
||||
ProjectPermissionActions.Create,
|
||||
ProjectPermissionActions.Edit
|
||||
].filter((action) =>
|
||||
entityPermission.permission.can(
|
||||
action,
|
||||
subject(ProjectPermissionSub.Secrets, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName,
|
||||
secretTags: secret?.tags?.map((el) => el.slug)
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
return {
|
||||
...entityPermission,
|
||||
allowedActions
|
||||
};
|
||||
};
|
||||
|
||||
const usersWithAccess = userPermissions.map(attachAllowedActions).filter((user) => user.allowedActions.length > 0);
|
||||
const identitiesWithAccess = identityPermissions
|
||||
.map(attachAllowedActions)
|
||||
.filter((identity) => identity.allowedActions.length > 0);
|
||||
const groupsWithAccess = groupPermissions
|
||||
.map(attachAllowedActions)
|
||||
.filter((group) => group.allowedActions.length > 0);
|
||||
|
||||
return { users: usersWithAccess, identities: identitiesWithAccess, groups: groupsWithAccess };
|
||||
};
|
||||
|
||||
const getSecretsRaw = async ({
|
||||
projectId,
|
||||
path,
|
||||
@@ -2946,6 +3015,7 @@ export const secretServiceFactory = ({
|
||||
getSecretsCountMultiEnv,
|
||||
getSecretsRawMultiEnv,
|
||||
getSecretReferenceTree,
|
||||
getSecretsRawByFolderMappings
|
||||
getSecretsRawByFolderMappings,
|
||||
getSecretAccessList
|
||||
};
|
||||
};
|
||||
|
||||
@@ -190,6 +190,12 @@ export type TGetSecretsRawDTO = {
|
||||
keys?: string[];
|
||||
} & TProjectPermission;
|
||||
|
||||
export type TGetSecretAccessListDTO = {
|
||||
environment: string;
|
||||
secretPath: string;
|
||||
secretName: string;
|
||||
} & TProjectPermission;
|
||||
|
||||
export type TGetASecretRawDTO = {
|
||||
secretName: string;
|
||||
path: string;
|
||||
|
||||
Reference in New Issue
Block a user