AI Security
Securely Connecting an OpenAI Coding Agent to a Private GitHub Repository with Fine‑Grained Scopes
TL;DR: Use the OpenAI Agents SDK, create a fine‑grained GitHub personal access token (PAT) limited to the exact repository and actions the agent needs, store the token in a secret manager (e.g., Cloudflare Workers KV, HashiCorp Vault, or .env with restricted file permissions), inject it into the agent at runtime, test with a read‑only operation first, and rotate the token every 30‑60 days. Document the token’s purpose and expiry in a simple log.
Why a Dedicated, Scoped Token Matters
OpenAI’s Agents documentation describes how an agent can call external APIs, including GitHub, to fetch code, run tests, or push changes. If you grant the agent a PAT with broad permissions (e.g., repo or admin:org), a compromised prompt could expose all your private repositories or even delete them. Applying the principle of least privilege limits the blast radius of a potential injection attack.
Step 1 – Create a Fine‑Grained GitHub PAT
- Log in to GitHub and navigate to Settings → Developer settings → Personal access tokens → Tokens (fine‑grained).
- Click Generate new token and give it a clear name, e.g.,
openai‑coding‑agent‑repo‑access. - Under Resource owner, select the organization or user that owns the target repository.
- In the Repository access section, choose Only select repositories and tick the exact repo(s) the agent will touch.
- Set the permissions you actually need:
Contents – Read & writeif the agent will commit changes.Pull requests – Read & writeif it will open PRs.- Leave everything else (e.g.,
Secrets,Deployments) unchecked.
- Set an expiration date (GitHub now supports token expiry) – 30 days is a good baseline.
- Generate the token and copy it securely; you won’t see it again.
Step 2 – Store the Token Securely
Never hard‑code the PAT in source code or configuration files that end up in version control. Choose one of the following approaches:
- Cloudflare Workers KV (or Secrets): If you run the agent inside a Cloudflare Worker, add the token as a secret via
wrangler secret put GITHUB_TOKEN. - Environment file with restricted permissions: Create a
.envfile withchmod 600 .envand addGITHUB_TOKEN=…. Ensure the file is listed in.gitignore. - Dedicated secret manager: HashiCorp Vault, AWS Secrets Manager, or Azure Key Vault provide audit logs and automatic rotation hooks.
Whichever method you pick, the token should only be readable by the process that launches the agent.
Step 3 – Wire the Token into the OpenAI Agent
The OpenAI Agents SDK lets you define custom tools. Below is a minimal Python example that injects the token as a header when calling GitHub’s REST API.
import os
import requests
from openai import OpenAI
client = OpenAI()
def github_api(path, method="GET", json=None):
token = os.getenv("GITHUB_TOKEN")
headers = {"Authorization": f"Bearer {token}", "Accept": "application/vnd.github+json"}
url = f"https://api.github.com{path}"
response = requests.request(method, url, headers=headers, json=json)
response.raise_for_status()
return response.json()
# Register as a tool the agent can call
client.tools.register(name="github_api", func=github_api, description="Interact with the private repo")
# Example prompt that asks the agent to list files
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "List the top‑level files in the repo."}],
tools=[{"type": "function", "function": {"name": "github_api"}}]
)
print(response)
Notice the token is accessed only at runtime via os.getenv. The SDK never logs the token value, and the request is limited to the repository you scoped earlier.
Step 4 – Verify the Least‑Privilege Model
Before allowing write operations, run a read‑only test:
- Ask the agent to fetch
README.mdand compare the returned content with the known file. - Attempt an unauthorized endpoint (e.g.,
/user/orgs) and confirm the API returns a403error.
If the agent can’t reach anything outside the chosen repo, you’ve successfully limited its scope.
Step 5 – Rotate and Revoke Tokens Regularly
Even with fine‑grained scopes, a compromised token is a risk. Implement a rotation schedule:
- Set a calendar reminder (or CI job) 5 days before expiry.
- Generate a new token with the same limited permissions.
- Update the secret store (e.g., replace the KV entry or .env value).
- Invalidate the old token from the GitHub UI.
Document each rotation in a simple log file (date, token name, expiry, who performed the change). This log can be part of your broader AI‑automation audit trail.
Step 6 – Add a Human‑in‑the‑Loop Guardrail
For any push or PR creation, have the agent return a diff and ask a human reviewer to approve before the final git push call. You can implement this with a lightweight webhook that posts the diff to Slack or email, letting the reviewer click an “Approve” button that triggers the final push.
Summary Checklist
- Create a fine‑grained PAT limited to the target repo and actions.
- Store the token in a secret manager with least‑privilege access.
- Inject the token at runtime via environment variables.
- Test read‑only operations before enabling writes.
- Rotate tokens every 30‑60 days and log each rotation.
- Require human approval for any write‑back to the repository.
Following this checklist lets a small team enjoy the productivity boost of an OpenAI coding agent while keeping source code safe from accidental or malicious exposure.
FAQ
- Can I use a GitHub App instead of a PAT? Yes, a GitHub App gives even finer control (installation‑scoped permissions) but requires additional setup (JWT signing, webhook handling). For most solo founders, a fine‑grained PAT is simpler.
- What if the agent needs to access multiple private repos? Create a single PAT that lists each repo under “Only select repositories.” Avoid granting organization‑wide
reposcope. - How do I prevent the token from being printed in logs? Ensure your logging framework redacts environment variables named
*TOKEN*and never logs the raw response body of the GitHub API. - Is it safe to cache the token in the agent’s memory? Yes, as long as the process runs in an isolated environment (container, worker) and the memory isn’t exposed via debugging endpoints.
- What if the agent needs to run CI pipelines after pushing code? Use a separate PAT with
workflowpermission limited to the repository’s Actions, and keep that token in a distinct secret. Treat each token as a separate capability.
Need a practical AI security review?
AISecAll reviews prompts, tool permissions, document flows, and agent behavior so small teams can use AI without guessing where the risk sits.