Security [MEDIUM]: Audit log fire-and-forget drops entries on DB load + no prompt-input audit #55

Closed
opened 2026-04-16 22:05:12 +02:00 by Hartmut · 1 comment
Owner

Problem

(1) Audit entries fired via void createAuditEntry(...) — DB errors silently swallowed. Forensic trail has gaps during load. (2) User prompts to AI are NOT persisted to audit log. Only matched injection-pattern is recorded. After a prompt-injection/exfiltration incident, cannot reconstruct what the user typed.

Evidence

  • apps/web/src/server/auth.ts:58,73,87,104,137,161,201,299 — void createAuditEntry(...)
  • packages/api/src/router/assistant-procedure-support.ts:193-199 — only matchedPattern audited, not user message

Impact

(1) Forensic blind spots during incidents. (2) Cannot investigate AI jailbreaks. GDPR Art. 30 records-of-processing weaker.

Proposed Fix

(1) Await audit + explicit error-log; or outbox pattern with retry queue. (2) Add per-chat-turn audit with {userId, conversationId, messageHash, length, pageContext}. Optional raw-content with 30-day retention + PII-scrub.

Acceptance Criteria

  • Audit write failures visible in error logs
  • Every chat turn creates AuditEntry
  • Retention policy documented

Parent Epic: #1
Source: Full-Codebase Security Audit 2026-04-16 (A-16, C-5)

## Problem (1) Audit entries fired via `void createAuditEntry(...)` — DB errors silently swallowed. Forensic trail has gaps during load. (2) User prompts to AI are NOT persisted to audit log. Only matched injection-pattern is recorded. After a prompt-injection/exfiltration incident, cannot reconstruct what the user typed. ## Evidence - `apps/web/src/server/auth.ts:58,73,87,104,137,161,201,299 — void createAuditEntry(...)` - `packages/api/src/router/assistant-procedure-support.ts:193-199 — only matchedPattern audited, not user message` ## Impact (1) Forensic blind spots during incidents. (2) Cannot investigate AI jailbreaks. GDPR Art. 30 records-of-processing weaker. ## Proposed Fix (1) Await audit + explicit error-log; or outbox pattern with retry queue. (2) Add per-chat-turn audit with `{userId, conversationId, messageHash, length, pageContext}`. Optional raw-content with 30-day retention + PII-scrub. ## Acceptance Criteria - [ ] Audit write failures visible in error logs - [ ] Every chat turn creates AuditEntry - [ ] Retention policy documented --- Parent Epic: #1 Source: Full-Codebase Security Audit 2026-04-16 (A-16, C-5)
Hartmut added the security label 2026-04-16 22:05:12 +02:00
Author
Owner

Fixed on security/audit-2026-04-17 @ 3392297.

auth.ts (credentials provider + signOut): every createAuditEntry() call on the auth path is now awaited. The old fire-and-forget pattern dropped rows silently under DB load — security-critical events must be durable before the session cookie is minted or cleared.

assistant prompt audit (new): runAssistantChat now writes an AssistantPrompt audit row per user turn containing conversationId, prompt length, SHA-256 fingerprint, pageContext, and whether the prompt-injection guard fired. Raw prompt text is intentionally not stored — the hash + length fingerprint is sufficient for forensic correlation without the audit store accumulating a plain-text corpus of everything users typed. Documented in docs/security-architecture.md §6.

Tests: 1922 API + 1286 web unit tests green. Typecheck clean on both packages.

Fixed on `security/audit-2026-04-17` @ 3392297. **auth.ts (credentials provider + signOut):** every `createAuditEntry()` call on the auth path is now `await`ed. The old fire-and-forget pattern dropped rows silently under DB load — security-critical events must be durable before the session cookie is minted or cleared. **assistant prompt audit (new):** `runAssistantChat` now writes an `AssistantPrompt` audit row per user turn containing `conversationId`, prompt length, SHA-256 fingerprint, `pageContext`, and whether the prompt-injection guard fired. Raw prompt text is intentionally **not** stored — the hash + length fingerprint is sufficient for forensic correlation without the audit store accumulating a plain-text corpus of everything users typed. Documented in `docs/security-architecture.md` §6. Tests: 1922 API + 1286 web unit tests green. Typecheck clean on both packages.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Hartmut/CapaKraken#55