HKUDS/Vibe-Trading · error · HTTPException

Settings writes require API_AUTH_KEY or a local loopback cli

Error message

Settings writes require API_AUTH_KEY or a local loopback client

What it means

When no API_AUTH_KEY is configured, settings writes fall back to loopback-only trust: any non-local client attempting to modify settings gets 403. Because writes change credential routing, the key-less mode is intentionally stricter than simple reads that might be public.

Source

Thrown at agent/src/api/security.py:653

            status_code=status.HTTP_403_FORBIDDEN,
            detail="Settings access requires API_AUTH_KEY or a local loopback client",
        )


async def require_settings_write_auth(
    request: Request,
    cred: Optional[HTTPAuthorizationCredentials] = Security(_security),
) -> None:
    """Require explicit authorization before changing credential-routing settings."""
    api_key = _configured_api_key()
    if api_key:
        token = _auth_credential_from_header_or_query(cred, None, allow_query=False)
        if not token or not hmac.compare_digest(token, api_key):
            raise HTTPException(status_code=401, detail="Invalid or missing API key")
        return

    if not _is_local_client(request):
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Settings writes require API_AUTH_KEY or a local loopback client",
        )


_LEGACY_LAZY_NAMES = {
    "_API_KEY": _get_api_key,
    "_CORS_ORIGINS": _get_cors_origins,
    "_EXTRA_LOOPBACK_HOSTS": _get_extra_loopback_hosts,
}


def __getattr__(name: str):
    if name in _LEGACY_LAZY_NAMES:
        return _LEGACY_LAZY_NAMES[name]()
    raise AttributeError(f"module {__name__!r} has no attribute {name!r}")

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Set API_AUTH_KEY on the server and send it in the Authorization header for any remote settings write
  2. Perform key-less writes only from the same host via 127.0.0.1
  3. Fix proxy/container networking so the real client IP is visible if loopback trust is intended
  4. Bind dev servers to loopback so remote write attempts can't happen by accident

Example fix

# before (server key-less, remote client)
curl -X PATCH http://10.0.0.5:8000/settings/routing -d '{...}'   # 403

# after
# on server: export API_AUTH_KEY=...; restart
curl -X PATCH http://10.0.0.5:8000/settings/routing -H "Authorization: Bearer $API_AUTH_KEY" -d '{...}'
Defensive patterns

Strategy: validation

Validate before calling

import os
from urllib.parse import urlparse
assert os.environ.get("API_AUTH_KEY") or urlparse(BASE).hostname in ("127.0.0.1", "localhost"), \
    "Remote settings writes are 403 without API_AUTH_KEY"

Try / catch

try:
    r = client.patch("/settings/routing", json=payload); r.raise_for_status()
except httpx.HTTPStatusError as e:
    if e.response.status_code == 403:
        raise RuntimeError("Loopback-only writes: set API_AUTH_KEY for remote writes") from e
    raise

Prevention

When it happens

Trigger: A settings write (PATCH/POST) from a non-loopback client address on a server where API_AUTH_KEY is unset/empty.

Common situations: Remote admin script or dashboard writing settings on a dev box without a key; containerized control plane calling the API across the bridge network; accessing the API through its LAN hostname; proxy making requests appear non-local.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/31a8f217d017dd5f. Report an issue: GitHub.