Skip to content

fix(permissions): bound Windows ACL commands - #89

Merged
steipete merged 2 commits into
mainfrom
fix/permissions-exec
Aug 2, 2026
Merged

fix(permissions): bound Windows ACL commands#89
steipete merged 2 commits into
mainfrom
fix/permissions-exec

Conversation

@steipete

@steipete steipete commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

What changed

  • Bound each built-in Windows permission command to 10 seconds and terminate a timed-out child with a hard kill.
  • Return an explicit unverified permission result when owner inspection fails, without starting a follow-up ACL command.
  • Remove duplicate direct permission inspections from the two Windows secure-read integration tests; the secure-read result already carries the same verified permission record.
  • Keep the ordinary Node matrix deliberately on the shipping JavaScript/command fallback, while the native job retains bundled-binding coverage.

This supersedes #88. Credit to @Yigtwxx for the careful diagnosis of the missing native build, the six-spawn test shape, and the unbounded production executor.

Why

The timeout increase in #88 treated runner latency rather than the underlying issues. Without the native binding, each permission inspection launches PowerShell for owner facts and icacls for ACL facts. The affected tests inspected once directly and then repeated that work through the secure read. More importantly, the production executor had no deadline, so a wedged system command could hang a caller indefinitely.

The ordinary matrix intentionally remains a fallback test rather than building native everywhere. That preserves real Windows coverage of shipping fallback code. Removing the duplicate inspection cuts each affected test from six real process launches to four, including its two ACL setup commands.

Proof

On macOS, a fake PowerShell executable that sleeps indefinitely left the pre-change public inspection call running beyond 2.00 seconds. With this change, inspectPathPermissions() returned source: "unknown" with an explicit timeout error in 10.07 seconds.

Both real Windows fallback jobs are green. reads from a validated Windows ACL and owner completed in 3.962 seconds on Node 22 and 4.367 seconds on Node 24; the extended-path case completed in 439 ms and 430 ms. The deterministic wedged-child regression passed in the same jobs as part of the 157 ms / 155 ms permission-executor suite.

@steipete
steipete requested a review from a team as a code owner August 2, 2026 20:57
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal priority bug or improvement with limited blast radius. merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Aug 2, 2026
@clawsweeper

clawsweeper Bot commented Aug 2, 2026

Copy link
Copy Markdown

Codex review: needs maintainer review before merge. Reviewed August 2, 2026, 5:10 PM ET / 21:10 UTC.

ClawSweeper review

What this changes

The PR gives fallback Windows owner and ACL commands a 10-second deadline, returns an unverified result after owner-query failure, removes duplicate secure-read inspections from Windows tests, and documents fallback CI coverage.

Merge readiness

⚠️ Ready for maintainer review - 4 items remain

This PR addresses a real unbounded Windows permission-fallback path that remains on current main. The implementation is focused, cleanly mergeable, documented, and backed by real fallback-run proof; the remaining merge question is whether maintainers accept the intentional 10-second fail-closed behavior for existing Windows fallback users.

Priority: P2
Reviewed head: 04efaf1447ee1e1579e68112e3c56bbcd5225734
Owner decision: Required. See Decision needed.

Review scores

Measure Result What it means
Overall readiness 🐚 platinum hermit (4/6) The patch is focused and well-proven; the remaining concern is the intentional upgrade-visible timeout policy rather than implementation correctness.
Proof confidence 🦞 diamond lobster (5/6) Sufficient (live_output): The PR body provides after-fix timing from a deliberately wedged command and measured passing Windows fallback jobs, directly demonstrating the changed runtime behavior.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Verified Sufficient (live_output): The PR body provides after-fix timing from a deliberately wedged command and measured passing Windows fallback jobs, directly demonstrating the changed runtime behavior.
Evidence reviewed 6 items Current fallback has no deadline: Current main's default Windows permission executor calls execFile without a timeout, so a wedged owner, ACL, or SID-resolution command can leave inspection pending.
Proposed fallback fails closed: The branch adds a shared 10-second command executor and returns source: "unknown" before starting ACL inspection when owner inspection fails; secure reads reject unknown Windows permission results.
Focused regression coverage: The branch adds deterministic coverage for a wedged child process, halting after owner inspection fails, and a secure read performing one owner and ACL inspection.
Findings None None.
Security None None.

How this fits together

Windows permission inspection protects secure file reads when the optional native binding is unavailable. The fallback gathers Windows owner and ACL facts through system commands, classifies access, and secure reads reject files whose ownership or permissions cannot be verified.

flowchart LR
  A[Secure file read] --> B[Permission inspection]
  B --> C{Native binding available?}
  C -->|Yes| D[Native ACL facts]
  C -->|No| E[Bounded Windows commands]
  D --> F[Permission classification]
  E --> F
  F --> G{Safe and verified?}
  G --> H[Read file or reject]
Loading

Decision needed

Question Recommendation
Should the package accept a fixed 10-second deadline for existing Windows command-fallback permission checks, with secure reads failing closed when that deadline is exceeded? Accept the 10-second fail-closed deadline: Merge the patch and retain the documented behavior that commands exceeding 10 seconds yield an unverified permission result rather than an indefinite wait.

Why: The code and runtime proof support the security and availability benefit, but the chosen deadline changes observable behavior for existing fallback users and therefore needs maintainer compatibility intent.

Before merge

  • Resolve merge risk (P2) - Existing Windows fallback users whose PowerShell, icacls.exe, or whoami.exe command legitimately exceeds 10 seconds will now receive an unverified secure-read failure instead of waiting indefinitely.
  • Resolve merge risk (P1) - Advanced callers that inject PermissionExec retain responsibility for enforcing an executor deadline, as the updated documentation explains.
  • Complete next step (P2) - The remaining merge gate is maintainer acceptance of the explicit 10-second compatibility boundary, not a mechanical repair.
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Patch scope 7 files affected; 173 added, 37 removed The change is localized to the Windows permission fallback, its tests, documentation, CI wording, and release notes.
Duplicate inspection removal 2 Windows integration tests simplified Each test now validates the secure-read permission record instead of performing an additional direct inspection.

Root-cause cluster

Relationship: canonical
Canonical: #89
Summary: This PR is the canonical candidate fix for the runtime timeout and duplicate-inspection problem surfaced by the linked test-budget PR.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge-risk options

Maintainer options:

  1. Merge with the documented deadline (recommended)
    Accept the 10-second fail-closed fallback limit, supported by focused regressions and real Windows fallback CI proof.
  2. Pause for a different deadline policy
    Hold the PR if maintainers need a different fallback timeout or upgrade strategy for unusually slow Windows systems.

Technical review

Best possible solution:

Keep the bounded, explicit, fail-closed fallback; merge it once maintainers accept the documented 10-second compatibility boundary and retain separate native and JavaScript-fallback CI coverage.

Do we have a high-confidence way to reproduce the issue?

Yes. Current main has no deadline in the default Windows permission executor, and the branch adds a deterministic wedged-child regression that exercises the new bounded executor and public inspection behavior.

Is this the best way to solve the issue?

Yes, subject to the compatibility decision. A shared bounded executor plus an unverified result after owner failure is narrower and safer than retaining an unbounded command path or only relaxing test timeouts.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 2477f5681f68.

Labels

Label justifications:

  • P2: This fixes a real but Windows-fallback-specific reliability and fail-closed permission behavior.
  • merge-risk: 🚨 compatibility: A pre-existing fallback command that exceeds 10 seconds now produces an unverified secure-read failure instead of continuing indefinitely.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body provides after-fix timing from a deliberately wedged command and measured passing Windows fallback jobs, directly demonstrating the changed runtime behavior.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body provides after-fix timing from a deliberately wedged command and measured passing Windows fallback jobs, directly demonstrating the changed runtime behavior.

Evidence

What I checked:

  • Current fallback has no deadline: Current main's default Windows permission executor calls execFile without a timeout, so a wedged owner, ACL, or SID-resolution command can leave inspection pending. (src/permissions.ts:119, 2477f5681f68)
  • Proposed fallback fails closed: The branch adds a shared 10-second command executor and returns source: "unknown" before starting ACL inspection when owner inspection fails; secure reads reject unknown Windows permission results. (src/permission-exec.ts:6, 04efaf1447ee)
  • Focused regression coverage: The branch adds deterministic coverage for a wedged child process, halting after owner inspection fails, and a secure read performing one owner and ACL inspection. (test/permissions-exec.test.ts:18, 04efaf1447ee)
  • Integration test scope: The Windows secure-read integration tests still assert a verified ACL and trusted owner through the returned secure-read permission record, while removing only the duplicate direct inspection. (test/new-primitives.test.ts:221, 04efaf1447ee)
  • Feature-history provenance: The current permission implementation is attributed by blame to the v0.5.1 release commit by Peter Steinberger; he also authored both commits in this PR. (src/permissions.ts:151, 16e1bd489ae8)
  • Merge and runtime proof: The supplied GitHub state reports a clean merge, all listed CI checks successful, a real wedged-command result returning after about 10 seconds, and passing Windows fallback jobs with measured durations. (04efaf1447ee)

Likely related people:

  • steipete: Peter Steinberger authored the current release-backed permission implementation and both commits on this fix branch. (role: feature owner and recent area contributor; confidence: high; commits: 16e1bd489ae8, 803cb0f4543a, 04efaf1447ee; files: src/permissions.ts, src/permission-exec.ts, test/permissions-exec.test.ts)
  • Yigtwxx: The related earlier PR documented the no-native fallback spawn pattern and the unbounded production executor that this branch addresses. (role: adjacent diagnosis contributor; confidence: medium; files: test/new-primitives.test.ts)

Rank-up moves

Optional improvements that raise the rating; they are not merge blockers.

  • Obtain maintainer acceptance of the fixed 10-second fail-closed fallback deadline before merge.

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

History

Review history (1 earlier review cycle)
  • reviewed 2026-08-02T21:06:14.043Z sha 04efaf1 :: needs maintainer review before merge. :: none

@steipete
steipete force-pushed the fix/permissions-exec branch from 04efaf1 to 9726e1d Compare August 2, 2026 21:43
@steipete
steipete merged commit 64f7742 into main Aug 2, 2026
21 checks passed
@steipete
steipete deleted the fix/permissions-exec branch August 2, 2026 21:43
steipete added a commit that referenced this pull request Aug 2, 2026
The 10-second bound added in #89 was too tight for the command fallback and
fired on contended Windows runners, producing an intermittent
permission-unverified failure on unrelated pull requests. That code means "we
could not verify", which a consumer may reasonably treat as a security signal,
so emitting it because a runner was busy is a false alarm with real
consequences.

Successful runs of the affected secure-read test measure 1.930s to 5.400s, and
one Node 24 leg passed at 9.349s with roughly 651ms of margin. The contended
failures on #94 and #95 landed at 10.130s and 10.173s, which is the old bound
firing rather than a hang.

Thirty seconds is over five times the slowest observed success and about three
times the overloaded cutoff, while still terminating a genuinely wedged command
rather than letting it hang indefinitely. The deadline stays per process, since
each child is the independently wedgable unit and an overall budget would let
several slow-but-successful commands compete for one allowance and reproduce
the same false result.

Fail-closed behavior is unchanged: a real failure or timeout still yields
source "unknown", and secure reads still reject it as permission-unverified.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 compatibility 🚨 Merging this PR could break existing users, config, migrations, defaults, or upgrades. P2 Normal priority bug or improvement with limited blast radius. proof: sufficient Contributor real behavior proof is sufficient. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant