CPalius CMF 2.2.2
Released: 2026-09-23 · Channel: stable · Critical: no
Roles stay the default. AACP can now attach sparse grant/deny exceptions to one user without minting a new role or writing system.* through a checkbox wall. Dead public URLs can 301/302 in Studio, and missing pages use a themed 404 instead of Symfony's "Oops!".
What's new
Per-user capability overlay. Role YAML is unchanged. Each user may inherit, grant, or deny a registered capability. Deny wins over the role union, a T1.4 record grant, and the T1.5 Access event. system.* cannot be granted through the overlay (a raw SQL grant row is ignored). The last admin, and your own account, cannot be denied system.aacp.access, system.users.manage, system.module.manage, or system.update.manage. Reset deletes overlay rows only. One SELECT per user per request. Design: cp-core/src/Core/Security/USER_CAPABILITY_OVERRIDES.md.
Forum section ACL is unchanged. Overlay speaks module capability strings. Board-level Forum permissions stay in ForumPermissionService.
Themed 404 / 403 / 500. TwigBundle exception pages replace the Symfony default and send noindex.
Studio SEO redirects. Map a dead path to a URL (301 or 302). Skips admin/AACP/profiler. Seo 1.1.0.
Upgrade notes
cp:update applies Version20260923010000 (cp_user_capability_overrides) and the Seo cp_seo_redirects SQL. After files land, empty cp-core/var/cache/prod/ (leave the folder).
Overlay appears on AACP user edit only, below the role form.
Known limits
A raw SQL deny of system.aacp.access on the last admin is an operator disaster, same as deleting that admin. The writer refuses it; the voter does not re-scan every user on each is_granted.