can1357/oh-my-pi · critical · HTTPException

gh-proxy: ROBOMP_GH_PROXY_HMAC_KEY not configured

Error message

gh-proxy: ROBOMP_GH_PROXY_HMAC_KEY not configured

What it means

HMAC request authentication needs the shared secret from ROBOMP_GH_PROXY_HMAC_KEY. `_resolve_hmac_key`, invoked by `_authenticate` on every authenticated request, raises this HTTP 500 when the setting is absent, so no request can be verified.

Source

Thrown at python/robomp/src/proxy/server.py:231

def _workspace_repo_dir(cfg: Settings, workspace_key: str) -> Path:
    # Defense-in-depth: workspace_key is constructed by `sandbox.workspace_key`
    # as `<repo_with_underscores>__<number>`. Reject anything outside that shape.
    if "/" in workspace_key or workspace_key.startswith(".") or ".." in workspace_key:
        raise HTTPException(400, f"invalid workspace_key {workspace_key!r}")
    return Path(cfg.workspace_root) / workspace_key / "repo"


def _resolve_token(cfg: Settings) -> str:
    if cfg.github_token is None:
        # Will already have been caught at startup, but stay defensive.
        raise HTTPException(500, "gh-proxy: GITHUB_TOKEN not configured")
    return cfg.github_token.get_secret_value()


def _resolve_hmac_key(cfg: Settings) -> bytes:
    if cfg.gh_proxy_hmac_key is None:
        raise HTTPException(500, "gh-proxy: ROBOMP_GH_PROXY_HMAC_KEY not configured")
    return cfg.gh_proxy_hmac_key.get_secret_value().encode("utf-8")


_ORIGIN_READ_TIMEOUT_SECONDS = 5.0


_REMOTE_HELPER_RE = re.compile(r"^[A-Za-z][A-Za-z0-9+.-]*::")
_FORBIDDEN_URL_BYTES_RE = re.compile(r"[\x00-\x1f\x7f]|%(?:00|0a|0d)", re.IGNORECASE)
_GITHUB_REPO_RE = re.compile(r"^[A-Za-z0-9][A-Za-z0-9-]{0,38}/[A-Za-z0-9._-]+$")
_GIT_PROBE_SCRUBBED_ENV_KEYS = (
    "ROBOMP_GIT_HTTP_AUTH",
    "GITHUB_TOKEN",
    "GH_TOKEN",
    "GITHUB_WEBHOOK_SECRET",
    "ROBOMP_REPLAY_TOKEN",
    "ROBOMP_GH_PROXY_HMAC_KEY",
)

View on GitHub (pinned to 9690622007)

Solutions

  1. Set ROBOMP_GH_PROXY_HMAC_KEY (the shared HMAC secret) in the proxy's environment and restart.
  2. Verify the exact env var spelling — a typo makes the settings field None and triggers this error.
  3. Ensure client and server use the same secret value so HMAC signatures verify after startup succeeds.
  4. In deployments, wire the secret via your secrets manager and confirm the container actually receives it (e.g. docker inspect / kubectl describe).

Example fix

// before
services:
  gh-proxy:
    environment: [GITHUB_TOKEN]
// after
services:
  gh-proxy:
    environment: [GITHUB_TOKEN, ROBOMP_GH_PROXY_HMAC_KEY]
Defensive patterns

Strategy: fallback

Validate before calling

import os
key = os.environ.get("ROBOMP_GH_PROXY_HMAC_KEY")
if not key:
    raise RuntimeError("ROBOMP_GH_PROXY_HMAC_KEY must be set on the gh-proxy server")

Type guard

def has_hmac_key(cfg: object) -> TypeGuard[object]:
    return getattr(cfg, "gh_proxy_hmac_key", None) is not None

Try / catch

try:
    resp = http.post(f"{base}/git/fetch", json=payload, headers=sign(payload))
    resp.raise_for_status()
except httpx.HTTPStatusError as e:
    if e.response.status_code == 500 and "HMAC_KEY not configured" in e.response.text:
        raise RuntimeError("gh-proxy missing ROBOMP_GH_PROXY_HMAC_KEY; configure and restart") from e
    raise

Prevention

When it happens

Trigger: Any proxied request reaching _authenticate while the proxy process was started without ROBOMP_GH_PROXY_HMAC_KEY configured.

Common situations: Clients and server deployed from the same template but the server manifest omits the HMAC secret; local dev runs without the .env; secret rotated on clients but not added to the server; typo in the env var name so the loader sees None.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/3291d9131ccd3e85. Report an issue: GitHub.