Skip to content

feat: team admin role#3040

Open
msmithstubbs wants to merge 12 commits into
Logflare:mainfrom
msmithstubbs:feat/admin-api-scope
Open

feat: team admin role#3040
msmithstubbs wants to merge 12 commits into
Logflare:mainfrom
msmithstubbs:feat/admin-api-scope

Conversation

@msmithstubbs

@msmithstubbs msmithstubbs commented Dec 15, 2025

Copy link
Copy Markdown
Contributor

This PR adds an admin role which is required for destructive account actions.

  • create/update/delete a team or backend requires team admin permission
  • admin is granted to:
    • the team owner
    • a team user with admin role
    • an API request bearing a private:admin token

Team roles

  • Adds role attribute to TeamUser, can be user or admin.
  • All existing team users are user by default.
  • admin permission (as detailed above) is required to update a team user role.

Access tokens and API scopes

  • API tokens can be created with private:admin scope
  • admin permission (as detailed above) is required to create private:admin tokens through the UI or API
  • private:admin is a superset of private scope and is accepted where a private scope is required

Role management UI

The dashboard and account preferences will display and 'admin' label next to a team user with the admin role.

CleanShot 2025-12-16 at 10 20 26@2x

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:admin scope by checking Admin

CleanShot 2026-06-10 at 15 30 35@2x

Documentation

Updates documentation to include private:admin scope and note in OpenAPI spec.

CleanShot 2026-06-10 at 11 35 30@2x

Part of O11Y-1251 and O11Y-1149

@msmithstubbs msmithstubbs marked this pull request as ready for review December 15, 2025 04:59
@msmithstubbs msmithstubbs changed the title wip: admin api scope feat: private:admin API scope Dec 15, 2025
@msmithstubbs msmithstubbs changed the title feat: private:admin API scope feat: admin API scope Dec 15, 2025
@Ziinc

Ziinc commented Dec 24, 2025

Copy link
Copy Markdown
Contributor

should /api/sources/:token/backends/:backend_token require admin scope?

attaching sources to a backend doesn't need admin scope. fine to let users view the backends as readonly.

Comment thread lib/logflare/teams/team_context.ex Outdated
Comment thread lib/logflare/auth.ex Outdated
@msmithstubbs msmithstubbs force-pushed the feat/admin-api-scope branch 3 times, most recently from 15f66cd to 6986bf9 Compare February 17, 2026 00:39
@msmithstubbs msmithstubbs force-pushed the feat/admin-api-scope branch 2 times, most recently from 3abc904 to 647008c Compare February 20, 2026 00:13
@msmithstubbs msmithstubbs force-pushed the feat/admin-api-scope branch 2 times, most recently from a10d02e to f440a66 Compare March 23, 2026 04:07
@msmithstubbs msmithstubbs force-pushed the feat/admin-api-scope branch from f440a66 to 5d72de9 Compare June 8, 2026 23:02
Comment thread lib/logflare_web/router.ex
@msmithstubbs msmithstubbs force-pushed the feat/admin-api-scope branch from 5d72de9 to 80a4a26 Compare June 9, 2026 00:05
Comment thread lib/logflare_web/live/access_tokens_live.ex Outdated
@msmithstubbs msmithstubbs force-pushed the feat/admin-api-scope branch from 80a4a26 to 6fe4919 Compare June 9, 2026 00:22
@msmithstubbs msmithstubbs marked this pull request as draft June 9, 2026 00:35
@msmithstubbs msmithstubbs force-pushed the feat/admin-api-scope branch 3 times, most recently from d50ac78 to e473440 Compare June 9, 2026 04:34
@msmithstubbs msmithstubbs force-pushed the feat/admin-api-scope branch from e473440 to 55b57c4 Compare June 9, 2026 23:12
@msmithstubbs msmithstubbs changed the title feat: admin API scope feat: team admin role Jun 10, 2026
@msmithstubbs msmithstubbs force-pushed the feat/admin-api-scope branch from 55b57c4 to 3d703a3 Compare June 10, 2026 01:12
@msmithstubbs msmithstubbs force-pushed the feat/admin-api-scope branch from 3d703a3 to aecac2e Compare June 10, 2026 01:24
@msmithstubbs msmithstubbs force-pushed the feat/admin-api-scope branch 3 times, most recently from 5a37c5c to ccefc38 Compare June 10, 2026 05:29
@msmithstubbs msmithstubbs marked this pull request as ready for review June 10, 2026 23:11
@msmithstubbs msmithstubbs force-pushed the feat/admin-api-scope branch from ccefc38 to 69f1c27 Compare June 14, 2026 23:41
require Logger

plug LogflareWeb.Plugs.AuthMustBeOwner
plug LogflareWeb.Plugs.AuthMustBeTeamAdmin

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.

🟠 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:

  1. 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. Since TeamContext.team_owner?/1 already exists and team_context is available in conn.assigns, you can create a lightweight AuthMustBeTeamOwner plug (analogous to the existing AuthMustBeTeamAdmin) that calls TeamContext.team_owner?(team_context) and apply it with plug LogflareWeb.Plugs.AuthMustBeTeamOwner when action in [:update, :delete, :new_api_key, :change_owner].

  2. Additionally, remove :email and :provider_uid from @user_allowed_fields in lib/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 separate owner_allowed_changeset/2 that includes those fields and call it only when the requestor is verified as the owner.

@msmithstubbs msmithstubbs force-pushed the feat/admin-api-scope branch from fc020dd to 9186484 Compare June 15, 2026 23:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants