Skip to content

feat(auth): auto-promote members of SUPERUSER_GROUP#5

Merged
mxhash merged 1 commit into
mainfrom
feat/superuser-group
May 19, 2026
Merged

feat(auth): auto-promote members of SUPERUSER_GROUP#5
mxhash merged 1 commit into
mainfrom
feat/superuser-group

Conversation

@mxhash
Copy link
Copy Markdown
Member

@mxhash mxhash commented May 19, 2026

Summary

Optional auto-superuser feature driven by group membership.

  • New setting `SUPERUSER_GROUP` (case-insensitive). When set, members of that group are superusers.
  • OIDC: the `groups` scope is auto-appended to the OIDC request, and the `groups` claim is evaluated on each login. Match → `is_superuser=True`; no match → `is_superuser=False`.
  • SCIM: every group create/update/patch/delete re-derives the flag globally. Members of the named group are promoted, everyone else demoted. Renaming a group away from the configured name or deleting it clears its members' superuser flag.
  • Manual `struudel superuser grant/revoke` still works but is overridden by the next login/SCIM sync when the setting is configured. Leaving `SUPERUSER_GROUP` empty makes the CLI authoritative (no-op behaviour).

Test plan

  • PR image `ghcr.io/netways/struudel:pr-` built by CI
  • Set `SUPERUSER_GROUP=` on the server, recreate app+worker
  • In Authentik, ensure the user-info groups claim is enabled and the SCIM connector still syncs cleanly
  • Log in as a user in the configured group → `g.user.is_superuser` is true (admin nav visible)
  • Remove the user from the group in the IdP → next SCIM sync demotes them; relog confirms via OIDC too
  • Empty `SUPERUSER_GROUP` → CLI grant/revoke still works and isn't overwritten

Adds an optional SUPERUSER_GROUP setting. When set, membership in the
named group becomes the source of truth for User.is_superuser:

- OIDC login: the `groups` scope is auto-appended to the OIDC request,
  and the `groups` claim is checked against SUPERUSER_GROUP on each
  callback to set/clear the flag.
- SCIM: every group create / update / patch / delete re-derives
  is_superuser globally — current members of the named group are
  promoted, everyone else is demoted. Group rename or deletion clears
  superusers accordingly.

Matching is case-insensitive (Group.canonical_name vs. settings value
both lowercased). When SUPERUSER_GROUP is empty the feature is a
no-op and manual CLI grants remain authoritative.
@mxhash mxhash merged commit b8c27c0 into main May 19, 2026
1 check passed
@mxhash mxhash deleted the feat/superuser-group branch May 19, 2026 09:58
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.

1 participant