AI security · Watch

Your agents already keep a record.
Nothing reads it.

Every coding agent on the machine writes a transcript as it works. RepoOps runs deterministic detectors over that record, says which OWASP LLM categories your capture tier can actually see, and inventories the MCP servers and long-lived keys an agent can reach. No new capture, no LLM call, no traffic leaving the machine.

Rule-based and local · a matched secret is masked to its first and last four characters · the coverage matrix names what it cannot see

What it does

The parts, and the module behind each one.

Four read surfaces. None of them changes anything, and each one says when it could not run rather than reporting a quiet machine it never looked at.

Nine detector families over the transcript

Credential exposure, risky commands, prompt-injection markers, exfiltration shape, tool poisoning, system-prompt leakage, excessive agency and unbounded consumption run on every install. A ninth, live egress, fires only while the optional Tap is recording outbound requests. Every family is matched by a declarative rule or a predicate, never by a model.

lib/session-signals.mjslib/session-signals-rules.mjs

Coverage stated at your capture tier

The matrix maps each family to its OWASP LLM Top 10 category and, where one fits, a MITRE ATLAS technique, then reports what this machine's capture tier covers. Four categories are out of scope and are listed by name with the reason, so the page shows the shape of the coverage rather than only its strengths.

lib/session-signals-coverage.mjs

An inventory of the MCP surface

Every MCP server configured across Claude Code, Claude Desktop, Cursor, Windsurf and VS Code, read from the config files themselves. No server is ever executed to check it, and environment variable names are read while values never are. On top of the inventory sit drift alerts, a pinned allowlist, canary honeytokens and a red-team runner.

lib/mcp-config-inventory.mjslib/mcp-security/drift-alerts.mjs

The long-lived keys an agent can reach

A coding agent runs with your API keys sitting in its environment. Those are non-human identities, and RepoOps inventories one row per secret plus an over-exposure report when a short run is backed by a long-lived token. A row carries a hash prefix, the pattern type and the metadata. It never carries the key.

lib/nhi/inventory.mjs

Findings that survive the scan window

The scanner recomputes on read over a bounded window, and transcripts rotate, so a signal from six weeks ago would simply be gone. The durable store writes each finding down instead, which is what lets a case still point at one next month and what puts a recurrence count beside a pattern you have seen before.

lib/security-findings.mjs

One batched alert, not a stream

A periodic scan diffs its result for new critical and high signals, skipping the ones you muted and the ones already alerted, then sends a single batched alert per tick to whichever sinks you configured. It reuses the alert senders that already ship rather than adding a second set of clients.

lib/session-signals-alert.mjslib/session-signals-suppress.mjs

Where it lands

What the platform gets, and what you get.

How it helps the platform

Watching is the sensing leg. Everything downstream in RepoOps starts with a detector firing.

  • It opens the cases the rest of the loop works onA finding is what Trace walks backwards and what Fix builds a pull request against. Without a detector firing there is no case, so the quality of every later act is bounded by what this one sees.
  • One finding store, several surfacesThe durable findings feed the Today queue, the OWASP coverage card, the recurrence count beside a signal, and the team rollup. They are written once and read by each surface rather than recomputed per page.
  • There is no instrumentation to addThe detectors read telemetry and transcripts the agents already write. That is why the security layer costs nothing to turn on and why it works on a machine that was never set up for it.

How it helps you

You get an answer to what your agents did without reading a transcript, and reviewing a finding never re-exposes the thing it found.

  • A matched secret is never stored wholeCredential matches are masked to their first and last four characters before they reach a row, and excerpts are capped. You can review the catch, rotate the key and file the incident without the value passing through a second surface.
  • Triaged once, then quietMute a single signal after you review it, or mute a whole rule for one repo. Filter by repo, rule, family, severity and time window. Rescan clears the memo and recomputes from source, so a mute is a decision rather than a lost row.
  • It says what it cannot seeA category outside the capture tier reads as not covered with the reason, and a family whose channel is absent reports no signal rather than a clean one. An empty result from a scan that never ran looks identical to a clean machine, and only one of those is good news.

In practice

Three days this changes.

Each one runs on the modules above. The situation, what RepoOps does with it, and what you are left holding.

  1. 01

    A production key pasted into a prompt

    The situation
    A developer pastes a live key into a prompt so the agent can reproduce a failing API call, then forgets it was ever there.
    What RepoOps does
    The credential-exposure family matches the secret shape in the prompt and writes a row masked to the first and last four characters, joined to the session that held it.
    What you get
    You know which key, which session and which day, so the rotation is scoped. The finding itself carries no secret to leak a second time.
  2. 02

    A tool result that gives the agent orders

    The situation
    A fetched page or a dependency README comes back through a tool call carrying instruction-shaped text aimed at the model rather than at you.
    What RepoOps does
    The prompt-injection-marker family fires on instruction-shaped text arriving in a tool result, which is the direction that matters: the same words in your own prompt are just a prompt.
    What you get
    You find out the agent was talked to by its inputs, and you can see the run it happened in before you decide whether anything it wrote is trustworthy.
  3. 03

    Permissions that widened halfway through a run

    The situation
    A session starts with a careful permission posture, hits friction, and ends with a path moved from ask to allow.
    What RepoOps does
    Per-session permission capture records timestamped change points, and the mid-session pass fires on a real baseline-to-latest relaxation with the concrete before and after.
    What you get
    A widening you can see and argue with. When there is no baseline to compare against, nothing fires, so the alert means what it says.

The limits

What this does not do.

Stated here rather than found out later. The long version, with the module behind each boundary, is on the proof page.

It reads. It does not act

A detector firing changes nothing on its own. Blocking a tool call, killing a run or pinning egress belongs to Contain, and every one of those controls ships off until you arm it.

Four OWASP categories are out of scope

Data and model poisoning is a training-time risk, improper output handling belongs to the app downstream, vector and embedding weaknesses live in a retrieval layer, and misinformation is a truth claim about generated text. The matrix names all four with these reasons.

Live egress needs the optional Tap

Two rules read outbound request metadata a passive transcript scan cannot see. Without the Tap store, which is the default, that family produces no signal rather than a clean verdict.

Rules, not judgment

The detectors are deterministic, so a paraphrase no rule describes goes unmatched. An opt-in semantic layer widens a few families to catch obfuscated secrets and reworded injection, and it is off unless you switch it on.

Read further

Where this is documented in full.

  • Session signalsthe families, the muting, the export, and what deep capture adds
  • MCP securitydrift alerts, the pinned allowlist, canaries and the red-team runner
  • Permission posturethe resolved mode and rules behind the excessive-agency family
  • Agent tracesthe run each finding links back to, span by span
  • Security as proofevery claim above, linked to the module that implements it

Install it and read your own record.

One developer, no account, nothing leaving the machine. Arm a control when you want one.