Skip to content

DiLoCo proxy: tag upstream 401/403 with X-Upstream-Auth-Failed to suppress reauth bounce #94

@jdinalt

Description

@jdinalt

The webui's fetch wrapper at `webui/src/auth.ts:82-83` already suppresses the auth-required event when the response carries `X-Upstream-Auth-Failed: 1`. The inference proxy, dataset_server proxy, and cluster proxy all set this header on upstream 401/403:

  • `tools/forgather_server/routes/inference_proxy.py:268`
  • `tools/forgather_server/routes/dataset_server.py:429`
  • `tools/forgather_server/routes/cluster.py:3301`

The DiLoCo proxy at `tools/forgather_server/routes/diloco.py` (added in PR #93) does not. So when the upstream DiLoCo server legitimately returns 401 (e.g. the operator's registry token is stale, or the per-port file got out of sync), the webui treats it as a session-expired and bounces the operator to the login screen.

This regresses the spirit of PR #86 / issue #81 ("webui: only force reauth on 401"), even though that PR's actual code wasn't broken — DiLoCo just doesn't yet participate in the X-Upstream-Auth-Failed protocol.

Fix

In `routes/diloco.py`:

  1. Add `_UPSTREAM_AUTH_FAILED_HEADER = "x-upstream-auth-failed"` constant.
  2. Add `_upstream_auth_headers(status: int) -> Dict[str, str]` returning the tag for 401/403, mirroring the dataset_server pattern.
  3. Apply the tag in the proxy's response construction (`_proxy_get` and `proxy_control`).
  4. Test that an upstream 401 surfaces with the tag.

This is a small fix; the only reason it wasn't included in PR #93 is I didn't realize the webui side already expected the protocol.

Reproduction

  1. Configure a DiLoCo server registry entry with a stale token.
  2. Click the entry in the DiLoCo view.
  3. Observe: bounced to login.

Acceptance

  • Upstream 401/403 from a DiLoCo proxy endpoint surfaces in the UI as an inline error ("upstream auth failed") rather than a login redirect.
  • Webui keeps the operator's session intact.

Cross-references: PR #86, issue #81, PR #93.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions