Encrypt the streaming data

This commit is contained in:
Owen
2026-04-03 15:33:20 -04:00
parent c45308f234
commit e89e60d50b
4 changed files with 63 additions and 6 deletions

View File

@@ -23,6 +23,8 @@ import {
} from "@server/db";
import logger from "@server/logger";
import { and, eq, gt, desc, max, sql } from "drizzle-orm";
import { decryptData } from "@server/lib/encryption";
import privateConfig from "#private/lib/config";
import {
LogType,
LOG_TYPES,
@@ -34,6 +36,21 @@ import { LogDestinationProvider } from "./providers/LogDestinationProvider";
import { HttpLogDestination } from "./providers/HttpLogDestination";
import type { EventStreamingDestination } from "@server/db";
// ---------------------------------------------------------------------------
// Encryption helpers
// ---------------------------------------------------------------------------
let encryptionKey: Buffer | undefined;
function getEncryptionKey(): Buffer {
if (!encryptionKey) {
const keyHex =
privateConfig.getRawPrivateConfig().server.encryption_key;
encryptionKey = Buffer.from(keyHex, "hex");
}
return encryptionKey;
}
// ---------------------------------------------------------------------------
// Configuration
// ---------------------------------------------------------------------------
@@ -272,13 +289,14 @@ export class LogStreamingManager {
return;
}
// Parse config skip destination if config is unparseable
// Decrypt and parse config skip destination if either step fails
let config: HttpConfig;
try {
config = JSON.parse(dest.config) as HttpConfig;
const decryptedConfig = decryptData(dest.config, getEncryptionKey());
config = JSON.parse(decryptedConfig) as HttpConfig;
} catch (err) {
logger.error(
`LogStreamingManager: destination ${dest.destinationId} has invalid JSON config`,
`LogStreamingManager: destination ${dest.destinationId} has invalid or undecryptable config`,
err
);
return;

View File

@@ -22,6 +22,8 @@ import createHttpError from "http-errors";
import logger from "@server/logger";
import { fromError } from "zod-validation-error";
import { OpenAPITags, registry } from "@server/openApi";
import { encryptData } from "@server/lib/encryption";
import privateConfig from "#private/lib/config";
const paramsSchema = z.strictObject({
orgId: z.string().nonempty()
@@ -89,6 +91,11 @@ export async function createEventStreamingDestination(
const { type, config, enabled } = parsedBody.data;
const encryptionKeyHex =
privateConfig.getRawPrivateConfig().server.encryption_key;
const encryptionKey = Buffer.from(encryptionKeyHex, "hex");
const encryptedConfig = encryptData(config, encryptionKey);
const now = Date.now();
const [destination] = await db
@@ -96,7 +103,7 @@ export async function createEventStreamingDestination(
.values({
orgId,
type,
config,
config: encryptedConfig,
enabled,
createdAt: now,
updatedAt: now,

View File

@@ -22,6 +22,19 @@ import logger from "@server/logger";
import { fromError } from "zod-validation-error";
import { OpenAPITags, registry } from "@server/openApi";
import { eq, sql } from "drizzle-orm";
import { decryptData } from "@server/lib/encryption";
import privateConfig from "#private/lib/config";
let encryptionKey: Buffer;
function getEncryptionKey(): Buffer {
if (!encryptionKey) {
const keyHex =
privateConfig.getRawPrivateConfig().server.encryption_key;
encryptionKey = Buffer.from(keyHex, "hex");
}
return encryptionKey;
}
const paramsSchema = z.strictObject({
orgId: z.string().nonempty()
@@ -121,9 +134,22 @@ export async function listEventStreamingDestinations(
.from(eventStreamingDestinations)
.where(eq(eventStreamingDestinations.orgId, orgId));
const key = getEncryptionKey();
const decryptedList = list.map((dest) => {
try {
return { ...dest, config: decryptData(dest.config, key) };
} catch (err) {
logger.error(
`listEventStreamingDestinations: failed to decrypt config for destination ${dest.destinationId}`,
err
);
return { ...dest, config: "" };
}
});
return response<ListEventStreamingDestinationsResponse>(res, {
data: {
destinations: list,
destinations: decryptedList,
pagination: {
total: count,
limit,

View File

@@ -22,6 +22,8 @@ import logger from "@server/logger";
import { fromError } from "zod-validation-error";
import { OpenAPITags, registry } from "@server/openApi";
import { and, eq } from "drizzle-orm";
import { encryptData } from "@server/lib/encryption";
import privateConfig from "#private/lib/config";
const paramsSchema = z
@@ -117,7 +119,11 @@ export async function updateEventStreamingDestination(
};
if (type !== undefined) updateData.type = type;
if (config !== undefined) updateData.config = config;
if (config !== undefined) {
const encryptionKeyHex = privateConfig.getRawPrivateConfig().server.encryption_key;
const encryptionKey = Buffer.from(encryptionKeyHex, "hex");
updateData.config = encryptData(config, encryptionKey);
}
if (enabled !== undefined) updateData.enabled = enabled;
if (sendAccessLogs !== undefined) updateData.sendAccessLogs = sendAccessLogs;
if (sendActionLogs !== undefined) updateData.sendActionLogs = sendActionLogs;