Add logging to MI secret endpoints

This commit is contained in:
Tuan Dang
2023-12-04 17:48:32 +07:00
parent 282830e7a2
commit c917cf8a18
5 changed files with 126 additions and 5 deletions

View File

@@ -3,6 +3,7 @@ import crypto from "crypto";
import { Request, Response } from "express";
import { Types } from "mongoose";
import {
IMachineIdentity,
IMachineIdentityClientSecretData,
IMachineIdentityTrustedIp,
MachineIdentity,
@@ -12,6 +13,7 @@ import {
Organization,
} from "../../../models";
import {
ActorType,
EventType,
Role
} from "../../models";
@@ -34,6 +36,7 @@ import {
} from "../../services/RoleService";
import { ForbiddenError } from "@casl/ability";
import { checkIPAgainstBlocklist } from "../../../utils/ip";
import { getUserAgentType } from "../../../utils/posthog";
const packageClientSecretData = (clientSecretData: IMachineIdentityClientSecretData) => ({
_id: clientSecretData._id,
@@ -60,7 +63,7 @@ export const getMIClientSecrets = async (req: Request, res: Response) => {
const machineMembershipOrg = await MachineMembershipOrg.findOne({
machineIdentity: new Types.ObjectId(machineId)
});
}).populate<{ machineIdentity: IMachineIdentity }>("machineIdentity");
if (!machineMembershipOrg) throw ResourceNotFoundError();
@@ -85,6 +88,20 @@ export const getMIClientSecrets = async (req: Request, res: Response) => {
})
.sort({ createdAt: -1 })
.limit(5);
await EEAuditLogService.createAuditLog(
req.authData,
{
type: EventType.GET_MACHINE_IDENTITY_CLIENT_SECRETS,
metadata: {
machineId: machineMembershipOrg.machineIdentity._id.toString(),
clientId: machineMembershipOrg.machineIdentity.clientId,
}
},
{
organizationId: machineMembershipOrg.organization
}
);
return res.status(200).send({
clientSecretData: clientSecretData.map((clientSecretDatum) => packageClientSecretData(clientSecretDatum))
@@ -110,7 +127,7 @@ export const createMIClientSecret = async (req: Request, res: Response) => {
const machineMembershipOrg = await MachineMembershipOrg.findOne({
machineIdentity: new Types.ObjectId(machineId)
});
}).populate<{ machineIdentity: IMachineIdentity }>("machineIdentity");
if (!machineMembershipOrg) throw ResourceNotFoundError();
@@ -147,6 +164,21 @@ export const createMIClientSecret = async (req: Request, res: Response) => {
accessTokenVersion: 1,
expiresAt
}).save();
await EEAuditLogService.createAuditLog(
req.authData,
{
type: EventType.CREATE_MACHINE_IDENTITY_CLIENT_SECRET,
metadata: {
machineId: machineMembershipOrg.machineIdentity._id.toString(),
clientId: machineMembershipOrg.machineIdentity.clientId,
clientSecretId: machineIdentityClientSecretData._id.toString()
}
},
{
organizationId: machineMembershipOrg.organization
}
);
return res.status(200).send({
clientSecret,
@@ -169,7 +201,7 @@ export const deleteMIClientSecret = async (req: Request, res: Response) => {
const machineMembershipOrg = await MachineMembershipOrg.findOne({
machineIdentity: new Types.ObjectId(machineId)
});
}).populate<{ machineIdentity: IMachineIdentity }>("machineIdentity");
if (!machineMembershipOrg) throw ResourceNotFoundError();
@@ -194,6 +226,21 @@ export const deleteMIClientSecret = async (req: Request, res: Response) => {
if (!clientSecretData) throw ResourceNotFoundError();
await EEAuditLogService.createAuditLog(
req.authData,
{
type: EventType.DELETE_MACHINE_IDENTITY_CLIENT_SECRET,
metadata: {
machineId: machineMembershipOrg.machineIdentity._id.toString(),
clientId: machineMembershipOrg.machineIdentity.clientId,
clientSecretId: clientSecretId
}
},
{
organizationId: machineMembershipOrg.organization
}
);
return res.status(200).send({
clientSecretData: packageClientSecretData(clientSecretData)
})
@@ -306,6 +353,35 @@ export const loginMI = async (req: Request, res: Response) => {
secret: await getAuthSecret()
});
const userAgent = req.headers["user-agent"] ?? "";
await EEAuditLogService.createAuditLog(
{
actor: {
type: ActorType.MACHINE,
metadata: {
machineId: machineIdentity._id.toString(),
name: machineIdentity.name
}
},
authPayload: machineIdentity,
ipAddress: req.realIP,
userAgent,
userAgentType: getUserAgentType(userAgent)
},
{
type: EventType.LOGIN_MACHINE_IDENTITY,
metadata: {
machineId: machineIdentity._id.toString(),
clientId,
clientSecretId: validatedClientSecretDatum._id.toString()
}
},
{
organizationId: machineIdentity.organization
}
);
return res.status(200).send({
accessToken,
expiresIn: machineIdentity.accessTokenTTL,

View File

@@ -34,6 +34,10 @@ export enum EventType {
CREATE_MACHINE_IDENTITY = "create-machine-identity",
UPDATE_MACHINE_IDENTITY = "update-machine-identity",
DELETE_MACHINE_IDENTITY = "delete-machine-identity",
LOGIN_MACHINE_IDENTITY = "login-machine-identity",
CREATE_MACHINE_IDENTITY_CLIENT_SECRET = "create-machine-identity-secret",
DELETE_MACHINE_IDENTITY_CLIENT_SECRET = "delete-machine-identity-secret",
GET_MACHINE_IDENTITY_CLIENT_SECRETS = "get-machine-identity-secrets",
CREATE_ENVIRONMENT = "create-environment",
UPDATE_ENVIRONMENT = "update-environment",
DELETE_ENVIRONMENT = "delete-environment",

View File

@@ -225,6 +225,8 @@ interface DeleteServiceTokenEvent {
};
}
// TODO: review all logging for MIs including params etc.
interface CreateMachineIdentityEvent {
type: EventType.CREATE_MACHINE_IDENTITY;
metadata: {
@@ -257,6 +259,41 @@ interface DeleteMachineIdentityEvent {
};
}
interface LoginMachineIdentityEvent {
type: EventType.LOGIN_MACHINE_IDENTITY ;
metadata: {
machineId: string;
clientId: string;
clientSecretId: string;
};
}
interface CreateMachineIdentitySecretEvent {
type: EventType.CREATE_MACHINE_IDENTITY_CLIENT_SECRET ;
metadata: {
machineId: string;
clientId: string;
clientSecretId: string;
};
}
interface DeleteMachineIdentitySecretEvent {
type: EventType.DELETE_MACHINE_IDENTITY_CLIENT_SECRET ;
metadata: {
machineId: string;
clientId: string;
clientSecretId: string;
};
}
interface GetMachineIdentitySecretsEvent {
type: EventType.GET_MACHINE_IDENTITY_CLIENT_SECRETS ;
metadata: {
machineId: string;
clientId: string;
};
}
interface CreateEnvironmentEvent {
type: EventType.CREATE_ENVIRONMENT;
metadata: {
@@ -502,6 +539,10 @@ export type Event =
| CreateMachineIdentityEvent
| UpdateMachineIdentityEvent
| DeleteMachineIdentityEvent
| CreateMachineIdentitySecretEvent
| DeleteMachineIdentitySecretEvent
| LoginMachineIdentityEvent
| GetMachineIdentitySecretsEvent
| CreateEnvironmentEvent
| UpdateEnvironmentEvent
| DeleteEnvironmentEvent

View File

@@ -29,7 +29,7 @@ export const MembersPage = withPermission(
<div className="flex items-center">
<p>App Clients</p>
<div className="ml-2 rounded-md text-yellow text-sm inline-block bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] opacity-80 hover:opacity-100 cursor-default">
Beta
New
</div>
</div>
</Tab>

View File

@@ -34,7 +34,7 @@ export const MembersPage = withProjectPermission(
<div className="flex items-center">
<p>App Clients</p>
<div className="ml-2 rounded-md text-yellow text-sm inline-block bg-yellow/20 px-1.5 pb-[0.03rem] pt-[0.04rem] opacity-80 hover:opacity-100 cursor-default">
Beta
New
</div>
</div>
</Tab>