{"id":13828267,"url":"https://github.com/givebutter/laravel-keyable","last_synced_at":"2026-01-11T15:54:24.804Z","repository":{"id":45061562,"uuid":"181373867","full_name":"givebutter/laravel-keyable","owner":"givebutter","description":"Add API keys to your Laravel models.","archived":false,"fork":false,"pushed_at":"2025-07-08T05:41:07.000Z","size":73,"stargazers_count":183,"open_issues_count":2,"forks_count":24,"subscribers_count":21,"default_branch":"master","last_synced_at":"2025-07-08T06:56:30.974Z","etag":null,"topics":["api-keys","apis","authentication","laravel","php","rest"],"latest_commit_sha":null,"homepage":"","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/givebutter.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-04-14T21:58:24.000Z","updated_at":"2025-07-08T05:40:03.000Z","dependencies_parsed_at":"2024-03-28T16:48:04.813Z","dependency_job_id":"1f7e49e0-397a-48db-a1ca-d9552e6f62da","html_url":"https://github.com/givebutter/laravel-keyable","commit_stats":{"total_commits":27,"total_committers":7,"mean_commits":3.857142857142857,"dds":0.5185185185185186,"last_synced_commit":"1257a0237f9c037e14100adae0949be3b7f0c3b5"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/givebutter/laravel-keyable","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/givebutter%2Flaravel-keyable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/givebutter%2Flaravel-keyable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/givebutter%2Flaravel-keyable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/givebutter%2Flaravel-keyable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/givebutter","download_url":"https://codeload.github.com/givebutter/laravel-keyable/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/givebutter%2Flaravel-keyable/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264238113,"owners_count":23577675,"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","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":["api-keys","apis","authentication","laravel","php","rest"],"created_at":"2024-08-04T09:02:39.150Z","updated_at":"2026-01-11T15:54:24.722Z","avatar_url":"https://github.com/givebutter.png","language":"PHP","funding_links":[],"categories":["PHP"],"sub_categories":[],"readme":"# Laravel Keyable\r\n\r\nLaravel Keyable is a package that allows you to add API Keys to any model. This allows you to associate incoming requests with their respective models. You can also use Policies to authorize requests.\r\n\r\n[![Latest Stable Version](https://poser.pugx.org/givebutter/laravel-keyable/v/stable)](https://packagist.org/packages/givebutter/laravel-keyable) [![Total Downloads](https://poser.pugx.org/givebutter/laravel-keyable/downloads)](https://packagist.org/packages/givebutter/laravel-keyable) [![License](https://poser.pugx.org/givebutter/laravel-keyable/license)](https://packagist.org/packages/givebutter/laravel-keyable)\r\n\r\n## Installation\r\n\r\nRequire the ```givebutter/laravel-keyable``` package in your ```composer.json``` and update your dependencies:\r\n\r\n```bash\r\ncomposer require givebutter/laravel-keyable\r\n```\r\n\r\nPublish the migration and config files:\r\n```bash\r\nphp artisan vendor:publish --provider=\"Givebutter\\LaravelKeyable\\KeyableServiceProvider\"\r\n```\r\n\r\nRun the migration:\r\n```bash\r\nphp artisan migrate\r\n```\r\n\r\n## Usage\r\n\r\nAdd the ```Givebutter\\LaravelKeyable\\Keyable``` trait to your model(s):\r\n\r\n```php\r\nuse Illuminate\\Database\\Eloquent\\Model;\r\nuse Givebutter\\LaravelKeyable\\Keyable;\r\n\r\nclass Account extends Model\r\n{\r\n    use Keyable;\r\n\r\n    // ...\r\n}\r\n```\r\n\r\nAdd the ```auth.apiKey``` middleware to the ```mapApiRoutes()``` function in your ```App\\Providers\\RouteServiceProvider``` file:\r\n\r\n```php\r\n// ...\r\n\r\nprotected function mapApiRoutes()\r\n{\r\n    Route::prefix('api')\r\n        -\u003emiddleware(['api', 'auth.apikey'])\r\n\t-\u003enamespace($this-\u003enamespace . '\\API')\r\n\t-\u003egroup(base_path('routes/api.php'));\r\n}\r\n\r\n// ...\r\n```\r\n\r\nThe middleware will authenticate API requests, ensuring they contain an API key that is valid.\r\n\r\n### Generating API keys\r\n\r\nYou can generate new API keys by calling the `createApiKey()` method from the `Keyable` trait.\r\n\r\nWhen you do so, it returns an instance of `NewApiKey`, which is a simple class the contains the actual `ApiKey` instance that was just created, and also contains the plain text api key, which is the one you should use to authenticate requests.\r\n\r\n```php\r\n$newApiKey = $keyable-\u003ecreateApiKey();\r\n\r\n$newApiKey-\u003eplainTextApiKey // This is the key you should use to authenticate requests\r\n$newApiKey-\u003eapiKey // The instance of ApiKey just created\r\n```\r\n\r\nYou can also manually create API keys without using the `createApiKey` from the `Keyable` trait, in that case, the instance you get back will have a property called `plainTextApikey` populated with the plain text API key.\r\n\r\n```php\r\n$myApiKey = ApiKey::create([\r\n    'keyable_id' =\u003e $account-\u003egetKey(),\r\n    'keyable_type' =\u003e Account::class,\r\n    'name' =\u003e 'My api key',\r\n]);\r\n\r\n$myApiKey-\u003eplainTextApikey // Token to be used to authenticate requests\r\n```\r\n\r\nKeep in mind `plainTextApikey` will only be populated immediately after creating the key.\r\n\r\n### Accessing keyable models in your controllers\r\nThe model associated with the key will be attached to the incoming request as ```keyable```:\r\n\r\n```php\r\nuse App\\Http\\Controllers\\Controller;\r\n\r\nclass FooController extends Controller {\r\n\r\n    public function index(Request $request)\r\n    {\r\n        $model = $request-\u003ekeyable;\r\n\r\n        // ...\r\n    }\r\n\r\n}\r\n```\r\nNow you can use the keyable model to scope your associated API resources, for example:\r\n```php\r\nreturn $model-\u003efoo()-\u003eget();\r\n```\r\n\r\n### Keys Without Models\r\n\r\nSometimes you may not want to attach a model to an API key (if you wanted to have administrative access to your API). By default this functionality is turned off:\r\n\r\n```php\r\n\u003c?php\r\n\r\nreturn [\r\n\r\n    'allow_empty_models' =\u003e true\r\n\r\n];\r\n```\r\n\r\n## Making Requests\r\n\r\nBy default, laravel-keyable uses bearer tokens to authenticate requests. Attach the API key to the header of each request:\r\n\r\n```\r\nAuthorization: Bearer \u003ckey\u003e\r\n```\r\n\r\nYou can change where the API key is retrieved from by altering the setting in the `keyable.php` config file. Supported options are: `bearer`, `header`, and `parameter`.\r\n```php\r\n\u003c?php\r\n\r\nreturn [\r\n\r\n    'mode' =\u003e 'header',\r\n\r\n    'key' =\u003e 'X-Authorization',\r\n\r\n];\r\n```\r\n\r\nNeed to pass the key as a URL parameter? Set the mode to `parameter` and the key to the string you'll use in your URL:\r\n```php\r\n\u003c?php\r\n\r\nreturn [\r\n\r\n    'mode' =\u003e 'parameter',\r\n\r\n    'key' =\u003e 'api_key'\r\n\r\n];\r\n```\r\nNow you can make requests like this:\r\n```php\r\nhttps://example.com/api/posts?api_key=\u003ckey\u003e\r\n```\r\n\r\n## Authorizing Requests\r\n\r\nLaravel offers a great way to perform [Authorization](https://laravel.com/docs/5.8/authorization) on incoming requests using Policies. However, they are limited to authenticated users. We replicate that functionality to let you authorize requests on any incoming model.\r\n\r\nTo begin, add the `AuthorizesKeyableRequests` trait to your base `Controller.php` class:\r\n\r\n```php\r\n\u003c?php\r\n\r\nnamespace App\\Http\\Controllers;\r\n\r\n// ...\r\n\r\nuse Givebutter\\LaravelKeyable\\Auth\\AuthorizesKeyableRequests;\r\n\r\nclass Controller extends BaseController\r\n{\r\n    use AuthorizesKeyableRequests;\r\n}\r\n```\r\n\r\nNext, create the `app/Policies/KeyablePolicies` folder and create a new policy:\r\n\r\n```php\r\n\u003c?php\r\n\r\nnamespace App\\Policies\\KeyablePolicies;\r\n\r\nuse App\\Models\\Post;\r\nuse Illuminate\\Database\\Eloquent\\Model;\r\nuse Givebutter\\LaravelKeyable\\Models\\ApiKey;\r\n\r\nclass PostPolicy {\r\n\r\n    public function view(ApiKey $apiKey, Model $keyable, Post $post) {\r\n    \treturn !is_null($keyable-\u003eposts()-\u003efind($post-\u003eid));\r\n    }\r\n\r\n}\r\n```\r\n\r\nLastly, register your policies in `AuthServiceProvider.php`:\r\n\r\n```php\r\n\u003c?php\r\n\r\nnamespace App\\Providers;\r\n\r\n// ...\r\n\r\nuse App\\Models\\Post;\r\nuse App\\Policies\\KeyablePolicies\\PostPolicy;\r\nuse Givebutter\\LaravelKeyable\\Facades\\Keyable;\r\n\r\nclass AuthServiceProvider extends ServiceProvider\r\n{\r\n\r\n    // ...\r\n\r\n    protected $keyablePolicies = [\r\n        Post::class =\u003e PostPolicy::class\r\n    ];\r\n\r\n    public function boot(GateContract $gate)\r\n    {\r\n        // ...\r\n        Keyable::registerKeyablePolicies($this-\u003ekeyablePolicies);\r\n    }\r\n\r\n}\r\n```\r\n\r\nIn your controller, you can now authorize the request using the policy by calling `$this-\u003eauthorizeKeyable(\u003cability\u003e, \u003cmodel\u003e)`:\r\n\r\n```php\r\n\u003c?php\r\n\r\nnamespace App\\Http\\Controllers\\PostController;\r\n\r\nuse App\\Models\\Post;\r\nuse Illuminate\\Http\\Request;\r\nuse App\\Http\\Controllers\\Controller;\r\n\r\nclass PostController extends Controller {\r\n\r\n    public function show(Post $post) {\r\n        $this-\u003eauthorizeKeyable('view', $post);\r\n        // ...\r\n    }\r\n\r\n}\r\n```\r\n\r\n## Keyable Model Scoping\r\n\r\nWhen using implicit model binding, you may wish to scope the first model such that it must be a child of the keyable model. Consider an example where we have a post resource:\r\n\r\n```php\r\nuse App\\Models\\Post;\r\n\r\nRoute::get('/posts/{post}', function (Post $post) {\r\n    return $post;\r\n});\r\n```\r\n\r\nYou may instruct the package to apply the scope by invoking the `keyableScoped` method when defining your route:\r\n\r\n```php\r\nuse App\\Models\\Post;\r\n\r\nRoute::get('/posts/{post}', function (Post $post) {\r\n    return $post;\r\n})-\u003ekeyableScoped();\r\n```\r\n\r\nThe benefits of applying this scope are two-fold. First, models not belonging to the keyable model are caught before the controller. That means you don't have to handle this repeatedly in the controller methods. Second, models that don't belong to the keyable model will trigger a 404 response instead of a 403, keeping information hidden about other users.\r\n\r\nYou may use this in tandem with Laravel's scoping to ensure the entire heirarchy has a parent-child relationship starting with the keyable model:\r\n\r\n```php\r\nuse App\\Models\\Post;\r\nuse App\\Models\\User;\r\n\r\nRoute::get('/users/{user}/posts/{post}', function (User $user, Post $post) {\r\n    return $post;\r\n})-\u003escopeBindings()-\u003ekeyableScoped();\r\n```\r\n\r\n## Artisan Commands\r\n\r\nGenerate an API key:\r\n\r\n```bash\r\nphp artisan api-key:generate --id=1 --type=\"App\\Models\\Account\" --name=\"My api key\"\r\n```\r\n\r\nDelete an API key:\r\n```bash\r\nphp artisan api-key:delete --id=12345\r\n```\r\n\r\n## Upgrading\r\n\r\nPlease see [UPGRADING](UPGRADING.md) for details.\r\n\r\n## Security\r\n\r\nIf you discover any security related issues, please email [liran@givebutter.com](mailto:liran@givebutter.com).\r\n\r\n## License\r\nReleased under the [MIT](https://choosealicense.com/licenses/mit/) license. See [LICENSE](LICENSE.md) for more information.\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgivebutter%2Flaravel-keyable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgivebutter%2Flaravel-keyable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgivebutter%2Flaravel-keyable/lists"}