8000 feat(audit): log what Lens caught of prompt injection by adeelahmad · Pull Request #344 · adeelahmad/lense · GitHub
[go: up one dir, main page]

Skip to content

feat(audit): log what Lens caught of prompt injection - #344

Merged
adeelahmad merged 1 commit into
mainfrom
claude/project-thread-mj7ggd
Oct 10, 2026
Merged

adeelahmad merged 1 commit into
mainfrom
claude/project-thread-mj7ggd

Conversation

@adeelahmad
Copy link
Copy Markdown
Owner

Requested by Adeel · project thread

Description

Before: when the assistant flagged a tool result as reading like instructions to an AI (#329), the MCP server added its note (#343), or a chat-room answer had links broken up (#338), only that one answer showed it. An admin had no way to see that someone was trying to steer Lens through the archive.

After: each of these goes into the audit log (GET /api/v1/audit, Settings → Audit for admins):

  • assistant.injection_flagged on chat:<id>, with the tool and the reasons;
  • mcp.injection_flagged, with the reasons;
  • bridge.links_broken on chat:<id>, with how many links.

The audit row holds the reasons and counts, never the text itself. docs/assistant.md now also says how the layers stand on their own, so one failing doesn't open the path.

Sixth of the prompt-injection series (#302 marking, #309 asks first, #329 flags, #338 room links, #343 MCP). Next: an optional local classifier, and the threat-model update.

Motivation and Context

Adeel asked for multi-layered security; the coordinator's brief named audit logging as one of the layers. An attempt that every other layer stopped still says someone planted text in a document or a room, which an admin wants to know.

How: auth.audit(...) calls in Toolbox.call (when untrusted.flags matched), in mcp_tools.call and in bridge.answer (when safe_links changed the text).

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change; ! in the title)

Checklist:

  • The title is a Conventional Commit.
  • My code follows the code style of this project (make hooks checks it on commit).
  • I added or updated tests.
  • My change requires documentation updates, and I have updated docs/ accordingly.
  • Users need more than the title to understand it, so I wrote it under ## Unreleased in CHANGELOG.md. (n/a: the title and docs/authentication.md say it)

Done questions (AGENTS.md)

  • Goal: the audit layer of the injection defenses; merged on green CI.
  • Agents: the rows are in GET /api/v1/audit, which agents with an admin token read too.
  • Zero setup: on whenever the other layers are.
  • Fewest clicks and keystrokes: nothing to click.
  • Configurable: follows ai.injection_check and bridge.safe_links; the audit log itself has no switch.
  • Light: one row per catch.
  • Private and secure: reasons and counts only, never the third-party text; the threat-model update is the last PR of this series.
  • Cost: no model calls.
  • User decides: logging only; existing defaults unchanged.
  • Upgrades: new audit actions in the existing table; no stored data changes.
  • Honest: docs list exactly which actions are logged.
  • Tests (tests/api/test_prompt_injection.py, tests/api/test_mcp.py), docs (assistant.md, authentication.md, chat-rooms.md, mcp.md); no generated files touched.
  • Open standards; no new dependencies.
  • Result reported with evidence; refine later: a count of caught attempts on the admin dashboard.

🤖 Generated with Claude Code

https://claude.ai/code/session_01BVez82cREgCJtFk6yHReed


Generated by Claude Code

Tool results the assistant or the MCP server flagged as reading like
instructions to an AI (assistant.injection_flagged,
mcp.injection_flagged) and chat-room answers that had links broken up
(bridge.links_broken) go into the audit log, with the reasons and
counts, never the text. docs/assistant.md says how the injection layers
stand on their own.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BVez82cREgCJtFk6yHReed
@adeelahmad adeelahmad self-assigned this Oct 10, 2026
@adeelahmad
adeelahmad merged commit 1b4049c into main Oct 10, 2026
10 checks passed
@adeelahmad
adeelahmad deleted the claude/p 8000 roject-thread-mj7ggd branch October 10, 2026 23:21
adeelahmad added a commit that referenced this pull request Oct 11, 2026
…349)

"Stay private and safe" now covers flagging instruction-like text (patterns or the optional local classifier, #329,
#347), asking before the browser acts on what the assistant wrote (#333), breaking up links in chat-room answers
(#338), the archive as data over MCP (#343) and the audit log of what was caught (#344). "See what it costs" adds the
overall budget asked for in setup (#281). "In progress" drops what merged and adds #337, #341 and #346.


Claude-Session: https://claude.ai/code/session_01HDx7PPUauyjMn1LZs8JAsS

Co-authored-by: Adeel Ahmad <noreply@anthropic.com>
adeelahmad pushed a commit that referenced this pull request Oct 14, 2026
P-INJECTION-EGRESS: once an answer has read text from outside Lens,
outbound tools and setup changes ask first, and chat-room answers keep
only the links people, the archive, tools or Lens wrote. Correctness-only,
a bypass is VALID-HARDENING (Q26). The Assistant x-prompt-injection row
is now claimed; N-PROMPT says marking and flagging make injection less
likely and are not claimed; MCP results and the optional classifier are
described; Q26 lists #302, #309, #329, #338, #343, #344 and #347.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BVez82cREgCJtFk6yHReed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

0