fix(ingestion): authenticate the REST API as a whole, not route by route

Only /mcp was wrapped in BearerMiddleware; /query, /write, /ingest*,
/promote, /pending and the rest on the same mux had no auth, and
infra#517 found them on the internet (mitigated there by narrowing the
ingress). They are still open on the tailnet and LAN NodePort 30330.

mountREST puts the REST routes on their own mux, mounted at "/" behind
the same bearer middleware and credential as /mcp. Routes registered on
the outer mux stay explicitly public (/mcp has its own auth, /capture,
the HMAC webhook, OAuth metadata, /metrics); anything else, including a
route added later, is authenticated by default.

The hyperguild CLI (cmd/hyperguild and internal/brain) now sends
BRAIN_MCP_TOKEN, which it never did. brain-ui and brain-ingest-ntfy
already send theirs.

Refs #149

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-03 16:17:45 +02:00
co-authored by Claude Opus 5.5
parent a6da93332d
commit 99fedeaa98
7 changed files with 192 additions and 11 deletions
+5
View File
@@ -13,6 +13,7 @@ import (
"io"
"log/slog"
"net/http"
"os"
"strings"
)
@@ -42,6 +43,10 @@ func Query(ctx context.Context, baseURL, query string, limit int) (string, error
return "", nil
}
req.Header.Set("Content-Type", "application/json")
// The REST API requires a bearer token since hyperguild#149.
if tok := os.Getenv("BRAIN_MCP_TOKEN"); tok != "" {
req.Header.Set("Authorization", "Bearer "+tok)
}
resp, err := http.DefaultClient.Do(req)
if err != nil {