feat: added lease permission for dynamic secret

This commit is contained in:
=
2024-10-18 00:33:36 +05:30
parent 2f691db0a2
commit 7cd83ad945
12 changed files with 166 additions and 67 deletions
@@ -4,7 +4,10 @@ import ms from "ms";
import { SecretKeyEncoding } 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 {
ProjectPermissionDynamicSecretActions,
ProjectPermissionSub
} from "@app/ee/services/permission/project-permission";
import { getConfig } from "@app/lib/config/env";
import { infisicalSymmetricDecrypt } from "@app/lib/crypto/encryption";
import { BadRequestError, NotFoundError } from "@app/lib/errors";
@@ -73,7 +76,7 @@ export const dynamicSecretLeaseServiceFactory = ({
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionDynamicSecretActions.Lease,
subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path })
);
@@ -146,7 +149,7 @@ export const dynamicSecretLeaseServiceFactory = ({
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Edit,
ProjectPermissionDynamicSecretActions.Lease,
subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path })
);
@@ -220,7 +223,7 @@ export const dynamicSecretLeaseServiceFactory = ({
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Delete,
ProjectPermissionDynamicSecretActions.Lease,
subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path })
);
@@ -285,7 +288,7 @@ export const dynamicSecretLeaseServiceFactory = ({
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionDynamicSecretActions.Lease,
subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path })
);
@@ -321,7 +324,7 @@ export const dynamicSecretLeaseServiceFactory = ({
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionDynamicSecretActions.Lease,
subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path })
);
@@ -3,7 +3,10 @@ import { ForbiddenError, subject } from "@casl/ability";
import { SecretKeyEncoding } 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 {
ProjectPermissionDynamicSecretActions,
ProjectPermissionSub
} from "@app/ee/services/permission/project-permission";
import { infisicalSymmetricDecrypt, infisicalSymmetricEncypt } from "@app/lib/crypto/encryption";
import { BadRequestError, NotFoundError } from "@app/lib/errors";
import { OrderByDirection } from "@app/lib/types";
@@ -77,7 +80,7 @@ export const dynamicSecretServiceFactory = ({
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Create,
ProjectPermissionDynamicSecretActions.Create,
subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path })
);
@@ -146,7 +149,7 @@ export const dynamicSecretServiceFactory = ({
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Edit,
ProjectPermissionDynamicSecretActions.Edit,
subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path })
);
@@ -225,7 +228,7 @@ export const dynamicSecretServiceFactory = ({
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Edit,
ProjectPermissionDynamicSecretActions.Edit,
subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path })
);
@@ -282,7 +285,7 @@ export const dynamicSecretServiceFactory = ({
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Edit,
ProjectPermissionDynamicSecretActions.Edit,
subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path })
);
@@ -328,7 +331,7 @@ export const dynamicSecretServiceFactory = ({
// verify user has access to each env in request
environmentSlugs.forEach((environmentSlug) =>
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionDynamicSecretActions.Lease,
subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path })
)
);
@@ -364,7 +367,7 @@ export const dynamicSecretServiceFactory = ({
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionDynamicSecretActions.Lease,
subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path })
);
@@ -410,7 +413,7 @@ export const dynamicSecretServiceFactory = ({
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionDynamicSecretActions.Lease,
subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path })
);
@@ -452,7 +455,7 @@ export const dynamicSecretServiceFactory = ({
// verify user has access to each env in request
environmentSlugs.forEach((environmentSlug) =>
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionDynamicSecretActions.Lease,
subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path })
)
);
@@ -23,6 +23,14 @@ export enum ProjectPermissionCmekActions {
Decrypt = "decrypt"
}
export enum ProjectPermissionDynamicSecretActions {
Read = "read",
Create = "create",
Edit = "edit",
Delete = "delete",
Lease = "lease"
}
export enum ProjectPermissionSub {
Role = "role",
Member = "member",
@@ -88,7 +96,7 @@ export type ProjectPermissionSet =
)
]
| [
ProjectPermissionActions,
ProjectPermissionDynamicSecretActions,
(
| ProjectPermissionSub.DynamicSecrets
| (ForcedSubject<ProjectPermissionSub.DynamicSecrets> & DynamicSecretSubjectFields)
@@ -397,7 +405,7 @@ export const ProjectPermissionV2Schema = z.discriminatedUnion("subject", [
z.object({
subject: z.literal(ProjectPermissionSub.DynamicSecrets).describe("The entity this permission pertains to."),
inverted: z.boolean().optional().describe("Whether rule allows or forbids."),
action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe(
action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionDynamicSecretActions).describe(
"Describe what action an entity can take."
),
conditions: SecretConditionV1Schema.describe(
@@ -414,7 +422,6 @@ const buildAdminPermissionRules = () => {
[
ProjectPermissionSub.Secrets,
ProjectPermissionSub.SecretFolders,
ProjectPermissionSub.DynamicSecrets,
ProjectPermissionSub.SecretImports,
ProjectPermissionSub.SecretApproval,
ProjectPermissionSub.SecretRotation,
@@ -447,6 +454,17 @@ const buildAdminPermissionRules = () => {
);
});
can(
[
ProjectPermissionDynamicSecretActions.Read,
ProjectPermissionDynamicSecretActions.Edit,
ProjectPermissionDynamicSecretActions.Create,
ProjectPermissionDynamicSecretActions.Delete,
ProjectPermissionDynamicSecretActions.Lease
],
ProjectPermissionSub.DynamicSecrets
);
can([ProjectPermissionActions.Edit, ProjectPermissionActions.Delete], ProjectPermissionSub.Project);
can([ProjectPermissionActions.Read, ProjectPermissionActions.Create], ProjectPermissionSub.SecretRollback);
can([ProjectPermissionActions.Edit], ProjectPermissionSub.Kms);
@@ -489,10 +507,11 @@ const buildMemberPermissionRules = () => {
);
can(
[
ProjectPermissionActions.Read,
ProjectPermissionActions.Edit,
ProjectPermissionActions.Create,
ProjectPermissionActions.Delete
ProjectPermissionDynamicSecretActions.Read,
ProjectPermissionDynamicSecretActions.Edit,
ProjectPermissionDynamicSecretActions.Create,
ProjectPermissionDynamicSecretActions.Delete,
ProjectPermissionDynamicSecretActions.Lease
],
ProjectPermissionSub.DynamicSecrets
);
@@ -629,7 +648,7 @@ const buildViewerPermissionRules = () => {
can(ProjectPermissionActions.Read, ProjectPermissionSub.Secrets);
can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretFolders);
can(ProjectPermissionActions.Read, ProjectPermissionSub.DynamicSecrets);
can(ProjectPermissionDynamicSecretActions.Read, ProjectPermissionSub.DynamicSecrets);
can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretImports);
can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretApproval);
can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback);
@@ -3,7 +3,10 @@ import { z } from "zod";
import { SecretFoldersSchema, SecretImportsSchema, SecretTagsSchema } from "@app/db/schemas";
import { EventType, UserAgentType } from "@app/ee/services/audit-log/audit-log-types";
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
import {
ProjectPermissionDynamicSecretActions,
ProjectPermissionSub
} from "@app/ee/services/permission/project-permission";
import { DASHBOARD } from "@app/lib/api-docs";
import { BadRequestError } from "@app/lib/errors";
import { removeTrailingSlash } from "@app/lib/fn";
@@ -195,7 +198,7 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
const allowedDynamicSecretEnviroments = // filter envs user has access to
environments.filter((environment) =>
permission.can(
ProjectPermissionActions.Read,
ProjectPermissionDynamicSecretActions.Lease,
subject(ProjectPermissionSub.DynamicSecrets, { environment, secretPath })
)
);