> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sesameterminal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 0008. Public health check, authenticated status

# 0008. Public health check, authenticated status

* **Status:** Accepted
* **Date:** 2026-09-30

## Context

In Phase 0, `GET /api/health` was public and returned the backend version, whether
trading was enabled, and the geoblock result with country and region. The Phase 0
security review (finding F20) noted that anyone who can reach the server could learn:

* the software version, which helps target known flaws;
* whether live trading is on, which marks the host as worth attacking;
* where the server is, from the geoblock country and region.

A public endpoint is still needed. A container runtime, a reverse proxy or an uptime
monitor has to check that the process is up without holding a session.

## Decision

* `GET /api/health` stays public and returns only `{"status": "ok" | "degraded"}` with
  HTTP 200. When the backend reports `degraded` is defined by implementation.
* `GET /api/status` requires a session and returns `version`, `trading_enabled`,
  `geoblock` and `feeds`. It is a `GET`, so it needs no CSRF token.
* The same `Status` object is sent on the authenticated `status` WebSocket topic.
* No other public endpoint returns version, trading state, location, account or feed
  details.

This moves the fields that [ADR 0005](0005-no-geoblock-workarounds.md) said were on
`/api/health`.

## Consequences

* An unauthenticated visitor learns only that the service is up and whether it is
  degraded.
* Liveness checks keep working without credentials. A check must read the body to tell
  `ok` from `degraded`, because both return 200.
* Checking the geoblock result or `trading_enabled` needs a login: through the UI's status
  indicator, or by opening `/api/status` in the logged-in browser. `curl` against
  `/api/health` no longer shows them.
* The UI reads status from the WebSocket topic and the REST endpoint, which serve the
  same state.

## Alternatives considered

* **Keep all details on the public endpoint.** Rejected: finding F20.
* **Require a session for `/health` as well.** Rejected. Liveness checks would need a
  credential, and a stored session for a monitor is a new secret to protect.
* **Show details only to requests from localhost.** Rejected. Behind the reverse proxy
  every request arrives from localhost, so the details would be public again; the backend
  does not trust proxy headers to find the real client.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.