feat: keep Windows RDP sessions alive while connected#915
Conversation
Issue coder#200 asks for Windows RDP sessions to prevent a workspace from stopping while a user is still connected through RDP. The existing windows-rdp module enabled Remote Desktop and Devolutions Gateway, but it did not report activity or extend the workspace deadline after the startup script completed. That meant an active RDP session could still be shut down by the normal workspace schedule. This change keeps the fix scoped to the registry module. It adds an opt-in-by-default PowerShell keepalive monitor that is installed by the existing startup script, checks for established local RDP connections on port 3389, and uses the workspace agent token to call Coder's documented workspace deadline extension endpoint. The monitor is written to ProgramData, logs to a module-specific log file, and the installer stops any previous monitor process before starting a new one so repeated starts do not stack duplicate loops. The Terraform surface is intentionally small: keepalive_enabled controls the feature, keepalive_interval_seconds controls how often the RDP connection check runs, and keepalive_extension_minutes controls how far ahead the deadline is extended. The extension window is validated at 30 minutes or more because Coder's server-side deadline validation rejects deadlines that are too close to the current time. Disabling keepalive removes the generated monitor script and leaves the rest of the Windows RDP module behavior unchanged. Tests now assert the rendered coder_script installs the monitor by default, includes the RDP connection detection logic, sends the Coder-Session-Token header, calls /api/v2/workspaces/{workspace}/extend with the deadline body, supports custom interval/extension values, and can disable the monitor cleanly. The README documents the new behavior, configuration variables, disable switch, and log path. Validation performed locally: bun test registry/coder/modules/windows-rdp/main.test.ts; terraform -chdir=registry/coder/modules/windows-rdp validate; bun x prettier --check registry/coder/modules/windows-rdp/README.md registry/coder/modules/windows-rdp/main.test.ts registry/coder/modules/windows-rdp/main.tf; terraform fmt -check -recursive registry/coder/modules/windows-rdp; PowerShell parser checks for rdp-keepalive.ps1.tftpl and powershell-installation-script.tftpl. AI-assisted with Codex.
|
/claim #200 |
matifali
left a comment
There was a problem hiding this comment.
Thank you for your contribution. Please attach a recorded demo of your solution working.
The keepalive monitor should only extend the workspace while an established local RDP connection exists. During demo verification, the no-connection path correctly skipped the extend request, but PowerShell logged the absence of matching TCP connections as an inspection error because Get-NetTCPConnection used ErrorAction Stop. Use ErrorAction SilentlyContinue for the normal idle case so a disconnected workspace remains quiet while still returning false from Test-RDPConnectionActive. The test now asserts the rendered script uses the idle-safe connection query. Validation performed locally: bun test registry/coder/modules/windows-rdp/main.test.ts; terraform -chdir=registry/coder/modules/windows-rdp validate; prettier check for changed formatted files; terraform fmt check for the module; PowerShell parser check for rdp-keepalive.ps1.tftpl.
|
Hi @matifali, I attached a recorded demo of the keepalive flow working. Demo GIF: The demo runs the rendered
Raw evidence:
This is a local recorded demo using the exact rendered keepalive script and a local mock Coder Agent API endpoint so the API call can be shown deterministically. If you specifically need a full Coder deployment recording with a real Windows workspace, I can provide that once I have access to a suitable Coder Windows environment. |
|
Please share recording with a real Coder Instance (tell me if you are AI) and a real Windows based Template on some Cloud provider like AWS or GCP or Azure. Where user connects to RDP from the official RDP client. |
|
Hi @matifali, thanks for the clarification. I recorded a new demo using a real Coder instance, a real Azure Windows Server workspace/template, and the official Microsoft Remote Desktop client. Recorded demo (MOV): https://github.com/Rafly0078/registry/releases/download/rdp-keepalive-real-demo-915-v1/rdp-keepalive-real-coder-azure-demo.mov Release page: https://github.com/Rafly0078/registry/releases/tag/rdp-keepalive-real-demo-915-v1 Summary of what the recording shows:
Transparency note: this contribution and the demo/debugging work were AI-assisted with Codex. I am the PR author, and I used Codex as an assistant for implementation, testing, debugging, and preparing the demo evidence. |
| @@ -111,9 +118,10 @@ resource "coder_script" "windows-rdp" { | |||
| devolutions_gateway_version = var.devolutions_gateway_version | |||
| keepalive_enabled = var.keepalive_enabled | |||
| keepalive_script_contents = templatefile("${path.module}/rdp-keepalive.ps1.tftpl", { | |||
| workspace_id = data.coder_workspace.me.id | |||
| interval_seconds = var.keepalive_interval_seconds | |||
| extension_minutes = var.keepalive_extension_minutes | |||
| workspace_id = data.coder_workspace.me.id | |||
| interval_seconds = var.keepalive_interval_seconds | |||
| extension_minutes = var.keepalive_extension_minutes | |||
| coder_session_token = var.keepalive_coder_session_token != null ? var.keepalive_coder_session_token : "" | |||
| }) | |||
There was a problem hiding this comment.
Please use the coder-login module to get a token
There was a problem hiding this comment.
I just pushed a new commit to address this:
- Dropped the custom
keepalive_coder_session_tokenvariable entirely from the module. - The keepalive script now simply reads from
$env:CODER_SESSION_TOKEN(populated bycoder-login) if it's available, and falls back to$env:CODER_AGENT_TOKENif not. - Updated the README and tests to reflect this new flow.
Let me know if this looks good to you now!
There was a problem hiding this comment.
can you also attach the video inline or Loom or Youtube? the MOV file doesn't play.
There was a problem hiding this comment.
Ah, sorry about that! I've uploaded the demo video to YouTube so it should play perfectly inline now.
You can watch the full RDP connection demo and the deadline extension process here: https://youtu.be/5BTZdUdit_Y
Let me know if you need anything else to proceed!
|
Hi @Rafly0078 just FYI, We have now stopped the bounty program. |

/claim #200
Summary
This PR adds an RDP keepalive monitor to the
coder/windows-rdpmodule so a workspace can keep extending its deadline while a user is actively connected over RDP.The change is intentionally scoped to the registry module and does not require a core
coder/coderchange. It follows the module-side approach discussed in #200: detect an active RDP connection inside the Windows workspace and use the workspace agent token to extend the workspace deadline.What changed
keepalive_enabled,keepalive_interval_seconds, andkeepalive_extension_minutesvariables to the Windows RDP module.rdp-keepalive.ps1monitor from Terraform and installs it from the existing startup script.3389.PUT /api/v2/workspaces/{workspace}/extendendpoint with the workspace agent token while RDP is active.keepalive_enabled = false, which also removes the generated monitor script.Safety notes
C:\ProgramData\Coder\windows-rdp\rdp-keepalive.loginstead of failing the startup script.Verification
Proof screenshot:
Raw proof log: https://gist.githubusercontent.com/Rafly0078/0584b83b1022a9d1bc2f6d4aff099e12/raw/3d222f8f08f3e5cac23907fc780929ca8bf83bb9/verification-clean.log
Commands run locally:
The targeted module test path is green:
7 pass,0 fail.I also attempted the full Bun suite locally. Many unrelated container-backed tests fail on this Windows environment without a real Docker daemon, so I did not treat that as a regression from this module change.
References
CODER_AGENT_TOKEN: https://coder.com/docs/reference#workspace-agentsAI-assisted with Codex.