---
title: "Install-first server startup and safer auth boundaries"
date: "2026-04-21"
---

<Warning>
**Fabro now expects one public API and web origin for browser auth.** Deployments should route API and web traffic through the same external origin, then set `server.api.url` and `server.web.url` to that origin.

To migrate:
1. Put API and web traffic behind the same public origin.
2. Update `settings.toml` so both URLs point at that origin.
3. Re-run `fabro auth login` from clients that still have old target metadata.
</Warning>

## `fabro server start` is the setup path

The happy path for a fresh machine now starts with the server itself. If settings do not exist yet, `fabro server start` enters install mode, opens the browser wizard, and guides you through configuring the deployment before normal server traffic begins.

```bash
fabro server start
```

The install flow no longer enables dev-token material when GitHub App auth is selected, keeps loading states visible until the install session resolves, and carries GitHub App manifest state as form data instead of URL query data.

## Auth failures are easier to recover from

CLI commands now return exit code `4` for authentication-required failures, giving scripts a stable signal that the user needs to log in. When a GitHub-authenticated server has no runs yet, the blank-slate quick start in the web app starts with `fabro auth login` so the first command users copy is the one they actually need.

The OAuth callback and CLI resume pages were restyled to match the Fabro app, making browser auth feel like part of the product instead of a detached server page.

## More

<Accordion title="CLI">
- Added exit code `4` for authentication-required command failures
- `fabro exec` now classifies auth-required responses consistently with other server commands
</Accordion>

<Accordion title="Improvements">
- Browser auth and CLI resume pages now use the Fabro auth theme
- API status types now reuse the domain run status shape in generated Rust API types
- GitHub auth translation now converts non-JWT auth into bearer tokens before request handling
</Accordion>

<Accordion title="Fixes">
- Fixed markdown links in run stage output so unsafe links are sanitized before rendering
- Fixed detached MCP launch commands by shell-quoting interpolated command values
- Fixed event replay so unknown stage statuses do not stop run event streaming
- Fixed Linux process checks so zombie-only process groups are treated as stopped
- Restricted CLI start session reuse to GitHub-authenticated sessions
</Accordion>
