Title: User Teams
Author: Dion Hulse
Published: <strong>May 11, 2026</strong>
Last modified: May 11, 2026

---

Search plugins

![](https://s.w.org/plugins/geopattern-icon/user-teams.svg)

# User Teams

 By [Dion Hulse](https://profiles.wordpress.org/dd32/)

[Download](https://downloads.wordpress.org/plugin/user-teams.0.5.zip)

 * [Details](https://wordpress.org/plugins/user-teams/#description)
 * [Reviews](https://wordpress.org/plugins/user-teams/#reviews)
 * [Development](https://wordpress.org/plugins/user-teams/#developers)

 [Support](https://wordpress.org/support/plugin/user-teams/)

## Description

On a large multisite network, granting a group of people the same role across many
sites usually means adding each user to each site by hand — and remembering to remove
them everywhere when they leave. User Teams turns that into:

 1. Create a team, pick a role.
 2. Add the user to the team.
 3. They have that role everywhere the team applies.
 4. Remove them from the team  access is gone everywhere.

User Teams is multisite-only by design — on a single-site install, native WordPress
roles and capabilities already cover the whole feature set, so WordPress won’t offer
it for activation there.

#### Features

 * **Teams with roles.** Each team carries a WordPress role (editor, administrator,
   a custom role, or none).
 * **Runtime capability grants.** Team access is added via the `user_has_cap` filter,
   so removing a user from a team drops their access on the next request — no stale
   capabilities usermeta to clean up.
 * **Multisite-native.** Team definitions are real `wp_users` rows (“team accounts”),
   so `WP_Users_List_Table`, `is_user_member_of_blog()`, and every column-adding
   plugin “just work”.
 * **Site scoping.** A team can apply network-wide (including sites added later)
   or to a specific list of sites, each with its own role.
 * **Admin UI.** Network Admin  Users  Teams. Per-user checkboxes on the Edit User
   screen. Team rows with “— Team” markers on the Users list table.
 * **Cleans up after itself.** Deleting a team removes its memberships. Deleting
   a user drops their memberships. Deleting a site removes its grants from any team
   that targeted it.

#### How access is granted

Team-derived capabilities are merged in at runtime, never written into the member
user’s own meta:

 * `user_has_cap` — adds the team role’s capabilities to the user’s effective caps,
   plus `role-{slug}` for plugins that check by role.
 * `get_blogs_of_user` — adds team-linked sites to the user’s “My Sites” navigation.
 * `get_user_metadata` — returns an empty-array `{prefix}{blog_id}_capabilities`
   for team members so `is_user_member_of_blog()` returns true without stamping 
   real capabilities on the user. Workaround for [Core #65096](https://core.trac.wordpress.org/ticket/65096).

The user’s actual `{prefix}capabilities` usermeta is never modified. That’s what
makes team-based access instantly revocable.

#### Capability requirements

 * Managing teams (create / edit / delete) requires `manage_network_users` — super
   admin only.
 * Attaching an existing team to the current site uses `promote_users`, the same
   cap as inviting an individual user there.

Team management is restricted to super admins so a compromised single-site admin
can’t grant themselves access across the network.

#### Extension filters

 * `user_teams_team_caps_for_user( $caps, $user_id, $blog_id )` — modify the capability
   map computed from a user’s teams.
 * `user_teams_team_applies_to_site( $applies, $team_id, $blog_id, $team )` — gate
   coverage (e.g. pause a team during a freeze).
 * `user_teams_team_save_data( $data, $team_id_or_null, $op )` — filter sanitised
   input on create/update.

## FAQ

### Does this work on a single-site install?

No. On a single-site install, native roles and capabilities already cover the whole
feature set, so the plugin is marked `Network: true` and WordPress won’t offer it
for activation.

### What happens to a user’s role when they’re removed from a team?

Nothing is persisted on the user, so removing them from the team drops the team-
derived capabilities on the next request. The user’s own native role on each site
is untouched.

### Where are teams stored?

Each team is a real `wp_users` row (a “team account”) marked with `user_teams_is_team`
meta. Per-site role grants use native `wp_{blog_id}_capabilities` meta on that row.
Memberships are on the member user’s own `user_teams` meta. No custom tables.

### How do I create a team programmatically?

use dd32\WordPress\UserTeams\Plugin;

    ```
    $id = Plugin::create_team( 'Meta Team', 'meta-team', 'editor' );
    Plugin::add_team_to_site( $id, 1, 'editor' );
    Plugin::add_team_to_site( $id, 4, 'author' );
    Plugin::add_user_to_team( $user_id, $id );
    ```

Checking access uses the normal cap system — team-derived caps participate via `
user_has_cap`:

    ```
    if ( user_can( $user_id, 'edit_others_posts' ) ) {
        // ...
    }
    ```

### Where’s development happening?

On GitHub at [dd32/wp-user-teams](https://github.com/dd32/wp-user-teams). That’s
where the source, issues, pull requests, and release tags live.

### I have a bug report or feature request

File it on [GitHub](https://github.com/dd32/wp-user-teams/issues). General support
questions belong in the [WordPress.org Support Forums](https://wordpress.org/support/plugin/user-teams/).

## Reviews

There are no reviews for this plugin.

## Contributors & Developers

“User Teams” is open source software. The following people have contributed to this
plugin.

Contributors

 *   [ Dion Hulse ](https://profiles.wordpress.org/dd32/)

[Translate “User Teams” into your language.](https://translate.wordpress.org/projects/wp-plugins/user-teams)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/user-teams/), check
out the [SVN repository](https://plugins.svn.wordpress.org/user-teams/), or subscribe
to the [development log](https://plugins.trac.wordpress.org/log/user-teams/) by 
[RSS](https://plugins.trac.wordpress.org/log/user-teams/?limit=100&mode=stop_on_copy&format=rss).

## Meta

 *  Version **0.5**
 *  Last updated **1 day ago**
 *  Active installations **Fewer than 10**
 *  WordPress version ** 6.9 or higher **
 *  Tested up to **7.0**
 *  PHP version ** 7.4 or higher **
 * Tags
 * [multisite](https://wordpress.org/plugins/tags/multisite/)[permissions](https://wordpress.org/plugins/tags/permissions/)
   [roles](https://wordpress.org/plugins/tags/roles/)[team](https://wordpress.org/plugins/tags/team/)
   [users](https://wordpress.org/plugins/tags/users/)
 *  [Advanced View](https://wordpress.org/plugins/user-teams/advanced/)

## Ratings

No reviews have been submitted yet.

[Your review](https://wordpress.org/support/plugin/user-teams/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/user-teams/reviews/)

## Contributors

 *   [ Dion Hulse ](https://profiles.wordpress.org/dd32/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/user-teams/)