Skip to main content

Module security_events

Module security_events 

Source
Expand description

Provable security events for the value surface.

lean-ctx’s default-on protections (secret redaction, the shell allowlist, the path jail, prompt-injection screening) used to act silently: nothing a user could later point to. This module turns each firing into

  1. a hash-chained, signed crate::core::audit_trail entry — the proof, and
  2. a session counter (SecurityCounts) — what the status line shows.

Counting is once per tool result. Deep code (redaction, allowlist) calls note, which only lands in the collector that collect opens around one MCP tool handler; the dispatch layer then records the tally for that single result. note outside a collector (CLI, hooks, config loading) is deliberately dropped, so a secret redacted twice on its way through nested passes, or a re-rendered cache entry outside a tool call, never inflates the count. Undercounting is acceptable; claiming more than happened is not. Prompt-injection flags go further: one per flagged object per process (record_injections), however often the same object is delivered again.

The audit trail’s event_type enum is not extended: an older binary verifying a trail that contains an unknown variant would report it as tampered. The kind is committed in the (hashed) action field instead.

Structs§

CallTally
What one tool call noted: the per-kind counts and the boundary refusals, which are recorded with their RefusalClass.
InjectionFlag
One object the prompt-injection heuristic flagged: which pattern families matched and the object’s SHA-256 — never its content.
SecurityCounts
Per-kind event counts. Persisted inside SessionStats, so every field is serde(default) and old session files load unchanged.

Enums§

RefusalClass
Why the I/O boundary refused a path a call asked for. The trail records this class only: like every other entry, never the path, a digest of it or any content.
SecurityKind
What a protection did. The wording each kind renders with is part of the honesty contract: injections are flagged, never “neutralized”.

Functions§

anchor_receipt
Anchors a Context Gateway receipt in the signed, hash-chained audit trail: the digest in the hashed action binds the stored receipt to the chain. Not a counted kind (parse_action ignores it), so nothing is counted twice.
collect
Runs f (one synchronous tool handler) with a fresh collector and returns what it noted. Nested calls keep the outer collector’s tally intact.
collect_call
collect, including the call’s boundary refusals (record_call).
drain_pending
Takes the counts recorded since the last drain (the MCP server folds them into the current session’s stats).
note
Notes n firings of kind into the collector of the tool call running on this thread. A no-op outside collect — see the module docs for why.
note_refusals
Notes n boundary refusals of class into the running call’s collector, like note (a no-op outside one). A call that refuses several paths of one class gets one trail entry carrying the count.
parse_action
Splits a recorded action (<kind>:<n>[|<detail>…][|session=<id>]) into its parts; details (an injection flag’s pattern kinds) are skipped.
record
Records one tool result’s security tally: one audit-trail entry per kind (the proof) plus the pending session counters (the display).
record_call
Records one tool call’s CallTally: the counted kinds (record) and one entry per refusal class.
record_injections
Records flagged objects: one audit-trail entry per object this process has not recorded yet (with the pattern kinds and a digest prefix, never content) plus the pending session counter. Returns how many were recorded.
record_one
Convenience for a single event recorded outside a handler (dispatch layer).
record_refusals
Records n boundary refusals of class for one tool call: one trail entry with the reason class (never the path) plus the session counter.