🌐 US-Proxy
class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
Skip to content

fix(coderd): allow user-admin password resets to succeed - #26537

Merged
geokat merged 2 commits into
mainfrom
george/plat-316-user-admin-cannot-reset-another-users-password
Jul 7, 2026
Merged

fix(coderd): allow user-admin password resets to succeed#26537
geokat merged 2 commits into
mainfrom
george/plat-316-user-admin-cannot-reset-another-users-password

Conversation

@geokat

@geokat geokat commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Problem

Resetting a password revokes all of the target user's API keys via DeleteAPIKeysByUserID, whose dbauthz check requires api_key:delete on those keys. The user-admin role has full access to ResourceUser but no permissions on ResourceApiKey, so the revocation failed authorization inside the transaction and surfaced as a 500. Owners worked only because they hold wildcard permissions.

Fix

Add a narrowly-scoped AsAPIKeyRevoker dbauthz actor that can delete only the API keys owned by a specific user, and nothing else. Use it for the key revocation in both the admin password-reset path (putUserPassword) and the one-time-passcode reset path, which previously leaned on the much broader AsSystemRestricted.

Refs: https://linear.app/codercom/issue/PLAT-316

User Admin password resets could update the target user's hashed
password but fail while revoking that user's API keys. The transaction
then rolled back and returned HTTP 500, so the password was never
changed.

Add a user-scoped API key revoker actor and use it in both password
reset flows so key revocation succeeds without broader system auth.

Refs: https://linear.app/codercom/issue/PLAT-316
@linear-code

linear-code Bot commented Jun 19, 2026

Copy link
Copy Markdown

PLAT-316

@geokat
geokat marked this pull request as ready for review June 19, 2026 00:46
@geokat
geokat requested a review from Emyrk as a code owner June 19, 2026 00:46
Comment thread coderd/users_test.go Outdated
Split generated token values before calling APIKeyByID, and confirm the
keys resolve before password reset so later 404s prove the records were
removed.
@geokat
geokat requested a review from jscottmiller June 23, 2026 22:37

@jscottmiller jscottmiller left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have much wisdom on our auth code, but the approach seems reasonable. Initially I was surprised that the "user admin" role wasn't expanded, but it seems like we lack the granularity to restrict the permission to keys owned by actual users (vs. system accounts), plus granting that priv generally means that a user admin can delete individual keys outside of a reset (perhaps good, perhaps bad, but somewhat out of scope).

I'm curious how someone more familiar with the AsXXX methods and their intended use cases see this change. Being new, it's hard to see if this pattern is working as intended or if we are hacking around a rigid core.

@geokat

geokat commented Jun 24, 2026

Copy link
Copy Markdown
Contributor Author

I'm curious how someone more familiar with the AsXXX methods and their intended use cases see this change.

Fair. I don't see a lot of AsXXX helpers in the code either. To me it made sense to introduce one here since it's already the second time we need it (and the use of AsSystemRestricted is frowned upon).

@jscottmiller

Copy link
Copy Markdown
Contributor

Makes sense, and it's probably the best path. And definitely better than AsSystemRestricted :)

@jscottmiller jscottmiller left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm; I'm curious if @Emyrk has any auth-thoughts.

@github-actions github-actions Bot added the stale This issue is like stale bread. label Jul 3, 2026
@github-actions github-actions Bot closed this Jul 7, 2026
@geokat geokat removed the stale This issue is like stale bread. label Jul 7, 2026
@geokat geokat reopened this Jul 7, 2026

@Emyrk Emyrk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actors are cheap 👍

@geokat
geokat merged commit ba094c5 into main Jul 7, 2026
60 of 62 checks passed
@geokat
geokat deleted the george/plat-316-user-admin-cannot-reset-another-users-password branch July 7, 2026 16:05
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 7, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants