{"id":33997054,"url":"https://github.com/tpg/deadbolt","last_synced_at":"2025-12-13T08:53:18.936Z","repository":{"id":38330978,"uuid":"242950191","full_name":"tpg/deadbolt","owner":"tpg","description":"Dead simple permissions for Laravel","archived":false,"fork":false,"pushed_at":"2025-04-13T09:49:28.000Z","size":221,"stargazers_count":16,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-08-25T23:58:53.276Z","etag":null,"topics":["authorization","deadbolt","laravel","permissions","php"],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tpg.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-02-25T08:38:14.000Z","updated_at":"2025-04-13T09:49:31.000Z","dependencies_parsed_at":"2023-01-21T22:46:14.975Z","dependency_job_id":null,"html_url":"https://github.com/tpg/deadbolt","commit_stats":null,"previous_names":[],"tags_count":27,"template":false,"template_full_name":null,"purl":"pkg:github/tpg/deadbolt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tpg%2Fdeadbolt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tpg%2Fdeadbolt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tpg%2Fdeadbolt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tpg%2Fdeadbolt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tpg","download_url":"https://codeload.github.com/tpg/deadbolt/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tpg%2Fdeadbolt/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27702787,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-13T02:00:09.769Z","response_time":147,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authorization","deadbolt","laravel","permissions","php"],"created_at":"2025-12-13T08:53:15.252Z","updated_at":"2025-12-13T08:53:18.928Z","avatar_url":"https://github.com/tpg.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n[![Tests](https://github.com/tpg/deadbolt/actions/workflows/tests.yml/badge.svg)](https://github.com/tpg/deadbolt/actions/workflows/tests.yml)\n\n## Why another authorization package?\n\nThere are plenty of authorization packages around. But I wanted something that was way simpler than what was on offer and something that I could use easily with my current stack which includes plenty of JavaScript. I've used many of the current top authorisation packages, and will likely use them in the future, but in some cases they're just a little over the top.\n\nDeadbolt is \"dead\" simple. It's in the name. You define your permissions in the config file (just so you have some source of truth), and you can assign them to your users. The only required database change is a `permissions` column on your `users` table. No need for any additional migrations or complicated configurations.\n\nDeadbolt is simple by design. If you need something more feature rich, there are plenty of other choices. If this doesn't fit the bill, then my go to package is Spatie's [laravel-permission](https://github.com/spatie/laravel-permission) package.\n\n## Requirements\n\nVersion 3 requires PHP 8.1 or later and Laravel 10 or later. If you're still using older versions then you'll need to stick with version 2.2. \n\n## Installation\n\nDeadbolt can be installed via Composer:\n\n```bash\ncomposer require thepublicgood/deadbolt\n```\n\n## Getting Started\n\nDeadbolt works by setting permissions in a JSON array in a column on your users table. So before you can use Deadbolt, you'll need to add that column. Deadbolt comes with a simple Artisan command that will do this for you:\n\n```bash\nphp ./artisan deadbolt:install\n```\n\nThis will do two things...\n\n1. Create a new migration named `add_deadbolt_permissions_column`,\n2. Place a copy of the Deadbolt config at `config/deadbolt.php`.\n\nYou can alter the migration if you need to, but the default will add a column named `permissions` to the `users` table.\n\nYou can now define your permissions in the `deadbolt.php` config file. That's it.\n\nThe `deadbolt:install` command is only available if the `deadbolt.php` file does not exist in the `config` directory. However, if you need to, you can always get the same result by running:\n\n```bash\nphp ./artisan vendor:publish --provider=TPG\\\\Deadbolt\\\\DeadboltServiceProvider\n```\n\n## Permissions\n\nPermissions are defined in the `deadbolt.php` config file,  in the appropriately named `$permissions` array. Permissions can be named anything you like, for example:\n\n```php\n$permissions = [\n\t'Create Articles',\n\t'Edit Articles',\n\t'Delete Articles',\n];\n```\n\nHowever, naming permissions this way could lead to errors later on. So Deadbolt provides a way to create simpler permissions names and provide a description for each permission:\n\n```php\n$permissions = [\n\t'articles.create' =\u003e 'Create Articles',\n\t'articles.edit' =\u003e 'Edit Articles',\n\t'articles.delete' =\u003e 'Delete Articles',\n];\n```\n\nThe point of defining your permissions here is to create a single source of truth for your permissions. Assigning a permission to a user that does not exist in this array will throw an exception. Similarly, checking if a user has a permission that does not exist will also throw an exception.\n\n## Working with permissions\n\n### The `Deadbolt` facade\n\nDeadbolt provides a Laravel facade named `Deadbolt`. Anything that Deadbolt can do can be handled through the use of this facade.\n\n### Getting the defined permissions\n\nYou can easily grab a list of permissions:\n\n```php\n$permissions = Deadbolt::all();\n\n/*\n[\n\t'articles.create',\n\t'articles.edit',\n\t'articles.delete',\n]\n*/\n```\n\nThis will return an array of permission names. If you also want the descriptions you defined for each permission, you can use the describe method:\n\n```php\n$permissions = Deadbolt::describe();\n\n/*\n[\n\t'articles.create' =\u003e 'Create Articles',\n\t'articles.edit' =\u003e 'Edit Articles',\n\t'articles.delete' =\u003e 'Delete Articles',\n]\n*/\n```\n\nYou can also use the describe method to get the description for just one permission, or a sub-set of permissions:\n\n```php\n$permission = Deadbolt::describe('articles.create');\n// $permission = 'Create Articles';\n\n$permissions = Deadbolt::describe(['articles.create', 'articles.edit']);\n\n/*\n[\n\t'articles.create' =\u003e 'Create Articles',\n\t'articles.edit' =\u003e 'Edit Articles',\n]\n*/\n```\n\n### Assigning permissions\n\nDeadbolt uses the word \"User\" to mean any model that has permissions that returns array of assigned permissions. This could be any Laravel model that has a \"permissions\" attribute, but it doesn't have to your actual `User` model. It could be `Role` model, or an `Organisation` model, for example.\n\nTo work with permissions on a \"user\" Deadbolt provides a `user()` method on the `Permissions` facade to which you need to pass your Laravel model:\n\n```php\n$deadbolt = Deadbolt::user($request-\u003euser());\n```\n\nThere are two main methods you can use to assign permissions. The `give()` method can be used to assign specific permissions, and the `super()` method is a quick way to assign ALL permissions.\n\n```php\n// Give a single permission\nDeadbolt::user($user)-\u003egive('articles.create');\n\n// Give muliple permissions\nDeadbolt::user($user)-\u003egive('articles.create', 'articles.edit');\n\n// Give an array of permissions\nDeadbolt::user($user)-\u003egive($arrayOfPermissions);\n```\n\nThe `super()` method is really just a shortcut for `give(Deadbolt::all())`:\n\n```php\nDeadbolt::user($user)-\u003esuper();\n```\n\nIf you attempt to assign a non-existent permission you'll get a `NoSuchPermissionException`.\n\n```php\nDeadbolt::user($user)-\u003egive('articles.publish');\n// Throws a NoSuchPermissionException.\n```\n\nYou can always get an array of permissions that are currently assigned to the user using the `all` method:\n\n```php\n$permissions = Deadbolt::user($user)-\u003eall();\n```\n\n### Taking permissions away\n\nYou can take permissions away from a user with the `revoke` method. It works in much the same way as `give`:\n\n```php\n// Revoke a single permission\nDeadbolt::user($user)-\u003erevoke('articles.edit');\n\n// Revoke multiple permissions\nDeadbolt::user($user)-\u003erevoke('articles.edit', 'articles.delete');\n\n// Revoke an array of permissions\nDeadbolt::user($user)-\u003erevoke($arrayOfArticles);\n```\n\nAgain, trying to revoke a permission that is not defined will throw a `NoSuchPermissionException`, however attempting to a permission DOES exist but not assigned to the user, the `revoke` method will do nothing.\n\nIn addition there is also a `revokeAll` method which is simply remove all permissions currently assigned to the user.\n\n```php\nDeadbolt::user($user)-\u003erevokeAll();\n```\n\n### Syncing permissions\n\nSometimes it can be useful to synchronise a users permissions. You can do this with the `sync` method, which will revoke permissions NOT in the passed array and assign permissions that are not already assigned:\n\n```php\nDeadbolt::user($user)-\u003esync($arrayOfPermissions);\n```\n\nEssentially, this is the same as doing `revokeAll()-\u003egive($arrayOfPermissions)`.\n\n## Testing for permissions\n\nNow that you have users with permissions, you need to be able to test for those permissions. Deadbolt provides a simple set of methods for this.\n\n### has\n\nUse the `has` method to check if a user has *ALL* of the specified permissions:\n\n```php\n// Check if a user has a permission\nDeadbolt::user($user)-\u003ehas('articles.create');\n\n// Check that a user has ALL of the permissions\nDeadbolt::user($user)-\u003ehas('articles.create', 'articles.edit');\n```\n\n### any\n\nUse the `any` method to check if a user has ANY of the permissions specified:\n\n```php\n// Will be true even if only one of the permissions is assigned.\nDeadbolt::user($user)-\u003eany('articles.edit', 'articles.delete');\n```\n\n### none\n\nUse the `none` method to ensure that a user has NONE of the permissions specified:\n\n```php\n// Will be false if the user has any of the specified permissions\nDeadbolt::user($user)-\u003enone('articles.create', 'articles.delete');\n```\n\n## Multiple users\n\nDeadbolt also allows you to deal with permissions across multiple users at the same time. By using the `users` method on the `Deadbolt` facade, you can use the same set of methods to work with more than one user at a time by passing a collection of user models:\n\n```php\n// Give all the users a permission\nDeadbolt::users($users)-\u003egive('articles.edit');\n\n// Remove the specified permisssions from all users.\nDeadbolt::users($users)-\u003erevoke('articles.delete');\n```\n\nFor testing permissions there are special set of methods specifically for testing across multiple users.\n\n### have\n\nUse the `have` method to test that all the users have the specified permissions:\n\n```php\n// All the users MUST HAVE all of the permissions\nDeadbolt::users($users)-\u003ehave($arrayOfPermissions);\n```\n\n### dontHave\n\nUse the `dontHave` method to ensure that NONE of the users have the specified permissions:\n\n```php\nDeadbolt::users($users)-\u003edontHave($arrayOfPermissions);\n```\n\n### any\n\n## The `HasPermissions` Trait\n\nDeadbolt also comes with a simple `HasPermissions` trait which you can add to your `User` model (or whichever model is given permissions. It works by simply doing the `Deadbolt::user($user)` part for you. To get started, simply add the `HasPermissions` trait to your model:\n\n```php\nclass User extends Authenticatable\n{\n    use HasPermissions;\n\n    //...\n}\n```\n\nNow you have access to Deadbolt directly on the user model through the `permissions()` method:\n\n```php\n$user = User::find(1);\n\n// Give a permission\n$user-\u003epermissions()-\u003egive('articles.edit');\n\n// Or revoke a permission\n$user-\u003epermissions()-\u003erevoke('articles.edit');\n\n// Or test for a permission\n$canEdit = $user-\u003epermissions()-\u003ehas('articles.edit');\n```\n\nThe `HasPermissions` trait is optional and there is no requirement for you to use it instead of using the `Deadbolt` facade directly. Either way is correct and you can choose whichever feels better.\n\n## Laravel Policies\n\nLaravel policies are a great way to deal with user abilities associated with your different models, and Deadbolt works perfectly with Laravel policies. You can read the Laravel documentation about policies [here](https://laravel.com/docs/authorization#creating-policies).\n\nA simple policy that uses Deadbolt could look something like this:\n\n```php\n\u003c?php\n\nnamespace App\\\\Policies;\n\nuse App\\\\User;\nuse Illuminate\\\\Auth\\\\Access\\\\HandlesAuthorization;\n\nclass ArticlePolicy\n{\n    use HandlesAuthorization;\n\n    public function create(User $user)\n    {\n        return Deadbolt::user($user)-\u003ehas('articles.create');\n\n\t\t// Or if you're using the HasPermissions trait:\n\t\treturn $user-\u003epermissions()-\u003ehas('articles.create');\n    }\n}\n```\n\nAnd you can test the policy with:\n\n```php\n$user-\u003ecan('create', Article::class);\n```\n\nAnd if a policy needs to test for more than one permission:\n\n```php\npublic function update(User $user, Article $article)\n{\n    return Deadbolt::user($user)-\u003ehasAll('articles.create', 'articles.edit');\n\n\t// Or if you're using the HasPermissions trait:\n\treturn $user-\u003ehasAll('articles.create', 'articles.edit');\n}\n```\n\nPolicies can be used to test abilities like this:\n\n```php\n$user-\u003ecan('update', $article);\n```\n\n## Drivers\n\nDeadbolt is designed for simplicity, but sometimes you might need something just a little more flexible. Deadbolt uses a simple driver system for sourcing permissions, so it's easy to provide your own custom implementations. This can be handy if you really do want to store your permissions in your database, for example.\n\nDeadbolt includes an `ArrayDriver` by default that sources permissions from the default `deadbolt.php` config file. If you want to write a custom driver you can do so by passing a new driver instance to the driver method before calling `user()`:\n\n```php\n$driver = new DatabaseDriver($config);\nDeadbolt::driver($driver))-\u003euser($user)-\u003egive('...');\n```\n\nIt's annoying to call the `driver` method every time you use Deadbolt, so you can set the custom driver in the config file:\n\n```php\nreturn [\n\n    'driver' =\u003e \\App\\Drivers\\DatabaseDriver::class,\n\n];\n```\n\n### Custom Drivers\n\nIf, for example, you need to source a list of permissions from your database, you can write your own driver. A custom driver class needs to implement `Drivers\\Contacts\\DriverInterface` and the only requirement is to implement a `permissions` method.\n\nThe `permissions` method must return an array of permission names:\n\n```php\n\u003c?php\n\nnamespace App\\\\Drivers;\n\nuse Illuminate\\\\Support\\\\Arr;\nuse Illuminate\\\\Support\\\\Facades\\\\DB;\nuse TPG\\\\Deadbolt\\\\Drivers\\\\Contracts\\\\DriverInterface;\n\nclass DatabaseDriver implements DriverInterface\n{\n    protected $config;\n\n    public function __construct(array $config)\n    {\n        $this-\u003econfig = $config;\n    }\n\n    public function permissions(): array\n    {\n        // return an array of permission names filtered by `$groups`\n        // Descriptions MUST be included, or null, even if not set.\n        return [\n            'articles.create' =\u003e 'Create articles',\n            'articles.edit' =\u003e null,\n            'articles.delete' =\u003e null,\n        ];        \n    }\n}\n```\n\nHow the `permissions` method sources permissions is up to you. It could a database request, or even a remote API request.\n\n## JavaScript Helper\nDeadbolt includes a simple JavaScript helper that provides some simple tools for checking permissions. You'll need to pass the user permissions to your front-end. You can import the `Deadbolt` class into your JavaScript component. If you're using Vue you could do something like this:\n\n```javascript\nimport Deadbolt from '../../vendor/thepublicgood/deadbolt/dist/Deadbolt';\n\nexport default {\n  props: {\n    user: Object,   // The object that has the \"permissions\" column\n  },\n  setup (props) {\n    \n    const permissions = new Deadbolt(props.user.permissions);\n    \n    // Check if the user has a permission\n    permissions.has('articles.create');\n    \n    // Check if the user has any permission\n    permissions.hasAny(['articles.create', 'articles.edit']);\n    \n    // Check if the user has all permissions\n    permissions.hasAll(['articles.edit', 'articles.delete']);\n    \n    // Check if the user has no permissions\n    permissions.hasNone(['articles.edit', 'articles.delete']);\n  }\n}\n```\n\n## Upgrading from version 1\n\nIf you're upgrading Deadbolt from version that is already used on a project, then you should be able to simply replace Deadbolt 1 with Deadbolt 2. However, if you have used the \"groups\" feature Deadbolt 1 you will need to look at an alternative since groups are no longer available as of Deadbolt 2.\n\nIn addition, if you are using a custom Driver, the removal of groups will affect the method signatures. The original `groups` method has been removed, and the `permissions` method no longer takes any parameters.\n\nDeadbolt 2 only supports PHP 7.3 and up, and Laravel 7.0 and up.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftpg%2Fdeadbolt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftpg%2Fdeadbolt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftpg%2Fdeadbolt/lists"}