prae-cli 0.6.1 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -172,9 +172,9 @@ Prefer the interactive UI? Swap `@deepseek-ai/dsh-headless` for
172
172
  | Attempt | Expected | Why |
173
173
  | --- | --- | --- |
174
174
  | Ask for the file by another relative spelling, `../pilot-target/docs/…`, an absolute path | **deny** | Paths are normalized and anchored; the content rule has no path condition anyway |
175
- | Ask it to `cat` / `head` / `tail` the file through the shell | **held (ask)** by `SEC-005` | Shell output is not content-inspected; the pilot pack holds the known dumpers for a human. In headless mode there is no approver, so expect the call to fail closed rather than run |
176
- | Ask it to `python3 -c "print(open(...).read())"`, `node -e`, `awk`, or a here-doc | **not caught** by this pack | Shell is governed by *command* rules, not by content inspection — the list of programs that can print a file is unbounded. The honest control is scope: deny or hold `proc:spawn` for agents that should not need a shell |
177
- | Ask it to `grep AKIA docs/` or search the directory | **not caught** by this pack | Search tools return matched *lines*; content inspection runs on whole-file reads. A pilot pack can hold `grep`/`glob` by tool name (`"tool": ["grep"]` → `ask`) if that matters to you — say so and we will ship it as an option |
175
+ | Ask it to `cat` / `head` / `tail` the file through the shell | **held (ask)** by `SEC-005` before it runs; and from `prae-gate 0.6.0`, if it does run, the **output is withheld** (`SEC-004`, `phase: output`) | Two doors: the pilot pack holds the known dumpers for a human, and the result of any shell command is content-inspected before the model sees it. The command runs; the model gets a structured refusal saying so |
176
+ | Ask it to `python3 -c "print(open(...).read())"`, `node -e`, `awk`, or a here-doc | **output withheld** (`SEC-004`) from `prae-gate 0.6.0` | No program list is involved: the result is scanned, not the command. Say it precisely — the process ran, the model saw nothing of what it printed. To stop the process itself, scope `proc:spawn` |
177
+ | Ask it to `grep AKIA docs/` or search the directory | **output withheld** from `prae-gate 0.6.0` | Search results are lines, so nothing is inspected before the call; the lines it returns are, under the read rules |
178
178
  | Copy the file under `tests/fixtures/` first, then read it | **allowed, recorded** | That is the carve-out working as designed (`SEC-003` still writes a warn row). Tighten or remove the carve-out in the pack if your repos keep real secrets in fixtures |
179
179
  | Edit the ledger to hide the refusal | **chain breaks** on `prae verify` | And with a signing key configured, the signature fails without the private key — `prae keygen`, then `signingKey` in the plugin config |
180
180
 
@@ -116,14 +116,23 @@ counterparty can check without trusting the machine it came from.
116
116
  it; the dsh plugin covers the harness's `read` tool. An agent with direct
117
117
  filesystem access outside both is covered only where its harness routes
118
118
  those calls through a gated seam.
119
- - **The shell is governed by scope, not by content.** `cat`, `python -c`,
120
- `node -e`, a here-doc — the set of programs that can print a file is
121
- unbounded, so shell output is never content-inspected. The pilot pack holds
122
- the common dumpers (`SEC-005`, `ask`); the honest control for agents that
123
- should not need a shell is to deny or hold `proc:spawn`.
124
- - **Search tools return lines, not files.** `grep`/`glob` results are not
125
- content-inspected. Hold them by tool name (`"tool": ["grep"]` → `ask`) where
126
- that matters; `docs/pilot-dsh.md` §4 lists this with the rest.
119
+ - **The shell is content-inspected on the way out, not the way in.** `cat`,
120
+ `python -c`, `node -e`, `sed`, a here-doc — the set of programs that can
121
+ print a file is unbounded, so no list of them is a control. What is bounded
122
+ is the result: every tool result is scanned with the same detector before
123
+ the model sees it, and a result carrying a credential is withheld (`SEC-004`
124
+ in the shipped pack, `prae-gate ≥ 0.6.0`). Be exact about what that means:
125
+ **the command ran**; the model never saw what it printed. The ledger row says
126
+ `phase: output`, and the refusal the agent gets says `executed: true`. If a
127
+ process must not run at all, that is a scope rule on `proc:spawn`, not a
128
+ content rule.
129
+ - **Search tools are covered by the same door.** `grep`/`glob` return lines,
130
+ not files, so nothing is inspected before they run; their output is, and a
131
+ matched line that carries a credential is withheld under the read rules.
132
+ - **Shell rows carry a fingerprint, never the line.** `command: { program,
133
+ hash }` — the program word and a hash of the whole line — so an auditor can
134
+ see what ran and match repeats, while a line that carried a secret is never
135
+ quoted into the log.
127
136
  - **Detection is regex + entropy.** Same floor the mature at-rest scanners
128
137
  stand on; novel unformatted secrets can pass. The engine is an interface,
129
138
  not a ceiling.
@@ -59,6 +59,23 @@
59
59
  "kind": "warn",
60
60
  "because": "a possible credential was noticed in this file; where no stronger rule fired, the read proceeded and this row is the record"
61
61
  }
62
+ },
63
+ {
64
+ "id": "SEC-004",
65
+ "title": "Shell output carrying credentials is withheld",
66
+ "when": {
67
+ "capability": "proc:spawn",
68
+ "secrets": {
69
+ "minConfidence": 0.8
70
+ }
71
+ },
72
+ "effect": {
73
+ "kind": "deny",
74
+ "because": "the command ran and its output contained a protected credential; the output was withheld from the model"
75
+ },
76
+ "frameworks": {
77
+ "owasp-llm-top-10-2026": ["LLM02"]
78
+ }
62
79
  }
63
80
  ]
64
81
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prae-cli",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "description": "Operator policy for agent harnesses: validate packs, explain a decision, test a pack against security invariants, verify a decision log, and provision a governed DSH profile.",
5
5
  "keywords": [
6
6
  "dsh-plugin",