[GH-ISSUE #567] Document that executable permission scope is containment-based, not exact-path #292

Closed
opened 2026-10-15 18:23:32 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @morluto on GitHub (Oct 5, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/567

Summary

executables in a permission scope is matched by containment, not exact path, but nothing says so. The semantics are correct; they are simply undiscoverable, so an operator can authorize a directory believing they authorized one binary.

What actually happens

src/domain/permissionPolicy.ts compares executable scope entries with isPathContained, so an entry authorizes any candidate beneath it:

executables: ["C:\\Program Files\\...\\Chrome\\Application"]   ->  authorizes .../chrome.exe

This is documented nowhere on the contract. PermissionScope.executables had no doc comment, and the JSON schema descriptions in src/contracts/errorSchemas.ts presented the field as a plain path list. roots behaves the same way and is equally undescribed.

Why it matters

The failure mode is silent acceptance, not a clear rejection. An operator who writes a directory believing it means "that binary" has authorized every executable inside it — including anything an attacker can drop there. That is the opposite of the direction the permission model takes elsewhere, and it is exactly the "unclear authority, no visible limit" case the guidelines warn about.

The inverse is also possible: someone expecting containment may add several entries when one would do.

Suggested direction

  • Document the semantics at both places a reader looks: the PermissionScope interface and the schema field descriptions.
  • Consider whether executables should be exact-match and a separate executable_roots should carry containment. The current single-field behaviour is the ambiguous part; two clearly-named fields would remove the question entirely. That is a contract change and should be decided deliberately.
  • Add a test that pins the current behaviour (a directory entry authorizes a contained binary; a sibling sharing a prefix does not) so the semantics cannot drift silently either way.

Notes

The behaviour is deliberate in the code — isPathContained is shared with root containment for a reason — so this is a documentation and naming question, not a bug fix. Worth pairing with any future revision of the permission contract rather than patching in isolation.

Originally created by @morluto on GitHub (Oct 5, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/567 ## Summary `executables` in a permission scope is matched by **containment**, not exact path, but nothing says so. The semantics are correct; they are simply undiscoverable, so an operator can authorize a directory believing they authorized one binary. ## What actually happens `src/domain/permissionPolicy.ts` compares executable scope entries with `isPathContained`, so an entry authorizes any candidate beneath it: ``` executables: ["C:\\Program Files\\...\\Chrome\\Application"] -> authorizes .../chrome.exe ``` This is documented nowhere on the contract. `PermissionScope.executables` had no doc comment, and the JSON schema descriptions in `src/contracts/errorSchemas.ts` presented the field as a plain path list. `roots` behaves the same way and is equally undescribed. ## Why it matters The failure mode is silent acceptance, not a clear rejection. An operator who writes a directory believing it means "that binary" has authorized every executable inside it — including anything an attacker can drop there. That is the opposite of the direction the permission model takes elsewhere, and it is exactly the "unclear authority, no visible limit" case the guidelines warn about. The inverse is also possible: someone expecting containment may add several entries when one would do. ## Suggested direction - Document the semantics at both places a reader looks: the `PermissionScope` interface and the schema field descriptions. - Consider whether `executables` should be exact-match and a separate `executable_roots` should carry containment. The current single-field behaviour is the ambiguous part; two clearly-named fields would remove the question entirely. That is a contract change and should be decided deliberately. - Add a test that pins the current behaviour (a directory entry authorizes a contained binary; a sibling sharing a prefix does not) so the semantics cannot drift silently either way. ## Notes The behaviour is deliberate in the code — `isPathContained` is shared with root containment for a reason — so this is a documentation and naming question, not a bug fix. Worth pairing with any future revision of the permission contract rather than patching in isolation.
Author
Owner

@morluto commented on GitHub (Oct 5, 2026):

Closing as not applicable — the type this describes no longer exists.

PermissionScope.executables, permissionPolicy.ts and isPathContained were all removed by #555, which deleted REA's permission grants, scope ceilings and the policy CLI commands. With no permission scope there is no containment-versus-exact-path ambiguity left to document, and executables no longer appears in src/contracts/errorSchemas.ts.

The underlying observation was correct for its time and is recorded here for history: naming a containing directory in executables authorized every executable beneath it, silently. If any future capability reintroduces scoped authority, this is the trap to avoid — two clearly-named fields (exact, roots) beat one field with implicit containment.

Related context: #545 covered the other half of the permission system's diagnostics.

<!-- gh-comment-id:5995073089 --> @morluto commented on GitHub (Oct 5, 2026): Closing as **not applicable** — the type this describes no longer exists. `PermissionScope.executables`, `permissionPolicy.ts` and `isPathContained` were all removed by #555, which deleted REA's permission grants, scope ceilings and the `policy` CLI commands. With no permission scope there is no containment-versus-exact-path ambiguity left to document, and `executables` no longer appears in `src/contracts/errorSchemas.ts`. The underlying observation was correct for its time and is recorded here for history: naming a containing directory in `executables` authorized every executable beneath it, silently. If any future capability reintroduces scoped authority, this is the trap to avoid — two clearly-named fields (`exact`, `roots`) beat one field with implicit containment. Related context: #545 covered the other half of the permission system's diagnostics.
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
morluto/rea#292
No description provided.