Skip to main content
Mounts give a session working checkouts of git repositories inside its sandbox. A mount declares which repository to fetch, where to place it, which ref to check out, and — for GitHub repositories — a capability-scoped GitHub App grant that becomes the session’s entire GitHub permission surface: both the brokered GitHub MCP tools and plain git push inherit exactly the capabilities the mount declares.

Field reference

mounts is an array on the agent (default []). kind: git is the only mount kind.
"git"
required
The mount kind. Only git exists.
string
required
The repository to fetch. A bare owner/repo resolves to https://github.com/owner/repo.git; a full URL (https://…) or git@… address passes through unchanged. GitHub App auth requires the owner/repo (GitHub) form.
string
required
Absolute path inside the sandbox where the checkout lands, for example /workspace/widgets. Must start with /. When the agent sets no workingDirectory, the first mount’s mountPath becomes the session’s working directory.
string
The ref to fetch and check out — a branch name (main), a fully qualified ref (refs/pull/128/head), or a template (see Ref templates).When ref is omitted, the staging fetch runs with no refspec, so the checkout resolves to whatever FETCH_HEAD happens to point at. Always set ref explicitly; every shipped template and example does.
integer
default:"1"
Fetch depth, a positive integer. Mounts are shallow by default — the checkout contains only the fetched ref at the requested depth, with no tags. Agents that need more history fetch it explicitly inside the sandbox.
object
default:"{ kind: \"none\" }"
Authentication for fetching and pushing. Two kinds:
  • kind: none — unauthenticated. Works for public repositories; the session gets no GitHub credentials for this mount.
  • kind: githubApp — authenticated through the project’s GitHub App connection. This is what unlocks pushes, the git credential helper, and GitHub MCP tools. Fields below.
string
Pins the GitHub App installation to mint tokens from. Rarely needed: when absent, the platform resolves the installation from the spawning event’s payload (GitHub-triggered sessions carry one), and otherwise from the project’s connection that covers the repository.
object
Sets the git identity for commits made in this mount: { name: <string>, email: <string containing @> }. Staging writes it as the checkout’s local user.name/user.email.When the session has an attributable human requester, the platform splits the identity — the requester becomes the git author and commitAuthor the committer — and installs a prepare-commit-msg hook that stamps a Co-Authored-By: trailer for the agent, so commit history records both who asked and which agent wrote the change.
object
The permission grant for this repository. Each capability is none, read, or write (merge is none or write only):One cross-field rule is enforced at apply time: merge: write requires contents: write and pullRequests: write, because GitHub has no standalone merge permission — merging is authorized through those two.Capabilities map onto the GitHub App installation-token permission body when the platform mints tokens for the mount, always including metadata: read so basic repository reads work at every level. merge maps to no token permission of its own; it is purely a proxy-layer gate on which tools the session may call.

Checkout behavior

Mounts are staged when the sandbox is created, before any setup commands run and before the agent’s first turn. For each mount the platform initializes the repository at mountPath (or reuses an existing one), points origin at the resolved URL, then runs a shallow fetch of the ref (--depth <depth> --no-tags), checks out FETCH_HEAD, hard-resets, and removes untracked and ignored files. Staging re-runs on every sandbox creation — including sandboxes restored from a cached environment snapshot — so the checkout always reflects the ref at session start even when the sandbox image is days old. For githubApp mounts, a first-turn auth preflight verifies the full in-sandbox credential path end to end before the agent runs; if authenticated git transport cannot be established, the session fails with a platform-owned error rather than surfacing GitHub’s misleading “Repository not found” to the model.

Ref templates

ref may interpolate {{ path.to.value }} tokens against the session’s persisted input. Trigger-spawned GitHub sessions store { triggerEventId, payload }, so PR-scoped agents check out the PR head like this:
This is the one templating surface in the agent file where the payload. prefix is correct — trigger message, initialPrompt, and displayTitle render against the payload directly and reject the prefix (see Variables and templating). A templated ref makes the agent event-dependent: manual starts and agent-to-agent spawns carry no event payload, so a session whose mount ref cannot be resolved from its input is refused at spawn time, with an error explaining that the agent must be started by a matching event trigger. Each token must also resolve to a scalar (string, number, or boolean).

Working directory and multiple mounts

An agent may declare several mounts; each fetches independently to its own mountPath. The session’s working directory resolves as:
  • No workingDirectory declared → the first mount’s mountPath.
  • Relative workingDirectory → resolved against the first mount’s mountPath; escaping it fails. Declaring a relative working directory with no mounts also fails.
  • Absolute workingDirectory → used as-is.
During import merge, mounts are a named array keyed by name (an authoring-only key, stripped from the stored spec) and otherwise by mountPath: an item with a matching key deep-merges into the imported item, new keys append. Mounts are deliberately not removable with the remove: directive (which supports only tools, triggers, and env) — to change a mount an import gave you, override it by key, or drop the import. See Imports and fragments.

Repository authorization

A githubApp mount only works for repositories covered by one of the project’s active GitHub connections. Authorization is checked at spawn time, before a session is created: if no active connection covers the repository — it was deleted, renamed, or removed from the GitHub App installation — the spawn is refused, and trigger-driven spawns are suppressed until the connection is restored. If GitHub later refuses access definitively at token-mint time, the platform prunes the repository from the stored grant so future spawns fail fast instead of launching doomed sessions. See Connections and identities.

How mounts feed GitHub access

Mounts are the single policy point for everything GitHub in a session. Two consumers derive their credentials from the mount’s capabilities: GitHub MCP tools. Any githubApp mount provisions the session’s brokered github MCP server; a kind: github entry in the agent’s tools only narrows the tool allowlist on top of that (and is a no-op without a mount). The proxy mints a fresh, capability-scoped installation token per tool call — the token never enters the sandbox. Capability-gated tool families are enforced at two levels: session-level visibility (a tool appears only if some mount grants the capability) and a per-call re-check against the target repository’s own mount:
  • merge_pull_request and enable_pull_request_auto_merge require merge: write.
  • actions_secret_list requires secrets: read or better; actions_secret_write requires secrets: write.
These stay invisible and uncallable without the grant even when the agent names them explicitly. Repositories the project may use that are not mounted get default capabilities through the proxy, with merge and secrets always denied. See GitHub MCP for the tool catalog. Plain git. Staging configures each githubApp mount with the agent-bridge credential helper. Every git network operation fetches a short-lived token from the platform’s credential broker, scoped to the git-wire subset of the mount’s capabilities: contents, plus workflows when granted, plus metadata: read — nothing else rides on the git credential. A mount with contents: none gets no git credential at all. Nothing is persisted in the sandbox; git holds the credential only in process memory.

Examples

A read-only reviewer that checks out the PR head and can comment but never push:
.auto/agents/pr-review.yaml
A coding agent that works on main, pushes branches, opens PRs, and attributes its commits:
.auto/agents/staff-engineer.yaml
The capability defaults are write-leaning (contents, pullRequests, and issues all default to write). Downscope explicitly for agents that should never push: a reviewer gets contents: read, and merge: write should remain a deliberate opt-in — merging to a production branch with no human in the loop is the highest-privilege action a mount can grant.