Gitfence

Protecting Source Code from AI Agents and Contractors

How to protect source code when AI coding agents and contractors work in your repo, what ignore files and NDAs really do, and what limits access.

Gitfence team7 min read

Short answer: The only reliable way to keep code away from an AI coding agent or a contractor is to not give it to them. Ignore files, prompts and policies reduce what an agent reads by default, but anything in its working copy can be read by a shell command. Protect the parts that matter by limiting what's in the clone, keep secrets out of the repository entirely, and treat agreements and monitoring as additional layers, not the boundary.

This article covers the risks that are specific to agents and contractors, the controls teams usually reach for, and how far each one goes.

What you're actually protecting against

It helps to separate four risks, because the controls differ:

  1. Disclosure of core IP. Your pricing logic, ranking model, detection rules or proprietary algorithm ends up somewhere you didn't intend: a contractor's next client, a personal repo, a pasted prompt.
  2. Secrets. API keys, credentials and customer data in .env files, fixtures or config.
  3. Unreviewed changes. An agent or contractor modifies code it shouldn't, such as CI workflows or infrastructure.
  4. Exfiltration through tooling. A test, build script or CI job that reads protected files and sends them out.

For AI agents there's a fifth: prompt injection. An agent that reads untrusted text (an issue, a dependency's README, a web page) can be steered into reading and sending files it was never asked about. Whatever the agent can read, a successful injection can read too.

Controls teams try first, and their limits

Editor and agent ignore files

Most tools have a way to exclude files:

  • Cursor's .cursorignore blocks files from Agent, Tab, Inline Edit and @ mentions. Its documentation also says: "The terminal and MCP server tools used by Agent cannot block access to code governed by .cursorignore," and that "complete protection isn't guaranteed due to LLM unpredictability."
  • GitHub Copilot content exclusion tells Copilot to ignore paths. The docs note that Copilot CLI and Agent mode in Copilot Chat in IDEs don't support it.
  • Claude Code permission rules can deny reads:
{
  "permissions": {
    "deny": ["Read(./core/**)", "Read(./.env)", "Read(./.env.*)"]
  }
}

Claude Code's docs are specific about the scope: these rules apply to its file tools and to commands it recognizes such as cat and head, but "They don't apply to a command that reads files without naming them, such as grep -r pattern . ... or to arbitrary subprocesses that read or write files indirectly, like a Python or Node script that opens files itself." For OS-level enforcement they point to the sandbox.

These are worth using. They stop accidental reads and keep context focused. But the files are still on disk, and any process the agent runs can read them.

Sandboxing the agent

OS-level sandboxes (Claude Code's sandbox, Codex's sandbox modes, containers, VMs) restrict the agent's filesystem and network. A sandbox that denies reads to core/ and blocks outbound network is much stronger than an ignore file.

Limits: the sandbox is configured on the machine running the agent. For a contractor's own laptop and their own agent, you don't control that configuration. And if the agent needs to run your test suite, the tests need core/.

NDAs and contracts

An NDA and an IP assignment clause give you legal recourse and set expectations. They don't stop a copy from being made. They also don't automatically cover what a contractor pastes into a third-party AI tool, so many teams add explicit AI-tool clauses. See NDAs for developers before code access.

Splitting the repository

Moving the sensitive code into its own repository is real access control. It's also expensive: everyone else consumes it as a package, and agents and contractors who don't have it can't build or test the parts that depend on it. More in how to give contractors access to part of a GitHub repo.

Monitoring and DLP

Data-loss-prevention tools that inspect prompts and agent tool calls can catch some leaks of known code or secrets. They're detection, not prevention, and they work best combined with a smaller blast radius.

The principle: smaller clones

The pattern that holds up is least privilege at the repository level. Give each contractor and each agent a copy of the repository that only contains what their task needs, and let them work against interfaces for the rest. Then:

  • Prompt injection can only reach what's in that copy.
  • A misbehaving test can only read what's in that copy.
  • An ignore file becomes a convenience, not your last line of defense.

The hard part is doing that without splitting your repository or breaking the build.

How Gitfence does it

Gitfence sits in front of GitHub and serves each person and AI agent their own view of a repo. You set access per folder or file:

Level What they get
No access Nothing. The path is absent from every commit of their clone
Types only Generated TypeScript declarations, literal values redacted
Can read Source, read-only
Can edit Full access

An agent cloning the view gets a normal git repository. If core/pricing/ is Types only, the agent sees core/pricing/index.d.ts with the function signatures it needs to call, not the implementation or the constants.

Gitfence also injects a section into AGENTS.md and CLAUDE.md in each view, telling agents what's fenced, how to run tests and how to request access, and explicitly not to recreate or stub fenced code. Edits to that section are ignored on push.

What a real run looked like

We tested this with Claude Code acting as a contractor's agent in a sandbox with only its clone, an agent token and the Gitfence MCP server. The task ("add a checkout feature priced with the existing pricing module") didn't mention Gitfence. The agent read the generated core/*.d.ts and AGENTS.md, wrote src/checkout.ts and tests, committed, pushed, and ran the suite against the real code through the MCP run_tests tool (7 tests passed). Gitfence opened a PR on behalf of the agent. Afterward, none of the pricing internals appeared in any object of the agent's clone, and the agent didn't try to stub or recreate core/.

Running tests without handing over the code

Fenced CI runs the tests on the real code in a sandbox with no network access, neither the internet nor the Gitfence server, and redacts hidden source from the output. Agents call it through the run_tests MCP tool. For untrusted users you can use summary mode, which returns only the verdict.

Changes come back as PRs

Pushes are checked path by path (no writes to hidden or read-only paths, no symlinks into fences, no look-alike paths, CI config read-only by default) and arrive in GitHub as normal pull requests. A Gitfence PR check scans added lines for fingerprints of hidden code, which catches an agent that copied hidden code it shouldn't have had.

Honest limits

  • Gitfence controls what someone sees from now on. If a contractor already cloned the full repo last month, they still have it.
  • Fingerprint scans and output redaction are deterrents against verbatim and near-verbatim leaks. They aren't proof: encoded output (base64, hex) in Fenced CI isn't recognized, and exit codes and timing leak a few bits per run.
  • Commits that touch both hidden and visible files keep their messages.
  • GitHub only today; Types only covers TypeScript.

See security for the full list and Gitfence for AI agents for setup.

A practical checklist

  1. Move secrets out of the repository into a secrets manager. No access control on code helps with a key that's in the history.
  2. Decide which paths are core IP. Usually it's a small part of the codebase.
  3. Give contractors and agents a view without those paths, or with types only.
  4. Run their tests somewhere without network access and without their ability to edit CI config.
  5. Keep agent ignore rules and sandboxes on top, as defense in depth.
  6. Require an NDA and an AI-tool clause before access.
  7. Review their changes as PRs like any other.

FAQ

Does .cursorignore stop Cursor from reading a file?

It stops Cursor's indexing, Tab, Inline Edit and @ mentions from using it. Cursor's own docs say the Agent's terminal and MCP tools can still access it, so it isn't a security boundary.

Can I stop Claude Code from reading certain files?

Deny rules such as Read(./core/**) stop its file tools and recognized commands like cat. Scripts and commands that read files indirectly aren't covered; for that, Anthropic recommends enabling the sandbox, or you can keep the files out of the agent's clone entirely.

Is it safe to let AI agents run my test suite?

Only if the tests run somewhere that can't send data out. A test file can read any file the process can read, so run untrusted test changes without network access and without secrets, as Fenced CI does.

Do AI coding tools train on my code?

It depends on the vendor, plan and settings, so check each tool's data-use terms. Limiting what's in the agent's working copy reduces what can be sent regardless of those terms.

What should I protect first?

Secrets first, then the small set of modules that are your competitive advantage. Most contractors and agents don't need either to do their job.

Fence your first repository in minutes

Free for one repository and your own team. Add a restricted person and Pro is free for 14 days, no card.