PROWEB

In an era of rapidly evolving AI agents, don't forget about security

Keys to CI, databases and clouds quietly pile up in agents' plain-text configs, and AGENTS.md instructions are not a security boundary. How to keep secrets in the system vault, run MCP servers through wrappers, and restrict agents with system-level permissions.

Muza Neuronova
7 minutes reading
In an era of rapidly evolving AI agents, don't forget about security

The zoo grows unnoticed

AI agents have become a firm fixture in software development: they edit code, work with CI/CD, read task trackers, talk to databases and clouds. Under the hood this works through MCP servers — and every such server needs a token. Repositories, Docker registries, a CMS, databases, monitors, secret managers. Six months after "let me just try an agent," you have a dozen keys neatly laid out in configs, in plain text.

Worse, these configs duplicate each other. The same token sits in the CLI agent's settings and in the editor's settings, in a project's .mcp.json and in a global config. Rotate a key — remember to visit four places. Leak one file — consider everything leaked.

You don't need an explanation of what a plaintext key in a file leads to: config backups and syncing, an accidental commit, screen sharing, any process on the machine with read access. A secret stored in plain text will eventually escape.

Secrets go to the system vault, launching goes through a wrapper

The cure is system tooling. macOS has Keychain, Linux has gnome-keyring with secret-tool, Windows has Credential Manager. The principle is the same: the key lives in the OS's protected storage, and the MCP server is launched not directly, but through a tiny shell wrapper that fetches the key at startup.

# store the key (the value is prompted for interactively)
security add-generic-password -a "$USER" -s mcp-my-service-token -w

# wrapper ~/mcp/bin/mcp-my-service.sh
#!/bin/bash
set -euo pipefail
TOKEN="$(security find-generic-password -a "$USER" -s mcp-my-service-token -w)" || {
  echo "mcp-my-service-token is missing from the keychain" >&2; exit 1
}
export MY_SERVICE_TOKEN="$TOKEN"
export MY_SERVICE_URL="https://example.com"
exec node "$HOME/mcp/my-service/dist/index.js"

The agent config is left with just the wrapper path — not a single secret:

"my-service": {
  "type": "stdio",
  "command": "/Users/you/mcp/bin/mcp-my-service.sh",
  "args": []
}

What this buys you: configs can be freely backed up, synced between machines, and shown at a conference; rotating a key is one command with the -U flag plus an editor restart; and a leaked config file is no longer a leak.

Two caveats from practice. First: prefer MCP servers that can read the secret from an environment variable — if a server takes the key only as a command-line argument, it will be visible in the process list. Second: an agent with terminal access can, in theory, request the key from the vault itself — the keychain protects your files from being carried away, but it doesn't replace the next section. And yes, the first launch from a new app will ask for access to the keychain item — that's normal, click "Always Allow" once.

AGENTS.md is a request, not a boundary

The second common illusion is treating AGENTS.md / CLAUDE.md instruction files and the system prompt as a "security system". We write "don't read the keys file", "don't touch production" — and consider the job done.

Such a file is just text in the same context as everything else the model sees. It competes for attention with repository contents, tasks, issues, and pages the agent opened with its browser tool. That data can carry a prompt injection — and then someone else's instruction "accidentally" outweighs yours. Plus, models make mistakes and hallucinate with no malicious intent at all. An instruction "don't do X" is a request: it's usually followed, but nobody promised anything.

The conclusion is simple: everything that truly matters must be protected so the agent cannot cause harm even if it wants to — with permissions at the system level, not with words in a prompt.

Restrictions at the system level

What that means in practice:

  • Least-privilege tokens. Give the agent its own token with a narrow role, not your personal admin one. A CI token scoped to the needed repositories only, database access scoped to the needed schema only, a secret-manager policy scoped to the needed folder. Then even "grabbed it and leaked it" yields nothing serious.
  • Read-only by default. Many MCP servers have write flags and path allowlists. Keep writing off, enable it deliberately and per task: "write actions" get turned on for a specific job and off afterwards.
  • Servers on point. Don't keep every MCP enabled "just in case" in every project. If an agent doesn't need production monitoring for a CSS task — switch that server off in that project.
  • The agent's own modes. Fully autonomous modes and bypassing confirmations belong only in isolated environments. On a working machine — confirmation of dangerous commands and diff review before applying.
  • The OS level. Secrets in the system vault (see above); for especially sensitive runs — a separate account or a container that physically has no access to anything extra.
  • Cheap rotation. If changing a key means an hour of edits across five configs, rotation will be postponed forever. When a key lives in one place and changes with one command, rotation stops being an event and becomes a routine.

Checklist

  • No secrets in agent configs or repositories — only in the system secret store
  • MCP servers launch through wrappers; the secret is fetched at startup
  • Agents get their own least-privilege tokens, not personal ones
  • Writes and dangerous actions are off by default, enabled deliberately
  • AGENTS.md describes the rules — but everything important is backed by system-level permissions
  • Key rotation costs less than a cup of coffee — otherwise it won't happen

In short

AI agents are a great amplifier, but they operate with exactly the rights you granted them — often silently and in advance. Keep secrets in the system vault and hand them out through wrappers, limit servers and tokens to the bare minimum, and treat AGENTS.md as work culture rather than a security boundary. The boundary is access permissions that can't be bypassed "even if it really wants to".

Share

Trust professionals to develop your project.