Skip to Content
How-to guidesHow-to guidesRestrict which repositories an agent can reach

Restrict which repositories an agent can reach

A scope says what an agent may do on GitHub: github:contents.read, github:contents.write, github:repo.create. A repository constraint on the same grant says where. The broker reads the owner and repository out of every request path (REST or git) and refuses anything not on the list, before the call reaches GitHub.

Unlike the recipient constraint on messaging platforms, this one binds reads as well as writes. The point is “what this identity can reach”, not “where it can deliver”: an agent restricted to acme/ledger-service cannot list, clone or read any other repository through the broker.

Available on Studio and above.

Add a constraint

  1. Open Agents and pick the agent.
  2. On the GitHub grant row, expand Restrict to repositories.
  3. Add entries:
    • owner/repo for one repository (acme/ledger-service). Start typing and pick from the list of repositories the connection can see, or type it in full.
    • owner/* for every repository under one owner or organisation (acme/*).
  4. If the grant includes github:repo.create, an Allow creating repositories switch appears. Off by default. When on, the agent may create repositories only under an owner that appears in the list.
  5. Save. The change is live on the agent’s next call.

Names are matched case-insensitively. Up to 64 entries per grant.

What is refused

RequestResult
Any REST call under /repos/<owner>/<repo>/… for a repository not on the listrepo_not_allowed
git clone, fetch, pull or push via governed git for a repository not on the listrepo_not_allowed
Forking, transferring or importing a repository, and gists, on a restricted grantrefused: they move content somewhere the path does not name
Code search (/search/…) on a restricted grantrefused: it spans every repository the token can see
Listing repositories (GET /user/repos, GET /orgs/<org>/repos), GET /user, GET /rate_limitallowed: names and metadata, not code
Creating a repository without Allow creating repositories, or under an owner not on the listrefused

What the agent sees

{ "error": "Permission denied", "reason": "repo_not_allowed", "constraint": { "kind": "repos", "reason": "repo_not_allowed", "violating": ["someone-else/private-repo"] } }

Over git the same refusal is one line of text, because git prints it verbatim:

AgentValet: repo_not_allowed — someone-else/private-repo is not in this agent's allowed repositories

The audit row records the repositories that failed. A violation is a hard refusal, never an approval request: an owner cannot approve past a constraint they set on the grant themselves.

Child agents

A child agent inherits its parent’s repository constraint and cannot loosen it. A parent limited to acme/* can issue a child limited to acme/ledger-service, but not one that names other-org/anything, and a child cannot turn on repository creation unless the parent has it.

Pair it with a GitHub App connection

The allow-list is enforced by the broker before any call is made. If the organisation connects GitHub as a GitHub App bot identity rather than a personal login, the token the broker mints for each call is additionally scoped to that one repository at GitHub’s end, so even the upstream credential cannot reach a repository outside the call.

When to use this rather than a guardrail

A guardrail is org-wide and platform-level (“no agent may write to GitHub without approval”). A repository constraint is per grant: this agent, this connection, these repositories. Use both when you want a floor for everyone and a tighter list for a specific agent, contractor machine or locked-down developer VM.

Last updated on