feat: log tailnet tunnels to the connection log - #27005
Closed
cdigiamo-ant wants to merge 1 commit into
Closed
Conversation
Contributor
|
All contributors have signed the CLA ✍️ ✅ |
cdigiamo-ant
marked this pull request as draft
July 6, 2026 16:31
Agent-reported SSH/VSCode/JetBrains connection_log rows have no user_id
because the agent does not know which Coder user connected (see the
comment in coderd/agentapi/connectionlog.go). This makes it impossible
to attribute SSH/IDE sessions to a Coder user from the connection log.
Every such session is carried over a tailnet tunnel that the client
opens via /api/v2/workspaceagents/{id}/coordinate using the user's API
key, so coderd knows the user at that point.
Add a new connection_type 'tailnet' and write one connection_log row
from workspaceAgentClientCoordinate whenever an authenticated user
successfully upgrades the coordinate WebSocket. The row carries
user_id, ip, user_agent, workspace_id and agent_name, and is rendered
via WebInfo alongside workspace_app / port_forwarding.
cdigiamo-ant
force-pushed
the
cdigiamo/connection-log-tailnet-type
branch
from
July 6, 2026 17:01
5527069 to
44f36a3
Compare
cdigiamo-ant
marked this pull request as ready for review
July 6, 2026 17:01
Contributor
Author
|
I have read the CLA Document and I hereby sign the CLA |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #27006.
Summary
Today the connection log has no user attribution for SSH / IDE sessions. The
agent reports
ssh/vscode/jetbrains/reconnecting_ptyrows, but bythe time the connection reaches the agent the Coder user identity is gone — see
the comment in
coderd/agentapi/connectionlog.go:As a result
connection_logs.user_idis always NULL for those rows, and thereis no way to answer "which Coder user opened an SSH session into workspace X"
from the connection log alone. For enterprise audit use-cases (cross-user
workspace access, long-lived-token misuse) that's a significant gap.
Every such session is carried over a tailnet tunnel that the client opens via
GET /api/v2/workspaceagents/{id}/coordinate. That request is made with theuser's API key, so coderd does know who is connecting at that moment.
This PR adds a new
connection_typevaluetailnetand writes one connectionlog row from
workspaceAgentClientCoordinateeach time a client successfullyupgrades the coordinate WebSocket. The row carries:
user_id— fromhttpmw.APIKeyOptional(r)ip/user_agent— from the HTTP request (real client IP onceCODER_PROXY_TRUSTED_*is configured)workspace_id/agent_name— the tunnel targetThe event is treated like the other coderd-originated connection types
(
workspace_app,port_forwarding): it's a point-in-time authorization eventwith no
disconnect_time, so it's excluded from thestatus:filter andrendered via
WebInfo(which already surfaces the connecting user in thedashboard).
Why not fill
user_idon the existing SSH rows?Those rows are emitted by the agent over
ReportConnection, which doesn't haveaccess to the Coder user or API key (the comment above is still accurate).
Plumbing identity down to the agent would be a protocol change; this approach
gets the same attribution without touching the agent API.
What about
/api/v2/tailnet(Coder Desktop)?tailnetRPCConnis user-scoped rather than workspace-scoped, so it doesn'thave a single target workspace to log against. It already reports
UserTailnetConnectiontelemetry. I've left it out of this PR to keep thechange small; happy to follow up if there's interest in logging it too.
Notes
same order of magnitude as coordinator handshakes — typically far below the
workspace-app rate.
skipped.
api_key_idisn't recorded becauseconnection_logshas no column for it;user_id+user_agent+ipis what the existing web types store too.I'd like to add an
api_key_idcolumn in a follow-up (or here, if preferred)so these rows — and potentially
workspace_app/port_forwardingrows —can also record which key was used; it's available at both write sites.
DialAgentcaller (coder ssh,coder port-forward,the VS Code extension,
coder ping,coder speedtest, etc.), so atailnetrow means "user opened a tunnel to this agent", not "user ran SSH". There is
currently no debounce on reconnect; if volume turns out to be a concern the
same
workspace_app_audit_sessionspattern could be applied here.tailnet→tunnel(or similar) if that reads better.