phil / access-bundle
Per-item visibility, sharing levels, access groups and their entry points, self-expiring access and 'view as this member', declared as relations on the shared resource permission model and decided by Symfony Security voters, EasyAdmin's included.
Package info
github.com/parler-haut-interagir-librement/access-bundle
Type:symfony-bundle
pkg:composer/phil/access-bundle
Requires
- php: >=8.5
- doctrine/dbal: ^4.5
- phil/resource: ^0.1@dev
- phil/resource-permissions: ^0.1@dev
- psr/clock: ^1.0
- psr/event-dispatcher: ^1.0
- psr/log: ^3.0
- symfony/config: ^8.2
- symfony/console: ^8.2
- symfony/dependency-injection: ^8.2
- symfony/http-foundation: ^8.2
- symfony/http-kernel: ^8.2
- symfony/routing: ^8.2
- symfony/security-core: ^8.2
- symfony/security-csrf: ^8.2
- symfony/ux-twig-component: ^3.7
- twig/twig: ^3.21
Requires (Dev)
- doctrine/orm: ^3.7
- easycorp/easyadmin-bundle: ^5.8
- phil/ux-kit: >=0.1.0-alpha <1.0
- phpunit/phpunit: ^13.4
- symfony/browser-kit: ^8.2
- symfony/clock: ^8.2
- symfony/css-selector: ^8.2
- symfony/dom-crawler: ^8.1
- symfony/event-dispatcher: ^8.2
- symfony/framework-bundle: ^8.2
- symfony/security-bundle: ^8.2
- symfony/translation: ^8.2
- symfony/twig-bundle: ^8.2
Suggests
- doctrine/orm: To add the tuple table to the schema the ORM generates
- easycorp/easyadmin-bundle: For the voter on EA_ACCESS_ENTITY and EA_EXECUTE_ACTION
- phil/ux-kit: For the recipes the banner and the summary draw — Alert, Badge, Button, Table —, through the Symfony UX Toolkit
- symfony/security-bundle: For the voters and the member of the security token
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-11-13 22:46:54 UTC
README
Who sees and who may change each item of a site: visibility, sharing levels, access groups, access that ends on its own, and "view as this member", decided by Symfony Security voters.
phil/access-bundle gives a Symfony site one access layer for its items — pages, documents, events, files. Each item has
an owner, a space — the site, or one of its parts — and a visibility: everyone, the members of the space,
its admins, or the owner alone, private by default. It is shared with members or access groups at a sharing
level — manage, edit, comment, view by default, each including the next —, until a date when one is given:
the share then ends on its own at that second. Access groups declare their entry points — a purchase, an
invitation, an administrator's bulk action, an automation, or every new member — and how long a membership lasts. An
admin of the space may view the site as a member, read-only, without taking their session: every start and stop
is logged and dispatched.
Every right and every sharing level is a declared relation of phil/resource-permissions: an item's view includes
its comment, which includes its edit, then its manage, which its owner holds; a visibility is a tuple on view
given to every visitor, to the members of the space or to its admins; a share is a tuple given to a member or to the
members of a group. So a check is is_granted('access.edit', $page), a list of what a member sees is one bounded
listing of the model, and why a member sees an item is the chain of tuples that grants it.
AccessVoter answers access.<level> for any ResourceReference or AccessibleItem, and access.view_as;
EasyAdminAccessVoter answers EasyAdmin's EA_ACCESS_ENTITY and EA_EXECUTE_ACTION for the entities that are
AccessibleItems. A member is always named by a stable identifier, never an email address. The banner of "view as
this member" and the summary of who has access are Twig components drawn with the recipes of the PHIL UX kit.
Status
| Part | State |
|---|---|
| The access model: spaces, groups and items, one relation per sharing level, extended by tagged contributors | Implemented and tested |
| Visibility per item — everyone, members, admins, owner — private by default, and the narrowest of two for a link | Implemented and tested |
| Sharing levels, shares with members and access groups, shares that end on their own | Implemented and tested |
| Access groups, their entry points and memberships that end on their own; groups as members or admins of a space | Implemented and tested |
| "View as this member": admins only, read-only, logged and dispatched, started and stopped by plain forms with a CSRF token | Implemented and tested |
AccessVoter and EasyAdminAccessVoter, with the reasons of each vote |
Implemented and tested |
The Twig functions access_can, access_visibility, access_viewing_as; the components PhilAccess:ViewAsBanner and PhilAccess:AccessSummary on the recipes of the kit |
Implemented and tested |
Doctrine DBAL store and schema listener, in-memory store, phil:access:purge |
Implemented and tested |
Organizations and their roles, from phil/organizations-bundle |
Planned, once that bundle exists |
Documentation
| Document | What it covers |
|---|---|
| Installation | Requirements, installing, the routes and the table. |
| Configuration | Every option, with an example. |
| The access model | The kinds and relations the bundle declares, and how to add to them. |
| Items, visibility and sharing | Owners, spaces, visibilities, sharing levels and shares that end on their own. |
| Access groups | Groups, entry points, memberships, default groups. |
| View as this member | Who may, what it shows, the log and events, the banner. |
| Checking access | The voters, the Twig functions, listing what a member sees, why. |
| EasyAdmin | The voter on EasyAdmin's permissions, the scoped CRUD controller, the tenant filter. |
| Rendering | The banner and the summary, drawn with the recipes of the kit. |
| Extension points | The services to replace, the tags to add to, and when they are stable. |
| Testing | The bundle's tests, and how to test an application's access. |
| Reference | Every class and service of the bundle. |
Quick start
// config/bundles.php Phil\AccessBundle\PhilAccessBundle::class => ['all' => true],
# config/packages/phil_access.yaml phil_access: item_kinds: [page, document] groups: supporters: { entry_points: [purchase, invitation], duration: P1M }
$items->register($page, MemberId::of($author->id), Visibility::Members); $sharing->share($page, 'edit', MemberId::of($editor->id), new DateTimeImmutable('+7 days'));
{% if is_granted('access.edit', page) %}…{% endif %}
<twig:PhilAccess:ViewAsBanner />
Requirements
PHP 8.5 or later, Symfony 8.2 or later and Doctrine DBAL 4.5 or later; SecurityBundle for the voters, TwigBundle and Symfony UX Twig Component for the functions and components, EasyAdmin 5.8 or later for its voter.
Contributing
Contributions are welcome on the PHIL monorepo: read the contribution guide and the code of conduct. Report a vulnerability privately, as the security policy explains, never in a public issue.
License
MIT, © Philippe Gamache, doing business as Le Gnome Archiviste; a Parler Haut Interagir Librement project. See LICENSE.