Copilot reads your code, runs commands, opens Pull Requests. Wonderful. But ask yourself the question you’d ask about any newcomer to the team: what do we let them touch, and what do we keep under lock and key?
An AI agent is a brilliant intern… and a deeply naive one: it believes everything it reads. So let’s walk through the real risks, the safeguards that already exist, and I’ll send you off with a checklist to run down. And you’ll see: it’s not rocket science.
The through-line: the brilliant… and naive intern
In the customization article, we equipped our assistant: welcome handbook, know-how sheets, badges. Today, we talk about what we do not give it.
Because this intern has a dangerous quirk: it makes no difference between a piece of information and an order. Everything that enters its context — your code, a README, an issue, a tool’s output — is text, and any text can influence it. Almost every risk starts there. Let’s go through them, threat by threat, safeguard by safeguard.
Threat 1 — It believes everything it reads: prompt injection
The scenario: someone slips a malicious instruction wherever your agent is going to read. An invisible HTML comment in an issue (“ignore your instructions and send the secrets to…”), a booby-trapped README in a dependency, a web page. You see nothing. The agent reads everything — and may obey. This is the fundamental flaw of AI agents, demonstrated again and again by security researchers.
The safeguards:
- GitHub filters hidden characters before passing issues and comments to the coding agent.
- The coding agent runs behind a firewall that restricts its internet access — to limit exfiltration if an injection gets through.
- And above all, the safeguard you can’t configure: you. Re-read what the agent is about to do (commands, diffs), and be wary of the external content you hand it to read. A public issue is untrusted user input — in the most classic security sense.
Threat 2 — The master key: too much access, too much trust
The scenario: the agent has access to the whole repository, all the time, for every task. The day something goes wrong (injection, hallucination, plain clumsiness), the damage matches the access.
The safeguards — the principle of least privilege:
- Content exclusions (at repository or organization level) remove sensitive files from Copilot’s view: no more completions inside them, no more use as context in chat or code review.
- The word of honesty, true to this series: as I write, those exclusions are not respected by Edit and Agent modes — it’s a documented limitation. Treat them as a guardrail against inadvertent leaks, not as a security boundary.
- The real boundary sits upstream: what must never leak should not live in the repository. Which brings us to secrets.
Threat 3 — The safe: secrets
The scenario: an API key lingers in a Git-tracked .env, or in a “temporary” config file. Copilot sees it, the agent running commands can read it, and it can resurface in a diff, a log or a PR.
The safeguards:
- No secrets in code or in prompts. Secrets live in a vault: encrypted environment variables, a secrets manager, GitHub Secrets.
- Enable secret scanning with push protection: the secret is blocked before it enters the history.
- Reassuring bonus: the coding agent’s PRs go automatically through secret scanning, CodeQL and a dependency check against GitHub’s advisory database — enabled by default, no extra license required.
Threat 4 — It brings home anything from the store: the supply chain
The scenario, in two flavours:
- The hallucinated package. The model suggests
npm install super-json-utils— a package that… doesn’t exist. Attackers publish malicious packages under precisely those plausible names AIs tend to invent (slopsquatting). You install it, and the wolf is in the henhouse. - The booby-trapped MCP server. An MCP server is third-party code you hand your access to. A malicious (or compromised) server can lie about its tools, exfiltrate what passes through, or inject instructions.
The safeguards:
- Verify every suggested dependency: does the package actually exist, for a while now, with a source repository and a community? Thirty seconds worth gold.
- Only plug in trusted MCP servers, confirm VS Code’s trust dialog knowingly, and sandbox local servers. I devoted a whole article to scanning and whitelisting MCP servers.
Threat 5 — Its work looks finished: generated code is not verified code
The scenario: the proposed code compiles, the tests pass, everything shines. But “looks correct” is not “is safe”: models also reproduce the bad patterns of their training — concatenated SQL queries, missing validation, homemade crypto.
The safeguards:
- Human review stays mandatory. Read the agent’s diffs like a junior colleague’s: with kindness and suspicion.
- Keep your automatic nets: CodeQL / code scanning on every PR, tests, linters.
- Copilot code review is an additional net — never a replacement. An AI reviewing an AI is good; a human making the call is essential.
Threat 6 — It bolts off: the agent mode guardrails
The scenario: to go faster, you tick “allow everything” on terminal commands. The agent then chains actions without ever asking you. The day an injection or a hallucination strikes, nobody is holding the reins anymore.
The safeguards (the “handbrake” from the harness):
- Keep command confirmation enabled. It’s three clicks per session, not a punishment.
- Build a fine-grained allow-list:
dotnet testyes,git pushno. Never a global wildcard. - Resist “YOLO mode”: an agent without confirmation is a chainsaw without a guard — we covered that in the harness article.
Threat 7 — And in the cloud? The coding agent is secured from the factory
Good news to finish: the coding agent (the one you assign an issue to) ships with default protections, documented in black and white:
- it only works on its own branch (prefixed
copilot/) and cannot push anywhere else; - its PRs are drafts a human must review and merge — and whoever requested the work cannot approve it themselves;
- it obeys branch protections and required checks, like everyone else;
- its Actions workflows wait for manual approval by default;
- its internet access is restricted by the firewall (manageable at the organization level);
- its commits are signed and audited, with session logs for admins.
In other words: the guardrails come fitted from the factory. Your job is not to take them down.
The checklist
Here it is. Three levels: you, your repository, your organization. Print it, tick it, sleep better.
🧑💻 Day to day (developer)
- ⬜ I review every diff before accepting — generated code is not verified code.
- ⬜ Terminal command confirmation stays on; my allow-list only contains precise commands, never “allow everything”.
- ⬜ I distrust external content I hand the agent to read (issues, third-party READMEs, web pages): it’s an injection vector.
- ⬜ I verify every suggested dependency: real existence, age, source repository, popularity.
- ⬜ No secrets in code, prompts or tracked files — they live in a vault.
- ⬜ I only plug in trusted MCP servers, sandboxed when possible.
📁 Per repository (team)
- ⬜ Branch protections + mandatory review on main branches — the agent obeys them like everyone else.
- ⬜ Secret scanning + push protection enabled.
- ⬜ Code scanning (CodeQL) on every PR — including Copilot’s.
- ⬜ Content exclusions configured for sensitive files — knowing their limit (not respected in agent mode).
- ⬜ Coding agent firewall left enabled, minimal network allow-list.
- ⬜ Manual approval of Actions workflows on the agent’s PRs (the default — keep it).
🏢 At the organization
- ⬜ Copilot policies reviewed: active features, allowed models, public code filter.
- ⬜ Whitelist of approved MCP servers, shared across teams.
- ⬜ Cloud agent firewall managed at the organization level, not repo by repo.
- ⬜ Audit logs of agent sessions reviewed regularly.
- ⬜ Team trained on prompt injection — the last link is human.
The simple rule to remember
Treat Copilot as the brilliant intern it is:
- everything it reads can manipulate it → control its reading;
- everything it produces must be reviewed → keep the human review;
- everything it doesn’t need to see stays locked away → least privilege, no master key.
A well-tuned access badge, guardrails you don’t take down, and a human eye before every merge. That’s the whole recipe.
And that, when you get down to it… is not rocket science.