Agent Configuration Over Prompts: Security Risks in AI Coding Assistants
This article explains why an AI coding assistant may follow project specification files in its working directory even when the system prompt forbids risky actions. It walks through a five-step attack chain, from an untrusted file landing in a user-writable folder to outbound connections and persistence. It then describes five detection controls for testing and security teams: entry control, configuration integrity, prompt and execution layering, egress allowlisting, and rotation upon detection.
The Core Problem: Not a Vendor Patch, but How the Agent Works
Testers often assume that if a prompt says “do not do X,” the system will not do X. For AI coding assistants, this assumption often fails. The assistant is designed to read the project specification files in the current working directory, treat the engineering conventions in them as authoritative instructions, and act on them. That includes modifying its global configuration, installing dependencies, and making network requests. When a specification file conflicts with the system prompt, the in-directory specification usually fits the current task context more closely, so the execution layer tends to follow it first.
This produces an apparent contradiction. The higher-level prompt says “do not perform dangerous operations,” while the configuration or specification file says “execution is welcome, install dependencies following the local process.” The assistant has not jailbroken. It is working as designed. Consider a browser rendering a phishing login page. The browser did its job. The problem lies in the page content, not in whether the browser engine is missing a patch. Likewise, an assistant that follows the specification in its folder is fulfilling its design.
For testing and security teams, this means they cannot rely on upstream model or assistant vendors shipping hotfixes. They must write the checks into their own gates: entry control, configuration integrity, separation of prompts and execution, egress allowlisting, and rotation upon detection.
How the Risk Plays Out: Five Detectable Actions
A real attack chain typically includes five actions. Each step corresponds to a checkpoint.
Step 1: An untrusted source writes a specification file into a user-writable directory. The browser download folder is one of the few locations a web page can write to on its own, and users rarely review what lands there. Operating systems already block automatic execution of downloaded executables. However, project specifications, documentation, and dependency manifests are not executables, so traditional executable guardrails do not apply to them. The file name can disguise it as “Engineering Standards” or “Local Development Conventions.” Its length can make it look like a thorough document, burying the dangerous installation and configuration instructions in the second half.
Step 2: The user starts the assistant in that directory. Download folders, extraction folders, and temporary clone directories are common working areas. An assistant session may also open a real browser to “verify the documentation,” which further widens the trust radius for untrusted content. The habit itself is not a vulnerability. However, it turns a file that silently appears into a file that is treated as a project specification and executed.
Step 3: The assistant reads the specification and rewrites global configuration. Typical consequences include changes to global hooks, default tool permissions, auto-approval policies, package source addresses, proxy settings, or credential lookup paths. Once global configuration is changed, the behavior may stay compromised even after the user leaves the original directory.
Step 4: Dependencies are installed or scripts are executed according to the specification. Installation can pull malicious packages, run package lifecycle scripts, and write user-level toolchains. A prompt-level “do not execute” has no binding force on this step unless it is tied to the tool-call policy.
Step 5: Outbound connections and persistence. Malicious logic may report environment information, fetch a second-stage payload, or write a backdoor into user-level startup items. At this point, prompt compliance is already too late to matter.
Five Executable Detection Controls
1. Entry: Who Can Place a Specification File in the Workspace
The goal is not to prohibit downloads. The goal is to prevent unreviewed specification files from automatically becoming authoritative sources for the assistant. Recommendations:
- When the assistant starts from a download, temporary, or extraction directory, default to a read-only specification mode. Code may be read, but specifications in the directory may not be used to modify global configuration.
- Specification files must come from a controlled repository path, or be hash-registered before they take effect.
- Same-named specification files delivered through web pages, email attachments, or instant messages are untrusted. They require manual confirmation or policy blocking.
Test cases should cover this scenario: a specification file is only placed in the download directory, with no click or confirmation. Is it still loaded when the assistant starts?
2. Configuration Integrity: Whether Directory Files Have Rewritten Global State
Treat the assistant’s global configuration as a critical asset, and establish a baseline with drift detection. Monitored items include auto-approval switches, tool allowlists, package sources and mirrors, hook script paths, environment variable injection, and credential search scope.
Illustrative check logic (language-neutral; adapt it to the actual configuration format):
# Pseudocode: configuration drift checkbaseline := load_signed_baseline()current := load_agent_global_config()for each key in sensitive_keys:if current[key] != baseline[key]:alert("drift", key, current[key])fail_gate()if current.package_source not in allowlist:alert("untrusted_source")fail_gate()if current.hooks.origin == "workspace_untrusted":alert("hook_from_workspace")fail_gate()
Gates should run both in the pipeline and in local pre-commit hooks. On drift, the check should fail rather than only alert while the build continues.
3. Prompt and Execution Layering: No “Compliant Text, Unauthorized Tools”
Split the policy into three layers, and assert each one during testing:
- Declaration layer: system prompts, safety statements, and refusal wording.
- Policy layer: whether tool calls may write global configuration, install dependencies, or make arbitrary network connections.
- Execution layer: actual file writes, process launches, and network connections.
The correct assertion is this: even if the declaration layer says “do not execute,” the execution layer can still run the action if the policy layer permits the corresponding tools. Tests should construct adversarial samples in which the declarations forbid an action and the specifications encourage it. Then verify that the policy layer rejects the tool calls. Do not only verify whether the model says it will not do the action.
The layering principle is that directory specifications may only influence project-local suggestions. They cannot elevate permissions. Permission elevation must come from an independent policy engine that defaults to deny.
4. Egress Allowlisting: Installation and Outbound Connections Must Be Enumerable
Dependency installation, script execution, and callback addresses must go through an allowlist. This includes:
- Package sources limited to the internal enterprise mirror.
- Package lifecycle scripts disabled by default, or allowed only for signed packages.
- Assistant tool network egress limited to documentation sites, internal APIs, and build caches.
- DNS and IP deviations from the baseline blocked.
Tests should record the full tool-call trace. Check whether a “follow the specification to install” action produced domains outside the baseline, or wrote user-level startup configuration. A test without a trace does not really test anything.
5. Rotation Upon Detection: Treat the Incident as a Key Leak
Once a specification is confirmed to have been executed, or global configuration is confirmed to have been altered, the response should resemble a credential leak response. Starting a new chat is not enough:
- Immediately revoke tokens that may have been read, including mirror credentials and repository tokens.
- Roll global configuration back to the signed baseline.
- Isolate the affected workspace and keep a forensic copy.
- Rotate the package caches and hooks on the development machine.
- Review outbound connections and commits in the same time window.
Write “rotation upon detection” as a runbook, and time it during drills so it does not remain only on paper.
Control Matrix
| Control Domain | Detection Question | Pass Criteria | Action on Failure |
|---|---|---|---|
| Entry | Does a specification file in an untrusted directory take effect automatically? | Not in effect by default, or explicit approval required | Block startup or enforce read-only mode |
| Integrity | Has global configuration changed from the baseline? | Sensitive keys match the baseline and are signed | Fail the gate and alert |
| Layering | Can tools still be invoked when prompts forbid it? | The policy layer rejects configuration writes and installs | Disable the corresponding tools |
| Egress | Are installations and network calls limited to the allowlist? | No out-of-baseline domains or scripts | Block outbound connections |
| Response | Are credentials rotated and configuration rolled back after detection? | Time-bound rotation and rollback evidence | Escalate to a security incident |
Recommendations for Testing Teams
Turn these controls into automated test cases rather than one-off manual reproductions. The minimum set includes: starting from an untrusted directory, specification-prompt conflicts, global configuration writes, dependency installation, abnormal outbound connections, and baseline rollback. Each test case must check both what the model said and what the system did.
For object storage, container platforms, log services, and monitoring and alerting on a cloud platform, assistant audit logs, config
