mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-17 08:35:52 +00:00
merge main
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
export enum LogProvider {
|
||||
Azure = "azure",
|
||||
Cribl = "cribl",
|
||||
Custom = "custom",
|
||||
Datadog = "datadog",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { LogProvider } from "./audit-log-stream-enums";
|
||||
import { TAuditLogStreamCredentials, TLogStreamFactory } from "./audit-log-stream-types";
|
||||
import { AzureProviderFactory } from "./azure/azure-provider-factory";
|
||||
import { CriblProviderFactory } from "./cribl/cribl-provider-factory";
|
||||
import { CustomProviderFactory } from "./custom/custom-provider-factory";
|
||||
import { DatadogProviderFactory } from "./datadog/datadog-provider-factory";
|
||||
@@ -8,6 +9,7 @@ import { SplunkProviderFactory } from "./splunk/splunk-provider-factory";
|
||||
type TLogStreamFactoryImplementation = TLogStreamFactory<TAuditLogStreamCredentials>;
|
||||
|
||||
export const LOG_STREAM_FACTORY_MAP: Record<LogProvider, TLogStreamFactoryImplementation> = {
|
||||
[LogProvider.Azure]: AzureProviderFactory as TLogStreamFactoryImplementation,
|
||||
[LogProvider.Datadog]: DatadogProviderFactory as TLogStreamFactoryImplementation,
|
||||
[LogProvider.Splunk]: SplunkProviderFactory as TLogStreamFactoryImplementation,
|
||||
[LogProvider.Custom]: CustomProviderFactory as TLogStreamFactoryImplementation,
|
||||
|
||||
@@ -3,6 +3,7 @@ import { TKmsServiceFactory } from "@app/services/kms/kms-service";
|
||||
import { KmsDataKey } from "@app/services/kms/kms-types";
|
||||
|
||||
import { TAuditLogStream, TAuditLogStreamCredentials } from "./audit-log-stream-types";
|
||||
import { getAzureProviderListItem } from "./azure/azure-provider-fns";
|
||||
import { getCriblProviderListItem } from "./cribl/cribl-provider-fns";
|
||||
import { getCustomProviderListItem } from "./custom/custom-provider-fns";
|
||||
import { getDatadogProviderListItem } from "./datadog/datadog-provider-fns";
|
||||
@@ -13,6 +14,7 @@ export const listProviderOptions = () => {
|
||||
getDatadogProviderListItem(),
|
||||
getSplunkProviderListItem(),
|
||||
getCustomProviderListItem(),
|
||||
getAzureProviderListItem(),
|
||||
getCriblProviderListItem()
|
||||
].sort((a, b) => a.name.localeCompare(b.name));
|
||||
};
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
import { TAuditLogs } from "@app/db/schemas";
|
||||
|
||||
import { LogProvider } from "./audit-log-stream-enums";
|
||||
import { TAzureProvider, TAzureProviderCredentials } from "./azure/azure-provider-types";
|
||||
import { TCriblProvider, TCriblProviderCredentials } from "./cribl/cribl-provider-types";
|
||||
import { TCustomProvider, TCustomProviderCredentials } from "./custom/custom-provider-types";
|
||||
import { TDatadogProvider, TDatadogProviderCredentials } from "./datadog/datadog-provider-types";
|
||||
import { TSplunkProvider, TSplunkProviderCredentials } from "./splunk/splunk-provider-types";
|
||||
|
||||
export type TAuditLogStream = TDatadogProvider | TSplunkProvider | TCustomProvider | TCriblProvider;
|
||||
export type TAuditLogStream = TDatadogProvider | TSplunkProvider | TCustomProvider | TAzureProvider | TCriblProvider;
|
||||
|
||||
export type TAuditLogStreamCredentials =
|
||||
| TDatadogProviderCredentials
|
||||
| TSplunkProviderCredentials
|
||||
| TCustomProviderCredentials
|
||||
| TAzureProviderCredentials
|
||||
| TCriblProviderCredentials;
|
||||
|
||||
export type TCreateAuditLogStreamDTO = {
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
import { RawAxiosRequestHeaders } from "axios";
|
||||
|
||||
import { request } from "@app/lib/config/request";
|
||||
import { BadRequestError } from "@app/lib/errors";
|
||||
import { blockLocalAndPrivateIpAddresses } from "@app/lib/validator";
|
||||
|
||||
import { AUDIT_LOG_STREAM_TIMEOUT } from "../../audit-log/audit-log-queue";
|
||||
import { TLogStreamFactoryStreamLog, TLogStreamFactoryValidateCredentials } from "../audit-log-stream-types";
|
||||
import { TAzureProviderCredentials } from "./azure-provider-types";
|
||||
|
||||
function createPayload(event: { createdAt?: Date | string } & Record<string, unknown>) {
|
||||
return [
|
||||
{
|
||||
...event,
|
||||
TimeGenerated: (event.createdAt ? new Date(event.createdAt) : new Date()).toISOString()
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
async function getAzureToken(tenantId: string, clientId: string, clientSecret: string) {
|
||||
const { data } = await request.post<{ access_token: string }>(
|
||||
`https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`,
|
||||
new URLSearchParams({
|
||||
grant_type: "client_credentials",
|
||||
client_id: clientId,
|
||||
client_secret: clientSecret,
|
||||
scope: "https://monitor.azure.com/.default"
|
||||
}),
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded"
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return data.access_token;
|
||||
}
|
||||
|
||||
export const AzureProviderFactory = () => {
|
||||
const validateCredentials: TLogStreamFactoryValidateCredentials<TAzureProviderCredentials> = async ({
|
||||
credentials
|
||||
}) => {
|
||||
const { tenantId, clientId, clientSecret, dceUrl, dcrId, cltName } = credentials;
|
||||
|
||||
await blockLocalAndPrivateIpAddresses(dceUrl);
|
||||
|
||||
const token = await getAzureToken(tenantId, clientId, clientSecret);
|
||||
|
||||
const streamHeaders: RawAxiosRequestHeaders = {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${token}`
|
||||
};
|
||||
|
||||
await request
|
||||
.post(
|
||||
`${dceUrl}/dataCollectionRules/${dcrId}/streams/Custom-${cltName}_CL?api-version=2023-01-01`,
|
||||
createPayload({ ping: "ok" }),
|
||||
{
|
||||
headers: streamHeaders,
|
||||
timeout: AUDIT_LOG_STREAM_TIMEOUT,
|
||||
signal: AbortSignal.timeout(AUDIT_LOG_STREAM_TIMEOUT)
|
||||
}
|
||||
)
|
||||
.catch((err) => {
|
||||
throw new BadRequestError({ message: `Failed to connect with Azure: ${(err as Error)?.message}` });
|
||||
});
|
||||
|
||||
return credentials;
|
||||
};
|
||||
|
||||
const streamLog: TLogStreamFactoryStreamLog<TAzureProviderCredentials> = async ({ credentials, auditLog }) => {
|
||||
const { tenantId, clientId, clientSecret, dceUrl, dcrId, cltName } = credentials;
|
||||
|
||||
await blockLocalAndPrivateIpAddresses(dceUrl);
|
||||
|
||||
const token = await getAzureToken(tenantId, clientId, clientSecret);
|
||||
|
||||
const streamHeaders: RawAxiosRequestHeaders = {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${token}`
|
||||
};
|
||||
|
||||
await request.post(
|
||||
`${dceUrl}/dataCollectionRules/${dcrId}/streams/Custom-${cltName}_CL?api-version=2023-01-01`,
|
||||
createPayload(auditLog),
|
||||
{
|
||||
headers: streamHeaders,
|
||||
timeout: AUDIT_LOG_STREAM_TIMEOUT,
|
||||
signal: AbortSignal.timeout(AUDIT_LOG_STREAM_TIMEOUT)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
return {
|
||||
validateCredentials,
|
||||
streamLog
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
import { LogProvider } from "../audit-log-stream-enums";
|
||||
|
||||
export const getAzureProviderListItem = () => {
|
||||
return {
|
||||
name: "Azure" as const,
|
||||
provider: LogProvider.Azure as const
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,52 @@
|
||||
import RE2 from "re2";
|
||||
import { z } from "zod";
|
||||
|
||||
import { LogProvider } from "../audit-log-stream-enums";
|
||||
import { BaseProviderSchema } from "../audit-log-stream-schemas";
|
||||
|
||||
export const AzureProviderCredentialsSchema = z.object({
|
||||
tenantId: z.string().trim().uuid(),
|
||||
clientId: z.string().trim().uuid(),
|
||||
clientSecret: z.string().trim().length(40),
|
||||
|
||||
// Data Collection Endpoint URL
|
||||
dceUrl: z.string().trim().url().min(1).max(255),
|
||||
|
||||
// Data Collection Rule Immutable ID
|
||||
dcrId: z
|
||||
.string()
|
||||
.trim()
|
||||
.refine((val) => new RE2(/^dcr-[0-9a-f]{32}$/).test(val), "DCR ID must be in dcr-*** format"),
|
||||
|
||||
// Custom Log Table Name
|
||||
cltName: z.string().trim().min(1).max(255)
|
||||
});
|
||||
|
||||
const BaseAzureProviderSchema = BaseProviderSchema.extend({ provider: z.literal(LogProvider.Azure) });
|
||||
|
||||
export const AzureProviderSchema = BaseAzureProviderSchema.extend({
|
||||
credentials: AzureProviderCredentialsSchema
|
||||
});
|
||||
|
||||
export const SanitizedAzureProviderSchema = BaseAzureProviderSchema.extend({
|
||||
credentials: AzureProviderCredentialsSchema.pick({
|
||||
tenantId: true,
|
||||
clientId: true,
|
||||
dceUrl: true,
|
||||
dcrId: true,
|
||||
cltName: true
|
||||
})
|
||||
});
|
||||
|
||||
export const AzureProviderListItemSchema = z.object({
|
||||
name: z.literal("Azure"),
|
||||
provider: z.literal(LogProvider.Azure)
|
||||
});
|
||||
|
||||
export const CreateAzureProviderLogStreamSchema = z.object({
|
||||
credentials: AzureProviderCredentialsSchema
|
||||
});
|
||||
|
||||
export const UpdateAzureProviderLogStreamSchema = z.object({
|
||||
credentials: AzureProviderCredentialsSchema
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { AzureProviderCredentialsSchema, AzureProviderSchema } from "./azure-provider-schemas";
|
||||
|
||||
export type TAzureProvider = z.infer<typeof AzureProviderSchema>;
|
||||
|
||||
export type TAzureProviderCredentials = z.infer<typeof AzureProviderCredentialsSchema>;
|
||||
@@ -146,7 +146,7 @@ export enum EventType {
|
||||
MOVE_SECRETS = "move-secrets",
|
||||
DELETE_SECRET = "delete-secret",
|
||||
DELETE_SECRETS = "delete-secrets",
|
||||
GET_WORKSPACE_KEY = "get-workspace-key",
|
||||
GET_PROJECT_KEY = "get-project-key",
|
||||
AUTHORIZE_INTEGRATION = "authorize-integration",
|
||||
UPDATE_INTEGRATION_AUTH = "update-integration-auth",
|
||||
UNAUTHORIZE_INTEGRATION = "unauthorize-integration",
|
||||
@@ -249,9 +249,9 @@ export enum EventType {
|
||||
UPDATE_ENVIRONMENT = "update-environment",
|
||||
DELETE_ENVIRONMENT = "delete-environment",
|
||||
GET_ENVIRONMENT = "get-environment",
|
||||
ADD_WORKSPACE_MEMBER = "add-workspace-member",
|
||||
ADD_BATCH_WORKSPACE_MEMBER = "add-workspace-members",
|
||||
REMOVE_WORKSPACE_MEMBER = "remove-workspace-member",
|
||||
ADD_PROJECT_MEMBER = "add-project-member",
|
||||
ADD_BATCH_PROJECT_MEMBER = "add-project-members",
|
||||
REMOVE_PROJECT_MEMBER = "remove-project-member",
|
||||
CREATE_FOLDER = "create-folder",
|
||||
UPDATE_FOLDER = "update-folder",
|
||||
DELETE_FOLDER = "delete-folder",
|
||||
@@ -264,8 +264,8 @@ export enum EventType {
|
||||
CREATE_SECRET_IMPORT = "create-secret-import",
|
||||
UPDATE_SECRET_IMPORT = "update-secret-import",
|
||||
DELETE_SECRET_IMPORT = "delete-secret-import",
|
||||
UPDATE_USER_WORKSPACE_ROLE = "update-user-workspace-role",
|
||||
UPDATE_USER_WORKSPACE_DENIED_PERMISSIONS = "update-user-workspace-denied-permissions",
|
||||
UPDATE_USER_PROJECT_ROLE = "update-user-project-role",
|
||||
UPDATE_USER_PROJECT_DENIED_PERMISSIONS = "update-user-project-denied-permissions",
|
||||
SECRET_APPROVAL_MERGED = "secret-approval-merged",
|
||||
SECRET_APPROVAL_REQUEST = "secret-approval-request",
|
||||
SECRET_APPROVAL_CLOSED = "secret-approval-closed",
|
||||
@@ -666,8 +666,8 @@ interface DeleteSecretBatchEvent {
|
||||
};
|
||||
}
|
||||
|
||||
interface GetWorkspaceKeyEvent {
|
||||
type: EventType.GET_WORKSPACE_KEY;
|
||||
interface GetProjectKeyEvent {
|
||||
type: EventType.GET_PROJECT_KEY;
|
||||
metadata: {
|
||||
keyId: string;
|
||||
};
|
||||
@@ -1559,24 +1559,24 @@ interface DeleteEnvironmentEvent {
|
||||
};
|
||||
}
|
||||
|
||||
interface AddWorkspaceMemberEvent {
|
||||
type: EventType.ADD_WORKSPACE_MEMBER;
|
||||
interface AddProjectMemberEvent {
|
||||
type: EventType.ADD_PROJECT_MEMBER;
|
||||
metadata: {
|
||||
userId: string;
|
||||
email: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface AddBatchWorkspaceMemberEvent {
|
||||
type: EventType.ADD_BATCH_WORKSPACE_MEMBER;
|
||||
interface AddBatchProjectMemberEvent {
|
||||
type: EventType.ADD_BATCH_PROJECT_MEMBER;
|
||||
metadata: Array<{
|
||||
userId: string;
|
||||
email: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
interface RemoveWorkspaceMemberEvent {
|
||||
type: EventType.REMOVE_WORKSPACE_MEMBER;
|
||||
interface RemoveProjectMemberEvent {
|
||||
type: EventType.REMOVE_PROJECT_MEMBER;
|
||||
metadata: {
|
||||
userId: string;
|
||||
email: string;
|
||||
@@ -1715,7 +1715,7 @@ interface DeleteSecretImportEvent {
|
||||
}
|
||||
|
||||
interface UpdateUserRole {
|
||||
type: EventType.UPDATE_USER_WORKSPACE_ROLE;
|
||||
type: EventType.UPDATE_USER_PROJECT_ROLE;
|
||||
metadata: {
|
||||
userId: string;
|
||||
email: string;
|
||||
@@ -1725,7 +1725,7 @@ interface UpdateUserRole {
|
||||
}
|
||||
|
||||
interface UpdateUserDeniedPermissions {
|
||||
type: EventType.UPDATE_USER_WORKSPACE_DENIED_PERMISSIONS;
|
||||
type: EventType.UPDATE_USER_PROJECT_DENIED_PERMISSIONS;
|
||||
metadata: {
|
||||
userId: string;
|
||||
email: string;
|
||||
@@ -3496,7 +3496,7 @@ export type Event =
|
||||
| MoveSecretsEvent
|
||||
| DeleteSecretEvent
|
||||
| DeleteSecretBatchEvent
|
||||
| GetWorkspaceKeyEvent
|
||||
| GetProjectKeyEvent
|
||||
| AuthorizeIntegrationEvent
|
||||
| UpdateIntegrationAuthEvent
|
||||
| UnauthorizeIntegrationEvent
|
||||
@@ -3585,9 +3585,9 @@ export type Event =
|
||||
| GetEnvironmentEvent
|
||||
| UpdateEnvironmentEvent
|
||||
| DeleteEnvironmentEvent
|
||||
| AddWorkspaceMemberEvent
|
||||
| AddBatchWorkspaceMemberEvent
|
||||
| RemoveWorkspaceMemberEvent
|
||||
| AddProjectMemberEvent
|
||||
| AddBatchProjectMemberEvent
|
||||
| RemoveProjectMemberEvent
|
||||
| CreateFolderEvent
|
||||
| UpdateFolderEvent
|
||||
| DeleteFolderEvent
|
||||
|
||||
@@ -87,6 +87,7 @@ export enum OrgPermissionBillingActions {
|
||||
|
||||
export enum OrgPermissionSubjects {
|
||||
Workspace = "workspace",
|
||||
Project = "project",
|
||||
Role = "role",
|
||||
Member = "member",
|
||||
Settings = "settings",
|
||||
@@ -117,6 +118,7 @@ export type AppConnectionSubjectFields = {
|
||||
|
||||
export type OrgPermissionSet =
|
||||
| [OrgPermissionActions.Create, OrgPermissionSubjects.Workspace]
|
||||
| [OrgPermissionActions.Create, OrgPermissionSubjects.Project]
|
||||
| [OrgPermissionActions, OrgPermissionSubjects.Role]
|
||||
| [OrgPermissionActions, OrgPermissionSubjects.Member]
|
||||
| [OrgPermissionActions, OrgPermissionSubjects.Settings]
|
||||
@@ -166,6 +168,10 @@ export const OrgPermissionSchema = z.discriminatedUnion("subject", [
|
||||
subject: z.literal(OrgPermissionSubjects.Workspace).describe("The entity this permission pertains to."),
|
||||
action: CASL_ACTION_SCHEMA_ENUM([OrgPermissionActions.Create]).describe("Describe what action an entity can take.")
|
||||
}),
|
||||
z.object({
|
||||
subject: z.literal(OrgPermissionSubjects.Project).describe("The entity this permission pertains to."),
|
||||
action: CASL_ACTION_SCHEMA_ENUM([OrgPermissionActions.Create]).describe("Describe what action an entity can take.")
|
||||
}),
|
||||
z.object({
|
||||
subject: z.literal(OrgPermissionSubjects.Role).describe("The entity this permission pertains to."),
|
||||
action: CASL_ACTION_SCHEMA_NATIVE_ENUM(OrgPermissionActions).describe("Describe what action an entity can take.")
|
||||
@@ -280,6 +286,7 @@ const buildAdminPermission = () => {
|
||||
const { can, rules } = new AbilityBuilder<MongoAbility<OrgPermissionSet>>(createMongoAbility);
|
||||
// ws permissions
|
||||
can(OrgPermissionActions.Create, OrgPermissionSubjects.Workspace);
|
||||
can(OrgPermissionActions.Create, OrgPermissionSubjects.Project);
|
||||
// role permission
|
||||
can(OrgPermissionActions.Read, OrgPermissionSubjects.Role);
|
||||
can(OrgPermissionActions.Create, OrgPermissionSubjects.Role);
|
||||
@@ -413,6 +420,7 @@ const buildMemberPermission = () => {
|
||||
const { can, rules } = new AbilityBuilder<MongoAbility<OrgPermissionSet>>(createMongoAbility);
|
||||
|
||||
can(OrgPermissionActions.Create, OrgPermissionSubjects.Workspace);
|
||||
can(OrgPermissionActions.Create, OrgPermissionSubjects.Project);
|
||||
can(OrgPermissionActions.Read, OrgPermissionSubjects.Member);
|
||||
can(OrgPermissionGroupActions.Read, OrgPermissionSubjects.Groups);
|
||||
can(OrgPermissionActions.Read, OrgPermissionSubjects.Role);
|
||||
|
||||
+1
-1
@@ -431,7 +431,7 @@ export const secretRotationQueueFactory = ({
|
||||
numberOfSecrets: numberOfSecretsRotated,
|
||||
environment: secretRotation.environment.slug,
|
||||
secretPath: secretRotation.secretPath,
|
||||
workspaceId: secretRotation.projectId
|
||||
projectId: secretRotation.projectId
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user