Skip to content

[PLT-4662] Add, remove and list user group members, and read the group audit log - #2091

Merged
Gabefire merged 1 commit into
developfrom
gu/plt-4662-group-members-audit
Oct 21, 2026
Merged

Gabefire merged 1 commit into
developfrom
gu/plt-4662-group-members-audit

Conversation

@Gabefire

@Gabefire Gabefire commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator

SDK half of PLT-4662. The API and MCP half shipped in Labelbox/intelligence#31630.

Airbnb runs vendor access through one group of ~490 people attached to ~230 projects, and could not tell who removed people from it. This lets them manage members from a script and read who changed what.

Added

  • UserGroup.add_members(members, notify_members=False): adds people with their group roles, without touching other members or projects (unlike update(), which replaces the whole group). Drives continueAddUsersToGroupBatch to completion for large additions. Uses addUsersToGroupsV2.
  • UserGroup.remove_members(users, notify_users=True, reason=None, notification_reason=None): uses removeUsersFromGroupV2.
  • UserGroup.list_members(): reads current members with their group roles, without overwriting unsaved fields the way get() does.
  • UserGroup.audit_events(...) for one group and UserGroup.get_audit_events(client, ...) across every group the caller can manage. Filters: member, actor, actor kind (person or automation), event types, project, time range. Return a PaginatedCollection of UserGroupAuditEvent. Uses userGroupAuditEvents.
  • UserGroupAuditEvent, UserGroupAuditEventType, UserGroupAuditActorKind, UserGroupAuditChannel, exported from labelbox, with a docs page. Unknown enum values from the server are kept as strings, as in LabelVersion.

Changes made through these methods are recorded in the audit log as channel=API, for the API key's owner.

Testing

  • New unit tests in tests/unit/schema/test_user_group_members_audit.py. All 303 tests in tests/unit/schema pass locally.
  • ruff (repo rules), ruff format and mypy pass on the changed files.
  • Not yet run against staging. Worth an integration check of add_members and audit_events before release.

🤖 Generated with Claude Code


Note

Medium Risk
Changes affect access-control workflows (group membership and project access) via new GraphQL mutations; behavior is gated on server APIs and batch-job completion loops, with solid unit coverage but staging integration not yet run per PR notes.

Overview
Adds incremental user group membership APIs and a queryable audit log to the Python SDK, so scripts can add/remove/list members without replacing the whole group via update(), and investigate who changed membership or project attachments.

UserGroup gains add_members (via addUsersToGroupsV2, with automatic continueAddUsersToGroupBatch polling for large adds), remove_members (removeUsersFromGroupV2, with notify/reason options), and list_members (server read that does not overwrite other unsaved fields like get()). UserGroup.audit_events and UserGroup.get_audit_events expose filtered, paginated userGroupAuditEvents (member, actor, type, project, time range).

New module user_group_audit defines UserGroupAuditEvent plus enums for event type, actor kind, and channel; unknown server enum values stay as strings. Types are exported from labelbox and documented in user-group-audit.rst. Unit tests cover mutations, batch continuation, audit filtering/parsing, and validation.

Reviewed by Cursor Bugbot for commit 2a47bfa. Bugbot is set up for automated code reviews on this repo. Configure here.

…p audit log

UserGroup.add_members, remove_members and list_members change or read one
group's members without replacing the whole group the way update() does.
UserGroup.audit_events and UserGroup.get_audit_events read the group audit
log: who added, removed or changed the role of a member, attached a group to
a project or detached it, or deleted a group, and whether a person or an
automation did it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Gabefire
Gabefire force-pushed the gu/plt-4662-group-members-audit branch from 218823f to 2a47bfa Compare October 21, 2026 15:14
@Gabefire
Gabefire merged commit 5252390 into develop Oct 21, 2026
1 check passed
@Gabefire
Gabefire deleted the gu/plt-4662-group-members-audit branch October 21, 2026 15:15

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

Reviewed by Cursor Bugbot for commit 2a47bfa. Configure here.

],
"notifyMembers": notify_members,
},
)["addUsersToGroupsV2"]["results"][0]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add_members crashes on missing resources

Medium Severity

add_members indexes the execute result immediately without raise_return_resource_not_found=True. A GraphQL RESOURCE_NOT_FOUND for a missing group or expired batch job returns None, so the subscript raises TypeError instead of ResourceNotFoundError. remove_members already passes the flag, and list_members treats None as missing.

Additional Locations (1)
Fix in Cursor Fix in Web

Triggered by learned rule: execute returns None on RESOURCE_NOT_FOUND

Reviewed by Cursor Bugbot for commit 2a47bfa. Configure here.

@Gabefire Gabefire mentioned this pull request Oct 22, 2026
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