hook: basename-aware protected-binary deny #55

Closed
opened 2026-06-03 21:48:32 +00:00 by coilysiren · 0 comments
Owner

Context

A deny rule keyed on a command name does not gate the capability, only the name. The 2026-05-08 deny-uv finding documented the failure shape: Bash(uv:*) was bypassed by invoking the venv binary by absolute path. The same hole exists for any protected host tool — a Route keyed on the bare leading token gcloud does not catch /opt/homebrew/bin/gcloud.

This is the hook-engine half of the ward security-doctor work (coilyco-flight-deck/ward#4). Depends on the repocfg security: schema.

Change

Add hook.Protected and a basename-aware deny to the PreToolUse engine. A configured protected binary is denied on:

  • the bare token (gcloud projects list)
  • any absolute-path spelling (/opt/homebrew/bin/gcloud auth list)
  • after env/sudo strip (already peeled upstream)
  • piped behind an allowed command

Matching keys on basename, so a path spelling cannot slip past a deny keyed on the bare name. protected is a trailing variadic parameter on PreToolUse, so existing callers are unaffected. Exports a Basename helper; interpreterName reuses it.

Acceptance

  • PreToolUse(..., protected...) blocks bare, absolute-path, env/sudo-prefixed, and piped invocations of a protected binary.
  • Substring near-misses (gcloudfoo) are not matched.
  • Deny message prefers a consumer hint, else synthesizes from allowed wrappers, else a bare deny.
  • Existing hook tests/callers unchanged.
## Context A deny rule keyed on a command name does not gate the capability, only the name. The 2026-05-08 deny-uv finding documented the failure shape: `Bash(uv:*)` was bypassed by invoking the venv binary by absolute path. The same hole exists for any protected host tool — a `Route` keyed on the bare leading token `gcloud` does not catch `/opt/homebrew/bin/gcloud`. This is the hook-engine half of the ward security-doctor work ([coilyco-flight-deck/ward#4](https://forgejo.coilysiren.me/coilyco-flight-deck/ward/issues/4)). Depends on the `repocfg` `security:` schema. ## Change Add `hook.Protected` and a basename-aware deny to the `PreToolUse` engine. A configured protected binary is denied on: - the bare token (`gcloud projects list`) - any absolute-path spelling (`/opt/homebrew/bin/gcloud auth list`) - after `env`/`sudo` strip (already peeled upstream) - piped behind an allowed command Matching keys on basename, so a path spelling cannot slip past a deny keyed on the bare name. `protected` is a trailing variadic parameter on `PreToolUse`, so existing callers are unaffected. Exports a `Basename` helper; `interpreterName` reuses it. ## Acceptance - `PreToolUse(..., protected...)` blocks bare, absolute-path, env/sudo-prefixed, and piped invocations of a protected binary. - Substring near-misses (`gcloudfoo`) are not matched. - Deny message prefers a consumer hint, else synthesizes from allowed wrappers, else a bare deny. - Existing hook tests/callers unchanged.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
coilyco-flight-deck/cli-guard#55
No description provided.