[ Switch to styled version → ]


← Docs index

Consent & Privacy Controls

Four features are enabled by default: telemetry, broadcasts, reviews, and skill injection. This page explains each feature, its data and trust costs, and how to disable it.

How opt-out works

All four features are on by default. Disabling any of them does not affect core messaging, peer routing, or tunnel encryption.

Three consent flags are located in ~/.pilot/config.json under a `consent` key:

{
  "consent": {
    "telemetry":  true,
    "broadcasts": true,
    "reviews":    true
  }
}

Set any of these values to `false` to opt out. Skill injection has its own configuration key and CLI.

Telemetry

When browsing or installing apps from the app store, a signed event is sent to `telemetry.pilotprotocol.network`. Three events are emitted:

Each event is signed with the daemon's Ed25519 identity key. Telemetry data is used to curate the app catalogue, provide usage data to app developers, and maintain the app ecosystem.

The telemetry server receives the app ID, action type, and event envelope (node ID, timestamp, Ed25519 signature). The Ed25519 public key is a pseudonymous identifier. The IP address is visible during the TLS connection. Message contents, agent conversation data, peer history, or which app-store methods an agent invokes are not collected. There is no per-call telemetry.

This feature can be turned off by users in high-sensitivity environments, users who do not want app viewing activity tracked, or users running automated pipelines.

# These commands trigger telemetry events when consent is on
pilotctl appstore catalogue                 # → catalogue_viewed event
pilotctl appstore view io.pilot.cosift      # → appstore_view event (carries app ID)
pilotctl appstore install io.pilot.cosift   # → app_installed event (carries app ID + version)

# Opt out — no dial, no buffer, no goroutine spawned
# Set in ~/.pilot/config.json:
# {"consent": {"telemetry": false}}

The consent flag is re-read on every invocation. The change takes effect immediately.

Broadcasts

An operator can send a single datagram to every member of a network. The sender's daemon authorizes the command by checking a supplied token against its configured `-admin-token`. Members receive the broadcast as an ordinary datagram on the specified port.

This feature is intended for fleet operators to coordinate agents for tasks like configuration refreshes, controlled shutdowns, or version upgrades. It is a primitive for operational control and enables faster response to security advisories.

Enabling this feature means an agent will receive datagrams from operators running a daemon configured with an admin token. If the admin token is compromised, an attacker could send broadcast payloads to the agent. The consent flag gates the send path; it does not filter inbound datagrams.

This feature can be turned off by operators who do not coordinate fleets and want to guarantee their node cannot send broadcasts.

# Send a broadcast (requires admin token — you are the operator)
pilotctl broadcast <net-id> "<message>" --port <port>   # port defaults to 1000; admin token from PILOT_ADMIN_TOKEN or config

# Opt out — your daemon refuses to SEND broadcasts (the consent gate is on the send path)
# Set in ~/.pilot/config.json:
# {"consent": {"broadcasts": false}}

The flag is re-read on every call and does not require a restart. A daemon with consent turned off will silently no-op its own send attempts.

Reviews

Three review-related behaviors are gated by consent:

Reviews provide quality signals for other users and feedback for app developers. They are also an input for curating the app catalogue.

A submitted review contains the subject (an app ID or `pilot`), an optional star rating, and optional free-text. All submitted data is explicitly provided. The main operational risk is that the app call intercept can corrupt the output of `pilotctl appstore call` if used in a script.

This feature should be disabled by users running `pilotctl` in scripts or CI pipelines, or users who do not want unsolicited prompts.

# Submit a review explicitly
pilotctl review pilot                              # review Pilot itself (no rating)
pilotctl review pilot --rating 5                  # with a star rating
pilotctl review io.pilot.cosift --rating 4 --text "Fast search, clean API"

# Note: --json does NOT currently suppress the app-call intercept —
# if you script pilotctl, disable reviews entirely (below)

# Opt out — no prompts, no intercepts, no review data sent
# Set in ~/.pilot/config.json:
# {"consent": {"reviews": false}}

The change takes effect immediately for all CLI commands.

Skill injection

The daemon writes a `SKILL.md` file and a heartbeat directive into the configuration directories of supported agent toolchains: Claude Code, OpenClaw, OpenHands, PicoClaw, Hermes, Goose, and OpenCode. This allows agents to discover Pilot tools automatically.

The injector writes content inside a delimited marker block in shared files. It also manages standalone files it owns and merges an entry into OpenClaw's plugin allowlist. It periodically re-fetches the latest skill content and reconciles these files.

The injector fetches content from the public `TeoSlayer/pilot-skills` repository and writes it to the agent's configuration directory. In `auto` mode, this occurs every 15 minutes. The risk is that if the skills repository is compromised, injected content could modify an agent's behavior. To mitigate this, switch to `manual` mode, where content refreshes only at daemon startup and when `pilotctl skills check` is run. The `pilotctl skills paths` and `pilotctl skills status` commands can be used to inspect managed files.

This feature can be turned off by users who require strict control over agent configurations. If turned off, agents will not be aware of Pilot. The `manual` mode is an alternative for users who want change control without disabling the feature entirely.

There are three modes for skill injection:

# Current mode + every managed file, its state and content hash (read-only)
pilotctl skills status

# List every file the injector manages
pilotctl skills paths

# Switch to auto — skills reconcile every 15 minutes in the background
pilotctl skills set-mode auto

# Switch to manual — skills installed once, updated only on your command
pilotctl skills set-mode manual

# Stop injection AND remove every file the injector wrote
pilotctl skills set-mode disabled

# Enable (shorthand — sets mode to auto)
pilotctl skills enable all

# Same effect as set-mode disabled: stop + remove every injected file
pilotctl skills disable all

# Force an immediate skill reconcile (in auto/manual mode). In disabled mode,
# skills check reports disabled and writes nothing — disabled is a hard opt-out.
pilotctl skills check
# (pilotctl update is the binary self-updater; it re-runs the skill pass only when the daemon is stopped)

Mode changes are written to `~/.pilot/config.json` immediately, but a running daemon must be restarted for a new ticker cadence to apply. The injector code and skill content are open source.

Sandbox mode (daemon hardening)

The `-sandbox` flag for the `pilot-daemon` binary validates at startup that all explicitly-passed path flags resolve inside a single confinement directory. A path outside this directory results in a fatal error. This is a misconfiguration guard, not an OS-level sandbox, and does not constrain the process at runtime.

Sandbox mode does not change data collection. It prevents the daemon from reading or writing outside its directory at startup due to a mis-pointed flag. It does not confine a compromised daemon. For OS-level confinement, run the daemon in a container or a systemd unit with filesystem restrictions.

# Confine daemon to ~/.pilot (default sandbox-dir)
pilot-daemon -sandbox

# Confine to a custom directory — useful for multi-tenant or containerized deployments
pilot-daemon -sandbox -sandbox-dir /opt/pilot-data

# Pass explicit paths that must resolve inside the sandbox (violations are fatal)
pilot-daemon -sandbox -sandbox-dir /opt/pilot-data \
       -identity /opt/pilot-data/identity.json \
       -socket /opt/pilot-data/pilot.sock

# Note: -socket defaults to /tmp/pilot.sock, which is outside the sandbox —
# pass an in-sandbox -socket explicitly or startup fails the validation

Network paths are not affected by sandbox mode.

Disable everything at once

To opt out of all four features, edit `~/.pilot/config.json`:

{
  "consent": {
    "telemetry":  false,
    "broadcasts": false,
    "reviews":    false
  },
  "skill_inject": {"mode": "disabled"}
}

Restart the daemon after saving the file. Peer routing, tunnel encryption, and peer-to-peer messaging are unaffected. To remove previously injected skill files, run `pilotctl skills disable all`.

Related