Affected Component
server/core/auth.py, api/v1-contract.md
What I found
server/core/auth.py:40 accepts the API key from either place:
provided = request.headers.get("X-API-Key") or request.query_params.get("api_key")
The contract documents only the header (api/v1-contract.md:14). The query-string channel is real and works, but appears in no doc I could find.
That matters because a credential in a query string ends up in places a header does not: reverse-proxy and access logs, browser history, and Referer headers on any outbound link. The module docstring mentions ?api_key=, so it looks deliberate rather than accidental — but an undocumented credential channel is hard for an operator to reason about when they are deciding what their logs may contain.
Suggested resolution
Whichever of these matches the intent:
- Keep it and document it in the contract, with an explicit note that it is for callers that cannot set headers (browser
EventSource, some webhook senders) and that it will be logged.
- Drop it, if nothing depends on it, and leave
X-API-Key as the single channel.
Happy to send a PR for either once someone says which.
Environment
Read at 1.5.0 (statewavedev/statewave:latest).
Affected Component
server/core/auth.py,api/v1-contract.mdWhat I found
server/core/auth.py:40accepts the API key from either place:The contract documents only the header (
api/v1-contract.md:14). The query-string channel is real and works, but appears in no doc I could find.That matters because a credential in a query string ends up in places a header does not: reverse-proxy and access logs, browser history, and
Refererheaders on any outbound link. The module docstring mentions?api_key=, so it looks deliberate rather than accidental — but an undocumented credential channel is hard for an operator to reason about when they are deciding what their logs may contain.Suggested resolution
Whichever of these matches the intent:
EventSource, some webhook senders) and that it will be logged.X-API-Keyas the single channel.Happy to send a PR for either once someone says which.
Environment
Read at 1.5.0 (
statewavedev/statewave:latest).