# Using private GitHub repositories with Vercel Sandbox

**Author:** Allen Zhou

---

When using [Vercel Sandbox](https://vercel.com/docs/vercel-sandbox) with private repositories, you need to authenticate with a [GitHub personal access token](#fine-grained-personal-access-token) or [Github App token](#github-app-installation-token). This guide explains how.

## Prerequisites

- A [Vercel](https://vercel.com/signup) account
  
- The `@vercel/sandbox` SDK [installed](https://vercel.com/docs/vercel-sandbox/quickstart#install-the-sdk)
  
- Access to a private GitHub repository
  

## Create a sandbox from a private repository

The `Sandbox.create()` method initializes the environment with the provided repository and configuration options, including authentication credentials, `timeout`, and exposed `ports`. Once created, you can execute commands inside the sandboxed environment using `runCommand`.

``import { Sandbox } from '@vercel/sandbox'; import ms from 'ms'; async function main() { const sandbox = await Sandbox.create({ source: { url: 'https://github.com/your-org/private-repo.git', type: 'git', username: 'x-access-token', password: process.env.GIT_ACCESS_TOKEN!, }, timeout: ms('5m'), ports: [3000], }); const result = await sandbox.runCommand('echo', ['Hello sandbox!']); console.log(`Message: ${await result.stdout()}`); } main().catch(console.error);`` ## Authentication options GitHub offers several authentication methods. Choose the one that best fits your use case. ### Fine-grained personal access token Fine-grained tokens offer repository-specific access and enhanced security. This is the recommended approach for individual developers. 1. Go to [GitHub Settings → Developer settings → Personal access tokens → Fine-grained tokens](https://github.com/settings/personal-access-tokens)
   
2. Click **Generate new token**
   
3. Configure the token:
   

- **Token name**: Give it a descriptive name (e.g., "Vercel Sandbox Access")
  
- **Expiration**: Set an appropriate expiration date
  
- **Resource owner**: Select your account or organization
  
- **Repository access**: Choose "Selected repositories" and select your private repo
  
- **Repository permissions**: Grant `Contents: Read` and `Metadata: Read`
  

1. Click **Generate token** and copy the token
   

### GitHub App installation token

For platforms where users install your GitHub App, use installation access tokens. This is the recommended approach for multi-tenant platforms.

GitHub App tokens provide several advantages:

- Short-lived tokens (1 hour) reduce security risk
  
- Users grant access through GitHub's familiar OAuth flow
  
- Tokens are scoped to specific installations
  
- Higher rate limits than personal access tokens
  

Generate an installation token using the GitHub API:

`import { App } from '@octokit/app'; import { Sandbox } from '@vercel/sandbox'; const app = new App({ appId: process.env.GITHUB_APP_ID!, privateKey: process.env.GITHUB_APP_PRIVATE_KEY!, }); async function createSandboxForUser(installationId: number, repoUrl: string) { // Generate a short-lived installation token const octokit = await app.getInstallationOctokit(installationId); const { token } = await octokit.rest.apps.createInstallationAccessToken({ installation_id: installationId, }); const sandbox = await Sandbox.create({ source: { url: repoUrl, type: 'git', username: 'x-access-token', password: token, }, timeout: 5 * 60 * 1000, ports: [3000], }); return sandbox; }` ### Classic personal access token Classic tokens work similarly to fine-grained tokens but with broader scope. Create one at [GitHub Settings → Developer settings → Personal access tokens → Tokens (classic)](https://github.com/settings/tokens) with the `repo` scope.

## Building a platform with user repositories

When building a platform where users bring their own private repositories, follow this pattern:

1. **Create a GitHub App** and configure it with the `Contents: Read` permission
   
2. **Users install your app** on their repositories through GitHub's OAuth flow
   
3. **Store the installation ID** when the user completes the installation
   
4. **Generate a fresh token** each time you create a sandbox
   
5. **Pass the token** to `Sandbox.create()` as shown above
   

## Running commands in the sandbox

After creating the sandbox, run commands to install dependencies and start your application:

``const sandbox = await Sandbox.create({ source: { url: 'https://github.com/your-org/private-repo.git', type: 'git', username: 'x-access-token', password: token, }, timeout: 5 * 60 * 1000, ports: [3000], }); // Install dependencies const install = await sandbox.runCommand({ cmd: 'npm', args: ['install'], stdout: process.stdout, stderr: process.stderr, }); if (install.exitCode !== 0) { throw new Error('Installation failed'); } // Start the dev server in the background await sandbox.runCommand({ cmd: 'npm', args: ['run', 'dev'], detached: true, }); // Get the sandbox URL console.log(`Sandbox running at: ${sandbox.domain(3000)}`);``

## Security considerations

- **Never log or store tokens in plain text**
  
- **Use environment variables** to pass tokens to your application
  
- **Prefer short-lived tokens** (GitHub App installation tokens) over long-lived personal access tokens
  
- **Grant minimal permissions** Read is sufficient for cloning
  
- **Rotate tokens regularly** if using personal access tokens
  

* * *

---

[View full KB sitemap](/kb/sitemap.md)
