{"id":14966332,"url":"https://github.com/yiisoft/rbac-php","last_synced_at":"2025-10-28T00:31:47.105Z","repository":{"id":39586477,"uuid":"180972872","full_name":"yiisoft/rbac-php","owner":"yiisoft","description":"RBAC PHP file storage.","archived":false,"fork":false,"pushed_at":"2024-08-23T04:09:02.000Z","size":202,"stargazers_count":23,"open_issues_count":5,"forks_count":8,"subscribers_count":18,"default_branch":"master","last_synced_at":"2024-10-29T14:35:33.737Z","etag":null,"topics":["access-control","files","hacktoberfest","rbac","yii3"],"latest_commit_sha":null,"homepage":"https://www.yiiframework.com/","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yiisoft.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":".github/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"open_collective":"yiisoft","github":["yiisoft"]}},"created_at":"2019-04-12T09:09:45.000Z","updated_at":"2024-08-23T04:09:04.000Z","dependencies_parsed_at":"2023-01-29T22:01:08.201Z","dependency_job_id":"d3d7b773-f730-4631-a3aa-087406e1bff0","html_url":"https://github.com/yiisoft/rbac-php","commit_stats":{"total_commits":95,"total_committers":16,"mean_commits":5.9375,"dds":0.6947368421052631,"last_synced_commit":"42d67df05ff7552002d0df83729539f3c908fa2a"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yiisoft%2Frbac-php","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yiisoft%2Frbac-php/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yiisoft%2Frbac-php/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yiisoft%2Frbac-php/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yiisoft","download_url":"https://codeload.github.com/yiisoft/rbac-php/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230731901,"owners_count":18272161,"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":["access-control","files","hacktoberfest","rbac","yii3"],"created_at":"2024-09-24T13:36:14.060Z","updated_at":"2025-10-28T00:31:41.827Z","avatar_url":"https://github.com/yiisoft.png","language":"PHP","funding_links":["https://opencollective.com/yiisoft","https://github.com/sponsors/yiisoft"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/yiisoft\" target=\"_blank\"\u003e\n        \u003cimg src=\"https://yiisoft.github.io/docs/images/yii_logo.svg\" height=\"100px\"\u003e\n    \u003c/a\u003e\n    \u003ch1 align=\"center\"\u003eYii RBAC PHP File Storage\u003c/h1\u003e\n    \u003cbr\u003e\n\u003c/p\u003e\n\n[![Latest Stable Version](https://poser.pugx.org/yiisoft/rbac-php/v)](https://packagist.org/packages/yiisoft/rbac-php)\n[![Total Downloads](https://poser.pugx.org/yiisoft/rbac-php/downloads)](https://packagist.org/packages/yiisoft/rbac-php)\n[![Build status](https://github.com/yiisoft/rbac-php/actions/workflows/build.yml/badge.svg)](https://github.com/yiisoft/rbac-php/actions/workflows/build.yml)\n[![codecov](https://codecov.io/gh/yiisoft/rbac-php/graph/badge.svg?token=YU8LVBNCQ8)](https://codecov.io/gh/yiisoft/rbac-php)\n[![Mutation testing badge](https://img.shields.io/endpoint?style=flat\u0026url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2Fyiisoft%2Frbac-php%2Fmaster)](https://dashboard.stryker-mutator.io/reports/github.com/yiisoft/rbac-php/master)\n[![static analysis](https://github.com/yiisoft/rbac-php/workflows/static%20analysis/badge.svg)](https://github.com/yiisoft/rbac-php/actions?query=workflow%3A%22static+analysis%22)\n[![type-coverage](https://shepherd.dev/github/yiisoft/rbac-php/coverage.svg)](https://shepherd.dev/github/yiisoft/rbac-php)\n\nThis package provides PHP file-based storage for [RBAC (Role-Based Access Control)](https://github.com/yiisoft/rbac)\npackage.\n\n## Requirements\n\n- PHP 8.1 or higher.\n\n## Installation\n\nThe package could be installed with [Composer](https://getcomposer.org):\n\n```shell\ncomposer require yiisoft/rbac-php\n```\n\nSee [yiisoft/rbac](https://github.com/yiisoft/rbac) for RBAC package installation instructions.\n\n## General usage\n\nThe storage is suitable for authorization data that is not too big (for example, the authorization data for a personal \nblog system) or for fairly static RBAC hierarchy.\n\nAuthorization data is stored in PHP files. PHP should be able to read and write these files. Non-existing files will be \ncreated automatically on any write operation.\n\n### Using storages\n\nThe storages are not intended to be used directly. Instead, use them with `Manager` from\n[Yii RBAC](https://github.com/yiisoft/rbac) package:\n\n```php\nuse Yiisoft\\Rbac\\Manager;\nuse Yiisoft\\Rbac\\Permission;\nuse Yiisoft\\Rbac\\Php\\AssignmentsStorage;\nuse Yiisoft\\Rbac\\Php\\ItemsStorage;\nuse Yiisoft\\Rbac\\RuleFactoryInterface;\n\n$directory = __DIR__ . '/rbac';\n$itemsStorage = new ItemsStorage($directory . '/items.php');\n$assignmentsStorage = new AssignmentsStorage($directory . '/assignments.php');\n/** @var RuleFactoryInterface $rulesContainer */\n$manager = new Manager(\n    itemsStorage: $itemsStorage, \n    assignmentsStorage: $assignmentsStorage,\n    // Requires https://github.com/yiisoft/rbac-rules-container or other compatible factory.\n    ruleFactory: $rulesContainer,\n),\n$manager-\u003eaddPermission(new Permission('posts.create'));\n```\n\n\u003e Note that it's not necessary to use both PHP storages. Combining different implementations is possible. A quite\n\u003e popular case is to manage items via PHP file while store assignments in database (see \n\u003e [Cycle](https://github.com/yiisoft/rbac-cycle-db) and [Yiisoft DB](https://github.com/yiisoft/rbac-db) \n\u003e implementations).\n\nMore examples can be found in [Yii RBAC](https://github.com/yiisoft/rbac) documentation.\n\n### File structure\n\nIn case you decide to manually edit the files, make sure to keep the following structure.\n\n#### Items\n\nRequired and optional fields:\n\n```php\nreturn [\n    [\n        'name' =\u003e 'posts.update',\n        'description' =\u003e 'Update a post', // Optional\n        'rule_name' =\u003e 'is_author', // Optional\n        'type' =\u003e 'permission', // or 'role'        \n        'created_at' =\u003e 1683707079, // UNIX timestamp, optional\n        'updated_at' =\u003e 1683707079, // UNIX timestamp, optional\n    ],\n];\n```\n\nWhile it's recommended to maintain created and updated timestamps, if any is missing, the file modification time will \nbe used instead as a fallback.\n\nThe structure for an item with children:\n\n```php\nreturn [\n    [\n        'name' =\u003e 'posts.redactor',\n        'type' =\u003e 'role',        \n        'created_at' =\u003e 1683707079,\n        'updated_at' =\u003e 1683707079,\n        'children' =\u003e [\n            'posts.viewer',\n            'posts.create',\n            'posts.update',\n        ],\n    ],\n];\n```\n\nThe complete example for managing posts:\n\n```php\nreturn [\n    [\n        'name' =\u003e 'posts.admin',        \n        'type' =\u003e 'role',        \n        'created_at' =\u003e 1683707079,\n        'updated_at' =\u003e 1683707079,\n        'children' =\u003e [\n            'posts.redactor',\n            'posts.delete',\n            'posts.update.all',\n        ],\n    ],\n    [\n        'name' =\u003e 'posts.redactor',\n        'type' =\u003e 'role',        \n        'created_at' =\u003e 1683707079,\n        'updated_at' =\u003e 1683707079,\n        'children' =\u003e [\n            'posts.viewer',\n            'posts.create',\n            'posts.update',\n        ],\n    ],\n    [\n        'name' =\u003e 'posts.viewer',\n        'type' =\u003e 'role',        \n        'created_at' =\u003e 1683707079,\n        'updated_at' =\u003e 1683707079,\n        'children' =\u003e [\n            'posts.view',\n        ],\n    ],\n    [\n        'name' =\u003e 'posts.view',\n        'type' =\u003e 'permission',        \n        'created_at' =\u003e 1683707079,\n        'updated_at' =\u003e 1683707079,\n    ],\n    [\n        'name' =\u003e 'posts.create',\n        'type' =\u003e 'permission',        \n        'created_at' =\u003e 1683707079,\n        'updated_at' =\u003e 1683707079,\n    ],\n    [\n        'name' =\u003e 'posts.update',\n        'rule_name' =\u003e 'is_author',\n        'type' =\u003e 'permission',        \n        'created_at' =\u003e 1683707079,\n        'updated_at' =\u003e 1683707079,\n    ],\n    [\n        'name' =\u003e 'posts.delete',        \n        'type' =\u003e 'permission',        \n        'created_at' =\u003e 1683707079,\n        'updated_at' =\u003e 1683707079,\n    ],\n    [\n        'name' =\u003e 'posts.update.all',\n        'type' =\u003e 'permission',        \n        'created_at' =\u003e 1683707079,\n        'updated_at' =\u003e 1683707079,\n    ],\n];\n```\n\n#### Assignments\n\n```php\nreturn [\n    [\n        'item_name' =\u003e 'posts.redactor',\n        'user_id' =\u003e 'john',\n        'created_at' =\u003e 1683707079, // Optional\n    ],\n    // ...\n    [\n        'item_name' =\u003e 'posts.admin',\n        'user_id' =\u003e 'jack',\n        'created_at' =\u003e 1683707079,\n    ],\n];\n```\n\nWhile it's recommended to maintain created timestamps, if it is missing, the file modification time will be used \ninstead as a fallback.\n\n### Concurrency\n\nBy default, working with PHP storage does not support concurrency. This might be OK if you store its files under VCS for\nexample. If your scenario is different and, let's say, some kind of web interface is used - then, to enable concurrency, \ndo not use the storage directly - wrap it with decorator instead:\n\n```php\nuse Yiisoft\\Rbac\\Manager;\nuse Yiisoft\\Rbac\\Permission;\nuse Yiisoft\\Rbac\\Php\\AssignmentsStorage;\nuse Yiisoft\\Rbac\\Php\\ConcurrentAssignmentsStorageDecorator;\nuse Yiisoft\\Rbac\\Php\\ConcurrentItemsStorageDecorator;\nuse Yiisoft\\Rbac\\Php\\ItemsStorage;\nuse Yiisoft\\Rbac\\RuleFactoryInterface;\n\n$directory = __DIR__ . DIRECTORY_SEPARATOR . 'rbac';\n$itemsSstorage = new ConcurrentItemsStorageDecorator(ItemsStorage($directory));\n$assignmentsStorage = new ConcurrentAssignmentsStorageDecorator(AssignmentsStorage($directory));\n/** @var RuleFactoryInterface $rulesContainer */\n$manager = new Manager(\n    itemsStorage: $itemsStorage, \n    assignmentsStorage: $assignmentsStorage,\n    // Requires https://github.com/yiisoft/rbac-rules-container or other compatible factory.\n    ruleFactory: $rulesContainer,\n),\n```\n\n\u003e Note that it will have an impact on performance so don't use it unless you really have to.\n\n#### Configuring file updated time\n\nA closure can be used to customize getting file modification time:\n\n```php\nuse Yiisoft\\Rbac\\Php\\AssignmentsStorage;\nuse Yiisoft\\Rbac\\Php\\ItemsStorage;\n\n$directory = __DIR__ . '/rbac',\n$getFileUpdatedAt = static fn (string $filePath): int|false =\u003e @filemtime($filePath)\n$itemsStorage = new ItemsStorage(\n    $directory . '/items.php',\n    getFileUpdatedAt: static fn (string $filePath): int|false =\u003e @filemtime($filePath),\n);\n$itemsStorage = new AssignmentsStorage(\n    $directory . '/assignments.php',\n    getFileUpdatedAt: static fn (string $filePath): int|false =\u003e @filemtime($filePath),\n);\n```\n\nThis is useful for 2 things:\n\n- Using for empty timestamps when files are edited manually.\n- Detection of file changes when concurrency is enabled. This helps to optimize perfomance by preventing of unnecessary\nloads (when file contents has not been changed).\n\n### Syncing storages manually\n\nThe storages stay synced thanks to manager, but there can be situations where you need to sync them manually. One of\nthem is [editing storage manually](https://github.com/yiisoft/rbac-php/?tab=readme-ov-file#file-structure).\n\nLet's say PHP files are used for both items and assignments and some items were deleted.\n\n```diff\nreturn [\n    [\n        'name' =\u003e 'posts.admin',        \n        'type' =\u003e 'role',        \n        'created_at' =\u003e 1683707079,\n        'updated_at' =\u003e 1683707079,\n        'children' =\u003e [\n            'posts.redactor',\n            'posts.delete',\n            'posts.update.all',\n        ],\n    ],\n-   [\n-       'name' =\u003e 'posts.redactor',\n-       'type' =\u003e 'role',        \n-       'created_at' =\u003e 1683707079,\n-       'updated_at' =\u003e 1683707079,\n-       'children' =\u003e [\n-           'posts.viewer',\n-           'posts.create',\n-           'posts.update',\n-       ],\n-   ],\n    [\n        'name' =\u003e 'posts.viewer',\n        'type' =\u003e 'role',        \n        'created_at' =\u003e 1683707079,\n        'updated_at' =\u003e 1683707079,\n        'children' =\u003e [\n            'posts.view',\n        ],\n    ],\n    [\n        'name' =\u003e 'posts.view',\n        'type' =\u003e 'permission',        \n        'created_at' =\u003e 1683707079,\n        'updated_at' =\u003e 1683707079,\n    ],\n    [\n        'name' =\u003e 'posts.create',\n        'type' =\u003e 'permission',        \n        'created_at' =\u003e 1683707079,\n        'updated_at' =\u003e 1683707079,\n    ],\n-   [\n-       'name' =\u003e 'posts.update',\n-       'rule_name' =\u003e 'is_author',\n-       'type' =\u003e 'permission',\n-       'created_at' =\u003e 1683707079,\n-       'updated_at' =\u003e 1683707079,\n-   ],\n    [\n        'name' =\u003e 'posts.delete',        \n        'type' =\u003e 'permission',        \n        'created_at' =\u003e 1683707079,\n        'updated_at' =\u003e 1683707079,\n    ],\n    [\n        'name' =\u003e 'posts.update.all',\n        'type' =\u003e 'permission',        \n        'created_at' =\u003e 1683707079,\n        'updated_at' =\u003e 1683707079,\n    ],\n];\n```\n\nThen related entries in assignments storage needs to be deleted as well:\n\n```diff\nreturn [\n-   [\n-       'item_name' =\u003e 'posts.redactor',\n-       'user_id' =\u003e 'john',\n-       'created_at' =\u003e 1683707079,\n-   ],\n    [\n        'item_name' =\u003e 'posts.admin',\n        'user_id' =\u003e 'jack',\n        'created_at' =\u003e 1683707079,\n    ],\n];\n```\n\nWhen using database as a second storage, this can be done within a migration. Depending on chosen implementation, refer\nto either [RBAC Cycle example](https://github.com/yiisoft/rbac-cycle-db?tab=readme-ov-file#syncing-storages-manually) or \n[RBAC DB example](https://github.com/yiisoft/rbac-db?tab=readme-ov-file#syncing-storages-manually).\n\n## Documentation\n\n- [Internals](docs/internals.md)\n\nIf you need help or have a question, the [Yii Forum](https://forum.yiiframework.com/c/yii-3-0/63) is a good place for that.\nYou may also check out other [Yii Community Resources](https://www.yiiframework.com/community).\n\n## License\n\nThe Yii RBAC PHP File Storage is free software. It is released under the terms of the BSD License.\nPlease see [`LICENSE`](./LICENSE.md) for more information.\n\nMaintained by [Yii Software](https://www.yiiframework.com/).\n\n## Support the project\n\n[![Open Collective](https://img.shields.io/badge/Open%20Collective-sponsor-7eadf1?logo=open%20collective\u0026logoColor=7eadf1\u0026labelColor=555555)](https://opencollective.com/yiisoft)\n\n## Follow updates\n\n[![Official website](https://img.shields.io/badge/Powered_by-Yii_Framework-green.svg?style=flat)](https://www.yiiframework.com/)\n[![Twitter](https://img.shields.io/badge/twitter-follow-1DA1F2?logo=twitter\u0026logoColor=1DA1F2\u0026labelColor=555555?style=flat)](https://twitter.com/yiiframework)\n[![Telegram](https://img.shields.io/badge/telegram-join-1DA1F2?style=flat\u0026logo=telegram)](https://t.me/yii3en)\n[![Facebook](https://img.shields.io/badge/facebook-join-1DA1F2?style=flat\u0026logo=facebook\u0026logoColor=ffffff)](https://www.facebook.com/groups/yiitalk)\n[![Slack](https://img.shields.io/badge/slack-join-1DA1F2?style=flat\u0026logo=slack)](https://yiiframework.com/go/slack)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyiisoft%2Frbac-php","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyiisoft%2Frbac-php","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyiisoft%2Frbac-php/lists"}