Implementation Guide

    Preventing AI agents from reading secrets and .env files through source-control MCP servers

    Layer your controls. Scope a separate token to each MCP server, restrict tools and local file access, keep secrets out of repositories with push protection and scanning, then enforce policy on each tool call. Inspect requests and responses for sensitive paths and secret patterns, and allow, redact, block or escalate before content reaches model context.

    Verify enforcement and retain evidence

    • Synthetic secrets for each pattern, stored in version control as test fixtures
    • Expected-denial cases for .env paths, history reads, diffs, search and PR content
    • Request and response tests, including a secret passed as a tool argument
    • A decision record per tool call with rule, outcome, tool and identity, and no secret values
    • A rotation procedure for any secret that reached history, a fork or model context
    • A current inventory of connected MCP servers and agent-triggered workflows that can read secrets

    How secrets reach an agent through a source-control MCP server

    A source-control MCP server gives an agent tools for reading repositories, branches, commits, diffs and files. Any tool that returns repository content can return a secret. The common routes are direct file reads of paths such as .env, code search results that match a key or token string, commit history that still contains a credential removed later, diffs that show a secret being added or deleted, and pull request or issue content that includes pasted credentials.

    OWASP notes that MCP servers, unlike traditional APIs, operate with delegated user permissions, dynamic tool-based architectures and chained tool calls. That raises the impact of a single weakness. A secret returned by one tool call sits in model context and can be passed as an argument to another tool. OWASP also describes credential exfiltration through tool arguments by a malicious or compromised MCP server, and token retrieval through prompt injection, compromised context or debug traces.

    Untrusted text is a second concern. Issue bodies, PR descriptions and comments from untrusted contributors can carry injected instructions that tell an agent to read a sensitive file and forward it. The agent does not need to be malicious for this to happen. It only needs a tool that will return the file.

    .gitignore does not close this gap. It keeps files out of future commits. It does not control what a tool returns from a working directory, and it does nothing for content already in history.

    Upstream controls: what each does and where it stops

    Start with credentials. OWASP recommends scoped, per-server credentials and says tokens should never be shared across servers. Where the platform allows, prefer read-only or resource-specific scopes. A token that can reach only the repositories an agent needs limits what any later failure can expose.

    Next, configure the server and agent. Grant the minimum tools required for the task, scope permissions per tool, and use separate tool sets for different trust levels. Run local MCP servers in a sandbox with minimal privileges and limited host access. Configure agents to deny reads of credential stores and sensitive local files by default, then add explicit exceptions. Audit every MCP server connected to the development environment, because tool definitions can change after approval.

    Then reduce what the repository holds. Server-side push protection moves secret control from detection to prevention, because the source control system rejects pushes containing known secret formats. It catches known formats only, so keep detection scanning as well. A secret found after a push is already in history, clones and forks retain it even after a history rewrite, and the credential must be rotated at the issuing service.

    These controls are necessary, but none of them inspects what a tool call returns. A correctly scoped token can still read a .env file the agent is permitted to open, and a secret in a format the scanner does not recognize can still sit in a file. The tool call is where that gap can be closed.

    Enforce policy on the tool call

    Place enforcement in the path between the agent and the MCP server so that it sees both directions. On the request, inspect the tool name, file path, search query and arguments. On the response, inspect file contents, diffs, search results and issue or PR text before they enter model context. Argument inspection matters as much as response inspection, because it can stop a secret already in context from being passed to another tool.

    Define three kinds of rule and combine them. Path rules match sensitive locations such as .env files, key files and credential directories, and apply before any content is fetched. Pattern rules match known secret formats in responses and arguments, such as provider key prefixes and private key headers. Content rules cover what patterns miss, for example high-entropy strings assigned to variables named like credentials. Path rules are cheap and precise. Pattern and content rules catch secrets in places paths cannot predict, at the cost of tuning for false positives.

    • Inventory the MCP servers, tools and agents in scope, and the tokens each uses.
    • Write path rules first, defaulting to deny for credential stores and sensitive files.
    • Add pattern rules for the secret formats your organization issues.
    • Add content rules for unrecognized formats, and review their false positives.
    • Assign an outcome to each rule and apply it to both requests and responses.
    • Run in a non-blocking mode first if you need to measure impact, then enforce.

    Choosing allow, redact, block or escalate

    The outcome should follow the cost of being wrong and whether the agent can still do useful work without the sensitive value. Redaction suits cases where the surrounding file is useful but the value is not. Blocking suits cases where there is no legitimate reason for the content to reach the model. Escalation suits the narrow set of cases where a person must decide.

    • Allow: Use for ordinary source files and tool calls that match no rule. Keep a decision record so the absence of a match is also evidenced.
    • Redact: Use when a secret appears inside otherwise useful content, such as a config file or diff. Replace the value and pass the rest on.
    • Block: Use for reads of .env and credential files, and for arguments that carry a detected secret to another tool.
    • Escalate for human approval: Use for rare, justified exceptions, such as a maintainer needing a specific sensitive file. Record who approved and why.

    Where Trussed fits

    Trussed enforces policy in the execution path across models, agents, tools, MCP servers and coding assistants. At the level of individual interactions and tool calls, it can allow, redact, block or escalate for human approval, and enforcement produces audit-ready evidence for the regulated enterprise. This is enforced at runtime, not reviewed after the fact. Trussed has run continuously in production in a regulated enterprise for more than 18 months.

    It is one way to implement the runtime layer described above, and it does not replace token scoping, sandboxing, push protection or scanning. Those controls reduce what can be exposed. Enforcement on the tool call decides what an agent is actually given.

    Control layers between a repository and model context

    Credential scoping

    One narrowly scoped token per MCP server

    Server configuration

    Minimum tools, sandboxing, default-deny on sensitive files

    Repository hygiene

    Push protection and detection scanning

    Runtime policy

    Inspect tool requests and responses at the call

    Evidence

    Decision records that never store secret values

    Put enforcement on the MCP tool call

    Review how policy in the execution path can allow, redact or block secret-bearing tool calls and produce audit-ready evidence.

    Request a Demo
    Next step

    How does your AI governance program compare?

    See where your program has gaps in less than 2 minutes.