feat: team admin role#3040
Conversation
4170eff to
9afd076
Compare
attaching sources to a backend doesn't need admin scope. fine to let users view the backends as readonly. |
9afd076 to
1ffc1fe
Compare
1ffc1fe to
9604375
Compare
9604375 to
2da3bee
Compare
15f66cd to
6986bf9
Compare
3abc904 to
647008c
Compare
a10d02e to
f440a66
Compare
f440a66 to
5d72de9
Compare
5d72de9 to
80a4a26
Compare
80a4a26 to
6fe4919
Compare
d50ac78 to
e473440
Compare
e473440 to
55b57c4
Compare
55b57c4 to
3d703a3
Compare
3d703a3 to
aecac2e
Compare
5a37c5c to
ccefc38
Compare
ccefc38 to
69f1c27
Compare
| require Logger | ||
|
|
||
| plug LogflareWeb.Plugs.AuthMustBeOwner | ||
| plug LogflareWeb.Plugs.AuthMustBeTeamAdmin |
There was a problem hiding this comment.
🟠 Severity: HIGH
Account takeover via email update. PUT /account/edit (update) calls Users.update_user_allowed(assigns.user, params) where assigns.user is the team owner. @user_allowed_fields includes :email and :provider_uid, allowing a team admin to change the owner's email address and effectively hijack the account.
Helpful? Add 👍 / 👎
💡 Fix Suggestion
Suggestion: The update action (and other mutating actions like delete, new_api_key, change_owner) should be restricted to the account owner only, not all team admins. There are two complementary approaches:
-
Scope the existing plug (line 8) to only cover read-only or safe actions:
plug LogflareWeb.Plugs.AuthMustBeTeamAdmin when action in [:edit, :api_show]. Then add a separate owner-only guard for mutating actions. SinceTeamContext.team_owner?/1already exists andteam_contextis available inconn.assigns, you can create a lightweightAuthMustBeTeamOwnerplug (analogous to the existingAuthMustBeTeamAdmin) that callsTeamContext.team_owner?(team_context)and apply it withplug LogflareWeb.Plugs.AuthMustBeTeamOwner when action in [:update, :delete, :new_api_key, :change_owner]. -
Additionally, remove
:emailand:provider_uidfrom@user_allowed_fieldsinlib/logflare/user.ex(or move them to a separate owner-only changeset). These are login-identity fields and should never be modifiable through a self-service update endpoint accessible to non-owning team admins. If email change is intentionally supported for the owner, create a separateowner_allowed_changeset/2that includes those fields and call it only when the requestor is verified as the owner.
Passes for both team owner and team user with admin role.
fc020dd to
9186484
Compare
This PR adds an admin role which is required for destructive account actions.
adminpermissionadminis granted to:adminroleprivate:admintokenTeam roles
roleattribute toTeamUser, can beuseroradmin.userby default.Access tokens and API scopes
private:adminscopeadminpermission (as detailed above) is required to createprivate:admintokens through the UI or APIprivate:adminis a superset ofprivatescope and is accepted where aprivatescope is requiredRole management UI
The dashboard and account preferences will display and 'admin' label next to a team user with the admin role.
The term 'admin' can be ambiguous as we also have internal admins. I've used 'team admin' where possible to distinguish this. A team admin is a user with admin privileges for a team: either the team owner, or a team user with the admin role.
A team admin can add and remove other admins.
All team users created using the invite link as regular users. They can be granted team admin status after creation.
CleanShot.2026-01-06.at.10.34.49.mp4
If a team admin tries to remove their own admin role a warning is shown first.
CleanShot.2026-01-06.at.14.05.36.mp4
Users can create an API token with
private:adminscope by checking AdminDocumentation
Updates documentation to include
private:adminscope and note in OpenAPI spec.Part of O11Y-1251 and O11Y-1149