Repository navigation
fix(coderd): allow agent auth during workspace shutdown - #21538
Conversation
8e38e41 to
f464c6b
Compare
| WHERE | ||
| workspace_id = workspace_build_with_user.workspace_id | ||
| -- Filter out builds that are not the latest, with exception for shutdown case. | ||
| AND ( |
There was a problem hiding this comment.
Would this benefit from using a CASE statement instead so we can do some form of short-circuiting for the normal case?
If no WHEN condition yields true, the value of the CASE expression is the result of the ELSE clause.
There was a problem hiding this comment.
Excellent call-out, I forgot that OR/AND isn't necessarily short-circuited. Definitely doing this 👍🏻
| WHERE l2.workspace_id = latest.workspace_id | ||
| ) | ||
| AND latest.transition = 'stop' | ||
| AND latest.template_version_id = workspace_build_with_user.template_version_id |
There was a problem hiding this comment.
I don't understand the purpose of the version check. Let's say we have a stop build for the workspace at a new version of the template: why does that mean we should refuse to authenticate the pervious agent that is in the process of being shut down?
There was a problem hiding this comment.
This was a defensive check against an unlikely scenario to prevent RBAC mismatches if start and stop use different template versions.
But upon further inspection, agents don't access template resources during shutdown, so the template version in the allowlist is never actually checked.
Removing it.
|
I think it's OK to ship as a stop gap, but this is an incomplete solution.
These issues suggest (to me) that we should consider moving to an architecture where Coderd first signals to all (connected) workspace agents that they should start shutting down. This means running scripts, but also terminating SSH and Reconnecting PTY connections, tearing down tailnet tunnels, etc. Then, the agent can signal Coderd it is finished. When all agents are finished, disconnected, or hit some configurable timeout, then we actually kick off the Terraform build. |
|
Great observation @spikecurtis, and I fully agree. We have an issue tracking this, #6175, though we don't have capacity for it right now. I'll update it with the extra scenarios you described, particularly externally provisioned workspaces and permission constraints, as those seem valuable to capture. This PR just fixes the immediate auth bug. For tasks, we're documenting provider configuration (coder/internal#1271, #6174). It wasn't considered before, but we may also want document, or at least mention, infra-based timeouts there. |
Agents were losing authentication during workspace shutdown, causing shutdown scripts to fail. The auth query required agents to belong to the latest build, but during shutdown a `stop` build becomes latest while the `start` build's agents are still running. Several approaches were considered: - Reusing agent tokens (no unique constraint, would break auth) - Separate validation functions (two queries for agent + latest build) - Grace period with workspace-level tokens (security risk, stale agents) - Agent lifecycle state tracking (requires migration, complex state management) Modified the auth query to allow `start` build agents to authenticate temporarily during `stop` execution. This is simpler than separate functions and avoids migrations. The query allows auth when: - Agent's `start` build job succeeded - Latest build is `stop` with `pending`/`running` job status - Builds are adjacent (`stop` is `build_number + 1`) - Template versions match The version check prevents RBAC issues if someone explicitly changes template versions between builds. Auth closes once `stop` completes. Renamed `GetWorkspaceAgentAndLatestBuildByAuthToken` to `GetAuthenticatedWorkspaceAgentAndBuildByAuthToken` since it returns the agent's build (not always latest) during shutdown. Added tests covering happy path, failure cases (completed stops, failed builds, version mismatches), and edge cases (multiple cycles, wrong transitions) at both database and middleware levels. Fixes coder/internal#1249 Fixes #19467
9b1c5a9 to
fb9472b
Compare
Agents were losing authentication during workspace shutdown, causing
shutdown scripts to fail. The auth query required agents to belong to
the latest build, but during shutdown a
stopbuild becomes latest whilethe
startbuild's agents are still running.Modified the auth query to allow
startbuild agents to authenticatetemporarily during
stopexecution. The query allows auth when:startbuild job succeededstopwithpending/runningjob statusstopisbuild_number + 1)Auth closes once
stopcompletes.Renamed
GetWorkspaceAgentAndLatestBuildByAuthTokentoGetAuthenticatedWorkspaceAgentAndBuildByAuthTokensince it returns theagent's build (not always latest) during shutdown.
Added tests covering happy path, failure cases (completed stops, failed
builds, version mismatches), and edge cases (multiple cycles, wrong
transitions) at both database and middleware levels.
Closes coder/internal#1249
Fixes #19467
Alternative approaches were considered:
However,
auth_tokenlacks unique constraint, so query would returnmultiple agents and break authentication.
GetWorkspaceAgentByAuthToken(validates token) and
GetLatestWorkspaceBuildForWorkspace(gets actuallatest). (Benefit unclear and requires test refactoring.)