You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: SECURITY.md
+21-20Lines changed: 21 additions & 20 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,28 +10,28 @@ We aim to acknowledge within 2 business days and ship a fix within 30 days for h
10
10
11
11
This plugin's surface includes:
12
12
13
-
-**Skills** (`skills/<name>/SKILL.md`) — Markdown prompts that Cursor loads as `/lua-*` slash commands. Symlinked into `~/.cursor/skills-cursor/` by `scripts/install.mjs`.
14
-
-**Subagents** (`agents/*.md`) — referenced by skills; specialised assistants for architect/build/debug/deploy/QA flows.
15
-
-**Hooks** (`hooks/*.mjs`) — run as Node subprocesses on `sessionStart`, `beforeSubmitPrompt`, `beforeShellExecution`, `afterShellExecution` events. Registered in `~/.cursor/hooks.json`by the install script.
16
-
-**MCP server** (`mcp/lua-platform/dist/server.js`) — a stdio MCP server exposing 5 read-only tools. Talks to `https://api.heylua.ai` over HTTPS using the user's API key. Registered in `~/.cursor/mcp.json`.
13
+
-**Skills** (`skills/<name>/SKILL.md`) — Markdown prompts that Codex loads as `/lua-*` slash commands. Bundled via the plugin manifest at `.codex-plugin/plugin.json`.
14
+
-**Subagents** (`agents/*.toml`) — Codex TOML-format subagent definitions with `name`, `description`, `developer_instructions`. Bundled with the plugin.
15
+
-**Hooks** (`hooks/*.mjs`) — run as Node subprocesses on `SessionStart`, `UserPromptSubmit`, `PreToolUse`, `PostToolUse` events. Registered in `hooks/hooks.json`(Claude-Code-shaped schema; Codex consumes it natively).
16
+
-**MCP server** (`mcp/lua-platform/dist/server.js`) — a stdio MCP server exposing 5 read-only tools. Talks to `https://api.heylua.ai` over HTTPS using the user's API key. Registered in `.mcp.json`.
17
17
-**Rules** (`rules/*.mdc`) — knowledge files attached to the architect agent's context via `@-mention`.
18
-
-**Install script** (`scripts/install.mjs`) — modifies `~/.cursor/mcp.json` and `~/.cursor/hooks.json` (always with backup). Runs only when explicitly invoked by the user.
18
+
-**Install script** (`scripts/install.mjs`) — runs `codex plugin marketplace add` + `codex plugin install`. Does not modify any user files outside Codex's plugin cache (`~/.codex/plugins/cache/`).
19
19
20
20
In scope for security reports:
21
21
22
22
- Credential exposure (API keys leaking into transcripts, logs, environment, or external systems)
23
23
- Safety-gate bypasses (deploys or destructive operations succeeding without the documented confirmation)
- Install script writing outside `~/.cursor/` or executing without explicit user invocation
27
-
- Symlink-target manipulation (an installed skill resolving to a path outside the cloned plugin)
26
+
- Symlink-target manipulation (a bundled component resolving to a path outside the cloned plugin)
28
27
29
28
Out of scope:
30
29
31
-
- Bugs in `lua-cli` itself (report to the lua-cli repo or via security@heylua.ai with `[lua-cli]` in the subject)
30
+
- Bugs in `lua-cli` itself (report to security@heylua.ai with `[lua-cli]` in the subject)
32
31
- Bugs in `lua-api` (report to security@heylua.ai with `[lua-api]` in the subject)
32
+
- Bugs in Codex CLI itself (report to OpenAI)
33
33
- Issues in user-installed third-party MCP servers
34
-
- Social-engineering / phishing of an Lua API key from a user
34
+
- Social-engineering / phishing of a Lua API key from a user
35
35
36
36
## Safety-critical contracts
37
37
@@ -41,25 +41,26 @@ The plugin enforces several safety contracts. Bypasses count as security issues.
41
41
|---|---|
42
42
|**§3.3 deploy gate**: bare `lua deploy` is denied |`hooks/before-shell-execution.mjs` (umbrella) + `hooks/confirm-deploy.mjs` (dedicated) |
43
43
|**§3.3 auto-deploy block**: `--auto-deploy` is denied |`hooks/before-shell-execution.mjs` + `hooks/block-auto-deploy.mjs`|
44
-
|**Credential isolation**: API key never enters chat transcript |`hooks/before-shell-execution.mjs` denies `lua auth key*` invocations + `commands/lua-doctor.md` Step 4 uses an authenticated metadata probe (`lua agents --json --ci`), not a key-printing command |
45
-
|**§3.7 single-permission contract**: each skill asks at most one prompt per invocation | Convention enforced in skill bodies; not yet machine-checked in the Cursor port (was lint-checked in the Claude Code plugin via `scripts/lint-single-permission.mjs`)|
44
+
|**Credential isolation**: API key never enters chat transcript |`hooks/before-shell-execution.mjs` denies `lua auth key*` invocations + `skills/lua-doctor/SKILL.md` Step 4 uses an authenticated metadata probe (`lua agents --json --ci`), not a key-printing command |
45
+
|**§3.7 single-permission contract**: each skill asks at most one prompt per invocation | Convention enforced in skill bodies |
46
46
47
47
If you find a way to bypass any of these without an explicit user prompt, please report.
48
48
49
-
### Hook safety model under Cursor
49
+
### Hook safety model under Codex
50
50
51
-
Cursor sends `beforeShellExecution` hooks structured stdin JSON `{command, cwd, ...}` and accepts either an exit code (2 = block) or a JSON return`{permission: "deny", user_message, agent_message}`. The plugin's hooks self-filter on `command` content rather than relying on Cursor's `matcher` field — a bug fix landed in `a85cff7` after the matcher proved unreliable in the wild and caused every shell command to be denied.
51
+
Codex sends `PreToolUse` hooks structured stdin JSON `{tool_input: {command, ...}, tool_name, hook_event_name, ...}`(the same shape as Claude Code) and accepts either an exit code (2 = block) or a JSON envelope`{hookSpecificOutput: {hookEventName, permissionDecision}}`. The plugin's hooks self-filter on `command` content rather than relying on Codex's `matcher` field — defense-in-depth in case Codex's matcher behaviour ever drifts (a bug-class we hit on the Cursor port; same mitigation applied here proactively).
52
52
53
-
The runtime adapter (`lib/hook-runtime.mjs`) detects whether it's running under Claude Codeor Cursor (via `CURSOR_TRACE_ID`env or input shape) and emits the host-appropriate output protocol. The same hook scripts run unchanged on either host.
53
+
The runtime adapter (`lib/hook-runtime.mjs`) detects whether it's running under Claude Code, Cursor, or Codex (via env vars or input shape) and emits the host-appropriate output protocol. The same hook scripts run unchanged on all three hosts.
54
54
55
55
## Audit history
56
56
57
-
This plugin is a port of[`claude-code-lua-plugin`](https://github.com/lua-ai-global/claude-code-lua-plugin), which underwent 13 iterations of structured audit (commits prefixed with `iteration-`) before public release, fixing 78 documented bugs across the plugin / hook / MCP / knowledge-file surfaces. See the iteration-history comments in each lint script (`scripts/lint-*.mjs`) for the rationale behind each structural guard.
57
+
This plugin is the third in a family ported from[`claude-code-lua-plugin`](https://github.com/lua-ai-global/claude-code-lua-plugin), which underwent 13 iterations of structured audit (commits prefixed with `iteration-`) before public release, fixing 78 documented bugs across the plugin / hook / MCP / knowledge-file surfaces. See the iteration-history comments in each lint script (`scripts/lint-*.mjs`) for the rationale behind each structural guard.
58
58
59
-
The Cursor port adds:
59
+
The Codex port adds:
60
60
61
61
- A new `before-shell-execution.mjs` umbrella hook covering all three §3.3 deny patterns
62
-
- Cursor-runtime detection + input/output normalisation in `lib/hook-runtime.mjs`
0 commit comments