Skip to content

Commit a572d36

Browse files
Nick Websterclaude
andcommitted
docs(v0.9): file R-v0.9-NEW-16 — no User-Agent header on outbound requests
Surfaced by a user inspection of the transport layer at v0.10 candidate-selection close-out (post-handoff). src/api/transport.ts: 102-107 (JSON) and src/api/multipart-transport.ts (multipart) set exactly three headers — Authorization, API-Version, Content-Type — with zero hits across src/ for user-agent. Node's global fetch (undici) therefore sends the default literal `User-Agent: node` (live-confirmed via httpbin probe at Node v24.10.0), indistinguishable from any other Node script hitting Monday's API. Filed LOW-priority because no shipped bug — Monday accepts requests fine, agents see no failure mode. But the gap is real: Monday's ops/abuse teams can't correlate traffic to monday-cli, can't selectively rate-limit by UA, can't whitelist us; an issue report carrying "monday-cli sent these calls" can't be cross-referenced against Monday-side logs. Lift adds a `monday-cli/<version> (node/<node-version>)` header on both transports + extends the reservedHeaderLowerNames set (matches the existing header-lockdown discipline at transport.ts:90-94 + security.md "Header lockdown"). Trigger: any session touching transport headers, a Monday ops request, a debugging session needing UA correlation, or a ride-along on an unrelated milestone already in src/api/transport.ts. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 317ae04 commit a572d36

1 file changed

Lines changed: 52 additions & 0 deletions

File tree

docs/v0.9-plan.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,3 +1450,55 @@ pending the user):
14501450
drifts AND the release-prep checklist fails to catch it.
14511451
Cross-refs R-NEW-82 (the release-prep cross-doc grep sibling —
14521452
the same audit-discipline muscle applied to a different surface).
1453+
1454+
- **R-v0.9-NEW-16 — No `User-Agent` header on outbound requests**
1455+
(code / observability gap, watch-item). Filed at v0.10
1456+
candidate-selection close-out (2026-05-22), surfaced by a user
1457+
inspection of the transport layer.
1458+
`src/api/transport.ts:102-107` (JSON) and
1459+
`src/api/multipart-transport.ts` (multipart) construct exactly
1460+
three caller-visible headers — `Authorization`, `API-Version`,
1461+
`Content-Type` — with zero hits across `src/` for `user-agent`.
1462+
Node's global `fetch` (undici) therefore sends the default literal
1463+
`User-Agent: node` (live-confirmed via httpbin probe 2026-05-22 at
1464+
Node v24.10.0), indistinguishable from any other Node script
1465+
targeting Monday's API. Monday's ops/abuse teams can't correlate
1466+
traffic to the CLI, can't selectively rate-limit by UA, can't
1467+
whitelist us; and an issue report carrying "`monday-cli` sent
1468+
these calls" can't be cross-referenced against Monday-side logs.
1469+
1470+
**Candidate:** add a `User-Agent` header on both transports with a
1471+
polite identifiable shape — e.g. `monday-cli/<version>
1472+
(node/<node-version>)` — sourced from `package.json` at startup
1473+
(single `getUserAgent()` helper in `src/api/transport.ts` or a new
1474+
`src/api/user-agent.ts`). Add `user-agent` to the
1475+
`reservedHeaderLowerNames` set at `transport.ts:90-94` so
1476+
caller-supplied headers can't spoof it (matches the `Authorization`
1477+
/ `API-Version` / `Content-Type` header-lockdown discipline +
1478+
`security.md` "Header lockdown" rule). The same UA goes on the
1479+
multipart transport via the parallel header-construction path.
1480+
Test surface: extend the existing transport unit tests with a
1481+
UA-presence assertion + a caller-spoofing-rejection assertion (the
1482+
reserved-set sibling test pattern).
1483+
1484+
**Cost / over-fit notes:** trivial. One helper + two
1485+
header-bag insertions + two `reservedHeaderLowerNames` updates +
1486+
~3 test additions. No new wire surface, no new ERROR_CODE, no
1487+
envelope change. The SDK-typed path (`@mondaydotcomorg/api`) may
1488+
set its own UA; the raw-GraphQL `client.request<T>()` legs + the
1489+
multipart upload path both go through our transport which doesn't,
1490+
so the CLI is "partly identifiable" today depending on call path —
1491+
the lift normalises this.
1492+
1493+
**Priority:** LOW (no shipped bug; identification / observability
1494+
gap only — Monday accepts the requests fine, agents see no failure
1495+
mode). **1st instance:** 2026-05-22 transport-layer audit at v0.10
1496+
candidate-selection close-out. **Trigger:** any session touching
1497+
the transport headers, OR a Monday-side request from their ops
1498+
team for identifiable traffic, OR a coordinated CLI / server-side
1499+
debugging session needing UA correlation, OR pre-flight on an
1500+
unrelated milestone that already touches `src/api/transport.ts`
1501+
(lift the header alongside as a small ride). Cross-refs the
1502+
`security.md` "Header lockdown" rule (the reserved-set discipline
1503+
the new header would extend) + `monday-api.md` (the endpoint
1504+
contract).

0 commit comments

Comments
 (0)