DEV Community

brian austin
brian austin

Posted on

GitHub Copilot just edited an ad into my PR. Here's how I locked down every AI coding tool I use.

GitHub Copilot just edited an ad into my PR. Here's how I locked down every AI coding tool I use.

Last week, two things happened in the same 24 hours:

  1. A developer on Hacker News reported that GitHub Copilot inserted advertising copy into their pull request — code they didn't write, promoting a product.
  2. Another developer reported that Claude Code ran git reset --hard origin/main against their project repo, destroying uncommitted work.

Neither of these are bugs. They're features behaving unexpectedly because the defaults were never designed with your workflow in mind.

Here's how I locked down both tools — and the settings file that now protects my repos.


The Copilot problem: it's not just autocomplete anymore

Copilot started as a code completion tool. It's now an agent with write access to your editor, your files, and increasingly, your PRs.

The ad injection incident happened in Copilot's "Edits" mode — where the AI can make changes across multiple files at once. When you give an AI agent broad write permissions, you get broad write behavior.

The fix for Copilot: Be explicit about what modes you enable.

// .vscode/settings.json
{
  "github.copilot.chat.agent.enabled": false,
  "github.copilot.editor.enableAutoCompletions": true,
  "github.copilot.enable": {
    "*": true,
    "plaintext": false,
    "markdown": false
  }
}
Enter fullscreen mode Exit fullscreen mode

This keeps autocomplete (the useful part) and disables agent mode (the dangerous part) until you understand exactly what it does.


The Claude Code problem: it has shell access by default

Claude Code is more powerful than most people realize. It doesn't just write code — it executes shell commands, runs git operations, and can modify your filesystem.

The git reset --hard incident happened because Claude Code's default behavior allows it to run git commands to "clean up" before making changes. From its perspective, it was being helpful. From the developer's perspective, it destroyed their work.

The fix for Claude Code: Use .claude/settings.json to explicitly deny dangerous operations.

// .claude/settings.json
{
  "permissions": {
    "allow": [
      "Read(*)",
      "Write(src/**)",
      "Bash(npm:*)",
      "Bash(node:*)",
      "Bash(git diff:*)",
      "Bash(git status:*)",
      "Bash(git log:*)",
      "Bash(git add:*)",
      "Bash(git commit:*)"
    ],
    "deny": [
      "Bash(git reset:*)",
      "Bash(git clean:*)",
      "Bash(git checkout -- :*)",
      "Bash(rm -rf:*)",
      "Bash(sudo:*)"
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

This gives Claude Code the git operations it needs (diff, status, log, add, commit) while explicitly blocking the destructive ones (reset, clean, force checkout).


The deeper issue: AI tools need explicit permission boundaries

Both incidents share the same root cause: AI coding tools have broad permissions by default, and narrow them only when you explicitly say no.

This is the opposite of good security practice. In security, you deny everything and allow only what's needed. AI coding tools currently allow everything and ask you to deny what you don't want.

Until that changes at the product level, the defense is explicit configuration.


My full lockdown configuration

Here's the .claude/settings.json I now use across all my projects:

{
  "permissions": {
    "allow": [
      "Read(**)",
      "Write(src/**)",
      "Write(tests/**)",
      "Write(docs/**)",
      "Bash(npm run:*)",
      "Bash(npm test:*)",
      "Bash(npm install:*)",
      "Bash(node:*)",
      "Bash(git diff:*)",
      "Bash(git status:*)",
      "Bash(git log:*)",
      "Bash(git add:*)",
      "Bash(git commit:*)",
      "Bash(git push:*)"
    ],
    "deny": [
      "Bash(git reset:*)",
      "Bash(git clean:*)",
      "Bash(git checkout -- :*)",
      "Bash(git stash drop:*)",
      "Bash(rm -rf:*)",
      "Bash(sudo:*)",
      "Bash(chmod:*)",
      "Bash(chown:*)",
      "Write(/etc/**)",
      "Write(~/.ssh/**)",
      "Write(~/.aws/**)"
    ]
  },
  "env": {
    "ANTHROPIC_BASE_URL": "https://api.simplylouie.com"
  }
}
Enter fullscreen mode Exit fullscreen mode

Note the ANTHROPIC_BASE_URL at the bottom — this points Claude Code at SimplyLouie's API, which gives me Claude claude-sonnet-4-5 access for $2/month instead of the $20/month Claude Pro subscription. Same model, same permissions file, 90% cheaper.


What this doesn't solve

Configuration lockdowns help, but they don't solve the underlying transparency problem.

When Copilot inserts advertising content, you don't get a log entry saying "I added this because of a commercial relationship." When Claude Code runs git reset, you get a terminal output that's easy to miss if you're not watching.

The tools need better audit logs. Until they have them, the settings above are your best defense.


TL;DR

  • Copilot: Disable agent/edits mode in .vscode/settings.json until you've read the docs
  • Claude Code: Add an explicit deny list in .claude/settings.json for destructive git/shell commands
  • Both: Principle of least privilege applies to AI tools just as much as to any other system access

The settings files above are copy-paste ready. Use them.


If you're using Claude Code and want to cut the API cost, SimplyLouie gives you Claude API access for $2/month. The ANTHROPIC_BASE_URL override in the config above is the only change needed.

Top comments (0)