Data Report · By Chris Sowa · Published
Last updated
Is It Safe to Give Claude Code My GitHub Token?
Only partly: with sandboxing on and the token masked, sandboxed shell commands see a sentinel and the real value is injected only for api.github.com, but Claude's Read tool, MCP servers and hooks run outside the sandbox. Safe is a setting with a boundary, and the real value still passes through a proxy on your machine.

A GitHub token is the credential most coding-agent setups reach for first, which is why this question gets asked about Claude Code before any other. Claude Code's documentation does describe a way to keep the real value away from the agent, and it is narrower than the word "masking" suggests: it applies to commands run in the sandboxed shell, while the file tools, MCP servers and hooks sit outside that boundary (Anthropic, 2026). The record type used here is a fine-grained token limited to one repository, first sitting in a .env file and then configured as a masked credential. The finding is that masking protects the shell path and leaves the file tools, the token's scope and the rest of the page to other controls. What Is Least Exposure? frames the underlying split between access and exposure, and the answer here depends on the tool the agent uses to reach the token and on where the settings are defined. Sandbox settings and permission rules are read separately here, because the documentation keeps them separate.
Key findings
- With sandboxing on and the token declared as a masked credential, Claude Code shows sandboxed commands a per-session sentinel, and the sandbox proxy substitutes the real value on outbound requests only to the hosts in injectHosts, such as api.github.com (Anthropic, 2026).
- The sandbox covers shell commands only: Read, Edit, Write, WebFetch and WebSearch follow permission rules instead, and a denyRead entry does not stop the Read tool, so a .env file stays readable through Read whatever the masking says (Anthropic, 2026).
- Local MCP servers, hooks and helper commands such as apiKeyHelper run with the user's full access outside the sandbox, and the proxy that restores the real value runs on the developer's own machine (Anthropic, 2026).
- GitGuardian's 2025 count, as reported, was 28,649,024 new credentials in public GitHub commits, with Claude Code co-authored commits leaking credentials at roughly double the baseline rate (Help Net Security, 2025).
- A governed environment that replaces values with consistent tokens before any model reads the screen leaves a misdirected agent holding tokens, not the credential or the records behind it (What Is Least Exposure?).
- Real values resolve only at an approved destination at the moment of an approved action, and a named person approves each consequential action, so the approval governs the act rather than the model's account of it (What Is a Tethered Agent?).
What does it mean to give Claude Code a GitHub token?
A GitHub token is a bearer credential: whatever holds the string can act as the account that issued it, within the token's scope. The record type used on this page is a fine-grained token scoped to one repository, held in two ways. In the first, the token sits in a .env file or an exported variable, in the environment the agent reads. In the second, sandboxing is on and the token is declared under sandbox.credentials with mode mask and injectHosts set to api.github.com.
Scope matters before anything else. Inside Claude Code, the sandbox wraps shell commands and the processes they start. The documentation states that Read, Edit, Write, WebFetch and WebSearch follow permission rules instead, that local MCP servers, command hooks and plugin monitors run with full access, and that excluded commands and unsandboxed retries also run outside it (Anthropic, 2026). Separately, the governed browser environment discussed at the end of this page covers what an agent reads and does on a rendered page, such as a repository settings page or an access-token page, and not the terminal, the IDE, the local filesystem, direct API calls or MCP.
Least privilege still comes first. GitHub's own documentation recommends fine-grained personal access tokens over classic ones and lets a token be limited to specific repositories (GitHub Docs, Managing, 2026). A token scoped to one repository follows the least-privilege advice; a token with account-wide reach does not, and no masking setting repairs it. How Do I Give a Coding Agent Access to GitHub Without a Personal Access Token? takes the identity question on its own.
What changes when the token is a masked credential?
Claude Code's documentation describes sandbox.credentials as a way to declare credential files and environment variables to protect from sandboxed commands. With mode mask, a sandboxed command is shown a per-session placeholder called the sentinel, and the sandbox proxy substitutes the real value on outbound requests to hosts you allow. When injectHosts is empty, the proxy substitutes the value on requests to every host in network.allowedDomains. The setting affects sandboxed Bash commands only, and it needs the proxy to terminate TLS. It is honored only from user settings, managed settings and the --settings flag, and it is ignored in a repository's own settings file (Anthropic, 2026).
| Dimension | Token in .env | Token as masked credential | What to verify |
|---|---|---|---|
| What a sandboxed command reads | The real token | A sentinel | Print the variable inside the session and confirm a sentinel appears |
| What Read returns for a .env file | The whole file | The whole file, as the sandbox does not wrap Read | Whether a permission rule denies Read on it |
| Where the real value is used | Anywhere the agent sends it | Only for hosts in injectHosts, at the proxy | That injectHosts names api.github.com and nothing broader |
| Outside the sandbox | Not applicable | Read, Edit, Write, WebFetch, WebSearch, MCP servers, hooks | Which of these the session uses |
Masking removes the string from what sandboxed commands read and log. It does not remove the authority: any call the agent makes to a listed host is made with the token's scope, so the token's scope and the approval of consequential actions still matter. The Read-tool row is the point the sibling page Does Claude Code Read My .env File? builds on. How Do I Keep API Keys Out of Claude Code's Context Window? covers the context side.
What do the vendors themselves say?
Anthropic's sandboxing documentation is the primary source for this page. It says the sandbox "covers shell commands only," that Claude's file tools, MCP servers and hooks run outside it, and that sandbox.credentials "affects sandboxed Bash commands only." It adds that to strip credentials from all subprocesses regardless of sandboxing, CLAUDE_CODE_SUBPROCESS_ENV_SCRUB is the setting to use. On macOS, a masked credential file cannot be read at all inside the sandbox, the same effect as deny, and on Linux and WSL2 the command reads a sentinel copy (Anthropic, 2026). Those are the documented properties of a control on the developer's machine. A record of which values the model was shown, or a named approver for actions taken through the token, is not described in the pages reviewed.
Coder's documentation states that "LLMs and agents can be dangerous if not run with proper boundaries," and advises separate identities with limited scope for autonomous work (Coder, 2026). It is guidance on the identity an agent runs as, and it does not address what a model reads on a screen.
GitHub's documentation says secret scanning "scans your entire Git history on all branches of your repository for hardcoded credentials," and that for a partner credential it notifies the provider so the credential can be revoked. It runs automatically and free on public repositories; for private repositories it is available with GitHub Secret Protection on Team or Enterprise Cloud (GitHub Docs, About, n.d.). It detects a token after it has been committed, and it does not act on what an agent reads before that.
What does the leak record say about tokens near coding agents?
GitGuardian's State of Secrets Sprawl, as reported by Help Net Security, counted "28,649,024 new secrets exposed in public GitHub commits across 2025," found that Claude Code co-authored commits "leaked secrets at roughly double the baseline rate," and counted "24,008 unique secrets exposed in MCP configuration files" (Help Net Security, 2025). The figures describe public repositories. They show a rate difference for co-authored commits; they do not establish why, and they do not measure any single tool's sandbox settings.
The worked example is a fine-grained token for one repository that starts in a .env file. Three routes lead from there to disclosure: the agent reads the file and the value enters the model's context and any transcript; the agent writes the value into a file that is committed; or a configuration file for an MCP server carries the value, which is the category the 24,008 figure counts. GitHub's secret scanning examines history on all branches, so a value committed once is findable in every branch afterward, and rotation is the repair rather than deletion.
A masked credential changes the first route only for the shell: a sandboxed command that reads the variable gets the sentinel. The Read tool is outside the sandbox, so reading the .env file with Read still returns the real token unless a permission rule blocks it, and a token placed in an MCP server's configuration is outside the sandbox as well. Does Claude Code Read My .env File? takes the file question directly, and How Do You Let an AI Agent Manage API Keys Without Reading Them? covers handling and rotation.
What does masking leave open?
Five things. First, the file tools: Read, Edit and Write run outside the sandbox, so a token that also sits in a .env file is not protected from Read by a sandbox.credentials entry. Second, custody: the real value passes through a proxy on the developer's machine, so the token is protected by that machine's controls and is not removed from it. Third, authority: calls to a listed host carry the token's scope, so a misdirected agent can act within that scope while the session runs.
Fourth, injection. Researchers bypassed 12 published defenses with "attack success rate above 90% for most," many of which had reported near-zero rates (Nasr et al., 2025). One peer-reviewed description of the mechanism: "poisoned data retrieved from one component can change the model's behavior and compromise the entire system, including coercing the model to spread confidential data to untrusted components" (Siddiqui et al., 2025). The conditions for harm are described in Is It Safe to Let AI Agents Read External Web Pages?: access to private data, exposure to untrusted content, and a way to communicate externally.
Fifth, content. A credential is one value among many on a screen. Web agents "are prone to inadvertent use of unnecessary sensitive information" (Zharmagambetov et al., 2025), and Columbia's DAPLab states that "trustworthy agent automation cannot be solved at a single layer of the stack" (Columbia DAPLab, 2026). Masking the token leaves the repository's issues, settings and private code as readable as before.
What does a governed environment change?
A governed environment is a control class, not a setting on one credential. It acts at the point where a screen is rendered, before any model reads it. Values chosen by policy are replaced with consistent tokens for the whole run, so the model works on tokens and never holds the real values. Real values resolve only at an approved destination, at the moment of an approved action. A named person confirms the tokenization policy and approves each consequential action. Every screen as tokens, every action and every approval is written to a record that exports to the organization's own monitoring.
Applied to this question, the contrast is with what a sentinel does. A sentinel hides one string from one process and relies on a proxy to restore it. A governed browser environment applies the same substitution to everything a policy names on the page the agent reads, whether that is an access-token field, an account identifier or a customer record, and it adds an approval and a record. Its scope is the rendered page: it does not govern a terminal, an IDE, the local filesystem, direct API calls or MCP, which is why it complements a sandbox and does not replace one.
OWASP names the failures this addresses: sensitive information disclosure (OWASP, LLM02:2025, 2025) and excessive agency (OWASP, LLM06:2025, 2025). The tether described in What Is a Tethered Agent? is a description of authority: the agent goes where its supervisor could go and does real work there, and it cannot slip the line back to the person who set it up.
Methodology and limitations
This page rests on Anthropic's Claude Code sandboxing documentation, Coder and GitHub documentation, three research papers, a press report of GitGuardian's secrets-sprawl data, a university lab page, OWASP guidance and existing RedactSure research pages. Sources were read between October 16, 2026 and October 20, 2026. Quoted facts are cited to the page that states them, and the press figures are cited as reported, not as independently measured. Where the sandboxing documentation is the only source for a mechanism, such as the sentinel and injectHosts, the page says so and treats it as the vendor's description of its own product.
RedactSure did not test Claude Code, its sandbox or the masking setting hands-on. "Not described in the pages reviewed" means the pages reviewed and nothing broader, and it is not a statement that a behavior is absent. Vendor features change, and the page carries its date. The GitGuardian figures describe public repositories and do not isolate any tool's configuration or any developer's settings. Statements about RedactSure describe its current design, and nothing here is a measurement of deployed results. Examples describe record types, such as a fine-grained token for one repository, and not organizations.
Determinations about whether a configuration meets a legal, contractual or regulatory requirement belong to counsel, assessors and the organization's own security and compliance officers. The page is a reading of public documents and research, dated as above, and it should be read with the vendor's current documentation open. Nothing here replaces a review of the organization's own Claude Code settings, GitHub token policy and token rotation procedure.
What the record shows
Claude Code's documentation describes a real mechanism with a clear boundary: with sandboxing on and the token masked, sandboxed shell commands hold a sentinel and the proxy substitutes the real value only for a listed host. The same documentation places Read, Edit, Write, WebFetch, WebSearch, MCP servers and hooks outside the sandbox. The leak record shows why the mechanism matters, since tokens in files and configuration are leaking at scale and co-authored commits leak at about twice the baseline rate. It also shows the limits. The real value still passes through a proxy on the developer's machine, calls to the listed host carry the token's full scope, the Read tool opens a .env file in full unless a permission rule blocks it, and a masked token does not mask anything else on the page. Safe is a setting, and it is also a scope. The practical test starts with one agent and one repository: ask what the model would read if the token were the only thing hidden, and who would approve the first write.
Frequently asked questions
Is it safe to keep a GitHub token in a .env file Claude Code can read?
Not as a default. Sandbox settings apply to shell commands, and the documentation states that the Read tool follows permission rules instead, so a .env file can be read in full whether or not the token is masked. The safer path is to take the token out of the file, declare it as a masked credential for the sandboxed shell, and add a permission rule against reading the file. If the token was ever committed, rotate it, because secret scanning covers all branches.
What does the sentinel actually protect?
It protects the token string from sandboxed commands and from anything that records what those commands read. A sandboxed command sees a per-session placeholder, and the proxy substitutes the real value only for hosts in injectHosts, such as api.github.com. It does not limit what the agent can do with the token's scope on that host, which is the part approvals cover, and it does not hide any other value on a screen or in a file the Read tool opens.
Does masking stop prompt injection?
No. Masking limits what an injected instruction can read and send from the sandboxed shell, because the string is not in the shell's environment. It does not stop the agent from being misdirected or from following hostile text it reads, and calls to a listed host still carry the token's scope. Adaptive attacks have bypassed published defenses with success rates above 90% for most, so approval of consequential actions by a named person remains necessary alongside the setting.
Which Claude Code tools run outside the sandbox?
According to the documentation, Read, Edit, Write, WebFetch and WebSearch follow permission rules instead of the sandbox. Local MCP servers, command hooks, plugin monitors, LSP servers and helper commands such as apiKeyHelper run with full access, as do excluded commands and unsandboxed retries. Setting CLAUDE_CODE_SUBPROCESS_ENV_SCRUB strips credentials from all subprocesses regardless of sandboxing, which is the setting that reaches beyond the shell and into every process.
Should I use a fine-grained token or another method?
Scope is the first control. GitHub recommends fine-grained personal access tokens over classic ones and allows a token to be limited to specific repositories, so a misdirected agent can do less with it. Whether to use a personal token at all is a separate question, taken up in the sibling page on giving a coding agent access to GitHub without a personal access token, which compares the identity options available to a coding agent.
What should a security team ask for in writing?
Ask for the sandbox and credential settings in force, the injectHosts list, the token's scope and expiry, and a statement of what the model reads when a token field appears on a page. Ask who approves any write to the repository. Ask also where the real value is held during a run and how it is rotated, because the documentation says the proxy runs on the developer's machine, and that defines who is accountable for that machine.
How RedactSure Keeps a GitHub Token Off the Pages a Coding Agent Reads
A sentinel hides a string from sandboxed commands, yet file tools, MCP servers and hooks run outside it, and none decides what the model reads on settings pages.
The environment that enforces this is built by RedactSure, an AI agent controls, governance and data protection company.
Before: the agent rotating the token opens the access-token page, reads the new token and the account identifiers beside it, which then sit in the transcript. Inside the governed environment: the page reaches the model as TOKEN_001 and ACCT_001, the rotation finishes, and the real value enters one credential field a named person approves.
RedactSure is deploying now with enterprise and government customers. GitGuardian's 2025 count, as reported, put Claude Code co-authored commits at roughly double the baseline leak rate.
Everyone else controls where data can go. RedactSure controls what the AI can see.
See it on your own workflow
A GitHub token in the model's context is within reach of any injected instruction. Bring a token rotation and see, with test values, what the model reads on the access-token page. Book a demo





