NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages

Open source

Teams for Laravel

Install
composer require roundly-consulting/teams-for-laravel
Requires: PHP ^8.4 · Laravel ^13.0

Overview

Teams, roles, permissions and invitations for Laravel. Any Eloquent model can own and join teams; members carry a role, roles carry permissions, and teams issue expiring, email-targeted invites or take join requests. Opt in, and each customer’s rows stay with their team — in requests and in queued jobs — teams can nest, members can start later, and permissions-for-laravel adds scoped, time-boxed grants per member. A discoverable Teams facade with team-scoped handles expresses the common operations in one line, every operation is a testable action class, and authorization runs through Laravel’s own Gate and Blade. MIT-licensed and dependency-light — Laravel plus a few small sibling Roundly packages that Composer installs for you.

What you get

Teams, members & ownership

Any Eloquent model can own and join many teams. Ownership transfer keeps the previous owner on the team as an admin.

Roles, per team if needed

Register roles in code or the database with an optional cache, and let one workspace’s Editor do more than another’s.

Facade, DI or actions

Teams::for($team) handles cover every operation — or inject TeamsManager, or call the actions. Teams::fake() records it all.

Native Gate & Blade

$user->can('teams.<permission>', $team), a built-in owner ability, and @teamPermission, @teamRole and @teamOwner.

Invites & seat pools

Expiring, email-targeted, single- or multi-use invites with a seat ledger, resend, revoke and accept-by-code.

Join requests & team settings

Users ask to join, admins decide. Per-team join policy, seat caps and optional multi-admin sign-off.

Scheduled & time-boxed membership

Book members to start later, give them an end date, report who lapses soon, and prune expired memberships on a schedule.

Per-team data isolation

Opt in to a current team that follows requests into queued jobs, fail-closed team-scoped models, a checked team switch and a doctor for every scoped table.

Nested teams & scoped grants

Optional company → department → team hierarchies with inherited roles, and per-member, time-boxed grants through permissions-for-laravel.

Documentation

Installation

Install via Composer, publish and run the teams migrations plus those of the five sibling packages, and optionally publish config and stubs.

Configuration

Every config key and its default — key types, roles and cache, invite and membership lifecycle, approvals, the Gate, team context, nesting, the bridge.

Model traits

HasTeams gives any model memberships, ownership, role and permission helpers; BelongsToTeam adds a switchable current team.

The Teams facade

One entry point: Teams::for($team) handles for members, invites, join requests and roles, plus the current team, global roles and housekeeping.

DI, actions & DTOs

Inject TeamsManager instead of the facade, or call the 26 single-purpose actions with their typed DTOs from your own jobs and commands.

Creating teams

Create a team and seat its owner with Teams::create(), create rows directly when you need to, and query teams with scopes and relations.

Ownership

Check and transfer team ownership; the previous owner stays on as an admin, and a built-in owner ability replaces owner-only permissions.

Members

Add, remove and inspect members; one row per member, idempotent adds that revive removed members, role-change events and soft-delete removal.

Time-boxed memberships

Book members to start later, give them an end date, renew in place, report who lapses soon with optional reminders, and prune expired rows.

Roles

Register roles with permissions in code or the database, use the * wildcard, and cache the database driver.

Per-team role overrides

Let each team redefine a role’s permissions on top of the global roles — tenant-scoped, off by default, zero queries when disabled.

Permissions

A permission registry for picker UIs with groups and role harvesting, plus programmatic permission and role checks.

Gate, Blade & policies

Authorize with $user->can('teams.<permission>', $team), @teamPermission / @teamRole / @teamOwner, and scaffolded team policies.

Permissions bridge

Optional bridge to permissions-for-laravel: several roles per member, time-boxed and direct grants inside a team, team-defined roles and cleanup.

Data isolation

Opt-in multi-tenancy: a current team that follows requests into queued jobs, fail-closed team-scoped models, a checked team switch and a doctor.

Nested teams

Optional company → department → team hierarchies: move teams, walk the tree, cap the depth and let roles held above apply below.

Invitations

Issue expiring, email-targeted invites, accept them by code, resend or revoke them, and wire the publishable accept route.

Multi-use invites & seat pools

Issue invite links usable N times or without limit, track consumed and remaining seats, and audit exactly who joined through each link.

Join requests

Let users ask to join a team, approve or deny with role fallback, set optional deadlines, and auto-decline stale requests.

Team settings

Typed per-team governance: join policy, seat cap, default member role and require-approval, backed by options-for-laravel.

Integrations

Multi-admin join sign-off via approvals, plus team contacts, addresses and team-to-team connections from sibling Roundly packages.

Events

Sixteen events cover members, invites, ownership, join requests, expiry, the team context and moves — plus a queued subscriber stub.

Artisan commands

Nine commands list roles and permissions, resend and prune invites, report and prune memberships, expire requests, scaffold policies and check scoping.

Exceptions

Typed exceptions for invites, join requests, members, the team context and nesting — expired, exhausted, revoked, refused — all extending TeamsException.

Models & schema

The six tables and models, their key types, swapping in your own model subclasses, and replacing the role provider.

Testing

Teams::fake() records every operation while still performing it, with an assertion per operation; Pest matchers, factories and actingInTeam() help.

Requirements

PHP 8.4+, Laravel 13, and seven small sibling Roundly packages that Composer installs for you.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.