This is the primary setup guide for users and contributors.
It is organized by goal so you can pick the fastest path:
| Path | Best For | Time |
|---|---|---|
| Path A | Run the web app locally against an existing backend | ~10-20 min |
| Path B | Contribute code locally (lint/typecheck/tests) | ~15-30 min |
| Path C | Deploy your own full stack | ~1-3 hours |
Open-Inspect is designed for single-tenant use. Everyone in your deployment shares the same GitHub App installation scope. Read the security model in README.md before production use.
Required:
- Node.js
22+(minimum supported:20+) - npm
- Git
Optional (needed for modal-infra development):
- Python
3.12+ uv(recommended) orpip- Modal CLI (
modal)
Optional (needed for full deployment):
- Terraform
1.9+ - Wrangler CLI
Quick check:
node -v
npm -v
git --versionFrom repository root:
bash .openinspect/setup.shWhat this does:
- installs JS dependencies
- builds
@open-inspect/shared - installs git hooks
- sets up Python env for
packages/modal-infrawhen possible
Use this when you already have a deployed control plane and sandbox backend, and only need local UI development.
cp packages/web/.env.example packages/web/.env.localEdit packages/web/.env.local:
# GitHub App OAuth
GITHUB_CLIENT_ID=your_github_app_client_id
GITHUB_CLIENT_SECRET=your_github_app_client_secret
# Google OAuth (optional — enables "Sign in with Google"). Create a Web OAuth
# client at https://console.cloud.google.com/apis/credentials with redirect URI
# http://localhost:3000/api/auth/callback/google. Set NEXT_PUBLIC_GOOGLE_ENABLED=true
# to reveal the button (inlined at build time — restart the dev server after changing).
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
NEXT_PUBLIC_GOOGLE_ENABLED=
# NextAuth
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your_generated_secret
# Backend endpoints (deployed)
CONTROL_PLANE_URL=https://open-inspect-control-plane-<name>.<subdomain>.workers.dev
NEXT_PUBLIC_WS_URL=wss://open-inspect-control-plane-<name>.<subdomain>.workers.dev
# Must match control-plane INTERNAL_CALLBACK_SECRET
INTERNAL_CALLBACK_SECRET=your_shared_secret
# Optional access control (a user is admitted if they match ANY allowlist)
ALLOWED_USERS=
ALLOWED_EMAIL_DOMAINS=
# Exact emails (any provider's verified email) — for users on shared domains
ALLOWED_EMAILS=
# GitHub orgs whose active members can sign in. Requests read:org only when set,
# then checks active org membership with the user's OAuth token. Requires GitHub
# App Organization permissions: Members read-only.
ALLOWED_GITHUB_ORGS=
UNSAFE_ALLOW_ALL_USERS=false
# Optional whitelabel branding (defaults shown). NEXT_PUBLIC_* vars are
# inlined into the client bundle at build time — restart `npm run dev`
# after changing them.
NEXT_PUBLIC_APP_NAME=Open-Inspect
# Short label for the sidebar header.
NEXT_PUBLIC_APP_SHORT_NAME=Inspect
NEXT_PUBLIC_APP_ICON_URL=Do not commit packages/web/.env.local.
Generate a secret value:
openssl rand -base64 32If you are using someone else's deployed backend, do not generate your own
INTERNAL_CALLBACK_SECRET. Use the value configured in that backend deployment.
In GitHub App settings, include:
http://localhost:3000/api/auth/callback/github
If this does not match exactly, sign-in will fail.
If you enabled Google login, also add this redirect URI to your Google OAuth client:
http://localhost:3000/api/auth/callback/google
npm run dev -w @open-inspect/webOpen http://localhost:3000.
- Sign in with GitHub.
- Open or create a session.
- Send a prompt.
- Confirm live events stream in the session page.
If session actions fail, validate:
CONTROL_PLANE_URLNEXT_PUBLIC_WS_URLINTERNAL_CALLBACK_SECRET
These must align with your deployed backend.
Use this for day-to-day engineering work in the monorepo.
# Build shared first if it changed
npm run build -w @open-inspect/shared
# Monorepo checks
npm run lint
npm run typecheck
npm test# Control plane
npm test -w @open-inspect/control-plane
npm run test:integration -w @open-inspect/control-plane
# Web
npm test -w @open-inspect/web
# Bots
npm test -w @open-inspect/github-bot
npm test -w @open-inspect/slack-bot
npm test -w @open-inspect/linear-botcd packages/modal-infra
# preferred (sandbox-runtime resolved automatically via uv.lock)
uv sync --frozen --extra dev
# alternative (install sandbox-runtime sibling package first)
pip install -e ../sandbox-runtime
pip install -e ".[dev]"
pytest tests/ -vFor full infrastructure setup, use:
Critical notes before deploy:
- Build workers before running Terraform apply.
- Build
@open-inspect/sharedfirst. - Use two-phase Terraform deploy for DO/service bindings.
- For Modal deployments, deploy with
modal deploy deploy.py(notsrc/app.py).
Your GitHub callback URL does not exactly match the running app URL.
Check ALLOWED_USERS, ALLOWED_EMAIL_DOMAINS, and ALLOWED_GITHUB_ORGS in
packages/web/.env.local. If ALLOWED_GITHUB_ORGS is set, make sure your GitHub App has
Organization permissions: Members read-only and that the updated permission was republished and
approved for the installation.
INTERNAL_CALLBACK_SECRET in web env does not match the control plane secret.
For deployed control plane use wss://..., for local control plane use ws://....
The control plane cannot reach the configured sandbox backend, or that backend is not properly configured/deployed.
- Architecture and internals: docs/HOW_IT_WORKS.md
- Full production deployment: docs/GETTING_STARTED.md
- GitHub integration usage: docs/integrations/GITHUB.md
- Linear integration usage: docs/integrations/LINEAR.md
- Debugging and observability: docs/DEBUGGING_PLAYBOOK.md
- Available models: docs/AVAILABLE_MODELS.md
- OpenAI model setup: docs/OPENAI_MODELS.md
- Contribution workflow: CONTRIBUTING.md