mirror of
https://github.com/Infisical/infisical.git
synced 2026-01-11 00:17:59 -05:00
feat: audit log disable storage flag (#4295)
* feat: audit log disable storage flag * fix: pr changes * fix: revert license fns * Update frontend/src/layouts/OrganizationLayout/components/AuditLogBanner/AuditLogBanner.tsx
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
// weird commonjs-related error in the CI requires us to do the import like this
|
||||
import knex from "knex";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
import { TDbClient } from "@app/db";
|
||||
import { TableName, TAuditLogs } from "@app/db/schemas";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { DatabaseError, GatewayTimeoutError } from "@app/lib/errors";
|
||||
import { ormify, selectAllTableCols, TOrmify } from "@app/lib/knex";
|
||||
import { logger } from "@app/lib/logger";
|
||||
@@ -188,5 +190,20 @@ export const auditLogDALFactory = (db: TDbClient) => {
|
||||
logger.info(`${QueueName.DailyResourceCleanUp}: audit log completed`);
|
||||
};
|
||||
|
||||
return { ...auditLogOrm, pruneAuditLog, find };
|
||||
const create: TAuditLogDALFactory["create"] = async (tx) => {
|
||||
const config = getConfig();
|
||||
|
||||
if (config.DISABLE_AUDIT_LOG_STORAGE) {
|
||||
return {
|
||||
...tx,
|
||||
id: uuidv4(),
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date()
|
||||
};
|
||||
}
|
||||
|
||||
return auditLogOrm.create(tx);
|
||||
};
|
||||
|
||||
return { ...auditLogOrm, create, pruneAuditLog, find };
|
||||
};
|
||||
|
||||
@@ -59,6 +59,7 @@ const envSchema = z
|
||||
AUDIT_LOGS_DB_ROOT_CERT: zpStr(
|
||||
z.string().describe("Postgres database base64-encoded CA cert for Audit logs").optional()
|
||||
),
|
||||
DISABLE_AUDIT_LOG_STORAGE: zodStrBool.default("false").optional().describe("Disable audit log storage"),
|
||||
MAX_LEASE_LIMIT: z.coerce.number().default(10000),
|
||||
DB_ROOT_CERT: zpStr(z.string().describe("Postgres database base64-encoded CA cert").optional()),
|
||||
DB_HOST: zpStr(z.string().describe("Postgres database host").optional()),
|
||||
@@ -482,6 +483,15 @@ export const overwriteSchema: {
|
||||
fields: { key: keyof TEnvConfig; description?: string }[];
|
||||
};
|
||||
} = {
|
||||
auditLogs: {
|
||||
name: "Audit Logs",
|
||||
fields: [
|
||||
{
|
||||
key: "DISABLE_AUDIT_LOG_STORAGE",
|
||||
description: "Disable audit log storage"
|
||||
}
|
||||
]
|
||||
},
|
||||
aws: {
|
||||
name: "AWS",
|
||||
fields: [
|
||||
|
||||
@@ -2144,7 +2144,8 @@ export const registerRoutes = async (
|
||||
inviteOnlySignup: z.boolean().optional(),
|
||||
redisConfigured: z.boolean().optional(),
|
||||
secretScanningConfigured: z.boolean().optional(),
|
||||
samlDefaultOrgSlug: z.string().optional()
|
||||
samlDefaultOrgSlug: z.string().optional(),
|
||||
auditLogStorageDisabled: z.boolean().optional()
|
||||
})
|
||||
}
|
||||
},
|
||||
@@ -2171,7 +2172,8 @@ export const registerRoutes = async (
|
||||
inviteOnlySignup: Boolean(serverCfg.allowSignUp),
|
||||
redisConfigured: cfg.isRedisConfigured,
|
||||
secretScanningConfigured: cfg.isSecretScanningConfigured,
|
||||
samlDefaultOrgSlug: cfg.samlDefaultOrgSlug
|
||||
samlDefaultOrgSlug: cfg.samlDefaultOrgSlug,
|
||||
auditLogStorageDisabled: Boolean(cfg.DISABLE_AUDIT_LOG_STORAGE)
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -65,7 +65,14 @@ Example values:
|
||||
default="false"
|
||||
optional
|
||||
>
|
||||
Determines whether your Infisical instance can automatically read the service account token of the pod it's running on. Used for features such as the IRSA auth method.
|
||||
Determines whether your Infisical instance can automatically read the service
|
||||
account token of the pod it's running on. Used for features such as the IRSA
|
||||
auth method.
|
||||
</ParamField>
|
||||
|
||||
<ParamField query="DISABLE_AUDIT_LOG_STORAGE" type="string" default="false">
|
||||
Disable storing audit logs in the database. This is useful if you're using
|
||||
audit log streams and don't want to store them in the database.
|
||||
</ParamField>
|
||||
|
||||
## CORS
|
||||
|
||||
@@ -35,6 +35,7 @@ export type TServerConfig = {
|
||||
initialized: boolean;
|
||||
allowSignUp: boolean;
|
||||
allowedSignUpDomain?: string | null;
|
||||
disableAuditLogStorage: boolean;
|
||||
isMigrationModeOn?: boolean;
|
||||
trustSamlEmails: boolean;
|
||||
trustLdapEmails: boolean;
|
||||
|
||||
@@ -5,4 +5,5 @@ export type ServerStatus = {
|
||||
secretScanningConfigured: boolean;
|
||||
redisConfigured: boolean;
|
||||
samlDefaultOrgSlug: string;
|
||||
auditLogStorageDisabled: boolean;
|
||||
};
|
||||
|
||||
@@ -6,10 +6,11 @@ import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { CreateOrgModal } from "@app/components/organization/CreateOrgModal";
|
||||
import { Banner } from "@app/components/page-frames/Banner";
|
||||
import { useServerConfig } from "@app/context";
|
||||
import { useServerConfig, useSubscription } from "@app/context";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
import { useFetchServerStatus } from "@app/hooks/api";
|
||||
|
||||
import { AuditLogBanner } from "./components/AuditLogBanner";
|
||||
import { InsecureConnectionBanner } from "./components/InsecureConnectionBanner";
|
||||
import { Navbar } from "./components/NavBar";
|
||||
import { OrgSidebar } from "./components/OrgSidebar";
|
||||
@@ -31,6 +32,7 @@ export const OrganizationLayout = () => {
|
||||
const containerHeight = config.pageFrameContent ? "h-[94vh]" : "h-screen";
|
||||
|
||||
const { data: serverDetails, isLoading } = useFetchServerStatus();
|
||||
const { subscription } = useSubscription();
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -41,6 +43,7 @@ export const OrganizationLayout = () => {
|
||||
<Navbar />
|
||||
{!isLoading && !serverDetails?.redisConfigured && <RedisBanner />}
|
||||
{!isLoading && !serverDetails?.emailConfigured && <SmtpBanner />}
|
||||
{!isLoading && subscription.auditLogs && <AuditLogBanner />}
|
||||
{!window.isSecureContext && <InsecureConnectionBanner />}
|
||||
<div className="flex flex-grow flex-col overflow-y-hidden md:flex-row">
|
||||
<OrgSidebar isHidden={isInsideProject} />
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { useOrganization } from "@app/context";
|
||||
import { useFetchServerStatus, useGetAuditLogStreams } from "@app/hooks/api";
|
||||
|
||||
import { OrgAlertBanner } from "../OrgAlertBanner";
|
||||
|
||||
export const AuditLogBanner = () => {
|
||||
const org = useOrganization();
|
||||
const { data: status, isLoading: isLoadingStatus } = useFetchServerStatus();
|
||||
const { data: streams, isLoading: isLoadingStreams } = useGetAuditLogStreams(org.currentOrg.id);
|
||||
|
||||
if (isLoadingStreams || isLoadingStatus || !streams) return null;
|
||||
|
||||
if (status?.auditLogStorageDisabled && !streams.length) {
|
||||
return (
|
||||
<OrgAlertBanner
|
||||
text="Attention: Audit logs storage is disabled but no audit log streams have been configured."
|
||||
link="https://infisical.com/docs/documentation/platform/audit-log-streams/audit-log-streams"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./AuditLogBanner";
|
||||
@@ -12,6 +12,7 @@ export const AuditLogsPage = () => {
|
||||
<link rel="icon" href="/infisical.ico" />
|
||||
<meta property="og:image" content="/images/message.png" />
|
||||
</Helmet>
|
||||
|
||||
<div className="flex h-full w-full justify-center bg-bunker-800 text-white">
|
||||
<div className="w-full max-w-7xl">
|
||||
<PageHeader
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Fragment } from "react";
|
||||
import { faFile } from "@fortawesome/free-solid-svg-icons";
|
||||
import { faCancel, faFile } from "@fortawesome/free-solid-svg-icons";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import {
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { Timezone } from "@app/helpers/datetime";
|
||||
import { useGetAuditLogs } from "@app/hooks/api";
|
||||
import { useFetchServerStatus, useGetAuditLogs } from "@app/hooks/api";
|
||||
import { TGetAuditLogsFilter } from "@app/hooks/api/auditLogs/types";
|
||||
|
||||
import { LogsTableRow } from "./LogsTableRow";
|
||||
@@ -30,6 +30,8 @@ type Props = {
|
||||
const AUDIT_LOG_LIMIT = 30;
|
||||
|
||||
export const LogsTable = ({ filter, refetchInterval, timezone }: Props) => {
|
||||
const { data: status } = useFetchServerStatus();
|
||||
|
||||
// Determine the project ID for filtering
|
||||
const filterProjectId =
|
||||
// Use the projectId from the filter if it exists
|
||||
@@ -79,7 +81,11 @@ export const LogsTable = ({ filter, refetchInterval, timezone }: Props) => {
|
||||
{isEmpty && (
|
||||
<Tr>
|
||||
<Td colSpan={3}>
|
||||
<EmptyState title="No audit logs on file" icon={faFile} />
|
||||
{status?.auditLogStorageDisabled ? (
|
||||
<EmptyState title="Audit log storage is disabled" icon={faCancel} />
|
||||
) : (
|
||||
<EmptyState title="No audit logs on file" icon={faFile} />
|
||||
)}
|
||||
</Td>
|
||||
</Tr>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user