Repository navigation
Description
Problem
The v1 auth field can only put the key in a request header:
"bearer"sendsAuthorization: Bearer <key>{"header": name, "prefix"?: text}sends<name>: [<prefix> ]<key>
(v1/schema.json $defs.auth; scripts/probe.mjs authHeader, which mirrors
Sprites.Gateway.Connector.auth_header/2.)
Some APIs accept credentials only as request parameters. Pushover
is one of them. Every endpoint takes the application token as a token
parameter, sent in the form-encoded body for POSTs and in the query string for
GETs. Pushover documents no header-based auth at all. So a Pushover connector
cannot be written in v1, and the only alternative is for the Sprite to hold the
token itself, which defeats the point of a connector.
Proposal
Add a parameter-based auth form alongside the header form, for example:
"auth": {"query": "token"}The gateway would set token=<key> in the query string of every forwarded
request and of the probe.
Requirements:
- Override, don't append. The gateway removes any
tokenparameter the
Sprite supplied before it adds its own. Otherwise a Sprite could swap in a
different key, or the API could receive the parameter twice and resolve the
duplicate unpredictably. - Redaction. The key now appears in the URL. Gateway request logs, error
reports, andprobe.mjs --write-fixturemust redact the URL, not only
headers.probe.mjscurrently records the request URL without redaction. - Probe and checker parity. Update
authHeader/buildProbeRequestin
scripts/probe.mjsand its tests to match the gateway's behaviour.
Query injection is enough for Pushover (verified)
Pushover documents token only as a body parameter for
POST /1/messages.json, but it also accepts the token in the query string.
This was tested on 2026-10-14 by calling Pushover directly, without the
gateway:
curl -s -X POST "https://api.pushover.net/1/messages.json?token=$PUSHOVER_TOKEN" \
--data-urlencode "user=$PUSHOVER_USER" \
--data-urlencode "message=sprites connector query-param test"
# {"status":1,"request":"e6d80a48-55b7-48d4-9c4f-c42eb069c5bf"}The message was delivered. Body-parameter injection, which would mean
re-encoding form and JSON bodies and recomputing content-length, is not
needed for this connector. Because the query-string behaviour is undocumented,
the connector should note that it relies on it.
A second fixed parameter (out of scope, noted for completeness)
Pushover's POST /1/messages.json also requires a user key, which is a
second secret identifying the recipient. CONTRIBUTING.md rules out "any secret
beyond the key", so even with parameter auth the Sprite would pass user
itself. That is acceptable for Pushover, because the user key cannot send
messages without an app token. I am not proposing a second injected secret
here.
Pushover connector this would unblock
base_url:https://api.pushover.net- Probe:
GET /1/apps/limits.json. It validates the token, has no side
effects, and returns{"limit":10000,"remaining":…,"reset":…,"status":1}. - Routes:
POST /1/messages.json,POST /1/users/validate.json,
GET /1/apps/limits.json,GET /1/receipts/{receipt}.json. The receipts route works today as pattern
/1/receipts/:receiptwith"path_param": "\\A[A-Za-z0-9]+\\.json\\z"
(checked againstscripts/lib/routes.mjs). It does not match
/1/receipts/X.json/cancel.json, so canceling receipts stays excluded. Routes for
groups, teams, subscriptions, licensing, glances, and the Open Client API are
excluded. - Operational notes for users: the message limit is 1,024 characters. Each
account gets 10,000 messages per month, and Pushover returns 429 when they
run out. Pushover temporarily blocks IPs that send repeated 4xx requests,
and all connector traffic comes from the shared gateway IP, so one
misbehaving Sprite could block every Pushover user of the gateway. That
shared-IP risk should be weighed when reviewing this connector, separately
from the schema change.
Activity
[-]v1 manifest: support sending the key as a query or body parameter (blocks Pushover)[/-][+]v1 manifest: support sending the key as a query parameter (blocks Pushover)[/+]aezell commentedon Oct 15, 2026
Thanks for this report. We can definitely support auth like this for community connectors. I'm working on it now!
aezell commentedon Oct 15, 2026
From this repository's side: the manifest format now accepts
"auth": {"query": "token"}(#6), pending the gateway release that understands it (superfly/sprites-api#1574). Both requirements hold as specified here: the gateway andscripts/probe.mjsreplace every parameter of that name the caller sent rather than appending, and the key, raw and URL-encoded, is redacted from everything the probe runner prints or records, including bodies and headers that echo the request URL. The contributor guide now describes the form, asks query-auth connectors to say in a notice that the key travels in the URL, and asks those whose API echoes request URLs in error bodies to setgateway_error_messagestofalse. The shared-IP concern for Pushover is a property of that connector rather than of the format; it will be weighed when the Pushover connector PR is reviewed.Support query-parameter auth (refs #5) (#6)
aezell commentedon Oct 15, 2026
@stahnma I've added support for query parameter auth. If you could try the Pushover connector PR again and let me know how it goes, I'd appreciate it. Thanks again!
stahnma commentedon Oct 16, 2026
Thanks @aezell, query auth works for Pushover. The connector is up in #7.
"auth": {"query": "token"}withscripts/probe.mjs: the probe passes with a real application token, and a wrong token is classified asinvalid_api_key(fixtures for both are in the PR).gateway_error_messagesat its default.POST /1/messages.jsonwith the token in the query string worked with both form-encoded and JSON bodies, tested directly against Pushover.I haven't tested through the gateway itself, since that depends on superfly/sprites-api#1574 being released. The shared-IP question from this issue is listed for review in #7.
Posted by Claude Code on behalf of @stahnma.
Add Pushover community connector (#7)