From 00697d9e5ed96fd1f0401dd0e80b23fdbd9edc2a Mon Sep 17 00:00:00 2001 From: Li-Yu Yu Date: Sat, 11 Apr 2026 00:22:27 +0900 Subject: [PATCH 1/2] command_filter: clarify language spec ambiguities - Define as excluding leading dash, as allowing it - Allow pipe alternation inside both () and [] groups - Restrict modifiers to built-in types only - Add 1-unambiguous rule: reject patterns where argument ownership is undecidable - Clarify multi-element alternatives each consume one argument per element --- command_filter/LANGUAGE.md | 57 ++++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/command_filter/LANGUAGE.md b/command_filter/LANGUAGE.md index 8f14eae..d1c8806 100644 --- a/command_filter/LANGUAGE.md +++ b/command_filter/LANGUAGE.md @@ -33,8 +33,8 @@ act as alternatives — a command is permitted if it matches any one of them. ### `define` Binds a name to a sub-pattern that can be referenced elsewhere. The name must -be wrapped in angle brackets and must not collide with built-in types -(`string`, `path`). +be wrapped in angle brackets and must not collide with the built-in type names +`string` or `path`. Definitions may reference other definitions. The reference graph must be acyclic (no recursion). @@ -55,31 +55,41 @@ allow rg --help Angle-bracketed names that match a single argument: -| Placeholder | Matches | -|----------------|--------------------------------------| -| `` | Any argument | -| `` | Any argument (dash-allowed modifier) | -| `` | A path the user can read | -| `` | A path the user can write | -| `` | Expands a `define`d sub-pattern | +| Placeholder | Matches | +|----------------|--------------------------------------------------| +| `` | Any argument that does not start with `-` | +| `` | Any argument, including those starting with `-` | +| `` | A path the user can read | +| `` | A path the user can write | +| `` | Expands a `define`d sub-pattern | + +Modifiers (the `:` suffix, e.g. `:-`, `:r`, `:w`) are only valid on built-in +types. User-defined names must be plain `` with no modifier. User-defined names are distinguished from built-in types by their presence in a `define` statement. ### Groups and alternatives -Parentheses group elements. Pipe separates alternatives within a group: +Parentheses `()` and square brackets `[]` both group elements. Pipe `|` +separates alternatives within the closest enclosing group: ``` (-g | -F) (-name | -type ) +[-l | -t | -h] ``` -A group matches exactly one of its alternatives. +A group matches exactly one of its alternatives. Each alternative may be a +sequence of multiple elements, where each element consumes one argument: + +``` +(-name | -type ) # each branch is two arguments +``` ### Optional -Square brackets mark an element or group as optional (zero or one): +Square brackets mark a group as optional (zero or one): ``` [] @@ -105,6 +115,29 @@ repetition of `...`: [-r | -f]... # zero or more of these flags ``` +## Ambiguity + +Patterns must be **1-unambiguous**: at every point where matching could follow +two paths (continue a repetition vs. advance to the next element, or choose +between alternatives), the sets of arguments each path accepts must be +disjoint. The matcher decides where each argument belongs by inspecting that +argument alone, with no lookahead or backtracking. + +A pattern that violates this property is rejected at parse time: + +``` +... # error: both sides accept paths +[]... # error: same type on both sides +[]... # error: is a superset of +``` + +Valid patterns keep choice points disjoint: + +``` +[-v | -r]... # ok: literals are disjoint from +[]... # ok: options expand to dash-prefixed flags +``` + ## Future extensions The keyword-prefixed design reserves space for future statement types (e.g. From 2285b4141269af680fdea2311e24f474c2860d55 Mon Sep 17 00:00:00 2001 From: Li-Yu Yu Date: Sat, 11 Apr 2026 00:39:15 +0900 Subject: [PATCH 2/2] README: tighten wording on secondary execution warning --- README.md | 35 +++++++++++++++++++++++++++++++++++ command_filter/LANGUAGE.md | 6 ++++++ 2 files changed, 41 insertions(+) diff --git a/README.md b/README.md index 64cfdc3..68d39c0 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,41 @@ Tools to let coding agents access the shell with opinionated defaults. +## Security model + +Most agent actions should run under [`//sandbox`](sandbox/BUILD.bazel). +Command filtering complements sandboxing by narrowly delegating selected CLI +capabilities, including commands that intentionally use the user's ambient +credentials. It is not a substitute for sandboxing. + +Command filtering is useful for narrowing which command lines an agent may run: +which binaries are allowed, which subcommands and flags are allowed, and which +logical paths may be passed as arguments. That is a least-authority delegation +mechanism, not a full security boundary. + +If an allowed command can use the user's ambient credentials, network access, +or other external authority, then allowing that command is effectively +granting that capability to the agent. Path restrictions such as `` +and `` only constrain named file arguments; they do not constrain +unrelated side effects a command may have. + +For example, a user might grant an agent permission to fetch GitHub Actions +logs via a narrow `gh` rule. That is different from allowing arbitrary `gh` +usage: the rule is a deliberate delegation of one credential-backed +capability, not blanket authority over the GitHub CLI. + +Some allowed tools may execute hooks, helpers, pagers, editors, or other +user-controlled programs as part of their normal behavior. +Rules should be written with those secondary execution paths in mind. + +Practical guidance: + +- Prefer running agent actions in `//sandbox`. +- Use command filters to grant narrow, reviewable capabilities, especially for + tools that intentionally act with the user's ambient credentials. +- Write rules per operation, not per binary. +- Treat each allow-rule as a permission grant that should be reviewed. + ## License Apache-2.0 diff --git a/command_filter/LANGUAGE.md b/command_filter/LANGUAGE.md index d1c8806..17ec5ff 100644 --- a/command_filter/LANGUAGE.md +++ b/command_filter/LANGUAGE.md @@ -4,6 +4,12 @@ A small language for defining allowed command invocations. Each rule file describes the permitted argument shapes for a command, with path arguments carrying read/write permission annotations. +This language describes which command lines are permitted. It does not by +itself provide process isolation. In this repository, most agent actions +should run under `//sandbox`; command filtering is used to narrowly delegate +specific CLI capabilities, including commands that intentionally use ambient +user credentials. + ## Statements Every line is one of two statement types, identified by a keyword prefix: