Data Report · By Chris Sowa · Published
Last updated
How Do I Make a GitHub API Call for an Agent Without Giving It the Token?
Give the agent an adapter, not the token: the adapter holds a repository-scoped token, the agent calls the adapter, and the adapter calls GitHub. Check that the grant names one repository and one operation, and that a named person approves the run.

An engineering team that lets an agent call the GitHub API is accountable for the token, and the fix is plumbing rather than a prompt. GitHub's own documentation says to "Treat your access tokens like passwords" and describes fine-grained tokens that can be "limited to only access specific repositories," so the same page treats the string as sensitive and its reach as something to shrink (GitHub, Managing, 2026). This page describes the canonical call for an agent: a GET request for repository contents, made by an adapter that holds the token and exposes only the operations a grant names. The agent sends the repository and the path, the adapter attaches the token and calls the API, and the string stays outside the model's context. The boundary matters because a browser-level control governs rendered pages and not the call itself, so the first section sets out what a governed browser environment covers when an agent works in GitHub. The decision the team faces is whether to write or buy that adapter and what its grant should name, while the pages where the token is created and displayed still need a governed environment around them.
Key findings
- Wiz's exposure report states that of 50 AI companies it examined, "65% had leaked verified secrets on GitHub" (Wiz, 2025).
- GitGuardian counted about 29 million credentials leaked on public GitHub in 2025, and its CEO said that "AI agents need local credentials to connect across systems" (GitGuardian, 2026).
- A study of neural code completion tools found that "two valid credentials were identified during our experiments" and that the tools "can not only return the precise piece of their training data" (Huang et al., Your, 2024).
- GitHub's token documentation states that a token can be "further limited to only access specific repositories for that user or organization," so the smallest useful credential is documented (GitHub, Managing, 2026).
- A governed environment replaces the token with a consistent placeholder such as GITHUB_TOKEN_01 before any model reads the settings page that shows it, so the string never enters the context window (How Do Data Masking and AI Tokenization Differ?).
- Real values resolve only at the approved destination at the moment of an approved action, so a token reaches the adapter's outbound call and not the transcript, the summary, or the next page the agent reads (What Is Least Exposure?).
What does a governed browser environment cover when an agent works in GitHub?
The scope comes first because the title asks for an API call and a browser control governs something else. A governed browser environment covers what an agent reads and does on a rendered page: a repository page, a token settings page, an issue page, a developer sign-up form. It does not cover the terminal, the IDE, the local filesystem, direct API calls or MCP. A GET request an agent sends from a script or an SDK is a direct API call, and no page-level control reaches it.
The pages are where the token is displayed and the call is where it is used. GitHub's token documentation calls personal access tokens (classic) "less secure" than the fine-grained alternative, a warning about a string that behaves like a password wherever it is rendered (GitHub, Managing, 2026). The settings page an agent opens to confirm a scope is a rendered page, and the token's name and scope are drawn on it. A page-level control reaches those values and not the request the token authorizes (What Can an AI Agent See in Your GitHub Settings?).
The record for this page is a fine-grained token creation page for one repository: the token is named for the repository, its permission list reads contents, read-only, and nothing else, and the confirmation page draws the value once so the agent can hand it to the adapter. Before the handover, the model has the string on the screen in the same context as the repository name, the scope and the task. That page is inside the governed scope; the request the token makes possible is outside it.
How does the adapter make the call without the agent holding the token?
The canonical shape has three parts. A credential store holds a fine-grained token scoped to one repository with contents read. An adapter outside the agent's context exposes named operations, in this case get repository contents: the agent sends the repository and the path, the adapter attaches the token and returns the body, and the model never sees the string that authorized the request. The grant says what a call may be, a distinction What Is a Tethered Agent? draws.
The grant is the part teams get wrong. A broad token behind an adapter is the same token with a new name. GitHub's secure use reference states that "It's good security practice to set the default permission for the GITHUB_TOKEN to read access only for repository contents" (GitHub, Secure, 2026). Its token page adds that "You should choose the minimal permissions necessary for your needs" (GitHub, Managing, 2026).
The adapter's operation list is the second lock, and the build-or-buy choice behind it is the one RedactSure vs Arcade: 2026 Comparison & Alternative sets out: a platform that federates more than 8,000 agent-optimized tools behind one endpoint is a catalog rather than a grant for one repository. A token scoped to one repository can still read every file in it, so the list decides which calls the agent can make at all:
| Where the token sits | Who can read it | What the model receives | Where it fails |
|---|---|---|---|
| In a prompt or a pasted instruction | The model, on every turn | The string itself | It stays in the transcript, the summary and every later turn |
| In the agent's environment or on a page it opens | Anything the agent can reach | The string when the value is drawn | One injected instruction carries it out with the next request |
| In the adapter's store, behind a named operation | The adapter only | The response body | The body can still hold another credential the task did not need |
The adapter does not make the response safe. A get contents response is a body, and a repository can hold a workflow definition with a cloud key or a settings value for a database. The operation list governs which bodies come back, not what they hold.
What do the vendors themselves say?
Three vendors describe custody of the credential, not the screen it appears on.
Arcade's post states that "Arcade holds the credential, makes the call, and returns only the result," a custody design for API traffic that does not describe what the agent reads on the pages around the call (Arcade, 2026). It adds that "by keeping tokens out of the context window entirely, prompt injection loses its prize."
NVIDIA's OpenShell documentation states that "the agent receives an opaque placeholder, not the real API key or access token," and that "every outbound connection from the sandbox goes through the CONNECT proxy," a sandbox design that does not describe a rendered page or who approves a call (NVIDIA, 2026).
Infisical's Agent Vault post states that "the agent should not be trusted with direct access to any secrets," and describes a proxy that terminates TLS rather than forwarding an opaque tunnel, a design for API traffic that leaves the rendered page to something else (Infisical, 2026).
GitHub's Actions documentation states that "Mask all sensitive information that is not a GitHub secret by using ::add-mask::VALUE," a control on output, and that "secrets are not passed to the runner when a workflow is triggered from a forked repository," a boundary on a workflow rather than on an agent reading a page (GitHub, Using, 2026). Masking hides a value in output while the process that holds it keeps the value.
What can an agent do with a token it reads on a page?
Once the model reads the string, the routes out are ordinary: an agent can paste it into an issue comment, a commit message, a pull request description, or the configuration of the adapter it was asked to set up. Wiz puts the result a second way: "Almost two-thirds of the AI companies analyzed had a verified secrets leak" (Wiz, 2025).
Agent Security Bench reports "critical vulnerabilities in different stages of agent operation" and "limited effectiveness shown in current defenses," so an agent's own caution is not the control that keeps a token out of a commit (Zhang et al., 2025). The abstract does not say which defense performed best or by how much.
Public commits keep producing material: GitGuardian counted "28,649,024 new secrets exposed in public GitHub commits across 2025," with "24,008 unique secrets exposed in MCP configuration files" (How Do You Let an AI Agent Manage API Keys Without Reading Them?). An adapter that returns any body the agent asks for hands over whatever those files hold, so the operation list and a path allowlist matter as much as the token's scope.
A web agent holding the string is also the one most exposed to a page that asks it to reveal one, and the recorded measure for that is an attack success rate of up to 70 percent in stealing users' personal information (Can an AI Agent Sign Up for Developer Services Without Seeing Your Payment Card or Identity?). A token in a context window is available to every later step of the same run.
How should a team scope and test the grant?
The grant should name four things: one repository, one operation, one permission level and one lifetime. A token that reaches one repository with contents read cannot push, cannot change settings and cannot open a pull request. GitHub's token documentation notes that "Infinite lifetimes are allowed but may be blocked by a maximum lifetime policy set by your organization or enterprise owner," so expiry is a policy a team can set rather than a property of the token (GitHub, Managing, 2026).
The adapter should enforce the same list from its side. A token scoped to one repository still reads every file in it, so the adapter's operation list and path allowlist are what keep a read task from becoming a browse of the whole tree. The audit is the third piece: the adapter's log should show the one operation the task needed, the repository and path it touched, and the token it used.
Then test it. Create a token for a test repository with contents read only, point the adapter at it, and run the task. Search the transcript, the tool output and any summary the agent wrote for the string. Check the adapter's log for the one operation the task needed and for any request the agent tried outside the list. Revoke the token and run the task again; the adapter should fail closed rather than fall back to another credential. Keep the transcript, the log and the token's scope beside the test, because the three together are the evidence a reviewer will ask for.
The grant is worth writing down as a sentence: this agent may read the contents of this repository for this run, under this token, approved by this person.
What does a governed environment change?
A governed environment is a control class that acts where a screen is rendered, before any model reads it. Values chosen by policy are replaced with consistent tokens for the whole run, so a token creation page renders GITHUB_TOKEN_01 where the string would be. Real values resolve only at the approved destination at the moment of an approved action. A named person confirms the tokenization policy and approves each consequential action, and creating a credential that reaches a repository is one. Every screen as tokens, every action and every approval is written to a record that exports to the organization's own monitoring.
For this page's question the control changes the pages around the call, not the call. The adapter still holds the token and still makes the request, and the settings page the agent reads still shows the token's name and scope, but the value the model reads is a placeholder. The approval is a person's, recorded with a name and a time, and the record states which page was read as tokens and which operation ran. A reviewer can then answer the question the leak figures make unavoidable: what did the model see, and who agreed to what it did.
The limit is scope. The control covers the rendered page and the approval, not the terminal, the IDE, the local filesystem, direct API calls or MCP, so the adapter remains a component the organization operates or buys, and the grant remains the token issuer's decision. What it adds is the page where the string would otherwise be drawn and the person who otherwise would not be there. That split is the whole page: the call is an engineering problem with a documented answer, and the page is a governance problem with a different one.
Methodology and limitations
This page rests on two research preprints, one on agent security benchmarking and one on credential memorization in code completion tools, on GitHub's documentation for personal access tokens, Actions secrets and secure use, on vendor posts from Arcade, Infisical and NVIDIA, on a vendor exposure report from Wiz, on one industry press release from GitGuardian as carried by CIO Dive, and on existing RedactSure research pages. Vendor pages were read as of October 20, 2026, and each Sources line carries the date for its page. Quoted facts are cited to the page that states them, and figures from vendor research are cited as reported, not as independently measured. The adapter pattern is described from the vendor pages that document credential custody and from GitHub's token documentation.
RedactSure did not test any named product hands-on. Where a page does not describe a mechanism, "not described in the pages reviewed" means the recorded facts for that page, and it is not a claim about what the product does. Vendor features change and the page carries its date, so a release after October 20, 2026 is unreviewed until the test in the last question section is repeated. Statements about RedactSure describe its current design, and RedactSure is deploying now with enterprise and government customers. The example describes a record type, a fine-grained token creation page for one repository, and not an organization.
Determinations about whether a token, a grant or an agent's access meets a contractual, regulatory or internal-control requirement belong to counsel, auditors and the organization's own security and compliance officers. Nothing here replaces a run of the organization's own agent against a test repository.
What the record shows
The evidence points one way from four directions. GitHub documents repository-scoped tokens and read-only default permissions; the vendors that sell credential custody describe holding the token outside the agent and returning only the result; the research record shows credentials memorized and credentials counted in the tens of millions; and the pages an agent reads are where the string is drawn in the first place. The adapter answers the call, and it is a component a team writes or buys rather than a setting. What it does not do is govern the page where the token is created and drawn, the half a governed environment covers, with RedactSure's environment built on that control. An owner can test both halves by running the GET through the adapter for one agent, one repository and one token, then asking which component held the string and what the model received on the page that showed it.
Frequently asked questions
Can an agent make a GitHub API call without holding the token?
Yes, if the call is made by a component the agent does not read from. The agent sends the repository and the path to an adapter, the adapter attaches a token it holds, calls the GitHub API and returns the body. The model receives the result and not the string. The limit is the body: a file the agent asked for can hold another credential, so the operation list and path allowlist carry as much weight as the token's scope. Use a test repository first.
Where should the token live?
In a store that the adapter reads and the agent cannot, which in practice means a credential store outside the agent's context, a token scoped to one repository with contents read, and an expiry a team sets. The alternative, a token in the agent's environment or on a page it opens, is a string in the context window and in every later step of the run. Keep it out of the transcript by keeping it out of the agent. Rotation is the backstop if the scope was wrong.
Is a fine-grained personal access token enough?
It bounds the reach of the credential, which is half the problem. GitHub documents tokens limited to specific repositories and a read-only default for repository contents, so a fine-grained token with contents read on one repository cannot push or change settings. It is still a password in whatever process holds it, so custody decides whether the model ever sees it. Scope and custody are separate decisions. A token can be narrow and still visible to the model, or broad and held by an adapter.
What can the agent leak if it never holds the token?
The bodies it receives, and the pages it reads. A get contents call returns whatever the file holds, including a workflow definition with a cloud key or a settings value for a database, and a repository page can draw a deploy key or a webhook secret. An operation list that names the paths and a page-level control that substitutes values both reduce what leaves with the run. A path allowlist that names the files the task needs is the cheapest version of that control.
Does masking the token in logs solve the problem?
No. GitHub's Actions documentation describes ::add-mask::VALUE as a way to mask sensitive information in output, which stops a value appearing in a log while the process that holds it keeps the value. An agent's context is not a log. A token drawn on a settings page reaches the model before any masking applies, so the control has to sit at the point the page is rendered. Masking and page-level substitution sit at different points and cover different failures.
How do I test the setup before trusting it?
Issue a token for a test repository with contents read, point the adapter at it and run the task. Search the transcript and any summary for the string, check the adapter's log for one operation and for requests outside the list, then revoke the token and confirm the adapter fails closed. Keep the three records together, because the test is only evidence if the scope, the log and the transcript can be read side by side. Repeat the test after any change to the adapter's list.
How RedactSure Keeps a GitHub Token Out of an Agent's Context
The adapter handles the API call, yet an agent creating a token still opens the page that draws it, putting the value in the model's context.
The environment that enforces this is built by RedactSure, an AI agent controls, governance and data protection company.
Before: the token creation page draws the string, and the model carries it into the handover and later steps. Inside: the page renders GITHUB_TOKEN_01, the adapter holds the string and makes the GET request, and the record shows the page as tokens with the approving person's name.
RedactSure is deploying now with enterprise and government customers. In Wiz's study of 50 leading AI companies, "65% had leaked verified secrets on GitHub."
Everyone else controls where data can go. RedactSure controls what the AI can see.
See it on your own workflow
A GitHub call should not require the model to hold the token that makes it. Bring a token setup task and see, with test values, what the model reads and what the record keeps. Book a demo







