sandbox-agent/docs/deploy/foundry-self-hosting.mdx
Nathan Flurry d8b8b49f37
Fix Foundry UI bugs: org names, sessions, and repo selection (#250)
* Fix Foundry auth: migrate to Better Auth adapter, fix access token retrieval

- Remove @ts-nocheck from better-auth.ts, auth-user/index.ts, app-shell.ts
  and fix all type errors
- Fix getAccessTokenForSession: read GitHub token directly from account
  record instead of calling Better Auth's internal /get-access-token
  endpoint which returns 403 on server-side calls
- Re-implement workspaceAuth helper functions (workspaceAuthColumn,
  normalizeAuthValue, workspaceAuthClause, workspaceAuthWhere) that were
  accidentally deleted
- Remove all retry logic (withRetries, isRetryableAppActorError)
- Implement CORS origin allowlist from configured environment
- Document cachedAppWorkspace singleton pattern
- Add inline org sync fallback in buildAppSnapshot for post-OAuth flow
- Add no-retry rule to CLAUDE.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Add Foundry dev panel from fix-git-data branch

Port the dev panel component that was left out when PR #243 was replaced
by PR #247. Adapted to remove runtime/mock-debug references that don't
exist on the current branch.

- Toggle with Shift+D, persists visibility to localStorage
- Shows context, session, GitHub sync status sections
- Dev-only (import.meta.env.DEV)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Add full Docker image defaults, fix actor deadlocks, and improve dev experience

- Add Dockerfile.full and --all flag to install-agent CLI for pre-built images
- Centralize Docker image constant (FULL_IMAGE) pinned to 0.3.1-full
- Remove examples/shared/Dockerfile{,.dev} and daytona snapshot example
- Expand Docker docs with full runnable Dockerfile
- Fix self-deadlock in createWorkbenchSession (fire-and-forget provisioning)
- Audit and convert 12 task actions from wait:true to wait:false
- Add bun --hot for dev backend hot reload
- Remove --force from pnpm install in dev Dockerfile for faster startup
- Add env_file support to compose.dev.yaml for automatic credential loading
- Add mock frontend compose config and dev panel
- Update CLAUDE.md with wait:true policy and dev environment setup

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* WIP: async action fixes and interest manager

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix Foundry UI bugs: org names, hanging sessions, and wrong repo creation

- Fix org display name using GitHub description instead of name field
- Fix createWorkbenchSession hanging when sandbox is provisioning
- Fix auto-session creation retry storm on errors
- Fix task creation using wrong repo due to React state race conditions
- Remove Bun hot-reload from backend Dockerfile (causes port drift)
- Add GitHub sync/install status to dev panel

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 20:48:22 -07:00

153 lines
4.3 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: "Foundry Self-Hosting"
description: "Environment, credentials, and deployment setup for Sandbox Agent Foundry auth, GitHub, and billing."
---
This guide documents the deployment contract for the Foundry product surface: app auth, GitHub onboarding, repository import, and billing.
It also covers the local-development bootstrap that uses `.env.development` only when `NODE_ENV=development`.
## Local Development
For backend local development, the Foundry backend now supports a development-only dotenv bootstrap:
- It loads `.env.development.local` and `.env.development`
- It does this **only** when `NODE_ENV=development`
- It does **not** load dotenv files in production
The example file lives at [`/.env.development.example`](https://github.com/rivet-dev/sandbox-agent/blob/main/.env.development.example).
To use it locally:
```bash
cp .env.development.example .env.development
```
Run the backend with:
```bash
just foundry-backend-start
```
That recipe sets `NODE_ENV=development`, which enables the dotenv loader.
### Local Defaults
These values can be safely defaulted for local development:
- `APP_URL=http://localhost:4173`
- `BETTER_AUTH_URL=http://localhost:7741`
- `BETTER_AUTH_SECRET=sandbox-agent-foundry-development-only-change-me`
- `GITHUB_REDIRECT_URI=http://localhost:7741/v1/auth/callback/github`
These should be treated as development-only values.
## Production Environment
For production or self-hosting, set these as real environment variables in your deployment platform. Do not rely on dotenv file loading.
### App/Auth
| Variable | Required | Notes |
|---|---:|---|
| `APP_URL` | Yes | Public frontend origin |
| `BETTER_AUTH_URL` | Yes | Public auth base URL |
| `BETTER_AUTH_SECRET` | Yes | Strong random secret for auth/session signing |
### GitHub OAuth
| Variable | Required | Notes |
|---|---:|---|
| `GITHUB_CLIENT_ID` | Yes | GitHub OAuth app client id |
| `GITHUB_CLIENT_SECRET` | Yes | GitHub OAuth app client secret |
| `GITHUB_REDIRECT_URI` | Yes | GitHub OAuth callback URL |
Use GitHub OAuth for:
- user sign-in
- user identity
- org selection
- access to the signed-in users GitHub context
## GitHub App
If your Foundry deployment uses GitHub App-backed organization install and repo import, also configure:
| Variable | Required | Notes |
|---|---:|---|
| `GITHUB_APP_ID` | Yes | GitHub App id |
| `GITHUB_APP_CLIENT_ID` | Yes | GitHub App client id |
| `GITHUB_APP_CLIENT_SECRET` | Yes | GitHub App client secret |
| `GITHUB_APP_PRIVATE_KEY` | Yes | PEM private key for installation auth |
For `.env.development` and `.env.development.local`, store `GITHUB_APP_PRIVATE_KEY` as a quoted single-line value with `\n` escapes instead of raw multi-line PEM text.
Recommended GitHub App permissions:
- Repository `Metadata: Read`
- Repository `Contents: Read & Write`
- Repository `Pull requests: Read & Write`
- Repository `Checks: Read`
- Repository `Commit statuses: Read`
Set the webhook URL to `https://<your-backend-host>/v1/webhooks/github` and generate a webhook secret. Store the secret as `GITHUB_WEBHOOK_SECRET`.
Recommended webhook subscriptions:
- `installation`
- `installation_repositories`
- `pull_request`
- `pull_request_review`
- `pull_request_review_comment`
- `push`
- `create`
- `delete`
- `check_suite`
- `check_run`
- `status`
Use the GitHub App for:
- installation/reconnect state
- org repo import
- repository sync
- PR creation and updates
Use GitHub OAuth for:
- who the user is
- which orgs they can choose
## Stripe
For live billing, configure:
| Variable | Required | Notes |
|---|---:|---|
| `STRIPE_SECRET_KEY` | Yes | Server-side Stripe secret key |
| `STRIPE_PUBLISHABLE_KEY` | Yes | Client-side Stripe publishable key |
| `STRIPE_WEBHOOK_SECRET` | Yes | Signing secret for billing webhooks |
| `STRIPE_PRICE_TEAM` | Yes | Stripe price id for the Team plan checkout session |
Stripe should own:
- hosted checkout
- billing portal
- subscription status
- invoice history
- webhook-driven state sync
## Mock Invariant
Foundrys mock client path should continue to work end to end even when the real auth/GitHub/Stripe path exists.
That includes:
- sign-in
- org selection/import
- settings
- billing UI
- workspace/task/session flow
- seat accrual
Use mock mode for deterministic UI review and local product development. Use the real env-backed path for integration and self-hosting.