Skip to content

Append agent/<id> to the User-Agent when driven by an AI coding agent - #219

Draft
ctufts wants to merge 5 commits into
masterfrom
agi-1011-agent-user-agent
Draft

ctufts wants to merge 5 commits into
masterfrom
agi-1011-agent-user-agent

Conversation

@ctufts

@ctufts ctufts commented Jul 17, 2026

Copy link
Copy Markdown

Detects the calling AI coding agent (Claude Code, Codex, Cursor, etc.) from a hardcoded environment-variable allowlist and appends agent/<id> to the tilesets Session User-Agent header when a match is found. The header is unchanged if nothing matches.

This doesn't change anything server-side or forward the environment: CloudFront already logs the User-Agent, and the agent's environment is already visible to this CLI's own subprocess.

agent_detect.py::detect_agent() checks about 22 harness-specific env vars in a fixed precedence order (most are presence-only checks; warp and vtcode require an exact value match), then falls back to AI_AGENT/AGENT if nothing else matched. That fallback is restricted to a safe charset so a stray value, like a newline, can't reach the header and break requests. The full environment is never read, logged, or transmitted, only the matched id.

Tested with pytest tests/test_agent_detect.py tests/test_utils.py (34 passing), plus a manual check of _get_session()'s header: a positive case (CLAUDECODE=1 -> .../<version> agent/claude-code) and a negative control (agent vars unset, header unchanged). This is a client-side header change with no server dependency, so there's no downstream or operational impact.

ctufts added 2 commits July 17, 2026 16:50
Detects the calling AI coding agent from a hardcoded env-var allowlist and
appends " agent/<id>" to the tilesets Session User-Agent when one is found.
No server dependency: the header is already logged by CloudFront, and the
agent's environment is directly visible to this CLI's subprocess.
- Reject fallback (AI_AGENT/AGENT) values outside a safe header charset so a
  stray newline/colon can no longer crash every CLI command with
  requests.exceptions.InvalidHeader.
- Treat empty/whitespace-only harness env vars as unset, matching the
  fallback path's existing empty-value handling.
@ctufts ctufts added the locationai-team-skills Opened via the location-ai PR creation skill label Jul 17, 2026
Comment thread mapbox_tilesets/agent_detect.py Outdated
Per review feedback (#219, line 70), the fallback
detector should only check whether AI_AGENT/AGENT is present, never
read and forward its value - an arbitrary, unvalidated string should
not become an "agent id" in production telemetry. Fold the fallback
into the allowlist itself as its lowest-precedence entry, returning a
fixed `custom-agent` id on presence instead of the variable's value.
This also removes the charset/length validation that existed only to
sanitize that value, since every returned id is now a fixed literal.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@ox-security

ox-security Bot commented Sep 10, 2026

Copy link
Copy Markdown

OX Security Logo

OX Security reviewed this pull request — nothing to fix.

No issues found

Branch agi-1011-agent-user-agentmaster

View scan in OX Security →

ctufts and others added 2 commits September 10, 2026 14:48
The allowlist's presence-check branch (expected is None) required a
non-empty, non-whitespace value, so an env var explicitly set to "" or
whitespace was treated as unset. Per feedback, existence is all that
should matter - whether the key is present at all, not what it's set
to. Check membership directly instead of stripping and testing
truthiness.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Every allowlist entry now tests presence only, never a value: collapse
the table from (agent_id, [(env_var, expected_value_or_None), ...]) to
a flat (agent_id, [env_var, ...]), and drop the equality-check branch
in detect_agent entirely.

The warp entry compared TERM_PROGRAM against "WarpTerminal" - dropped
outright, since TERM_PROGRAM is set by most terminal emulators (iTerm2,
Apple Terminal, VS Code, Hyper, ...), not just Warp, and an
existence-only check on it would misidentify most terminal sessions.
vtcode's VTCODE has no such collision risk and stays as a plain
presence check.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

locationai-team-skills Opened via the location-ai PR creation skill

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant