From 542ae597f9b75f6a702a50b1b898d8efd07aa7e2 Mon Sep 17 00:00:00 2001 From: x032205 Date: Mon, 8 Sep 2025 17:02:42 -0400 Subject: [PATCH] feat(audit-log-stream): cribl support --- .../audit-log-stream-router.ts | 10 +- .../v1/audit-log-stream-routers/index.ts | 14 +++ .../audit-log-stream-enums.ts | 5 +- .../audit-log-stream-factory.ts | 4 +- .../audit-log-stream/audit-log-stream-fns.ts | 10 +- .../audit-log-stream-types.ts | 6 +- .../cribl/cribl-provider-factory.ts | 58 ++++++++++ .../cribl/cribl-provider-fns.ts | 8 ++ .../cribl/cribl-provider-schemas.ts | 34 ++++++ .../cribl/cribl-provider-types.ts | 7 ++ backend/src/keystore/keystore.ts | 3 +- frontend/public/images/integrations/Cribl.png | Bin 0 -> 7546 bytes frontend/src/helpers/auditLogStreams.ts | 3 +- .../src/hooks/api/auditLogStreams/enums.ts | 5 +- .../hooks/api/auditLogStreams/types/index.ts | 5 +- .../types/providers/cribl-provider.ts | 10 ++ .../AuditLogStreamForm/AuditLogStreamForm.tsx | 7 ++ .../CriblProviderAuditLogStreamForm.tsx | 108 ++++++++++++++++++ 18 files changed, 282 insertions(+), 15 deletions(-) create mode 100644 backend/src/ee/services/audit-log-stream/cribl/cribl-provider-factory.ts create mode 100644 backend/src/ee/services/audit-log-stream/cribl/cribl-provider-fns.ts create mode 100644 backend/src/ee/services/audit-log-stream/cribl/cribl-provider-schemas.ts create mode 100644 backend/src/ee/services/audit-log-stream/cribl/cribl-provider-types.ts create mode 100644 frontend/public/images/integrations/Cribl.png create mode 100644 frontend/src/hooks/api/auditLogStreams/types/providers/cribl-provider.ts create mode 100644 frontend/src/pages/organization/SettingsPage/components/AuditLogStreamTab/AuditLogStreamForm/CriblProviderAuditLogStreamForm.tsx diff --git a/backend/src/ee/routes/v1/audit-log-stream-routers/audit-log-stream-router.ts b/backend/src/ee/routes/v1/audit-log-stream-routers/audit-log-stream-router.ts index bf10e48bf..e0ac0b6af 100644 --- a/backend/src/ee/routes/v1/audit-log-stream-routers/audit-log-stream-router.ts +++ b/backend/src/ee/routes/v1/audit-log-stream-routers/audit-log-stream-router.ts @@ -1,5 +1,9 @@ import { z } from "zod"; +import { + CriblProviderListItemSchema, + SanitizedCriblProviderSchema +} from "@app/ee/services/audit-log-stream/cribl/cribl-provider-schemas"; import { CustomProviderListItemSchema, SanitizedCustomProviderSchema @@ -19,13 +23,15 @@ import { AuthMode } from "@app/services/auth/auth-type"; const SanitizedAuditLogStreamSchema = z.union([ SanitizedCustomProviderSchema, SanitizedDatadogProviderSchema, - SanitizedSplunkProviderSchema + SanitizedSplunkProviderSchema, + SanitizedCriblProviderSchema ]); const ProviderOptionsSchema = z.discriminatedUnion("provider", [ CustomProviderListItemSchema, DatadogProviderListItemSchema, - SplunkProviderListItemSchema + SplunkProviderListItemSchema, + CriblProviderListItemSchema ]); export const registerAuditLogStreamRouter = async (server: FastifyZodProvider) => { diff --git a/backend/src/ee/routes/v1/audit-log-stream-routers/index.ts b/backend/src/ee/routes/v1/audit-log-stream-routers/index.ts index ea3d48b30..f40a82d89 100644 --- a/backend/src/ee/routes/v1/audit-log-stream-routers/index.ts +++ b/backend/src/ee/routes/v1/audit-log-stream-routers/index.ts @@ -1,4 +1,9 @@ import { LogProvider } from "@app/ee/services/audit-log-stream/audit-log-stream-enums"; +import { + CreateCriblProviderLogStreamSchema, + SanitizedCriblProviderSchema, + UpdateCriblProviderLogStreamSchema +} from "@app/ee/services/audit-log-stream/cribl/cribl-provider-schemas"; import { CreateCustomProviderLogStreamSchema, SanitizedCustomProviderSchema, @@ -47,5 +52,14 @@ export const AUDIT_LOG_STREAM_REGISTER_ROUTER_MAP: Record { + registerAuditLogStreamEndpoints({ + server, + provider: LogProvider.Cribl, + sanitizedResponseSchema: SanitizedCriblProviderSchema, + createSchema: CreateCriblProviderLogStreamSchema, + updateSchema: UpdateCriblProviderLogStreamSchema + }); } }; diff --git a/backend/src/ee/services/audit-log-stream/audit-log-stream-enums.ts b/backend/src/ee/services/audit-log-stream/audit-log-stream-enums.ts index 9c03dc2bd..78233f774 100644 --- a/backend/src/ee/services/audit-log-stream/audit-log-stream-enums.ts +++ b/backend/src/ee/services/audit-log-stream/audit-log-stream-enums.ts @@ -1,5 +1,6 @@ export enum LogProvider { + Cribl = "cribl", + Custom = "custom", Datadog = "datadog", - Splunk = "splunk", - Custom = "custom" + Splunk = "splunk" } diff --git a/backend/src/ee/services/audit-log-stream/audit-log-stream-factory.ts b/backend/src/ee/services/audit-log-stream/audit-log-stream-factory.ts index f70dc02a0..21d629a53 100644 --- a/backend/src/ee/services/audit-log-stream/audit-log-stream-factory.ts +++ b/backend/src/ee/services/audit-log-stream/audit-log-stream-factory.ts @@ -1,5 +1,6 @@ import { LogProvider } from "./audit-log-stream-enums"; import { TAuditLogStreamCredentials, TLogStreamFactory } from "./audit-log-stream-types"; +import { CriblProviderFactory } from "./cribl/cribl-provider-factory"; import { CustomProviderFactory } from "./custom/custom-provider-factory"; import { DatadogProviderFactory } from "./datadog/datadog-provider-factory"; import { SplunkProviderFactory } from "./splunk/splunk-provider-factory"; @@ -9,5 +10,6 @@ type TLogStreamFactoryImplementation = TLogStreamFactory = { [LogProvider.Datadog]: DatadogProviderFactory as TLogStreamFactoryImplementation, [LogProvider.Splunk]: SplunkProviderFactory as TLogStreamFactoryImplementation, - [LogProvider.Custom]: CustomProviderFactory as TLogStreamFactoryImplementation + [LogProvider.Custom]: CustomProviderFactory as TLogStreamFactoryImplementation, + [LogProvider.Cribl]: CriblProviderFactory as TLogStreamFactoryImplementation }; diff --git a/backend/src/ee/services/audit-log-stream/audit-log-stream-fns.ts b/backend/src/ee/services/audit-log-stream/audit-log-stream-fns.ts index 87a7736a3..d03a5c8a7 100644 --- a/backend/src/ee/services/audit-log-stream/audit-log-stream-fns.ts +++ b/backend/src/ee/services/audit-log-stream/audit-log-stream-fns.ts @@ -3,14 +3,18 @@ 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 { getCriblProviderListItem } from "./cribl/cribl-provider-fns"; import { getCustomProviderListItem } from "./custom/custom-provider-fns"; import { getDatadogProviderListItem } from "./datadog/datadog-provider-fns"; import { getSplunkProviderListItem } from "./splunk/splunk-provider-fns"; export const listProviderOptions = () => { - return [getDatadogProviderListItem(), getSplunkProviderListItem(), getCustomProviderListItem()].sort((a, b) => - a.name.localeCompare(b.name) - ); + return [ + getDatadogProviderListItem(), + getSplunkProviderListItem(), + getCustomProviderListItem(), + getCriblProviderListItem() + ].sort((a, b) => a.name.localeCompare(b.name)); }; export const encryptLogStreamCredentials = async ({ diff --git a/backend/src/ee/services/audit-log-stream/audit-log-stream-types.ts b/backend/src/ee/services/audit-log-stream/audit-log-stream-types.ts index d0f78f632..1ef33befe 100644 --- a/backend/src/ee/services/audit-log-stream/audit-log-stream-types.ts +++ b/backend/src/ee/services/audit-log-stream/audit-log-stream-types.ts @@ -1,16 +1,18 @@ import { TAuditLogs } from "@app/db/schemas"; import { LogProvider } from "./audit-log-stream-enums"; +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; +export type TAuditLogStream = TDatadogProvider | TSplunkProvider | TCustomProvider | TCriblProvider; export type TAuditLogStreamCredentials = | TDatadogProviderCredentials | TSplunkProviderCredentials - | TCustomProviderCredentials; + | TCustomProviderCredentials + | TCriblProviderCredentials; export type TCreateAuditLogStreamDTO = { provider: LogProvider; diff --git a/backend/src/ee/services/audit-log-stream/cribl/cribl-provider-factory.ts b/backend/src/ee/services/audit-log-stream/cribl/cribl-provider-factory.ts new file mode 100644 index 000000000..2e4eef93b --- /dev/null +++ b/backend/src/ee/services/audit-log-stream/cribl/cribl-provider-factory.ts @@ -0,0 +1,58 @@ +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 { TCriblProviderCredentials } from "./cribl-provider-types"; + +export const CriblProviderFactory = () => { + const validateCredentials: TLogStreamFactoryValidateCredentials = async ({ + credentials + }) => { + const { url, token } = credentials; + + await blockLocalAndPrivateIpAddresses(url); + + const streamHeaders: RawAxiosRequestHeaders = { + "Content-Type": "application/json", + Authorization: `Bearer ${token}` + }; + + await request + .post(url, JSON.stringify({ 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 Cribl: ${(err as Error)?.message}` }); + }); + + return credentials; + }; + + const streamLog: TLogStreamFactoryStreamLog = async ({ credentials, auditLog }) => { + const { url, token } = credentials; + + await blockLocalAndPrivateIpAddresses(url); + + const streamHeaders: RawAxiosRequestHeaders = { + "Content-Type": "application/json", + Authorization: `Bearer ${token}` + }; + + await request.post(url, JSON.stringify(auditLog), { + headers: streamHeaders, + timeout: AUDIT_LOG_STREAM_TIMEOUT, + signal: AbortSignal.timeout(AUDIT_LOG_STREAM_TIMEOUT) + }); + }; + + return { + validateCredentials, + streamLog + }; +}; diff --git a/backend/src/ee/services/audit-log-stream/cribl/cribl-provider-fns.ts b/backend/src/ee/services/audit-log-stream/cribl/cribl-provider-fns.ts new file mode 100644 index 000000000..f8b82509a --- /dev/null +++ b/backend/src/ee/services/audit-log-stream/cribl/cribl-provider-fns.ts @@ -0,0 +1,8 @@ +import { LogProvider } from "../audit-log-stream-enums"; + +export const getCriblProviderListItem = () => { + return { + name: "Cribl" as const, + provider: LogProvider.Cribl as const + }; +}; diff --git a/backend/src/ee/services/audit-log-stream/cribl/cribl-provider-schemas.ts b/backend/src/ee/services/audit-log-stream/cribl/cribl-provider-schemas.ts new file mode 100644 index 000000000..8c2a51f32 --- /dev/null +++ b/backend/src/ee/services/audit-log-stream/cribl/cribl-provider-schemas.ts @@ -0,0 +1,34 @@ +import { z } from "zod"; + +import { LogProvider } from "../audit-log-stream-enums"; +import { BaseProviderSchema } from "../audit-log-stream-schemas"; + +export const CriblProviderCredentialsSchema = z.object({ + url: z.string().url().trim().min(1).max(255), + token: z.string().trim().min(21).max(255) +}); + +const BaseCriblProviderSchema = BaseProviderSchema.extend({ provider: z.literal(LogProvider.Cribl) }); + +export const CriblProviderSchema = BaseCriblProviderSchema.extend({ + credentials: CriblProviderCredentialsSchema +}); + +export const SanitizedCriblProviderSchema = BaseCriblProviderSchema.extend({ + credentials: CriblProviderCredentialsSchema.pick({ + url: true + }) +}); + +export const CriblProviderListItemSchema = z.object({ + name: z.literal("Cribl"), + provider: z.literal(LogProvider.Cribl) +}); + +export const CreateCriblProviderLogStreamSchema = z.object({ + credentials: CriblProviderCredentialsSchema +}); + +export const UpdateCriblProviderLogStreamSchema = z.object({ + credentials: CriblProviderCredentialsSchema +}); diff --git a/backend/src/ee/services/audit-log-stream/cribl/cribl-provider-types.ts b/backend/src/ee/services/audit-log-stream/cribl/cribl-provider-types.ts new file mode 100644 index 000000000..6577f1bff --- /dev/null +++ b/backend/src/ee/services/audit-log-stream/cribl/cribl-provider-types.ts @@ -0,0 +1,7 @@ +import { z } from "zod"; + +import { CriblProviderCredentialsSchema, CriblProviderSchema } from "./cribl-provider-schemas"; + +export type TCriblProvider = z.infer; + +export type TCriblProviderCredentials = z.infer; diff --git a/backend/src/keystore/keystore.ts b/backend/src/keystore/keystore.ts index 45589e529..a6135e0ca 100644 --- a/backend/src/keystore/keystore.ts +++ b/backend/src/keystore/keystore.ts @@ -1,9 +1,10 @@ +import { Cluster, Redis } from "ioredis"; + import { buildRedisFromConfig, TRedisConfigKeys } from "@app/lib/config/redis"; import { pgAdvisoryLockHashText } from "@app/lib/crypto/hashtext"; import { applyJitter } from "@app/lib/dates"; import { delay as delayMs } from "@app/lib/delay"; import { ExecutionResult, Redlock, Settings } from "@app/lib/red-lock"; -import { Redis, Cluster } from "ioredis"; export const PgSqlLock = { BootUpMigration: 2023, diff --git a/frontend/public/images/integrations/Cribl.png b/frontend/public/images/integrations/Cribl.png new file mode 100644 index 0000000000000000000000000000000000000000..9e8282368718e443ca4dbbdee84f53002a1e1219 GIT binary patch literal 7546 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 literal 0 HcmV?d00001 diff --git a/frontend/src/helpers/auditLogStreams.ts b/frontend/src/helpers/auditLogStreams.ts index 00d2b9e51..eee2fc8da 100644 --- a/frontend/src/helpers/auditLogStreams.ts +++ b/frontend/src/helpers/auditLogStreams.ts @@ -8,6 +8,7 @@ export const AUDIT_LOG_STREAM_PROVIDER_MAP: Record< LogProvider, { name: string; image?: string; icon?: IconDefinition; size?: number } > = { + [LogProvider.Cribl]: { name: "Cribl", image: "Cribl.png", size: 60 }, [LogProvider.Custom]: { name: "Custom", icon: faCode }, [LogProvider.Datadog]: { name: "Datadog", image: "Datadog.png" }, [LogProvider.Splunk]: { name: "Splunk", image: "Splunk.png", size: 65 } @@ -19,8 +20,8 @@ export function getProviderUrl( ) { switch (logStream.provider) { case LogProvider.Custom: - return logStream.credentials.url; case LogProvider.Datadog: + case LogProvider.Cribl: return logStream.credentials.url; case LogProvider.Splunk: return `https://${logStream.credentials.hostname}:8088/services/collector/event`; diff --git a/frontend/src/hooks/api/auditLogStreams/enums.ts b/frontend/src/hooks/api/auditLogStreams/enums.ts index 9c03dc2bd..78233f774 100644 --- a/frontend/src/hooks/api/auditLogStreams/enums.ts +++ b/frontend/src/hooks/api/auditLogStreams/enums.ts @@ -1,5 +1,6 @@ export enum LogProvider { + Cribl = "cribl", + Custom = "custom", Datadog = "datadog", - Splunk = "splunk", - Custom = "custom" + Splunk = "splunk" } diff --git a/frontend/src/hooks/api/auditLogStreams/types/index.ts b/frontend/src/hooks/api/auditLogStreams/types/index.ts index d3dffe6a9..a360cd677 100644 --- a/frontend/src/hooks/api/auditLogStreams/types/index.ts +++ b/frontend/src/hooks/api/auditLogStreams/types/index.ts @@ -1,4 +1,5 @@ import { LogProvider } from "../enums"; +import { TCriblProviderLogStream } from "./providers/cribl-provider"; import { TCustomProviderLogStream } from "./providers/custom-provider"; import { TDatadogProviderLogStream } from "./providers/datadog-provider"; import { TSplunkProviderLogStream } from "./providers/splunk-provider"; @@ -6,9 +7,11 @@ import { TSplunkProviderLogStream } from "./providers/splunk-provider"; export type TAuditLogStream = | TCustomProviderLogStream | TDatadogProviderLogStream - | TSplunkProviderLogStream; + | TSplunkProviderLogStream + | TCriblProviderLogStream; export type TAuditLogStreamProviderMap = { + [LogProvider.Cribl]: TCriblProviderLogStream; [LogProvider.Custom]: TCustomProviderLogStream; [LogProvider.Datadog]: TDatadogProviderLogStream; [LogProvider.Splunk]: TSplunkProviderLogStream; diff --git a/frontend/src/hooks/api/auditLogStreams/types/providers/cribl-provider.ts b/frontend/src/hooks/api/auditLogStreams/types/providers/cribl-provider.ts new file mode 100644 index 000000000..aeda0390a --- /dev/null +++ b/frontend/src/hooks/api/auditLogStreams/types/providers/cribl-provider.ts @@ -0,0 +1,10 @@ +import { LogProvider } from "../../enums"; +import { TRootProviderLogStream } from "./root-provider"; + +export type TCriblProviderLogStream = TRootProviderLogStream & { + provider: LogProvider.Cribl; + credentials: { + url: string; + token: string; + }; +}; diff --git a/frontend/src/pages/organization/SettingsPage/components/AuditLogStreamTab/AuditLogStreamForm/AuditLogStreamForm.tsx b/frontend/src/pages/organization/SettingsPage/components/AuditLogStreamTab/AuditLogStreamForm/AuditLogStreamForm.tsx index 1af5e8d1a..6de5a0ecf 100644 --- a/frontend/src/pages/organization/SettingsPage/components/AuditLogStreamTab/AuditLogStreamForm/AuditLogStreamForm.tsx +++ b/frontend/src/pages/organization/SettingsPage/components/AuditLogStreamTab/AuditLogStreamForm/AuditLogStreamForm.tsx @@ -6,6 +6,7 @@ import { TAuditLogStream } from "@app/hooks/api/types"; import { DiscriminativePick } from "@app/types"; import { AuditLogStreamHeader } from "../components/AuditLogStreamHeader"; +import { CriblProviderAuditLogStreamForm } from "./CriblProviderAuditLogStreamForm"; import { CustomProviderAuditLogStreamForm } from "./CustomProviderAuditLogStreamForm"; import { DatadogProviderAuditLogStreamForm } from "./DatadogProviderAuditLogStreamForm"; import { SplunkProviderAuditLogStreamForm } from "./SplunkProviderAuditLogStreamForm"; @@ -44,6 +45,8 @@ const CreateForm = ({ provider, onComplete }: CreateFormProps) => { }; switch (provider) { + case LogProvider.Cribl: + return ; case LogProvider.Custom: return ; case LogProvider.Datadog: @@ -83,6 +86,10 @@ const UpdateForm = ({ auditLogStream, onComplete }: UpdateFormProps) => { }; switch (auditLogStream.provider) { + case LogProvider.Cribl: + return ( + + ); case LogProvider.Custom: return ( diff --git a/frontend/src/pages/organization/SettingsPage/components/AuditLogStreamTab/AuditLogStreamForm/CriblProviderAuditLogStreamForm.tsx b/frontend/src/pages/organization/SettingsPage/components/AuditLogStreamTab/AuditLogStreamForm/CriblProviderAuditLogStreamForm.tsx new file mode 100644 index 000000000..b839ddac8 --- /dev/null +++ b/frontend/src/pages/organization/SettingsPage/components/AuditLogStreamTab/AuditLogStreamForm/CriblProviderAuditLogStreamForm.tsx @@ -0,0 +1,108 @@ +import { Controller, FormProvider, useForm } from "react-hook-form"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { z } from "zod"; + +import { Button, FormControl, Input, ModalClose, SecretInput } from "@app/components/v2"; +import { LogProvider } from "@app/hooks/api/auditLogStreams/enums"; +import { TCriblProviderLogStream } from "@app/hooks/api/auditLogStreams/types/providers/cribl-provider"; + +type Props = { + auditLogStream?: TCriblProviderLogStream; + onSubmit: (formData: FormData) => void; +}; + +const formSchema = z.object({ + provider: z.literal(LogProvider.Cribl), + credentials: z.object({ + url: z.string().url().trim().min(1).max(255), + token: z.string().trim().min(21).max(255) + }) +}); + +type FormData = z.infer; + +export const CriblProviderAuditLogStreamForm = ({ auditLogStream, onSubmit }: Props) => { + const isUpdate = Boolean(auditLogStream); + + const form = useForm({ + resolver: zodResolver(formSchema), + defaultValues: auditLogStream ?? { + provider: LogProvider.Cribl + } + }); + + const { + handleSubmit, + control, + formState: { isSubmitting, isDirty } + } = form; + + return ( + +
+ ( + + To derive your Stream URL: Obtain your Cribl hostname (e.g. cribl.example.com), + Infisical HTTP data source port (e.g. 20000), and HTTP event API path (e.g. + /infisical). +
+
+ If your Infisical Data Source has TLS enabled, then use the https protocol. + + } + > + +
+ )} + /> + ( + + onChange(e.target.value)} + /> + + )} + /> +
+ + + + +
+ +
+ ); +};