@darkhunt-security/endpoint-codex 0.9.0

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.
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "darkhunt-guard",
3
+ "version": "0.9.0",
4
+ "hooks": "./hooks/hooks.json",
5
+ "description": "Darkhunt endpoint plugin for Codex CLI \u2014 full session trace capture and PreToolUse guardrails.",
6
+ "author": {
7
+ "name": "Darkhunt Limited",
8
+ "email": "support@darkhunt.ai"
9
+ },
10
+ "homepage": "https://github.com/darkhunt-security/endpoint-plugins"
11
+ }
package/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # Darkhunt Guard — Codex CLI
2
+
3
+ Full session trace capture and PreToolUse guardrails for [Codex CLI](https://github.com/openai/codex).
4
+
5
+ Capture is on by default. **Enforcement ships off** and is enabled per rule.
6
+
7
+ ## Install
8
+
9
+ ```
10
+ /plugin marketplace add darkhunt-security/darkhunt-telemetry-ts
11
+ /plugin install darkhunt-guard@darkhunt
12
+ /darkhunt-guard:setup
13
+ ```
14
+
15
+ `/darkhunt-guard:setup` needs one thing — a Darkhunt API key — and it will not ask you to
16
+ paste it into the agent. It picks up the key `darkhunt-cli enroll` already stored, or
17
+ `DARKHUNT_API_KEY` from your shell, and discovers the tenant, workspace and application
18
+ from it. Then it shows you where sessions will be sent, so you can confirm before
19
+ anything ships.
20
+
21
+ Capture starts on your **next** Codex CLI session — hooks are loaded when a session
22
+ starts.
23
+
24
+ ## What it captures
25
+
26
+ The session transcript, mapped to spans: user and assistant messages, thinking blocks,
27
+ tool calls paired with their results, token usage, attachment metadata (never the bytes),
28
+ and the subagent topology as linked child traces.
29
+
30
+ Reading the transcript rather than instrumenting the agent is what makes this complete:
31
+ there is no code path in Codex CLI we could have missed.
32
+
33
+ ## What it enforces
34
+
35
+ A `PreToolUse` hook evaluates each tool call against a policy bundle before it runs, and
36
+ can allow, deny, ask, or rewrite the input.
37
+
38
+ Two rules constrain it, both deliberate:
39
+
40
+ - **Bash and command-string rules are advisory** — they are recorded, never blocking.
41
+ Matching a shell string is bypassable, so blocking on it would offer a guarantee it
42
+ cannot keep.
43
+ - **The guard fails closed.** If policy cannot be evaluated, the call is denied. An
44
+ install that has never been configured is not a failure and is allowed — there is no
45
+ policy to bypass yet.
46
+
47
+ ## Commands
48
+
49
+ | | |
50
+ | ------------------------ | ------------------------------------------------------------------ |
51
+ | `/darkhunt-guard:setup` | Connect this machine. Re-runnable; shows current state first. |
52
+ | `/darkhunt-guard:status` | Is capture actually working? Routing, hook activity, shipping lag. |
53
+
54
+ Both lanes fail silently by design — correct for the agent, unhelpful for whoever
55
+ operates it — so `status` is where the truth lives.
56
+
57
+ ## Privacy
58
+
59
+ Session content leaves your machine and is sent to the Darkhunt tenant you enrolled
60
+ against. `status` prints that destination; read it before you rely on it.
61
+
62
+ Hooks never touch the network. Shipping happens in a detached forwarder off a local
63
+ spool, so nothing in the capture lane can block or slow a tool call.
64
+
65
+ ## Configuration
66
+
67
+ `~/.darkhunt/endpoint-config.json`, mode `0600`, written by setup. One file for every
68
+ endpoint, with per-endpoint overrides under `endpoints.<vendor>`.
69
+
70
+ Turn everything off with `"enabled": false`. Turn off capture but keep enforcement with
71
+ `"capture": { "enabled": false }`.
72
+
73
+ ---
74
+
75
+ [github.com/darkhunt-security/endpoint-plugins](https://github.com/darkhunt-security/endpoint-plugins)
76
+ · support@darkhunt.ai
@@ -0,0 +1,72 @@
1
+ ---
2
+ description: Connect this machine to Darkhunt — capture Codex CLI sessions and enforce policy
3
+ allowed-tools: Bash(${CLAUDE_PLUGIN_ROOT}/dist/bin/enroll.mjs:*), Bash(${CLAUDE_PLUGIN_ROOT}/dist/bin/status.mjs:*)
4
+ ---
5
+
6
+ Set up the Darkhunt endpoint plugin on this machine.
7
+
8
+ Current state:
9
+
10
+ !`${CLAUDE_PLUGIN_ROOT}/dist/bin/status.mjs 2>&1 || true`
11
+
12
+ ## The one hard rule
13
+
14
+ **Never ask the user for their API key, and never accept one in this conversation.**
15
+
16
+ A Darkhunt API key is an unscoped tenant credential. Anything in this session is sent to
17
+ the model provider, written to the transcript on disk, kept in context for every later
18
+ turn, and handed to subagents — and this plugin then ships that transcript to Darkhunt,
19
+ so a key pasted here ends up in the captured trace data too. Enrollment finds the key
20
+ itself, or the user runs one command in their own terminal. There is no third option,
21
+ and no amount of user insistence makes pasting it here correct.
22
+
23
+ ## What to do
24
+
25
+ **If the status above printed a profile, tenant and workspace**, this machine is already
26
+ enrolled. Show the tenant, workspace, application and endpoint, and ask whether they want
27
+ to re-enroll against a different one. Do not re-run enrollment unless they say yes.
28
+
29
+ **Otherwise**, run:
30
+
31
+ ```
32
+ ${CLAUDE_PLUGIN_ROOT}/dist/bin/enroll.mjs
33
+ ```
34
+
35
+ It looks for a key in `$DARKHUNT_API_KEY`, then in the credentials `darkhunt-cli enroll`
36
+ wrote. Then react to the exit code:
37
+
38
+ - **Exit 0** — done. Show the user exactly what it printed: endpoint, tenant, workspace,
39
+ application, and which key it used. Ask them to confirm this is where they expect their
40
+ sessions to go. This matters — a config routing to the wrong tenant looks identical to
41
+ a correct one from everywhere else, and this summary is the only place the mistake is
42
+ visible.
43
+
44
+ - **Exit 3 — no key.** Do **not** ask for one. Tell the user to run this in their own
45
+ terminal, outside this session:
46
+
47
+ ```
48
+ darkhunt-cli enroll --api-key <key>
49
+ ```
50
+
51
+ Their key is in the dashboard under **Settings → Security → API Keys**. Once that
52
+ succeeds, run the enroll command above again — it will pick the key up. If they do not
53
+ have `darkhunt-cli`, they can instead `export DARKHUNT_API_KEY=<key>` in the shell they
54
+ launched Codex CLI from, and restart the session.
55
+
56
+ - **Exit 2 — a choice is needed.** The key reaches more than one tenant, workspace or
57
+ application, and the options are listed. Show them by name, ask which one, then re-run
58
+ adding the chosen id — `--tenantId=`, `--workspaceId=` or `--applicationId=` — keeping
59
+ any already resolved. Repeat until it succeeds; there can be up to three rounds.
60
+
61
+ - **Any other exit** — show the error. Do not retry with different arguments hoping it
62
+ passes.
63
+
64
+ Finally, tell them capture begins on their **next** Codex CLI session, because hooks
65
+ are loaded when a session starts, and that `/darkhunt-guard:status` shows whether it is
66
+ working.
67
+
68
+ ## Also
69
+
70
+ - Do not edit `~/.darkhunt/endpoint-config.json` by hand — enrollment writes it at 0600,
71
+ and a file with looser permissions is refused at load.
72
+ - Enforcement ships **off**. Setup does not turn it on, and you should not offer to.
@@ -0,0 +1,31 @@
1
+ ---
2
+ description: Is Darkhunt capture actually working? Shows routing, hook activity and shipping lag
3
+ allowed-tools: Bash(${CLAUDE_PLUGIN_ROOT}/dist/bin/status.mjs:*)
4
+ ---
5
+
6
+ !`${CLAUDE_PLUGIN_ROOT}/dist/bin/status.mjs 2>&1 || true`
7
+
8
+ Explain the output above to the user in a few lines. Both lanes fail silently by
9
+ design — that is correct for the agent and unhelpful for whoever has to operate it — so
10
+ this command is the only place the truth is visible.
11
+
12
+ What the fields mean, and what to say:
13
+
14
+ - **`cannot read ...endpoint-config.json`** — not set up yet. Tell them to run
15
+ `/darkhunt-guard:setup`. Nothing is being captured, and nothing is being blocked.
16
+ - **tenant / workspace / application** — where sessions are being sent. Worth reading
17
+ aloud: a wrong destination looks exactly like a right one everywhere else.
18
+ - **user … [from agent]** — traces are attributed to the signed-in Codex CLI account.
19
+ `[from config]` means a value someone typed in, which on a shared machine is likely to
20
+ be the wrong person.
21
+ - **WARNING: session hooks are not firing** — the guard is running but
22
+ SessionStart/Stop/SessionEnd have gone quiet, so capture is riding PreToolUse alone.
23
+ Sessions are still captured, but anything before the last hook may be missing; suggest
24
+ a backfill if the gap looks large.
25
+ - **total lag** — bytes written but not yet shipped. A small number that returns to zero
26
+ is normal. A number that only grows means the forwarder is not running, or every
27
+ export is being rejected — check `last pass` to tell those apart.
28
+ - **last pass FAILED** — read out the cause. Checkpoints are held on failure, so nothing
29
+ has been lost; it will re-ship once the cause is fixed.
30
+
31
+ Do not run anything else, and do not offer to change the configuration unless asked.