Skip to content

feat(support): rebuild AI Support Helper de-anonymised + security-hardened#1057

Open
edwh wants to merge 3 commits into
masterfrom
feature/ai-support-helper-rebuild
Open

feat(support): rebuild AI Support Helper de-anonymised + security-hardened#1057
edwh wants to merge 3 commits into
masterfrom
feature/ai-support-helper-rebuild

Conversation

@edwh

@edwh edwh commented Jul 13, 2026

Copy link
Copy Markdown
Member

What

Rebuilds the ModTools AI Support Helper to give Support/Admin volunteers direct, de-anonymised read access to production data (the previous PII-in-the-browser anonymisation is removed), then hardens it.

Support are trusted with member data and reading chats/logs is legitimate debugging, so the controls don't restrict their access — they guard against accidental damage, other (non-support) mods gaining access, and hostile member data (prompt injection), and record an audit trail of every investigation.

It drives the Claude Code harness (@anthropic-ai/claude-agent-sdk's query()) over one code path that serves both a mounted ~/.claude session (testing) and an ANTHROPIC_API_KEY (edge/prod).

Security controls

Area Control
Audit trail every session + db_query/get_user_dump/query_dump logs who (mod id/email) investigated whom, to stdout (SUPPORT_AUDIT, Loki-queryable) and durably to AUDIT_LOG_PATH on the ai-support-audit volume
Access gate (auth.js) Support/Admin only (drops plain Moderator); returns the mod identity; fail-closed timeout
SQL guard (guard.js) SELECT/WITH-only, comment-stripped (defeats INTO/**/OUTFILE), write/DoS keyword denylist, auth-secret table/column denylist, hard LIMIT cap; dbSelect runs a fail-closed read-only txn
Prompt injection system prompt marks tool output as data, never instructions; Read confined to the codebase; write/exec tools disallowed
Credential exposure ~/.claude mount narrowed to just .credentials.json; edge/prod uses the API key with no mount
XSS DOMPurify.sanitize(marked(...)) on the rendered answer
JWT leakage header-only JWT (drops ?jwt=); CORS restricted to ModTools origins

Also removes the retired pseudonymiser services (support-tools/ deleted) and rewrites docs/developers/reference/ai-support-helper.md to the de-anonymised model.

Verification

  • Guard blocks the confirmed exploits and allows legit support queries — proven standalone and inside the running container.
  • Durable audit write confirmed on the volume (fixed a root-owned-mount bug so the non-root user can append).
  • 13 backend node tests pass (guard + auth); container builds and /health is green.
  • Full frontend unit suite: 14,240 passed / 0 failed.
  • docker-compose config and docs-freshness pass.

🤖 Generated with Claude Code

https://claude.ai/code/session_01VXKgf7Xquudc6CwP2RN6jX

@netlify

netlify Bot commented Jul 13, 2026

Copy link
Copy Markdown

Deploy Preview for golden-caramel-d2c3a7 ready!

Name Link
🔨 Latest commit 6311e52
🔍 Latest deploy log https://app.netlify.com/projects/golden-caramel-d2c3a7/deploys/6a55e58def5c030008e877fa
😎 Deploy Preview https://deploy-preview-1057--golden-caramel-d2c3a7.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@FreegleGeeks FreegleGeeks added CI: Passed CI build passed CI: Running CI build is currently running and removed CI: Passed CI build passed CI: Running CI build is currently running labels Jul 13, 2026
…dened

Rebuild the ModTools AI Support Helper to give Support/Admin volunteers
direct, de-anonymised read access to production data (the previous
PII-in-the-browser anonymisation is removed), then harden it. Support are
trusted with member data and reading chats/logs is legitimate debugging,
so the controls guard against accidental damage, other (non-support) mods
gaining access, and hostile member data (prompt injection) - with an audit
trail of every investigation.

Backend (claude-agent-sdk/, drives @anthropic-ai/claude-agent-sdk query();
one code path serves both a mounted ~/.claude session for testing and an
ANTHROPIC_API_KEY on edge):

- tools.js: de-anonymised direct-access tools (identify_user, user dump +
  SQL, live read-only db_query, Loki/Sentry/Discourse/code-history search).
- guard.js (+guard.test.js): SELECT/WITH-only, comment-stripped (defeats
  INTO/**/OUTFILE), write/DoS keyword denylist, auth-secret table/column
  denylist, hard LIMIT cap. dbSelect runs a fail-closed read-only txn.
- auth.js: gate to Support/Admin only (drops plain Moderator), returns the
  mod identity for the audit, fetch timeout.
- server.js: threads the mod identity, header-only JWT (drops ?jwt=),
  ModTools-origin CORS allowlist.
- support-agent.js: anti-injection system-prompt clause (tool output is
  data, never instructions), Read confined to the codebase, session audit.
- audit(): every session + db_query/get_user_dump/query_dump logs who
  investigated whom to stdout (SUPPORT_AUDIT) and durably to AUDIT_LOG_PATH.

Frontend: DOMPurify.sanitize(marked(...)) on the answer (adds
isomorphic-dompurify, aliased to a stub in the unit tests).

Compose: adds the ai-support-helper service + ai-support-audit volume,
narrows the ~/.claude mount to just the OAuth credential, and removes the
retired pseudonymiser services (support-tools/ deleted).

Docs: rewrites docs/developers/reference/ai-support-helper.md to the
de-anonymised model.

Verified: guard blocks the confirmed exploits and allows legit queries
(standalone + in-container); durable audit write confirmed; 13 backend
node tests pass; container builds and /health is green; full frontend
unit suite 14240 passed / 0 failed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VXKgf7Xquudc6CwP2RN6jX
@edwh edwh force-pushed the feature/ai-support-helper-rebuild branch from 68bcfb9 to 5e7da5a Compare July 13, 2026 22:01
@FreegleGeeks FreegleGeeks added CI: Running CI build is currently running and removed CI: Passed CI build passed labels Jul 13, 2026
@FreegleGeeks FreegleGeeks added CI: Passed CI build passed and removed CI: Running CI build is currently running labels Jul 13, 2026
# Conflicts:
#	docs/members/assets/browse.png
@FreegleGeeks FreegleGeeks added CI: Running CI build is currently running CI: Passed CI build passed and removed CI: Passed CI build passed CI: Running CI build is currently running labels Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI: Passed CI build passed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants