Skip to content

feat: correlate web terminal sessions by session_id - #27677

Open
aqandrew wants to merge 5 commits into
devex-659-session-id-tracing-middlewarefrom
devex-663-web-terminal-session-id
Open

feat: correlate web terminal sessions by session_id#27677
aqandrew wants to merge 5 commits into
devex-659-session-id-tracing-middlewarefrom
devex-663-web-terminal-session-id

Conversation

@aqandrew

@aqandrew aqandrew commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

What

Implements the web terminal client half of the
Connection log collection and correlation RFC
(DEVEX-663). Generates a per-session correlation ID and attaches it to the
web terminal's requests and client logs so a single session can be traced end
to end.

Stacked on #27671 (DEVEX-659, the coderd tracing middleware that reads the
session_id baggage). Review/merge that first.

Changes

Session ID

  • New generateSessionId() util: a 16-byte value encoded as a 32-character hex
    string, per RFC requirement 1.
  • Minted once per web terminal session: on TerminalPage load and on
    AgentsPage terminal panel mount. Unlike the reconnection token, it is not
    persisted in the URL, so a reload (or a new tab) is a new session, matching the
    RFC's session definition.

Propagation

  • HTTP API request: the reconnecting-pty signed-token request carries the ID
    via W3C baggage (baggage: session_id=<hex>), which the DEVEX-659 middleware
    reads.
  • PTY WebSocket: browsers cannot set the baggage header on a WebSocket
    handshake (the codebase already works around this for the session token), so
    the ID is sent as a session_id query parameter instead. The reconnecting-pty
    WebSocket handler reads and validates it and attaches it to the request and PTY
    logs.

Client logs

  • The terminal's connection-error console.error logs now include session_id.

Telemetry: the web terminal emits none today, so there is nothing to tag
(confirmed with the issue reporter).

Testing

  • site: unit tests for generateSessionId (format + uniqueness) and
    terminalWebsocketUrl (query param). Updated TerminalPage.test.tsx (mocks the
    generator to a fixed ID and asserts the WebSocket URL includes session_id).
    tsc, Biome, and the React Compiler check pass.
  • coderd: go test ./coderd/tracing/... and go vet ./coderd/workspaceapps/...
    pass; new ValidSessionID export reused by the PTY handler.
Design notes / decision log
  • Session vs reconnection token. The existing reconnect token is
    deliberately persisted in the URL to survive reloads. session_id is the
    opposite: a fresh value per page load, matching the RFC (a reload is a new
    session). They are separate identifiers.
  • Per-request baggage, not a global axios default. The frontend axios
    instance is a singleton shared by the whole app; a global baggage default
    would tag unrelated requests. The header is attached only to the terminal's
    signed-token request.
  • WebSocket uses a query param. Browser WebSocket cannot send custom
    headers, so baggage is impossible on the PTY handshake. The session_id query
    parameter is the counterpart, read server-side in workspaceAgentPTY.
  • Server-side scope. Reading the query param is localized to the web
    terminal's own WebSocket handler rather than broadening the shared tracing
    middleware to trust query params on every route.
  • Validation. Both the baggage and query-param paths validate the value as a
    32-char hex string (tracing.ValidSessionID) before logging, to avoid logging
    arbitrary client-controlled input.
  • AgentsPage compiler constraint. AgentsPage is React Compiler optimized
    (no useMemo/useCallback), so the panel mints its ID with useState lazy
    init instead.
  • Out of scope (other RFC tickets): agent-side middleware, connection_logs
    columns, Tailnet state-change logging, and the CLI CODER_TRACE_SESSION_ID
    env var.

Opened by Coder Agents on behalf of @aqandrew.

Generate a 16-byte session ID (32-char hex) per web terminal session and
attach it to the terminal's requests and client logs, per the connection-log
correlation RFC. This is DEVEX-663 and stacks on the coderd tracing middleware
change (DEVEX-659).

Frontend:
- Add generateSessionId and mint one session ID per web terminal page load
  (TerminalPage) and per AgentsPage terminal panel mount. Unlike the
  reconnection token, it is not persisted in the URL: a reload is a new
  session.
- Send it on the PTY WebSocket as a session_id query parameter (browsers
  cannot set the baggage header on a WebSocket handshake).
- Send it via W3C baggage on the reconnecting-pty signed-token API request.
- Include it in the terminal's connection-error console logs.

Backend:
- The reconnecting-pty WebSocket handler reads the session_id query parameter,
  validates it, and attaches it to the request and PTY logs so the WebSocket
  session correlates. Export tracing.ValidSessionID for reuse.
@linear-code

linear-code Bot commented Jul 30, 2026

Copy link
Copy Markdown

DEVEX-663

Copy link
Copy Markdown
Contributor Author

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

Comment thread site/src/pages/TerminalPage/TerminalPage.tsx Outdated
Comment thread site/src/pages/AgentsPage/components/TerminalPanel.tsx Outdated
Comment thread site/src/api/api.ts Outdated
Comment thread coderd/workspaceapps/proxy.go Outdated
Comment thread site/src/utils/sessionId.ts Outdated
aqandrew and others added 2 commits July 30, 2026 08:41
Co-authored-by: Danielle Maywood <danielle@themaywoods.com>
Co-authored-by: Danielle Maywood <danielle@themaywoods.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants