Module: database/repositories/workspaceSiemConfigRepo

SEC-007 Part C — per-workspace SIEM forwarder configuration.

Stores the admin-configured webhook target (URL, HMAC secret, optional custom headers) the audit-log forwarder uses to push every event to a customer's SIEM. Schema defined by migration 032.

Encryption-at-rest

The hmacSecret column is encrypted via credentialEncryption.js (AES-256-GCM) before persist and decrypted lazily on read. The encryption key is the same one used for AI provider keys and TOTP secrets — derived from JWT_SECRET (or CREDENTIAL_ENCRYPTION_KEY if explicitly set).

Read API conventions

  • getDecrypted(workspaceId) — full row with hmacSecret decrypted. ONLY for the forwarder to dispatch events. NEVER return this to a client.
  • getMasked(workspaceId) — same shape but hmacSecret replaced with "••••••••<last4>". Use for GET /siem-config admin responses.
Source:

Methods

(static) getDecrypted(workspaceId) → {Object|null}

Return the decrypted config for the forwarder.

SECURITY: the returned object contains the PLAINTEXT hmacSecret. Callers MUST NOT log it, return it in HTTP responses, or persist it back to disk. Only the in-process forwarder should ever call this.

Parameters:
Name Type Description
workspaceId string
Source:
Returns:
Type
Object | null

(static) getMasked(workspaceId) → {Object|null}

Return the masked config for client display (admin Settings panel). hmacSecret is masked; the raw value is NEVER exposed.

Parameters:
Name Type Description
workspaceId string
Source:
Returns:
Type
Object | null

(static) remove(workspaceId) → {boolean}

Delete the SIEM config for a workspace. Returns true if a row was removed, false when none existed (idempotent).

Parameters:
Name Type Description
workspaceId string
Source:
Returns:
Type
boolean

(static) upsert(workspaceId, cfg) → {Object}

Upsert the SIEM config for a workspace. The HMAC secret is encrypted before persist so even a DB-dump leak doesn't yield usable secrets.

hmacSecret semantics

  • Insert path (no existing row): hmacSecret is required — the caller MUST pass a non-empty string. Callers should validate length upstream (PUT route enforces ≥ 32 chars per NIST SP 800-107).
  • Update path (row exists): hmacSecret is OPTIONAL. Pass it to rotate the secret; omit (undefined) or pass the empty string to keep the existing encrypted secret unchanged. Admins editing just the targetUrl / enabled / headers should not be forced to re-enter the masked secret they can't see.
Parameters:
Name Type Description
workspaceId string
cfg Object
Properties
Name Type Attributes Default Description
targetUrl string

Validated by the route handler via SSRF guard.

hmacSecret string <optional>

Plaintext. Required on insert, optional on update.

headers Object | null <optional>

Optional headers object.

enabled boolean <optional>
true
Source:
Throws:

When inserting a new row and hmacSecret is missing/empty.

Type
Error
Returns:

The persisted row (without the plaintext secret).

Type
Object