Skip to content

feat(safety): opt-out safety layer (allowlist, PowerShell policy, confirmations, audit log, kill switch) - #528

Open
FaberVi wants to merge 2 commits into
CursorTouch:mainfrom
FaberVi:pr/safety-1-core
Open

FaberVi wants to merge 2 commits into
CursorTouch:mainfrom
FaberVi:pr/safety-1-core

Conversation

@FaberVi

@FaberVi FaberVi commented Oct 31, 2026

Copy link
Copy Markdown

Summary

Adds src/windows_mcp/safety/, a FastMCP middleware (SafetyGate) that runs before the desktop-control gate on every tool call, configured under [safety.*] in config.toml. Documented in docs/safety.md.

  • App/process allowlist for input tools, App launch/switch/resize and Process kill; unknown targets are refused.
  • PowerShell off by default; allowlist mode accepts one listed cmdlet and rejects chaining, substitution, redirection and encoded commands.
  • Native Yes/No confirmation dialog (default No, timeout = deny) before risky actions (process kill, file delete/move/overwrite, registry writes, installers, UAC targets).
  • JSONL audit log with redaction and optional screenshot.
  • Kill switch via flag file or global hotkey.
  • HTTP/SSE require a bearer token and refuse non-loopback binds unless explicitly allowed.
  • write_config round-trips [safety]; existing tests are adjusted to the new defaults.

Motivation

The server drives the real desktop on behalf of an AI agent. Today nothing stops a prompt-injected agent from killing processes, deleting files or running arbitrary PowerShell. This PR adds guard rails that a user can relax, instead of none.

Note for reviewers

This changes defaults (PowerShell disabled, allowlist enforced, auth required on HTTP). If you prefer, the defaults can be flipped to opt-in in a follow-up without changing the code structure. Windows calls are isolated in safety/win32.py, so the logic is unit-tested on Linux with a fake platform.

First PR of a stacked safety series (1 -> 2 -> 3 -> 4); the follow-ups depend on this one.

Testing

Testing: Linux run with Windows-only modules stubbed (pytest, Python 3.14). New tests test_safety_config/gate/policy/powershell pass (+95 tests). No new failures or collection errors compared with upstream main 7fd39b4 (on main the Linux harness has 6 known failures and 75 modules that cannot be collected without Windows). Also tested on a real Windows 11 desktop (LegionVins) with the Windows-only test modules and manual end-to-end runs.

…ions, audit log, kill switch

Add a SafetyGate FastMCP middleware (src/windows_mcp/safety/) that runs before the
desktop-control gate on every tool call. All protections are enabled by default and
configured under [safety.*] in config.toml:

- App/process allowlist for input tools (window under each point or foreground
  window), App launch/switch/resize and Process kill; unknown targets fail closed.
- PowerShell disabled by default; "allowlist" mode accepts a single listed cmdlet and
  rejects chaining, substitution, redirection, quoting and encoded/nested commands.
- Native MessageBoxTimeoutW confirmation (default No, timeout = deny) before process
  kill, closing/deleting shortcuts, FileSystem delete/move/overwrite, Registry
  set/delete, installer launches, UAC targets and risky cmdlets.
- JSONL audit log of every call and decision, with redaction and optional screenshot.
- Kill switch via flag file or latching global hotkey.
- HTTP/SSE transports require a bearer token (server.require_auth) and refuse
  non-loopback binds unless server.allow_remote_bind is set.

write_config now round-trips the [safety] section. Windows calls are isolated in
safety/win32.py; unit tests use a fake platform and run on Linux. Docs: docs/safety.md.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant