Permissions are declared by the addon contract and enforced by Core. The declaration makes permissions discoverable to Admin, system governance, Installer, and smoke tests; enforcement keeps runtime behavior honest.
Owners
- Core owns enforcement helpers in `core/security/permissions.php` and authentication catalog seeding in `core/security/authentication.php`.
- Addons own their permission keys and descriptions in `manifest.php` or a dedicated `src/permissions_contract.php`.
- Admin owns the permission management surface that lists, filters, assigns, and updates catalog entries.
How To Declare
- Put stable keys under the manifest `permissions` array, such as `wiki.view`, `wiki.edit`, `wiki.publish`, and `wiki.delete`.
- For larger addons, expose a `src/permissions_contract.php` that returns structured permission metadata and list it in the manifest `paths`.
- Reference permission keys on route/admin contracts so tooling knows the intended gate.
- In handlers, check permissions with `amv_core_permission_require($authContext, 'permission.key')` or an addon adapter such as `amv_wiki_admin_can()`.
Existing Usage
- Wiki declares permission keys in `addons/wiki/manifest.php` and mirrors structured details in `addons/wiki/src/permissions_contract.php`.
- Wiki route/admin contracts attach `wiki.view` and `wiki.edit` to admin routes and screens.
- Changelog declares `changelog.view` and `changelog.manage` in `addons/changelog/manifest.php`.
- Admin permission screens are dispatched from `admin/bootstrap/admin_bootstrap.php` and read the discovered catalog.
Do Not Duplicate
- Do not create addon-local role tables for generic admin permissions.
- Do not hide permission checks only in views; enforce them in route/action handlers too.
- Do not invent keys that are not declared in the manifest or contract.
- Do not change permission key spelling after records have been deployed unless a migration or compatibility alias owns the transition.