Repository navigation
v1.12.3
A patch release over 1.12.2. Whitespace around the controller's bearer token and the skills curator's API key no longer
matters, and one security fix: an API_BEARER_TOKEN made only of whitespace worked as a credential. Update the
controller (its image, or your source checkout) to get the fixes. The client, LangChain and MCP bridge packages change
too: they strip the token they send. If your token has spaces or tabs around it, update the controller before the
clients (Upgrade notes).
Upgrade notes
- The 32-character floor for
API_BEARER_TOKEN(production, or reachable off the box) now measures the token without
its surrounding whitespace. A token that cleared it only because of padding is refused at startup; replace it with a
longer one. - If your
API_BEARER_TOKENhas spaces or tabs around it, update the controller before the clients. The new clients
send the token stripped, which an older controller compares with the padded value and refuses; the new controller
accepts both.
Security
- An
API_BEARER_TOKENmade only of whitespace is no longer a credential (#252). It was compared like any other
token, soBearerfollowed by the same whitespace authenticated under uvicorn's default HTTP parser, and a run of 32
or more spaces even cleared the production length floor at startup. It now counts as unset, as an empty
API_BEARER_TOKEN=already did. Without namedAPI_BEARER_TOKENS, a controller reachable off the box or running with
APP_ENV=productionrefuses to start ("API_BEARER_TOKEN is required"), and one on loopback otherwise runs as the
documented no-token default and logs the existing warning. Exploiting it needed an operator to have set such a token;
nothing ships one.
Fixed
- Whitespace around the bearer token no longer matters (#252). The controller compared the whole
Authorization
header withBearer <API_BEARER_TOKEN>, byte for byte, so a token pasted with a space or newline around it matched
only a client that sent the same whitespace, and a trailing newline (common in secret files) matched nothing the HTTP
parser would pass through. The controller now stripsAPI_BEARER_TOKENandWITNESS_REMOTE_API_KEY(named
API_BEARER_TOKENSwere already stripped), and ignores spaces and tabs around the token in the header it receives
(Bearermust still be followed by a space), so curl, the repo's shell helpers and third-party MCP clients that send
a padded token still match. The rate limiter keys on the same normalized header, so every spelling of one token shares
its bucket. The first-party senders strip the token before sending: the MCP stdio bridge (--bearer-token,
AUTO_BROWSER_BEARER_TOKEN), the Python SDK client, the LangChainAutoBrowserToolandAutoBrowserNode, the eval
client behindscripts/agent_eval.py, and the dashboard. A client given a whitespace-only token sends no
Authorizationheader. Padding the HTTP library refused (a newline after the bridge's token, a space before the
witness key) used to put the whole value in the bridge's error reply and in the controller's witness-delivery warning;
it is stripped before sending now. - The skills curator's API key is stripped too (#251). 1.12.2 strips whitespace around the eight provider keys in
the controller's settings, but the curator (CURATOR_ENABLED) readsANTHROPIC_API_KEY,OPENAI_API_KEYor
GEMINI_API_KEYfrom the environment itself, so a key with a space or newline around it still went out as-is and the
provider refused it. The curator now strips it as well, and a key that is only whitespace counts as unset.