Merge pull request #4554 from Infisical/misc/added-audit-logs-for-role-ops

misc: added audit logs for project and org role management operations
This commit is contained in:
Sheen
2025-09-19 03:59:52 +08:00
committed by GitHub
7 changed files with 307 additions and 11 deletions
@@ -2,6 +2,7 @@ import { packRules } from "@casl/ability/extra";
import { z } from "zod"; import { z } from "zod";
import { ProjectMembershipRole, ProjectRolesSchema } from "@app/db/schemas"; import { ProjectMembershipRole, ProjectRolesSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { import {
backfillPermissionV1SchemaToV2Schema, backfillPermissionV1SchemaToV2Schema,
ProjectPermissionV1Schema ProjectPermissionV1Schema
@@ -50,6 +51,10 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => { handler: async (req) => {
const stringifiedPermissions = JSON.stringify(
packRules(backfillPermissionV1SchemaToV2Schema(req.body.permissions, true))
);
const role = await server.services.projectRole.createRole({ const role = await server.services.projectRole.createRole({
actorAuthMethod: req.permission.authMethod, actorAuthMethod: req.permission.authMethod,
actorId: req.permission.id, actorId: req.permission.id,
@@ -61,7 +66,23 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
}, },
data: { data: {
...req.body, ...req.body,
permissions: JSON.stringify(packRules(backfillPermissionV1SchemaToV2Schema(req.body.permissions, true))) permissions: stringifiedPermissions
}
});
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: req.permission.orgId,
projectId: role.projectId,
event: {
type: EventType.CREATE_PROJECT_ROLE,
metadata: {
roleId: role.id,
slug: req.body.slug,
name: req.body.name,
description: req.body.description,
permissions: stringifiedPermissions
}
} }
}); });
@@ -106,6 +127,10 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => { handler: async (req) => {
const stringifiedPermissions = req.body.permissions
? JSON.stringify(packRules(backfillPermissionV1SchemaToV2Schema(req.body.permissions, true)))
: undefined;
const role = await server.services.projectRole.updateRole({ const role = await server.services.projectRole.updateRole({
actorAuthMethod: req.permission.authMethod, actorAuthMethod: req.permission.authMethod,
actorId: req.permission.id, actorId: req.permission.id,
@@ -114,11 +139,26 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
roleId: req.params.roleId, roleId: req.params.roleId,
data: { data: {
...req.body, ...req.body,
permissions: req.body.permissions permissions: stringifiedPermissions
? JSON.stringify(packRules(backfillPermissionV1SchemaToV2Schema(req.body.permissions, true)))
: undefined
} }
}); });
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: req.permission.orgId,
projectId: role.projectId,
event: {
type: EventType.UPDATE_PROJECT_ROLE,
metadata: {
roleId: role.id,
slug: req.body.slug,
name: req.body.name,
description: req.body.description,
permissions: stringifiedPermissions
}
}
});
return { role }; return { role };
} }
}); });
@@ -155,6 +195,21 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
actor: req.permission.type, actor: req.permission.type,
roleId: req.params.roleId roleId: req.params.roleId
}); });
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: req.permission.orgId,
projectId: role.projectId,
event: {
type: EventType.DELETE_PROJECT_ROLE,
metadata: {
roleId: role.id,
slug: role.slug,
name: role.name
}
}
});
return { role }; return { role };
} }
}); });
@@ -1,6 +1,7 @@
import { z } from "zod"; import { z } from "zod";
import { OrgMembershipRole, OrgMembershipsSchema, OrgRolesSchema } from "@app/db/schemas"; import { OrgMembershipRole, OrgMembershipsSchema, OrgRolesSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { slugSchema } from "@app/server/lib/schemas"; import { slugSchema } from "@app/server/lib/schemas";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
@@ -42,6 +43,22 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
req.permission.authMethod, req.permission.authMethod,
req.permission.orgId req.permission.orgId
); );
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: req.permission.orgId,
event: {
type: EventType.CREATE_ORG_ROLE,
metadata: {
roleId: role.id,
slug: req.body.slug,
name: req.body.name,
description: req.body.description,
permissions: JSON.stringify(req.body.permissions)
}
}
});
return { role }; return { role };
} }
}); });
@@ -116,6 +133,22 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
req.permission.authMethod, req.permission.authMethod,
req.permission.orgId req.permission.orgId
); );
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: req.permission.orgId,
event: {
type: EventType.UPDATE_ORG_ROLE,
metadata: {
roleId: role.id,
slug: req.body.slug,
name: req.body.name,
description: req.body.description,
permissions: req.body.permissions ? JSON.stringify(req.body.permissions) : undefined
}
}
});
return { role }; return { role };
} }
}); });
@@ -146,6 +179,16 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
req.permission.authMethod, req.permission.authMethod,
req.permission.orgId req.permission.orgId
); );
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: req.permission.orgId,
event: {
type: EventType.DELETE_ORG_ROLE,
metadata: { roleId: role.id, slug: role.slug, name: role.name }
}
});
return { role }; return { role };
} }
}); });
@@ -2,6 +2,7 @@ import { packRules } from "@casl/ability/extra";
import { z } from "zod"; import { z } from "zod";
import { ProjectMembershipRole, ProjectRolesSchema } from "@app/db/schemas"; import { ProjectMembershipRole, ProjectRolesSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { checkForInvalidPermissionCombination } from "@app/ee/services/permission/permission-fns"; import { checkForInvalidPermissionCombination } from "@app/ee/services/permission/permission-fns";
import { ProjectPermissionV2Schema } from "@app/ee/services/permission/project-permission"; import { ProjectPermissionV2Schema } from "@app/ee/services/permission/project-permission";
import { ApiDocsTags, PROJECT_ROLE } from "@app/lib/api-docs"; import { ApiDocsTags, PROJECT_ROLE } from "@app/lib/api-docs";
@@ -52,6 +53,8 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => { handler: async (req) => {
const stringifiedPermissions = JSON.stringify(packRules(req.body.permissions));
const role = await server.services.projectRole.createRole({ const role = await server.services.projectRole.createRole({
actorAuthMethod: req.permission.authMethod, actorAuthMethod: req.permission.authMethod,
actorId: req.permission.id, actorId: req.permission.id,
@@ -63,9 +66,26 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
}, },
data: { data: {
...req.body, ...req.body,
permissions: JSON.stringify(packRules(req.body.permissions)) permissions: stringifiedPermissions
} }
}); });
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: req.permission.orgId,
projectId: role.projectId,
event: {
type: EventType.CREATE_PROJECT_ROLE,
metadata: {
roleId: role.id,
slug: req.body.slug,
name: req.body.name,
description: req.body.description,
permissions: stringifiedPermissions
}
}
});
return { role }; return { role };
} }
}); });
@@ -112,6 +132,7 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => { handler: async (req) => {
const stringifiedPermissions = req.body.permissions ? JSON.stringify(packRules(req.body.permissions)) : undefined;
const role = await server.services.projectRole.updateRole({ const role = await server.services.projectRole.updateRole({
actorAuthMethod: req.permission.authMethod, actorAuthMethod: req.permission.authMethod,
actorId: req.permission.id, actorId: req.permission.id,
@@ -120,9 +141,26 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
roleId: req.params.roleId, roleId: req.params.roleId,
data: { data: {
...req.body, ...req.body,
permissions: req.body.permissions ? JSON.stringify(packRules(req.body.permissions)) : undefined permissions: stringifiedPermissions
} }
}); });
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: req.permission.orgId,
projectId: role.projectId,
event: {
type: EventType.UPDATE_PROJECT_ROLE,
metadata: {
roleId: role.id,
slug: req.body.slug,
name: req.body.name,
description: req.body.description,
permissions: stringifiedPermissions
}
}
});
return { role }; return { role };
} }
}); });
@@ -161,6 +199,21 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
actor: req.permission.type, actor: req.permission.type,
roleId: req.params.roleId roleId: req.params.roleId
}); });
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: req.permission.orgId,
projectId: role.projectId,
event: {
type: EventType.DELETE_PROJECT_ROLE,
metadata: {
roleId: role.id,
slug: role.slug,
name: role.name
}
}
});
return { role }; return { role };
} }
}); });
@@ -2,6 +2,7 @@ import { packRules } from "@casl/ability/extra";
import { z } from "zod"; import { z } from "zod";
import { ProjectMembershipRole, ProjectRolesSchema } from "@app/db/schemas"; import { ProjectMembershipRole, ProjectRolesSchema } from "@app/db/schemas";
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
import { checkForInvalidPermissionCombination } from "@app/ee/services/permission/permission-fns"; import { checkForInvalidPermissionCombination } from "@app/ee/services/permission/permission-fns";
import { ProjectPermissionV2Schema } from "@app/ee/services/permission/project-permission"; import { ProjectPermissionV2Schema } from "@app/ee/services/permission/project-permission";
import { ApiDocsTags, PROJECT_ROLE } from "@app/lib/api-docs"; import { ApiDocsTags, PROJECT_ROLE } from "@app/lib/api-docs";
@@ -52,6 +53,8 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => { handler: async (req) => {
const stringifiedPermissions = JSON.stringify(packRules(req.body.permissions));
const role = await server.services.projectRole.createRole({ const role = await server.services.projectRole.createRole({
actorAuthMethod: req.permission.authMethod, actorAuthMethod: req.permission.authMethod,
actorId: req.permission.id, actorId: req.permission.id,
@@ -63,9 +66,26 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
}, },
data: { data: {
...req.body, ...req.body,
permissions: JSON.stringify(packRules(req.body.permissions)) permissions: stringifiedPermissions
} }
}); });
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: req.permission.orgId,
projectId: role.projectId,
event: {
type: EventType.CREATE_PROJECT_ROLE,
metadata: {
roleId: role.id,
slug: req.body.slug,
name: req.body.name,
description: req.body.description,
permissions: stringifiedPermissions
}
}
});
return { role }; return { role };
} }
}); });
@@ -112,6 +132,7 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => { handler: async (req) => {
const stringifiedPermissions = req.body.permissions ? JSON.stringify(packRules(req.body.permissions)) : undefined;
const role = await server.services.projectRole.updateRole({ const role = await server.services.projectRole.updateRole({
actorAuthMethod: req.permission.authMethod, actorAuthMethod: req.permission.authMethod,
actorId: req.permission.id, actorId: req.permission.id,
@@ -120,9 +141,26 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
roleId: req.params.roleId, roleId: req.params.roleId,
data: { data: {
...req.body, ...req.body,
permissions: req.body.permissions ? JSON.stringify(packRules(req.body.permissions)) : undefined permissions: stringifiedPermissions
} }
}); });
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: req.permission.orgId,
projectId: role.projectId,
event: {
type: EventType.UPDATE_PROJECT_ROLE,
metadata: {
roleId: role.id,
slug: req.body.slug,
name: req.body.name,
description: req.body.description,
permissions: stringifiedPermissions
}
}
});
return { role }; return { role };
} }
}); });
@@ -161,6 +199,21 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
actor: req.permission.type, actor: req.permission.type,
roleId: req.params.roleId roleId: req.params.roleId
}); });
await server.services.auditLog.createAuditLog({
...req.auditLogInfo,
orgId: req.permission.orgId,
projectId: role.projectId,
event: {
type: EventType.DELETE_PROJECT_ROLE,
metadata: {
roleId: role.id,
slug: role.slug,
name: role.name
}
}
});
return { role }; return { role };
} }
}); });
@@ -478,6 +478,14 @@ export enum EventType {
UPDATE_PROJECT = "update-project", UPDATE_PROJECT = "update-project",
DELETE_PROJECT = "delete-project", DELETE_PROJECT = "delete-project",
CREATE_PROJECT_ROLE = "create-project-role",
UPDATE_PROJECT_ROLE = "update-project-role",
DELETE_PROJECT_ROLE = "delete-project-role",
CREATE_ORG_ROLE = "create-org-role",
UPDATE_ORG_ROLE = "update-org-role",
DELETE_ORG_ROLE = "delete-org-role",
CREATE_SECRET_REMINDER = "create-secret-reminder", CREATE_SECRET_REMINDER = "create-secret-reminder",
GET_SECRET_REMINDER = "get-secret-reminder", GET_SECRET_REMINDER = "get-secret-reminder",
DELETE_SECRET_REMINDER = "delete-secret-reminder" DELETE_SECRET_REMINDER = "delete-secret-reminder"
@@ -3502,6 +3510,68 @@ interface ProjectDeleteEvent {
}; };
} }
interface ProjectRoleCreateEvent {
type: EventType.CREATE_PROJECT_ROLE;
metadata: {
roleId: string;
slug: string;
name: string;
description?: string | null;
permissions: string;
};
}
interface ProjectRoleUpdateEvent {
type: EventType.UPDATE_PROJECT_ROLE;
metadata: {
roleId: string;
slug?: string;
name?: string;
description?: string | null;
permissions?: string;
};
}
interface ProjectRoleDeleteEvent {
type: EventType.DELETE_PROJECT_ROLE;
metadata: {
roleId: string;
slug: string;
name: string;
};
}
interface OrgRoleCreateEvent {
type: EventType.CREATE_ORG_ROLE;
metadata: {
roleId: string;
slug: string;
name: string;
description?: string | null;
permissions: string;
};
}
interface OrgRoleUpdateEvent {
type: EventType.UPDATE_ORG_ROLE;
metadata: {
roleId: string;
slug?: string;
name?: string;
description?: string | null;
permissions?: string;
};
}
interface OrgRoleDeleteEvent {
type: EventType.DELETE_ORG_ROLE;
metadata: {
roleId: string;
slug: string;
name: string;
};
}
export type Event = export type Event =
| GetSecretsEvent | GetSecretsEvent
| GetSecretEvent | GetSecretEvent
@@ -3818,4 +3888,10 @@ export type Event =
| ProjectDeleteEvent | ProjectDeleteEvent
| SecretReminderCreateEvent | SecretReminderCreateEvent
| SecretReminderGetEvent | SecretReminderGetEvent
| SecretReminderDeleteEvent; | SecretReminderDeleteEvent
| ProjectRoleCreateEvent
| ProjectRoleUpdateEvent
| ProjectRoleDeleteEvent
| OrgRoleCreateEvent
| OrgRoleUpdateEvent
| OrgRoleDeleteEvent;
@@ -222,7 +222,15 @@ export const eventToNameMap: { [K in EventType]: string } = {
[EventType.UPDATE_ORG]: "Update Organization", [EventType.UPDATE_ORG]: "Update Organization",
[EventType.CREATE_PROJECT]: "Create Project", [EventType.CREATE_PROJECT]: "Create Project",
[EventType.UPDATE_PROJECT]: "Update Project", [EventType.UPDATE_PROJECT]: "Update Project",
[EventType.DELETE_PROJECT]: "Delete Project" [EventType.DELETE_PROJECT]: "Delete Project",
[EventType.CREATE_PROJECT_ROLE]: "Create Project Role",
[EventType.UPDATE_PROJECT_ROLE]: "Update Project Role",
[EventType.DELETE_PROJECT_ROLE]: "Delete Project Role",
[EventType.CREATE_ORG_ROLE]: "Create Org Role",
[EventType.UPDATE_ORG_ROLE]: "Update Org Role",
[EventType.DELETE_ORG_ROLE]: "Delete Org Role"
}; };
export const userAgentTypeToNameMap: { [K in UserAgentType]: string } = { export const userAgentTypeToNameMap: { [K in UserAgentType]: string } = {
+9 -1
View File
@@ -216,5 +216,13 @@ export enum EventType {
CREATE_PROJECT = "create-project", CREATE_PROJECT = "create-project",
UPDATE_PROJECT = "update-project", UPDATE_PROJECT = "update-project",
DELETE_PROJECT = "delete-project" DELETE_PROJECT = "delete-project",
CREATE_PROJECT_ROLE = "create-project-role",
UPDATE_PROJECT_ROLE = "update-project-role",
DELETE_PROJECT_ROLE = "delete-project-role",
CREATE_ORG_ROLE = "create-org-role",
UPDATE_ORG_ROLE = "update-org-role",
DELETE_ORG_ROLE = "delete-org-role"
} }