Agora

Authz

Bouncer-integrated, DB-backed RBAC for AdonisJS — roles, permissions, wildcard matching and multi-tenancy that plug into @adonisjs/bouncer rather than replacing it.

@adonis-agora/authz adds database-backed role / permission authorization (RBAC) to AdonisJS, integrated with @adonisjs/bouncer.

It does not replace Bouncer. Bouncer has no runtime API to register one ability per database row, so this package registers a small fixed set of static abilities — can and hasRole — whose body consults a DB-backed permission store. You keep writing ctx.bouncer.allows(...) and @can(...) exactly as before.

Highlights

  • Roles & permissions in the database — assign roles to users, grant permissions to roles, or grant permissions directly to a user.
  • Wildcard matching — a grant of posts.* satisfies a check for posts.edit (spatie/Laravel-style, segment-based).
  • Multi-tenancy — role assignments can be scoped to a tenant; global grants always apply.
  • Polymorphic users — never owns a users table; users are referenced by (type, id), so any model (or even non-Lucid identity) works.
  • Query scopesaccessibleBy(Post.query(), …) filters a collection at the DB layer from the same authorization data, instead of over-fetching and filtering in memory.
  • The single authority on roles — one union of the token claim, your domain tables and the store, readable forwards (effectiveRoles) and backwards (usersWithRole).
  • A route guardAuthzRoleMiddleware keeps whole route trees behind a role, with guest and denied redirects.
  • Frontend parity@adonis-agora/authz-react ships the effective grants to Inertia + React, so <Can> and the server agree on the same rule.
  • Pluggable stores — a lucid store for production and a zero-dependency memory store for tests, selected with the drivers-in-core config idiom.

This library is a faithful port of the NestJS nestjs-authz core (the gate resolution order, the wildcard matcher and the store contract), adapted to Bouncer and the AdonisJS provider/config conventions.

Next steps

On this page