# The privileged helper
Source: https://docs.privacycommand.privacykey.org/privileged-helper

What it does, what it deliberately can't do, and how to remove it.

Some of what privacycommand does needs root. Rather than asking you to run the
whole app as root, it ships a small privileged helper and keeps its API surface
deliberately tiny.

## What needs it

| Capability | Why root |
|---|---|
| File-event monitoring | `fs_usage` requires elevated privileges |
| [Background Task Management audit](https://docs.privacycommand.privacykey.org/background-tasks) | `sfltool dumpBTM` — through the helper this avoids an admin prompt mid-audit |
| [Network kill switch](https://docs.privacycommand.privacykey.org/kill-switch) | Installing a `pf` anchor needs `pfctl` |

Everything else — the whole static report, App Store privacy labels, the
telemetry callout, batch scan, exports — runs unprivileged. **The helper is
opt-in and privacycommand is useful without it.**

## How it's installed

The helper is embedded in the app bundle and registered as a daemon through
`SMAppService`. You're asked once; after that it stays out of your way.

## How it protects itself

The helper **validates its clients by code signature on connect**. It reads its
own Team ID at startup and then requires every connecting process to satisfy an
Apple anchor plus that same Team ID, so a binary signed by anyone else cannot
talk to it — even running as your user.

> **Warning**
>
> **That check only runs when the helper has a Team ID to compare against.**
> If the helper binary is unsigned, ad-hoc signed, or signed with Xcode's
> "Sign to Run Locally" (no team), the validator has nothing to match on. It
> logs `No Team ID — accepting connection (dev mode)` and returns true for
> every caller — no anchor check either. In that state any unprivileged process
> running as you can drive the whole root API: start the file monitor, run the
> BTM dump, install and remove the kill switch.
>
> Release builds are Developer ID-signed and do carry a Team ID, so this is a
> build-from-source condition rather than a shipped one. If you build locally
> and care about the boundary, set a signing team on the helper target — see
> [Build from source](https://docs.privacycommand.privacykey.org/develop/build-from-source).

## What it will not do

The helper exposes a handful of operations and nothing else: report its version,
start and stop the file monitor, run the BTM dump, install and remove the kill
switch, and uninstall itself.

There is no general "run this command as root" path. That's the point of a
narrow helper rather than a privileged app.

## Removing it

privacycommand can uninstall the helper itself — it exposes an uninstall
operation for exactly this. Use that in preference to deleting files by hand.

To confirm it's gone:

```bash
sudo launchctl print system/org.privacykey.privacycommand.HelperTool
```

A "could not find service" response is what you want. If you removed
privacycommand without uninstalling the helper first, reinstall the app, remove
the helper properly, then remove the app.

## If it misbehaves

Symptoms and where to look are collected in
[Troubleshooting](https://docs.privacycommand.privacykey.org/troubleshooting#the-helper).
