Open-source project
ColeMurray/background-agents avatar
ColeMurray/background-agents

Background Agents: Open-Inspect runs coding sessions in its own sandboxes

Project brief: An open-source background agents coding system. Background Agents: Open-Inspect An open-source background agents coding system inspired by Ramp's Inspect.

3,268 stars468 forksTypeScriptMIT

At a glance

What is it?
An open-source background coding agent inspired by Ramp's Inspect, built as a single-tenant system with a Cloudflare control plane and pluggable sandbox infrastructure. The security model is the first thing to read, not the feature list.
Who is it for?
Adopt it if your team is small, trusted, and already comfortable running Cloudflare Workers or the Docker Compose stack, and if you accept that every user of the system can reach every repository the shared GitHub App is installed on.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 8 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Open-Inspect actually solves

Most coding agents assume you are sitting in front of them. You type a prompt, you wait, you watch the diff appear. Open-Inspect inverts that: the session runs in a sandbox while you do something else, and you come back to a pull request. The README frames the project as an open-source background agents coding system inspired by Ramp's Inspect, and the inspiration matters because it explains the whole design. Inspect was built for internal use at one company, where every employee is trusted and has access to the same repositories. Open-Inspect copies that assumption rather than working around it.

The intended user is a team that wants its own hosted agent, not a subscription. Sessions can be started from a web UI, Slack, a GitHub PR, a Linear issue or a webhook, and the agent can open PRs with commit attribution to the person who prompted it. The README also lists scheduled automations for cron jobs and event-driven automations for GitHub events, Sentry alerts and webhooks. None of that is unusual for a coding agent. What is unusual is that the project ships the infrastructure to run it: sandbox providers, a control plane, and integrations as separate packages in one repository.

The control plane, the sandboxes, and who holds the git token

The repository is an npm workspace with one package per concern. control-plane is Cloudflare Workers plus Durable Objects. web is the Next.js client. sandbox-runtime is the shared in-sandbox agent runtime. Then there are four infrastructure packages that each target a different sandbox provider: modal-infra, daytona-infra, e2b-infra and opencomputer-infra. The integration packages (slack-bot, github-bot, linear-bot) turn messages and issues into sessions, and shared holds types and utilities.

The security model is the part worth reading twice. Git operations use a single shared GitHub App installation. The control plane mints short-lived installation tokens server-side and brokers them to sandboxes through the git credential helper on demand, so the sandbox never holds a long-lived credential. The README's own token table separates four token types: the GitHub App token for clone, fetch and push across every repository where the App is installed; the user's OAuth token for PR creation and user info; a sandbox auth token scoped to a single session; and a WebSocket token also scoped to a single session.

The consequence is stated plainly in the README: there is no per-user repository access validation before a session is created. If the App can see a repository, any user of the system can work on it. PR creation is the one place where per-user permissions reassert themselves, and only for GitHub logins, since those carry an OAuth token. Users who sign in through Google carry no SCM token, so their PRs fall back to the shared GitHub App bot. That is a deliberate trade, not an oversight, but it does mean the sign-in path you choose changes who the pull request appears to come from.

Installing the control plane with Docker Compose

The README points to docs/SETUP_GUIDE.md for practical setup and docs/GETTING_STARTED.md for deployment. The repository also ships a docker-compose.yml that the file's own comment describes as the stack the AWS instance runs, and as the local stand-in for it. It contains the Node host, MinIO for media and backups, and a Litestream sidecar replicating the global store. The web app is deliberately not part of it; the comment says it stays on Vercel and you run next dev locally.

Start by copying the environment file and filling it in, then bring the stack up:

bash
cp .env.example .env
docker compose up --build

The compose file pins the host's environment rather than reading it from .env: HOST is 0.0.0.0, PORT is 8787, DATA_DIR is /data and SHUTDOWN_TIMEOUT_MS is 30000. The comment explains why. A .env edit must not be able to move the host off its volume, its published port or its drain budget. The published port uses APP_BIND_ADDRESS and defaults to loopback, so nothing listens on a public interface unless you change it. The stop grace period is set to 40s so it outlasts SHUTDOWN_TIMEOUT_MS plus the 5 seconds the host keeps before forcing its own exit.

One detail that will save time if you pull the images manually: the compose file uses quay.io/minio/minio rather than Docker Hub, and the comment says MinIO withdrew both images from Hub, so a Hub reference now fails to pull anonymously. Same releases, same digests.

The .env.example file is not just a template. Its header notes that packages/control-plane/src/node/env-example.test.ts checks that the file names every variable the host reads and nothing else, and that the keys required at boot are exactly the ones marked Required. If you add a variable to the host and forget the example file, that test is what tells you.

Running the host directly, and why the migrations directory matters

If you would rather skip Compose, the .env.example header shows the direct form. The host reads its process environment, so any loader works:

bash
node --env-file=.env packages/control-plane/dist/node/main.js

The same header explains that on Cloudflare the deployment variables keep the same names and meanings, but they are Worker variables and secrets, and each line in the example names its source there: a terraform.tfvars entry, a value Terraform computes or generates, or nothing at all. On AWS the container's environment is materialized from SSM Parameter Store by the deploy step, and the header states that nothing in the file is baked into the image.

MIGRATIONS_DIR is the variable to understand before your first boot. It points at the D1 migration files that are applied to the global store at startup. The image sets it to its own copy, and the example says to leave it empty to use terraform/d1/migrations from a repository checkout. Get this wrong in a container and you are either applying migrations from a path that does not exist or applying none at all. DATA_DIR is the other one: it holds the global store (global.db), the per-session files under sessions/<id>.db, and the host alarm index, which is why the compose file mounts a named volume there.

Single-tenant is a real constraint, not a disclaimer

The README puts single-tenant deployment in a blockquote and calls it important, and the reasoning is specific rather than cautious boilerplate. Because all users share one GitHub App installation, repository access is defined by where the App is installed, not by who is asking. The README lists exactly what a multi-tenant version would need: per-tenant GitHub App installations, access validation at session creation, and tenant isolation in the data model. None of those exist today.

There is a second limitation that follows from the same architecture. Sandboxes are warmed aggressively. After each prompt the filesystem state is saved so follow-up sessions restore instead of re-cloning, pre-built images are rebuilt every 30 minutes with the latest commits and dependencies, and a sandbox begins spinning up as soon as you start typing. That is what makes sessions start quickly, but it also means sandbox state and pre-built images are shared infrastructure. If your repository contains material that cannot be persisted in a snapshot, the warming strategy is working against you.

Where this is the wrong tool is any situation where the people prompting the agent are not the people who own the repositories. A consultancy running sessions for clients, a platform team exposing the agent to other departments, or anything with an external user base all sit outside the design. The README's deployment recommendations read as a list of compensating controls for exactly this: deploy behind your organization's SSO or VPN, install the GitHub App only on intended repositories, restrict sign-in by allowed GitHub users, email domains or active organization membership, and select specific repositories rather than all repositories when installing the App.

How it differs from Cursor and Claude Code background agents

Cursor's background agents and Claude Code's background work both keep you inside a vendor's environment. You get the agent, the model routing, and the sandbox as one product, and the trade is that you do not operate any of it. Open-Inspect sits at the opposite end. The control plane is yours, the sandboxes run on infrastructure you choose from four providers, and the model is a configuration choice rather than a lock-in: the README lists Anthropic Claude, OpenAI Codex via a ChatGPT subscription, xAI Grok via a SuperGrok subscription, and OpenCode Zen.

That flexibility has a price that the hosted products do not charge. You are responsible for the Cloudflare Workers deployment or the Docker Compose stack, for the GitHub App and its installation scope, for MinIO and Litestream, and for the sign-in restrictions that stand in for per-user authorization. The README's own security section is essentially a list of things you must configure correctly, because the code will not stop you. If you want a background agent and you do not want to run a control plane, the hosted options are the better fit. If you want sessions that start from Slack, Linear and GitHub events against your own repositories, and you are willing to own the deployment, the gap Open-Inspect fills is real.

Licence, upgrade cost, and what the repository does not tell you

The project is MIT licensed, which permits commercial and private use with the usual attribution requirement. That is a permissive licence, but it says nothing about the services the system depends on. Cloudflare Workers and Durable Objects, Modal, Daytona, E2B, MinIO and the model providers all have their own terms, and running this stack means accepting them separately. The MIT grant covers the code in this repository, not the platform you deploy it onto.

The upgrade surface is broad because the system is a workspace of independently deployable pieces. The root package.json exposes typecheck, build, lint, test, test:integration and knip, and the build script builds @open-inspect/shared first before the remaining workspaces. Any upgrade has to move the control plane, the web client and the sandbox runtime together, since they share types through that package. There are no recent releases in the repository metadata, so upgrades track the main branch rather than tagged versions, and the CHANGELOG.md file is where release notes would appear. The README does not document a rollback procedure for the control plane or for applied D1 migrations, and it does not state a supported upgrade path between versions. With a single-tenant internal deployment that may be acceptable. Treat it as a system you deploy and operate, not one you install and forget.

Editorial conclusion

Adopt it if your team is small, trusted, and already comfortable running Cloudflare Workers or the Docker Compose stack, and if you accept that every user of the system can reach every repository the shared GitHub App is installed on. Do not adopt it as a multi-tenant product or as a hosted service for outside customers: the README states that per-tenant GitHub App installations, access validation at session creation and tenant isolation in the data model would all have to be built. Before deploying, verify three things in your own environment: that your GitHub App installation is scoped to specific repositories rather than all of them, that ALLOWED_GITHUB_ORGS or an equivalent sign-in restriction is set, and that the stack is reachable only behind your SSO or VPN.

Frequently asked questions

What are background agents in the context of Open-Inspect?

Open-Inspect is an open-source background agents coding system, described in the README as inspired by Ramp's Inspect. A session runs in a sandbox while you do other work, and the agent can open a pull request with commit attribution to the person who prompted it.

How do I use background agents with Open-Inspect?

You start a session from the web UI, Slack, a GitHub PR, a Linear issue or a webhook, and the agent works in a sandbox with a full development environment. The README points to docs/SETUP_GUIDE.md for local, contributor and deployment paths, and to docs/GETTING_STARTED.md for deployment instructions.

Can I get an AI agent for free?

The code is MIT licensed, so the software itself costs nothing to use. The infrastructure it depends on does not: the control plane runs on Cloudflare Workers and Durable Objects, sandboxes run on Modal, Daytona, E2B or OpenComputer, and the model comes from Anthropic, OpenAI, xAI or OpenCode Zen.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/colemurray-background-agents.svg)](https://hysenlabs.com/projects/colemurray-background-agents)