Clarifying Page-Level ACL Inheritance

Hi!
I’m trying to confirm the exact inheritance and behavior of Grav’s ACL system across the following layers (and anywhere else I might be missing):

  • Site-level defaults (user/config/site.yaml, plugins/login.yaml)
  • Groups (user/config/groups.yaml)
  • Users (user/accounts/<user>.yaml)
  • Page frontmatter (access:)

I’ve read the Login plugin docs and successfully tested examples like:

access:
  site.login: true
  groups: [editors]
  users: [eightysixed]

…but I can’t find a canonical example in the docs showing how these layers merge together.

Older forum posts mention this topic, but most were written before the later Grav 1.7.x updates — and some of those links are now gone.

In particular, I can’t find much on using the groups: and users: keys inside a page’s access: frontmatter in Grav’s docs/the Learn site.

Questions:

  1. Does Grav formally merge group → user → page ACLs at runtime?
  2. Are access.groups and access.users officially supported, or just respected by the Login plugin?
  3. Is login.visibility_requires_access: true still the correct way to hide restricted pages from menus and listings?

Any official clarification or example YAMLs would be super helpful — especially for new users setting up private sections, member areas, or simple editorial workflows. Thanks! :slight_smile:

Oops! I found the answer to my own question. I came back to this and went back through the docs. It was hidden in plain sight in the Advanced section. Plain as day. Not sure how I missed it :face_holding_back_tears:

Link here. It does indeed clarify and does explicitly that Group permissions are inherited by the user, and may be overridden or extended by the user’s own permission. An embarrassing oops, but a welcomed one. I hadn’t had a need for permission control in Grav, but this works perfectly.

I’ll leave this here in case it helps the next person who wonders the same thing and missed is it too :slight_smile:

edit: I was overthinking this and being too much of a micromanager with permissions, but I’m blaming that on the behavior of old app, another reason for the migration :slight_smile:

1 Like