# How to clone a private Git repository into a sandbox without exposing the token Store the token as a Runtime secret that adds git's Authorization header, then clone and push over HTTPS; on paid accounts SSH works too. **On Runtime the token never enters the sandbox.** A secret is sealed when you store it, and the host's proxy adds it to HTTPS requests bound for the hosts you name. The sandbox holds a worthless placeholder, so an agent that prints its environment, or a prompt injection that tries to send the token elsewhere, has nothing to leak. git is in every sandbox; Ubuntu 24.04's package is git 2.43.0, checked 25 September 2026. ## Clone over HTTPS with a header secret GitHub accepts a token over HTTPS as HTTP Basic credentials with the user name `x-access-token`, the form GitHub's own `actions/checkout` sends. Store that credential once, base64-encoded, as a secret whose header is `Authorization`: ```ts check import { Runtime } from "withruntime"; const runtime = new Runtime(); const token = process.env.GITHUB_TOKEN ?? ""; // a fine-grained token for the repositories the agent needs await runtime.secrets.set("GIT_GITHUB_AUTH", { value: Buffer.from(`x-access-token:${token}`).toString("base64"), hosts: ["github.com"], header: "Authorization", format: "Basic {value}", }); await using sbx = await runtime.sandboxes.create(); await sbx.exec("git clone --depth 1 https://github.com/acme/private-app.git app", { check: true, timeoutMs: 300_000, }); ``` ```python check import base64 import os from withruntime import Runtime runtime = Runtime() token = os.environ["GITHUB_TOKEN"] runtime.secrets.set( "GIT_GITHUB_AUTH", value=base64.b64encode(f"x-access-token:{token}".encode()).decode(), hosts=["github.com"], header="Authorization", format="Basic {value}", ) with runtime.sandboxes.create() as sbx: sbx.exec("git clone --depth 1 https://github.com/acme/private-app.git app", check=True, timeout_ms=300_000) ``` The URL carries no credentials. With `header`, the proxy sets that header on every HTTPS request to `github.com` and replaces any the sandbox sent, so git needs no credential helper and never prompts. The secret applies to every sandbox of the account from then on; replacing it keeps working sandboxes up to date within seconds. This works on the free trial, which reaches ports 80 and 443. ## Commit and push the agent's work Push goes to the same host, so the same secret covers it. Set an identity for the commit, work on a branch, and push: ```ts check import { Sandbox } from "withruntime"; const sbx = await Sandbox.connect(process.env.SANDBOX_ID ?? ""); const git = (args: string) => sbx.exec(`git -C /workspace/app ${args}`, { check: true, timeoutMs: 120_000 }); await git("config user.name 'Build Agent'"); await git("config user.email 'agent@example.com'"); await git("switch -c agent/fix-login"); await git("add -A"); await git("commit -m 'Fix the login redirect'"); await git("push -u origin agent/fix-login"); ``` Scope the token to what the agent should do. A fine-grained GitHub token can be limited to chosen repositories with only "Contents" read and write; a branch protection rule on `main` then keeps the agent to branches and pull requests. To open the pull request, see [the GitHub CLI in a sandbox](/integrations/github-cli). ## Which way to authenticate | Method | Trial | Paid | Where the credential lives | Notes | | -------------------------- | ----- | ---- | -------------------------------- | ------------------------------------------ | | HTTPS with a header secret | Yes | Yes | Sealed on Runtime's servers | The method above | | HTTPS, token in the URL | Yes | Yes | In the sandbox, in `.git/config` | Avoid: any code in the sandbox can read it | | SSH with a deploy key | No | Yes | In the sandbox, in `~/.ssh` | Port 22; one repository per key | | Public repository | Yes | Yes | None | `git clone https://...` as is | GitLab, Bitbucket and a self-hosted server work the same way over HTTPS: put their host in `hosts` and the credential their HTTPS git endpoint expects in the value. ## SSH on a paid account A paid sandbox reaches any public host on any port, so `git@github.com:` URLs work. SSH needs the private key in the sandbox, so use a deploy key: it belongs to one repository and is read-only unless you allow write access when you add it. ```python check import os from withruntime import Sandbox with Sandbox.create(funding="paid") as sbx: sbx.files.write("/workspace/.ssh/id_ed25519", os.environ["DEPLOY_KEY"], mode=0o600) sbx.exec("git clone git@github.com:acme/private-app.git app", check=True, timeout_ms=300_000, env={"GIT_SSH_COMMAND": "ssh -o StrictHostKeyChecking=accept-new"}) ``` `accept-new` records GitHub's host key on first contact instead of stopping to ask. If the sandbox has an allow list, add `github.com:22` to its `connect` rules ([the network](/docs/sandbox-environment#the-network)). ## Faster clones for big repositories | Need | Command | | --------------------------------- | ----------------------------------------------------------------------------------- | | The latest commit only | `git clone --depth 1 ` | | History, but no old file contents | `git clone --filter=blob:none ` | | One directory of a monorepo | `git clone --filter=blob:none --sparse `, then `git sparse-checkout set ` | The default 4 GiB disk has about 2.5 GiB free; give a large repository more with `diskMiB`. To start every sandbox with the repository already there, clone it once and keep a [snapshot](/glossary/sandbox-snapshot); new sandboxes from the snapshot only need `git pull`. ## Related - [A sandbox for a coding agent](/use-cases/coding-agent-sandbox) - [Open pull requests with the GitHub CLI](/integrations/github-cli) - [Secrets sandboxes never see](/docs/security#secrets-sandboxes-never-see) - [Run Claude Code in a sandbox](/integrations/claude-code) - [Egress control](/glossary/egress-control) ## Sources Checked 25 September 2026. - [actions/checkout, git-auth-helper.ts](https://github.com/actions/checkout/blob/main/src/git-auth-helper.ts): the `AUTHORIZATION: basic` header built from `x-access-token:` - [Managing deploy keys](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/managing-deploy-keys): one repository per key, read-only by default - [git in Ubuntu noble](https://packages.ubuntu.com/noble/git): 2.43.0 - [Managing personal access tokens](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) and [fine-grained token permissions](https://docs.github.com/en/rest/authentication/permissions-required-for-fine-grained-personal-access-tokens): "Only select repositories" and the "Contents" permission - [git clone](https://git-scm.com/docs/git-clone) and [git sparse-checkout](https://git-scm.com/docs/git-sparse-checkout): `--depth`, `--filter`, `--sparse` Facts on this page were checked on 25 September 2026.