Skip to content

security: verify zero-group user cannot retain admin access (QA row 511 / step 15.1) #948

Description

@cristim

Source: QA sheet row 511 / step 15.1.

Action (repro as reported by QA)

Create an Admin user that is not added to any Group (zero-group user), then log in as that user.

Expected (acceptance)

A user must not be able to hold admin access without an explicit group grant. Either:

  • user-create rejects a zero-group user, or
  • the user is auto-assigned to the Administrators group,

and admin capability is derived solely from group membership (Administrators group 00000000-0000-5000-8000-000000000001). A user with no group can do nothing.

Actual (observed at QA time)

The user stayed unassigned to any group and still had admin access when logged in. Admin was not strictly group-derived. SECURITY gap (privilege without an explicit grant).

Verification finding (current base: feat/multicloud-web-frontend)

Already fixed by #907/#912 ("group-membership-only authorization, remove roles, require >=1 group"), reinforced by #924/#923 (Purchaser group) and #941 (dropped last session.Role shortcut). Both failure modes are now closed on the current production base:

  1. Zero-group creation is rejected. Service.validateCreateUserRequest (internal/auth/service_user.go:134) returns ErrNoGroups -> 400 when len(req.GroupIDs) == 0. UpdateUser/guardGroupChange (:328) enforces the same on edit. You cannot create or leave a user with zero groups via the API.
  2. Admin is strictly group-derived. GetUserPermissions (internal/auth/service_group.go:67) sources permissions "exclusively from group memberships"; a zero-group user gets an empty permission set. UserHasAdminCapability / HasPermission only grant admin on the {admin, *} permission, which comes only from the Administrators group. The admin middleware gate (internal/api/middleware.go:266) calls HasPermissionAPI(admin, *) and returns 403 otherwise (fail-closed). No live role-based admin path remains: RoleAdmin (internal/auth/types.go:303) is referenced only in its own definition and doc comments; the last session.Role shortcut was removed in fix(api/purchases): drop removed session.Role shortcut in execute-direct gate (closes #940) #941.

Regression coverage already present:

  • internal/auth/service_group_only_authz_test.go — TestGroupOnlyAuthz_ZeroGroupFailClosed asserts a zero-group user is denied everything and UserHasAdminCapability is false; plus tests asserting ErrNoGroups on create/update.
  • internal/auth/service_user_test.go:187,508 — assert ErrNoGroups on zero-group create.

Conclusion

Already-fixed-by-#907/#912. No code change or PR required. Filing for traceability and to mark the QA row resolved. Recommend re-testing on the current production build to close the sheet row.

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions