edgrosvenor/tupleauth
TupleAuth adds tuple-based, relationship-driven authorization to Laravel. Define access as subject-relation-object tuples, then check permissions through familiar Gates and Blade directives without building complex role hierarchies.
Permission model selection (RBAC → ReBAC). TupleAuth is an implementation of relationship-based access control (ReBAC): access is expressed as subject–relation–object tuples rather than a role string on a user record. This is the package's entire value to a PM — it's a concrete, Laravel-native demonstration of the model. It directly supports the decision of whether to move from flat roles (admin, editor) to relationship-driven checks (user:42 is editor of folder:7, therefore can view doc:99) as your product grows nested resources, sharing, and inheritance. That decision is worth making explicitly, because retrofitting a permission model after you've shipped a permissions UI and an audit log is one of the more expensive migrations a product can undertake.
Sharing and collaboration roadmap. Any feature set involving per-object sharing, team folders, delegated access, or "who can see this?" flows needs an inheritance model. The tuple approach answers those questions compositionally instead of with combinatorial role codes. If the roadmap has a Q2 sharing feature and a Q3 enterprise-tier feature, this is the model to evaluate now, while the surface area is still small.
Multi-tenant and workspace scoping. Subject–relation–object generalizes cleanly to tenant boundaries (user:42 member_of org:9). Relevant to any decision about whether tenancy is a middleware concern or an authorization concern.
Build vs. buy vs. borrow. This is the most actionable decision the package informs, and it splits three ways. Borrow the design — the tuple model and Gate/middleware integration pattern are the reusable asset. Build the evaluator in-house behind Gate::define and policies, which is where most Laravel teams should land. Buy only if you genuinely need Zanzibar-grade scale, in which case a maintained external system (OpenFGA, SpiceDB) is the buy, not this package. The package itself does not survive scrutiny as a dependency (see below), but it shortens the design conversation.
Migration sequencing. Because the API is Gate-, policy-, and middleware-shaped, the pattern can be introduced incrementally behind existing authorization calls rather than as a flag-day rewrite. That supports a phased migration decision: keep the current checks, add tuple evaluation behind them, flip per-domain.
Auditability and enterprise procurement. "Why does this user have access?" is a question that shows up in security questionnaires and enterprise deals. Tuple models produce an answerable structure; scattered isAdmin() checks do not. If enterprise is on the roadmap, this is a supporting input to timing.
The honest framing: the product here is the pattern, not the package. The package is a reference implementation that happens to be archived.
Consider the package as a design reference when:
Look elsewhere — including away from this package entirely — when:
spatie/laravel-permission handles team-scoped roles for the majority of products; OpenFGA or SpiceDB are the right call if you actually need a general relationship graph with scale and tooling.Action before any decision: treat this as a one-to-two-day spike to extract the model, not a dependency evaluation. Read the source, write down the tuple schema and the evaluation semantics, then delete it and implement the evaluator you actually want.
For executives (two minutes). We evaluated a small Laravel package that implements a modern permissions model called relationship-based access control — the "you can see this document because you're an editor on the folder it lives in" model, rather than "you have the Editor role." The model is a good fit for the sharing and enterprise features on our roadmap, and it's cheaper to design in now than to retrofit later. The package itself is not usable: it's been archived since 2019, has one public user, and receives no security or version support. So the recommendation is not to adopt a dependency — it's to adopt the model and build a scoped version in-house, roughly one to two sprints of engineering behind our existing authorization layer. That keeps us off an unsupported dependency while avoiding an expensive permissions rewrite in eighteen months. No spend required; the cost is engineering time we should schedule deliberately.
For engineering (the working summary). The concept is sound and the API surface is the one we'd want anyway — tuples evaluated through Gate, policies, and route middleware, with role and relationship hierarchies, config-driven, no external services. The implementation is a dead reference: archived, last release October 2019, effectively zero adoption, no CI, no support commitment. Don't composer require it. Do read it — it's a compact worked example of the tuple schema and the Gate integration, and it will save us design time. Then implement the evaluator ourselves, behind a single interface (can(subject, relation, object)), so that if we outgrow it we can swap in OpenFGA or SpiceDB without touching call sites. Keep the evaluation logic isolated, keep the tuple store in our own schema, and write the "why does this user have access" query path from day one — that's the requirement that makes or breaks the model in practice, and it's the one thing a small package won't give us anyway.
How can I help you explore Laravel packages today?