PHPackages                             renoki-co/laravel-acl - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. renoki-co/laravel-acl

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

renoki-co/laravel-acl
=====================

Simple, AWS IAM-style ACL for Laravel applications, leveraging granular permissions in your applications with strong declarations.

90[7 PRs](https://github.com/renoki-co/laravel-acl/pulls)PHPCI passing

Since Dec 16Pushed 2mo ago1 watchersCompare

[ Source](https://github.com/renoki-co/laravel-acl)[ Packagist](https://packagist.org/packages/renoki-co/laravel-acl)[ RSS](/packages/renoki-co-laravel-acl/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependenciesVersions (29)Used By (0)

Laravel ACL 🔐
=============

[](#laravel-acl-)

[![CI](https://github.com/renoki-co/laravel-acl/workflows/CI/badge.svg?branch=master)](https://github.com/renoki-co/laravel-acl/workflows/CI/badge.svg?branch=master)[![codecov](https://camo.githubusercontent.com/f4bcdb5e5e464d5d8b1912277cd2454450f96d23fa7efe1b242d6378e5d20a84/68747470733a2f2f636f6465636f762e696f2f67682f72656e6f6b692d636f2f6c61726176656c2d61636c2f6272616e63682f6d61737465722f67726170682f62616467652e737667)](https://codecov.io/gh/renoki-co/laravel-acl/branch/master)[![StyleCI](https://camo.githubusercontent.com/f7a38e11f97804e71847946c2fce7115b5c76b30087da2b7b051a00fd8a4ffa8/68747470733a2f2f6769746875622e7374796c6563692e696f2f7265706f732f3537363934393134342f736869656c643f6272616e63683d6d6173746572)](https://github.styleci.io/repos/576949144)[![Latest Stable Version](https://camo.githubusercontent.com/71eae331a2dd92fa06914a145592cf8b2cc93ad300b92ff9a0b0b2164acbf071/68747470733a2f2f706f7365722e707567782e6f72672f72656e6f6b692d636f2f6c61726176656c2d61636c2f762f737461626c65)](https://packagist.org/packages/renoki-co/laravel-acl)[![Total Downloads](https://camo.githubusercontent.com/c25cddb1819a89a75b311e8449e2694be39fdd60a5007d36632e14882784cdb0/68747470733a2f2f706f7365722e707567782e6f72672f72656e6f6b692d636f2f6c61726176656c2d61636c2f646f776e6c6f616473)](https://packagist.org/packages/renoki-co/laravel-acl)[![Monthly Downloads](https://camo.githubusercontent.com/4499b2dda73ba93818a513d80dde5a5e4d3cd4567943893fa1a5b58332724f45/68747470733a2f2f706f7365722e707567782e6f72672f72656e6f6b692d636f2f6c61726176656c2d61636c2f642f6d6f6e74686c79)](https://packagist.org/packages/renoki-co/laravel-acl)[![License](https://camo.githubusercontent.com/50293799cbc0bcb6de9b375e443e07164b06eb78d301471cdc1ed860e5940887/68747470733a2f2f706f7365722e707567782e6f72672f72656e6f6b692d636f2f6c61726176656c2d61636c2f6c6963656e7365)](https://packagist.org/packages/renoki-co/laravel-acl)

Simple, AWS IAM-style ACL for Laravel applications, leveraging granular permissions in your applications with strong declarations. 🔐

🚀 Installation
--------------

[](#-installation)

You can install the package via composer:

```
composer require renoki-co/laravel-acl
```

Publish the config:

```
php artisan vendor:publish --provider="RenokiCo\LaravelAcl\LaravelAclServiceProvider" --tag="config"
```

Publish the migrations:

```
php artisan vendor:publish --provider="RenokiCo\LaravelAcl\LaravelAclServiceProvider" --tag="migrations"
```

🙌 Usage
-------

[](#-usage)

This package is based on [renoki-co/acl](https://github.com/renoki-co/acl), but leveraging the Laravel environment to quickly set up permissions.

In case you are familiar with how [ARNs](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) and [Policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction_access-management.html) work, you can now use the same syntax to define and check your ACL policies.

You can check more [IAM examples](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_examples.html) to get a sense how to define your policies.

The role of an ACL system is to assign policies or rules/statements to specific entities that can perform certain actions on a set of resources, so later you can verify them throughout the app.

In Laravel, the actor class is most of the times the authenticatable model. To set up the actor class, you have to trait it up with `HasPolicies`:

```
use RenokiCo\LaravelAcl\Concerns\HasPolicies;
use RenokiCo\LaravelAcl\Contracts\RuledByPolicies;
// ...

class User extends Authenticatable implements RuledByPolicies
{
    use HasPolicies;

    // ...
}
```

Whenever you require the actor to check for permissions, the package will automatically pull the attached permissions. To attach a policy, simply define a static AclPolicy and attach it directly to the actor, with a custom name (that can be helpful to identify a specific attachment):

```
use RenokiCo\Acl\Acl;
use RenokiCo\Acl\Statement;

$policy = Acl::createPolicy([
    Statement::make(
        effect: 'Allow',
        action: 'server:List',
        resource: [
            'arn:php:default:local:123:server',
        ],
    ),
]);

$user = Auth::user();

// Do this once, as it stores the policy in the database, in relation to the user.
$user->attachPolicy('ListServers', $policy);

$user->isAllowedTo(
    'server:List',
    'arn:php:default:local:123:server',
); // true
```

🧬 ARNables
----------

[](#-arnables)

**This documentation part might be outdated and was tweaked to represent this specific use case. Consider [reading the ACL documentation](https://github.com/renoki-co/acl#-arnables), taking into account this current guide.**

PHP is more object-oriented. ARNables can help turn your models or classes into a simpler version of ARNs, so you don't have to write all your ARNs each time, but instead pass them to the `isAllowedTo()` method, depending on either it's an ARN that is resource-agnostic, or an ARN that points to a specific resource.

### Resource-agnostic ARN vs Resource ARN

[](#resource-agnostic-arn-vs-resource-arn)

Resource-agnostic ARNs are the ones that are used for actions like `list` or `create`. They are not pointing to a specific resource, but rather to a "general" permission for that resource, that can lead to allowing listing or creating resources. For example, `arn:php:default:local:123:server`.

Resource ARNs are the ARNs that point to a specific resource. Actions like `delete`, `modify` and such are good examples that can be used in combination with these ARNs. For example, `arn:php:default:local:123:server/1` or `arn:php:default:local:123:backup/1`.

### Resolving the Region and Account IDs

[](#resolving-the-region-and-account-ids)

Let's take this ARN example: `arn:php:default:local:123:server`.

Since this ARN is agnostic, the `Server` class cannot be properly converted to an ARN without two key components:

- the region, in this case `local`
- the account ID, in this case `123`

Although the values do have defaults, you **must** let the ACL service know what the values should be.

For these values, you can take AWS' example: it lets you select the region (in console: by manually changing the region via the top-right selector; in the API: by specifying the `--region` parameter), and you must be authenticated to an account, in this case your current login session knows your Account ID.

### Resolving within Models

[](#resolving-within-models)

Any actor that has the `HasPolicies` trait alredy resolves the region as `local` and the account ID as the primary key. The best approach is to override the region resolver based on the current request session, for example:

```
class User extends Authenticatable implements RuledByPolicies
{
    use HasPolicies;

    /**
     * Resolve the account ID of the current actor.
     * This value will be used in ARNs for ARNable static instances,
     * to see if the current actor can perform ID-agnostic resource actions.
     *
     * @return null|string|int
     */
    public function resolveArnAccountId()
    {
        return $this->getKey();
    }

    /**
     * Resolve the region of the current actor.
     * This value will be used in ARNs for ARNable static instances,
     * to see if the current actor can perform ID-agnostic resource actions.
     *
     * @return null|string|int
     */
    public function resolveArnRegion()
    {
        return session('region', 'local');
    }
}

// i.e. Handle region change via HTTP requests
public function changeRegion(Request $request)
{
    $data = $request->validate([
        'region' => ['required', 'string', 'in:us-east-1,eu-central-1'],
    ]);

    session(['region' => $data['region']]);

    return redirect('/');
}
```

### Using ARNables with actors

[](#using-arnables-with-actors)

Let's say you have a model called `Server` instance that belongs to an user:

```
use RenokiCo\LaravelAcl\Concerns\HasArn;
use RenokiCo\LaravelAcl\Contracts\Arnable;
use RenokiCo\LaravelAcl\BuildResourceArn;

class Server extends Model implements Arnable
{
    use HasArn;

    protected $fillable = [
        'user_id',
        'name',
        'ip',
    ];

    public function arnResourceAccountId()
    {
        return $this->user_id;
    }
}
```

Instead of passing full ARNs to `->isAllowedTo`, you can now pass the server class name instead:

```
$policy = Acl::createPolicy([
    Statement::make(
        effect: 'Allow',
        action: 'server:List',
        resource: [
            'arn:php:default:local:123:server',
        ],
    ),
    Statement::make(
        effect: 'Allow',
        action: 'server:Delete',
        resource: [
            'arn:php:default:local:123:server/1',
        ],
    ),
]);

$user = Auth::user();

$user->isAllowedTo('server:List', Server::class); // true
```

To check permissions on a specific resource ARN, you may pass the object itself to the ARN parameter:

```
$server = Server::find('1');
$user->isAllowedTo('server:Delete', $server); // true
```

As you have seen previously, on the actor model you can specify the account identifier for them. In an ARN like `arn:php:default:local:123:server`, the part `123` is the account ID, or the account identifier. Thus, setting `resolveArnAccountId` to return `123`, the policies will allow the actor to `server:List` on that specific resource.

The resource ID gets resolved automatically to the model primary key, but you can override it:

```
class Server extends Model implements Arnable
{
    use HasArn;

    public function arnResourceId()
    {
        return $this->getKey();
    }
}
```

### Using ARNables with teams

[](#using-arnables-with-teams)

On a more complex note, having a model that groups more actors, like a `Team` having more `User`s is pretty common, especially if using [Laravel Jetstream](https//jetstream.laravel.com).

You still need to implement the policy checking at the user level, but with regard to resolving the "account ID" to be more like Team ID, as long as the resources are created under `Team`.

```
class Team extends Model
{
    //
}
```

```
use RenokiCo\LaravelAcl\Concerns\HasPolicies;
use RenokiCo\LaravelAcl\Contracts\RuledByPolicies;

class User extends Authenticatable implements RuledByPolicies
{
    use HasPolicies;

    public function resolveArnAccountId()
    {
        return $this->current_team_id;
    }
}
```

Im the ARNables' case, their models should resolve the account ID of the team:

```
class Server extends Model implements Arnable
{
    use HasArn;

    public function arnResourceAccountId()
    {
        return $this->team_id;
    }
}
```

### More resources

[](#more-resources)

- [Learn how ARNables are solved by ACL](https://github.com/renoki-co/acl#-arnables)
- [Learn about common good practices and guidelines when defining your permissions](https://github.com/renoki-co/acl#-guidelines)

🐛 Testing
---------

[](#-testing)

```
vendor/bin/phpunit
```

🤝 Contributing
--------------

[](#-contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

🔒 Security
----------

[](#--security)

If you discover any security related issues, please email  instead of using the issue tracker.

🎉 Credits
---------

[](#-credits)

- [Alex Renoki](https://github.com/rennokki)
- [All Contributors](../../contributors)

###  Health Score

28

—

LowBetter than 54% of packages

Maintenance57

Moderate activity, may be stable

Popularity6

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity36

Early-stage or recently created project

 Bus Factor1

Top contributor holds 90.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/21983456?v=4)[rennokki](/maintainers/rennokki)[@rennokki](https://github.com/rennokki)

---

Top Contributors

[![rennokki](https://avatars.githubusercontent.com/u/21983456?v=4)](https://github.com/rennokki "rennokki (10 commits)")[![StyleCIBot](https://avatars.githubusercontent.com/u/11048387?v=4)](https://github.com/StyleCIBot "StyleCIBot (1 commits)")

### Embed Badge

![Health badge](/badges/renoki-co-laravel-acl/health.svg)

```
[![Health](https://phpackages.com/badges/renoki-co-laravel-acl/health.svg)](https://phpackages.com/packages/renoki-co-laravel-acl)
```

###  Alternatives

[namshi/jose

JSON Object Signing and Encryption library for PHP.

1.8k99.6M101](/packages/namshi-jose)[league/oauth1-client

OAuth 1.0 Client Library

99698.8M106](/packages/league-oauth1-client)[bezhansalleh/filament-shield

Filament support for `spatie/laravel-permission`.

2.8k2.9M88](/packages/bezhansalleh-filament-shield)[gesdinet/jwt-refresh-token-bundle

Implements a refresh token system over Json Web Tokens in Symfony

70516.4M35](/packages/gesdinet-jwt-refresh-token-bundle)[league/oauth2-google

Google OAuth 2.0 Client Provider for The PHP League OAuth2-Client

41721.2M118](/packages/league-oauth2-google)[illuminate/auth

The Illuminate Auth package.

9327.3M1.0k](/packages/illuminate-auth)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
