Skip to content

fix(auth): provision global membership on user approval #632

Description

@XiaoSeS

Parent

Problem

Accounts created under the PENDING_APPROVAL access policy are stored as PENDING without a business session. When an administrator later changes such an account to ACTIVE, the current admin workflow updates only user_account.status; it does not provision the built-in @global namespace membership expected by active users. The approved user can therefore authenticate but encounter authorization failures in workflows that require global membership.

The OAuth flow also reevaluates PENDING_APPROVAL before resolving the existing binding, so an already approved account can be sent back to the pending page on every login. Separately, the generic status endpoint can currently reactivate a MERGED account.

Proposed solution

Make activation through the administrative user-status workflow provision the built-in @global MEMBER membership in the same transaction. Reuse the existing membership service so repeated activation remains idempotent, and roll back the account activation if membership provisioning fails.

For a policy decision of PENDING_APPROVAL, resolve the existing binding with PENDING only as the initial status: a new account remains pending, an existing approved account can log in, and an existing disabled account remains rejected. Reject attempts to reactivate MERGED accounts.

What to build

When an administrator activates a pending or disabled non-system account, SkillHub must atomically set the account to ACTIVE and ensure exactly one @global membership with role MEMBER. The completed approval must remain effective on subsequent OAuth logins even when the configured access policy continues to require approval.

Acceptance criteria

  • PENDING to ACTIVE creates an @global MEMBER membership.
  • DISABLED to ACTIVE creates an @global MEMBER membership.
  • Repeating the ACTIVE update does not create duplicate memberships.
  • A membership provisioning failure leaves the account in its previous PENDING or DISABLED status.
  • Updating an account to DISABLED does not provision membership.
  • An approved bound account can log in when policy evaluates to PENDING_APPROVAL.
  • A disabled bound account remains rejected when policy evaluates to PENDING_APPROVAL.
  • A MERGED or system account cannot be reactivated.
  • Authentication and domain-model documentation describe the approval behavior.
  • The deployed admin activation route and resulting @global membership have smoke coverage.

Blocked by

None - can start immediately.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingeffort/m中等改动,存在一定协同成本 / Medium change with noticeable coordination cost.priority/p1高优先级 / High priority triage bucket.risk/high涉及安全、鉴权、迁移或公共契约 / Touches security, auth, migrations, or public contracts.triage/needs-info需要补充更多信息后才能分流 / Issue needs more detail before it can be routed.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions