Appearance
Git Integration
The sandbox SDK includes a set of Git operation methods (accessed via sandbox.git) that cover common workflows such as repository cloning, branch management, commits, pushes, and pulls—without needing to construct raw git commands.
In addition to runtime Git operations inside the sandbox, the platform offers two secure Git collaboration capabilities (see GitHub Key Injection and Repository Resources):
GithubInjectionKey Injection: The token is injected by the platform at the gateway level and never enters the sandbox in plaintext. HTTPS requests fromgitcommands inside the sandbox togithub.com/api.github.comare automatically authenticated.GitRepositoryResourceResource Mounting: The platform pulls a repository snapshot before the sandbox starts and mounts it to a specified path. Ideal for "ready-to-use" code consumption scenarios.
Use cases include:
- AI Agents automatically modifying code and pushing changes back to a remote repository.
- Pulling project code into a sandbox for building, testing, or code review.
- Automated code migration and batch modification tasks.
Git Operations Inside the Sandbox
The following sections describe Git operations driven directly by the SDK inside the sandbox. All examples use @e2b/code-interpreter; other SDKs like Python have identical interfaces, differing only in naming style (snake_case).
Authentication and Identity
Reading from or writing to a Git repository typically requires credentials. The sandbox provides several ways to manage authentication information. It is recommended to prioritize GitHub Key Injection, as it keeps the token entirely out of the sandbox.
Method 1: GitHub Key Injection (Recommended)
By configuring GithubInjection when creating a sandbox, the token is held by the platform at the gateway and injected into outbound requests. Processes inside the sandbox cannot read the token content. You can directly execute git push / git pull inside the sandbox without passing any credentials.
See the full example in GitHub Key Injection and Repository Resources below.
Method 2: Inline Credentials
Pass username and password (Token) directly when calling push or pull. The token is not persisted to the sandbox disk after the request completes. username is still required when using token authentication.
javascript
import { Sandbox } from '@e2b/code-interpreter'
async function main() {
const sandbox = await Sandbox.create()
await sandbox.git.clone('https://github.com/owner/repo.git', { path: '/home/user/repo' })
// Explicitly pass credentials for subsequent push / pull
await sandbox.git.push('/home/user/repo', {
username: 'my-bot',
password: process.env.GIT_TOKEN,
})
await sandbox.kill()
}
main()Method 3: Credential Helper (Authenticate Once, Reuse Everywhere)
Use dangerouslyAuthenticate() to write credentials into the sandbox's git credential helper. After this, all HTTPS-based Git operations will automatically use those credentials.
javascript
await sandbox.git.dangerouslyAuthenticate({
username: 'my-bot',
password: process.env.GIT_TOKEN,
// Optional: specify host and protocol for self-hosted Git services
// host: 'git.example.com',
// protocol: 'https',
})⚠️ Security Warning:
dangerouslyAuthenticatestores credentials in plaintext on the sandbox disk. Any process or Agent with access to the sandbox can read these credentials. Only use in trusted sandboxes and ensure the sandbox is destroyed promptly after use. For running untrusted code like AI Agents, use GitHub Key Injection instead.
Method 4: Preserving Credentials in the Remote URL
By default, even if you embed a token in the URL during cloning, the sandbox strips the credentials from .git/config after cloning to prevent leakage. If you explicitly need to keep them, enable dangerouslyStoreCredentials: true.
javascript
await sandbox.git.clone('https://my-bot:TOKEN@github.com/owner/repo.git', {
path: '/home/user/repo',
dangerouslyStoreCredentials: true,
})⚠️ Security Warning: Enabling this option persists credentials in the repository's
.git/config. If the repository is subsequently copied, packaged, or uploaded, the credentials will be exposed.
Configuring Git Identity
Configure the author name and email before committing. This can be set globally or scoped to a specific repository.
javascript
import { Sandbox } from '@e2b/code-interpreter'
async function main() {
const sandbox = await Sandbox.create()
// Global setting
await sandbox.git.configureUser('AI Bot', 'bot@example.com')
// Scoped to this repository only
await sandbox.git.configureUser('AI Bot', 'bot@example.com', {
scope: 'local',
path: '/home/user/repo',
})
await sandbox.kill()
}
main()Cloning a Repository
clone supports specifying a local path, branch, and shallow clone depth.
javascript
import { Sandbox } from '@e2b/code-interpreter'
async function main() {
const sandbox = await Sandbox.create()
// Clone default branch
await sandbox.git.clone('https://github.com/owner/repo.git', { path: '/home/user/repo' })
// Clone a specific branch
await sandbox.git.clone('https://github.com/owner/repo.git', {
path: '/home/user/repo',
branch: 'main',
})
// Shallow clone, only fetch the latest commit
await sandbox.git.clone('https://github.com/owner/repo.git', {
path: '/home/user/repo',
depth: 1,
})
await sandbox.kill()
}
main()Repository Status and Branch Information
status returns a structured repository status, including the current branch, ahead/behind counts relative to the upstream, and a list of file changes. branches returns all local branches and the currently checked-out branch.
javascript
const status = await sandbox.git.status('/home/user/repo')
console.log(status.currentBranch, status.ahead, status.behind, status.fileStatus)
const branches = await sandbox.git.branches('/home/user/repo')
console.log(branches.currentBranch, branches.branches)Branch Management
| Operation | Method |
|---|---|
| Create and switch | createBranch(path, name) |
| Switch branch | checkoutBranch(path, name) |
| Delete branch | deleteBranch(path, name) |
| Force delete | deleteBranch(path, name, { force: true }) |
javascript
await sandbox.git.createBranch(repoPath, 'feature/auto-fix')
await sandbox.git.checkoutBranch(repoPath, 'main')
await sandbox.git.deleteBranch(repoPath, 'feature/auto-fix', { force: true })Staging and Committing
javascript
// Stage all changes
await sandbox.git.add(repoPath)
// Stage specific files only
await sandbox.git.add(repoPath, { files: ['README.md', 'src/index.ts'] })
// Create a commit
await sandbox.git.commit(repoPath, 'feat: add new feature')
// Specify author and allow empty commit
await sandbox.git.commit(repoPath, 'chore: trigger CI', {
authorName: 'AI Bot',
authorEmail: 'bot@example.com',
allowEmpty: true,
})Pushing and Pulling
javascript
// Push to upstream, set up tracking if not already associated
await sandbox.git.push(repoPath, {
remote: 'origin',
branch: 'feature/auto-fix',
setUpstream: true,
})
// Pull latest changes
await sandbox.git.pull(repoPath, { remote: 'origin', branch: 'main' })If you are not using dangerouslyAuthenticate or GitHub Key Injection, you can also pass credentials directly via username and password in push / pull.
Managing Remotes
remoteAdd adds a new remote. It supports the following optional parameters:
fetch: true— Perform a fetch immediately after adding.overwrite: true— Overwrite the URL if the remote name already exists.
javascript
await sandbox.git.remoteAdd(repoPath, 'upstream', 'https://github.com/upstream/repo.git', {
fetch: true,
overwrite: true,
})Reading and Writing Git Configuration
You can read or write Git configuration items, supporting global or repository-local scope.
javascript
// Global setting
await sandbox.git.setConfig('pull.rebase', 'false')
const value = await sandbox.git.getConfig('pull.rebase')
// Scoped to this repository only
await sandbox.git.setConfig('user.signingkey', 'KEYID', {
scope: 'local',
path: repoPath,
})GitHub Key Injection and Repository Resources
The platform provides two closely related capabilities for GitHub collaboration. They can be used independently or combined for optimal security and developer experience.
| Capability | Configuration Location | Description |
|---|---|---|
GithubInjection | CreateParams.Injections | At sandbox runtime, automatically injects a GitHub Token into outbound HTTPS requests to github.com / api.github.com. The token never enters the sandbox in plaintext. |
GitRepositoryResource | CreateParams.Resources | Before the sandbox starts, the platform clones a specified GitHub repository snapshot and mounts it to an absolute path inside the sandbox. |
The platform caches repository snapshots after the first fetch. Subsequent sandboxes may reuse this snapshot without refreshing to the latest HEAD. If freshness is critical, actively refresh inside the sandbox using
sandbox.git.pull.
How It Works
text
Before Start: Platform clones GitHub repo snapshot ──▶ Mounts to sandbox MountPath
At Runtime: Sandbox ── HTTPS ──▶ Sandbox Platform ── Injects GitHub Token ──▶ github.com
(no real token) (injects per rules)- HTTPS requests initiated by processes inside the sandbox are intercepted by the gateway. Only when the target domain matches
github.comorapi.github.comdoes the gateway injectAuthorization: Bearer <token>. - The token is managed by the platform and cannot be read from within the sandbox by any means.
- Commands like
git clone/git push/git pulluse HTTPS under the hood, so thesandbox.git.*API can operate on private repositories directly from within the sandbox without any credentials.
Enabling Only GitHub Key Injection
Suitable for scenarios where the AI Agent inside the sandbox decides whether to pull or push code autonomously. The token never enters the sandbox in any form.
bash
curl -X POST "$SUFY_SANDBOX_API_URL/sandboxes" \
-H "X-API-Key: $SUFY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"templateID": "base",
"injections": [
{
"type": "github",
"token": "'"$GITHUB_TOKEN"'"
}
]
}'After the sandbox starts, Git commands inside the sandbox can authenticate to GitHub over HTTPS without exposing the token in the environment or file system.
Key points:
- There is no GitHub token inside the sandbox. Even if the sandbox is misused by an Agent or its filesystem is dumped, the token will not be leaked.
- The platform only injects the token when the target is
github.com/api.github.com. Other outbound requests pass through transparently. - All GitHub repositories within the same sandbox share the same token.
Enabling GitHub Repository Resources (Pre-cloning)
Suitable for scenarios where the sandbox should have repository code ready at startup for direct building, testing, or code review. The platform clones the repository before the sandbox starts, and the mounted path is immediately accessible after startup.
bash
curl -X POST "$SUFY_SANDBOX_API_URL/sandboxes" \
-H "X-API-Key: $SUFY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"templateID": "base",
"resources": [
{
"type": "github_repository",
"url": "https://github.com/owner/private-repo.git",
"mount_path": "/workspace/repo",
"authorization_token": "'"$GITHUB_TOKEN"'"
}
]
}'Key points:
urlsupports HTTPS addresses or GitHub SSH-style addresses likegit@github.com:owner/repo.git; the platform converts them to HTTPS for processing.mount_pathmust be an absolute path.authorization_tokenis currently required even for public repositories. The platform uses it to clone the repository and automatically derives a runtime GitHub injection, allowing HTTPS requests togithub.com/api.github.comfrom within the sandbox to continue working.- Multiple repository resources within the same sandbox must currently share the same token.
- The platform's initial fetch snapshot may be reused by subsequent sandboxes. For the latest commits, run
git pullin the mounted repository after sandbox startup.
Combined Usage: Pre-cloning + Runtime Push
The most common AI Agent workflow is to pull a repository snapshot at startup, let the Agent modify the code inside the sandbox, and then push the changes back to GitHub. Throughout the process, the token is always held by the platform.
Important: When
resourcesalready includes agithub_repositoryresource, do not explicitly pass a GitHub injection. The server will reject this combination and return a400 github_repository resources do not support explicit github injectionserror. The platform automatically derives a runtime GitHub injection based on theauthorization_tokenin the resource.
bash
cd /workspace/repo
git checkout -b feature/auto-fix
git config user.name "AI Bot"
git config user.email "bot@example.com"
git add .
git commit -m "feat: auto fix"
git push -u origin feature/auto-fixIf your workflow does not require pre-cloning and you only want the sandbox to clone code itself via git clone, use the GitHub key injection approach above.
Working with Saved Injection Rules
GitHub injection can also be saved as a reusable named rule through the Sufy Console or Open API, then referenced by ID when creating a sandbox:
bash
curl -X POST "$SUFY_SANDBOX_API_URL/sandboxes" \
-H "X-API-Key: $SUFY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"templateID": "base",
"injections": [
{
"type": "id",
"id": "<rule-id>"
}
]
}'For complete injection rule management, see Key Injection.
Security Recommendations
- Prioritize GitHub Key Injection: Avoid any form of token entering the sandbox in AI Agent scenarios.
- Use tokens with minimal permissions (e.g., GitHub Fine-grained PATs), granting only the necessary read/write access to required repositories.
- Use
dangerouslyAuthenticateanddangerouslyStoreCredentialswith caution. Only enable them when you have full control over the sandbox lifecycle and are certain its image or snapshot will not be leaked. - Call
sandbox.kill()to destroy the sandbox instance immediately after use to prevent credentials or cloned code from persisting.