how to scope an agent to one repo or service
Least-privilege scoping for agents: dedicated service accounts, access to exactly one repo or service, path allowlists, blocked escape hatches, and boundary testing. Use when connecting an agent to GitHub, cloud, or production APIs, or after an agent touched systems outside its task. Triggers: 'scope agent to one repo', 'least privilege AI agents', 'restrict agent single service'. Not for: cross-service orchestrator agents, or web-fetch scoping.
how to scope an agent to one repo or service
TL;DR
Give the agent its own credentials that can reach exactly one repo or service and nothing else. Least privilege is not a philosophy here, it is a blast-radius setting. When the agent goes sideways, "sideways" should mean one repo, not the whole org.
how to scope an agent to one repo or serviceUse this when
- An agent works on one codebase, one service, or one dataset
- You are connecting an agent to GitHub, your cloud, or a production API
- A past incident involved an agent touching systems outside its task
- You want a template for scoping every new agent the same way
Not for this skill when
- The agent legitimately orchestrates across many services (scope per task instead)
- You are scoping what the agent can read on the web (that is URL allowlisting)
- The agent only needs read access to docs (still scope it, but the risk is low)
Steps
1. Create a dedicated service account for the agent.
Not your account, not a shared bot account. One account per agent, named after it. Everything the agent does is then attributable and revocable in one move.
Expected: the agent authenticates as its own identity everywhere it goes.
2. Grant it access to exactly one repo or service.
Add the account as a collaborator on that one repo, or attach the one IAM role for that one service. Default to read; add write only if the task needs it, and never admin.
scope:
repos:
- myorg/payments
permissions: read
deny:
- "*"Expected: a permission record showing one repo, minimal permissions, explicit deny elsewhere.
3. Enforce path allowlists inside the agent's file tools.
Even within the repo, restrict which paths the agent's tools can touch if the task is narrow. A docs-fixing agent does not need write access to the deploy scripts.
Expected: a write outside the allowed paths fails at the tool layer with a clear denial.
4. Block the cross-repo escape hatches.
Agents are creative: they will try package registries, CI configs, submodules, and API tokens they find in the repo to reach further. Scope the token so those paths dead-end, and strip CI secrets the agent does not need.
Expected: the agent's token returns permission denied on any repo or API outside its scope.
5. Test the boundary with a denied action.
Before going live, have the agent (in a sandbox) try to read another repo, list org members, or call an out-of-scope API. Every attempt should fail. If one succeeds, your scoping has a hole.
gh api /repos/myorg/other-service --header "Accept: application/json"Expected: a permission-denied response, proving the token cannot see the other repo.
6. Review the scope when the task changes.
Tasks creep. When the agent takes on a second repo, go through this list again deliberately instead of widening permissions in a hurry. Each scope expansion is a small security decision; make it consciously.
Expected: a changelog of scope grants with dates and reasons, reviewed quarterly.
Variant: least privilege for AI agents
This skill is least privilege applied to agents: dedicated identity, minimal permissions, explicit denies, tested boundaries. The principle is old; agents just make violations faster and weirder.
Variant: agent only access one github repo
Use a fine-grained personal access token or a GitHub App installation limited to that repo, with contents read or write as needed. Never use a classic token with broad scopes for an agent.
Variant: restrict agent to a single service
Same pattern outside GitHub: one IAM role, one service, resource-level permissions where the platform supports them. Name the role after the agent so the next person understands it.
Variant: scoped API keys for agents
Issue per-agent keys with the narrowest scopes the provider offers, short expiries, and IP or referrer restrictions where available. One key per agent per integration, so rotation is surgical.
Why this happens
The default is always too broad: people hand agents their own credentials or a shared admin token because it works immediately. That works right up until the agent misreads a task and the blast radius is the entire organization. Scoping feels slow on day one and looks brilliant on the day something goes wrong.
Edge cases and pitfalls
- The agent needs a second repo "just this once": do the full scoping pass for the second repo. "Just this once" permissions are how agents end up with org-wide read.
- Tokens with more scopes than the UI shows: audit the actual token scopes via the provider's API, not the settings page you clicked through. Providers add scopes to defaults quietly.
- The agent finds credentials inside the repo: that is a separate finding: rotate those credentials and remove them from the repo. The agent was not supposed to see them either.
- CI pipelines run as the agent: CI jobs inherit whatever the agent can do. Scope the CI role separately and do not let the agent edit workflow files unless that is the task.
- Scope is right but the agent is shared across tasks: one agent doing five jobs with one repo's scope will eventually need a sixth repo. Split agents by task instead of widening one agent forever.
Provenance
Resolved from the public thread: https://vectle.com/posts/pstgJfaiGHDhxxaHyKUQP9EA