Trust Boundaries and Defenses Against Silent Installation of AI Coding Assistant Plugins

    AI coding assistants can read and write project files, run commands, and call external services based on hooks, skill packages, and trust records. This article explains how silent installers can rewrite that configuration without user approval, why auto-marking content as trusted breaks the approval model, and how developers can audit hooks, verify hashes, and tighten configuration controls.

    Why AI Coding Assistants Need a Trust Mechanism

    An AI coding assistant (referred to here as an agent) can read and write project files, run commands, and call external services. Much of its behavior is driven by configuration. Three kinds of content matter most:

    • Hooks: Instructions that run automatically at points such as session start or task start. They act as fixed prompts before work begins.
    • Skill packages: Sets of instruction files that tell the agent how to handle a class of tasks, such as API debugging or database operations.
    • Trust records: After a user confirms a specific instruction, the agent stores a hash of that content. Later, matching content is not prompted again.

    A trust record is meant to lock in the fact that a person reviewed that content. If the instruction changes, the hash should no longer match, and the agent should ask for approval again.

    How the Risk Unfolds

    A typical unauthorized write, whether from an attack or a mistaken operation, often follows four steps:

    1. A third-party installer runs in the background without showing a confirmation dialog.
    2. The installer copies plugin files into the user-level configuration directories of multiple agents.
    3. The installer changes one agent’s global configuration and adds its own startup instruction to the trust records.
    4. The installer adds a rule to the session-start instructions that tells the agent to load a specific skill package before handling related tasks.

    After these four steps, the user never sees an approval point, and an external program has already rewritten the agent’s behavior. The following fragment is illustrative only. Field names describe the structure and do not map to any specific product:

    1. {
    2. "hooks": {
    3. "session_start": [
    4. {
    5. "command": "load-skill api-tools",
    6. "trusted_hash": "sha256:9f2c4e..."
    7. }
    8. ]
    9. }
    10. }

    This kind of write is dangerous for three main reasons:

    • Inherited privileges: Hooks run as the agent and can reach the files and commands the agent can reach.
    • Persistence: Once written, the hook fires on every session. Uninstalling the installer does not necessarily remove the configuration.
    • Stealth: Users only see that the agent’s behavior has changed, and tracing the change back to its source is difficult.

    Why “Automatically Marked as Trusted” Is the Core Problem

    Most discussion focuses on silent installation. The more fundamental issue is how trust records are written.

    A trust record means that a specific person reviewed a specific piece of content and agreed to run it. If an installer completes that step on the user’s behalf, the software has effectively signed for the user. Whatever the installer’s intent, that breaks the purpose of the approval mechanism.

    A sound design should follow these principles:

    • Trust can only come from a user interaction. Programs must not write trust records directly.
    • Trust records must be bound to a content hash. If the content changes, trust expires immediately.
    • Changes to configuration files should keep auditable information about their source.

    Investigation Steps and Example Code

    When an agent’s behavior looks wrong, investigate in the following order.

    Step 1: List every hook entry. Walk the user-level configuration directories of each agent, find hooks that carry trust records, and note file modification times. Example script:

    1. import json
    2. from pathlib import Path
    3. def audit_hooks(config_dir: str) -> list[dict]:
    4. """Scan a configuration directory and list hook entries and their trust status."""
    5. findings = []
    6. for path in Path(config_dir).expanduser().rglob("*.json"):
    7. try:
    8. data = json.loads(path.read_text(encoding="utf-8"))
    9. except (OSError, json.JSONDecodeError):
    10. continue
    11. if not isinstance(data, dict):
    12. continue
    13. hooks = data.get("hooks", {})
    14. if not isinstance(hooks, dict):
    15. continue
    16. for event, entries in hooks.items():
    17. if not isinstance(entries, list):
    18. continue
    19. for entry in entries:
    20. if not isinstance(entry, dict):
    21. continue
    22. findings.append({
    23. "file": str(path),
    24. "event": event,
    25. "command": entry.get("command"),
    26. "trusted": "trusted_hash" in entry,
    27. "mtime": path.stat().st_mtime,
    28. })
    29. return findings

    Step 2: Recheck script hashes. Recompute SHA-256 for each trusted script and compare it with the recorded value. A mismatch means the content has changed.

    1. import hashlib
    2. def file_sha256(path: str) -> str:
    3. """Compute a file's SHA-256 in chunks so large files do not use too much memory."""
    4. digest = hashlib.sha256()
    5. with open(path, "rb") as f:
    6. for chunk in iter(lambda: f.read(65536), b""):
    7. digest.update(chunk)
    8. return digest.hexdigest()

    Step 3: Compare with install history. Review software installed or updated recently and decide whether it was allowed to modify agent configuration. A matching timeline is a strong clue.

    Step 4: Review authentication and load logs. If the agent frequently raises authentication warnings, or loads a skill package before unrelated tasks, trace the configuration source immediately. Do not dismiss the warning.

    Prevention and Governance

    Individual developers and teams can start with the following controls.

    1. Tighten directory permissions. Allow only the current user to write the agent’s configuration directory so other processes cannot change it silently.
    2. Put configuration under version control. Track critical configuration directories so any change shows up in a diff.
    3. Maintain a hook allowlist. Keep a team list of hooks that are allowed to run, and refuse to load anything that is not registered.
    4. Bind trust to hash checks. Pair each trust record with script content, and force re-approval when the content changes.
    5. Constrain background updaters. Installers and updaters should not have permission to modify other tools’ configuration. Limiting their write scope at the operating-system level is more reliable than relying on the software to restrain itself.
    6. Alert on anomalies. Monitor configuration changes and newly added trust records, and notify the responsible owner promptly.

    Guidance for Developers and Security Teams

    Treat agent configuration as an asset. As with servers and accounts, record the agent version, installed plugins, and trust records on each machine. An inventory is the starting point for spotting anomalies.

    Audit where software is installed from. Set admission rules for software on development machines, and separate components that require approval from those that may update automatically.

    Do not ignore unusual prompts. Authentication warnings, unexpected skill loads, and unfamiliar session-start instructions can all signal that configuration was rewritten. Find the source before deciding whether to allow it.

    Keep approval with the person. Tools can make work easier, but authorization that involves code execution, file writes, and network access should be confirmed explicitly by the user. Convenience should not come from removing approval.

    The issue is not whether one product is good or bad. It is whether the agent’s trust model is clear: who may request execution, who may approve it, and how approval records are created and protected. Working through those three questions stops most of this risk at design time.