(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.
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.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
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 messageImpact
(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
Parent Epic: #1
Source: Full-Codebase Security Audit 2026-04-16 (A-16, C-5)
Fixed on
security/audit-2026-04-17@3392297.auth.ts (credentials provider + signOut): every
createAuditEntry()call on the auth path is nowawaited. 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):
runAssistantChatnow writes anAssistantPromptaudit row per user turn containingconversationId, 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 indocs/security-architecture.md§6.Tests: 1922 API + 1286 web unit tests green. Typecheck clean on both packages.