How to properly restrict node access (including update/delete) based on field value? I have following requirements:


Users have (among others) role "tier1", "tier2" or "tier3". Higher value means more permissions and anonymous users are considered "tier0".
Users from tier2 and tier3 can create certain node type - MyNode. And only these users can update and delete them.
The node type MyNode contains (my custom) field for restricting access - it's a simple integer. 0 means all users can access it, 1 means users of tier 1-3 can access it, etc.


What's the proper way to implement the node restriction?

What I tried &amp; longer description of the problem

After Googling and reading documentation, I found hook_entity_access. I simply iterated all fields and if I found my access field type, read the value and handle it. It was working pretty nicely for viewing, editing and deleting. But not for views - they completely ignored that.

After some more googling, I found that hook_entity_access/hook_node_access are ignored in views as explained on Node access rights. This page also explains that this problem should be solved by using  hook_query_TAG_alter, however I can't understand how it should be used. It seems to me I'm missing some bigger picture and failed to google it. But I found another solution - to use hook_node_access_records with hook_node_grants. I implemented this solution (with a tutorial help).

So each instance of MyNode provide grant based on field value, e.g. gid 2 means tier 2-3 can access the node. Each user is given grants based on their tier role, e.g. user with tier1 receive grants with gid 1, 2 and 3. This fixed view problem, but caused another one - if I set access of a node to 3, then users of tier 0-2 cannot view it (that's correct), but user of tier 2 can edit it (that's problem).

After some testing, it seems like permissions are handled differently for view and update/delete. View grant permissions are AND-ed with basic permission system (/admin/people/permissions), but update/delete permissions are OR-ed. I used the basic permission system to determine which roles can generally create, update and delete MyNode nodes.

So my current solution is merge of both approaches - grant system for views and hook_node_access for working with nodes directly. However, it seems to me quite hacky, dirty solution - I practically implemented same thing twice in different systems, because each system can handle only subset of all operations. And so, my question is - what's the proper implementation? What is correct Drupal-way?

Note: of course, I looked at modules to solve this. I rejected most of them, because they're still in alpha/beta/rc phase, while lifetime of D8 is ending. How much time I would have to wait for D9 implementation? Others were imho too bloated for "simple" "compare numeric value with role and accept/reject".

My system: Drupal version: 8.8.3
What's the proper way to implement the node restriction?


Don't re-invent the wheel ... The Group module is what you should be looking at. 
It creates groups as entities, making them fully fieldable, extensible and exportable. For this specific question, you'd enable the gnode submodule, and for each group type you would define the appropriate permissions (view, edit, delete, etc) for the various Content Types.

More info


Refer to "What are the various roles supported by the Group module?" for more details about the supported roles.
Refer to my answer to "How to configure access to courses for teachers and students?" for a sample configuration.


Resources


Community documentation for the Group module.
Video tutorial "How to use the Group module in Drupal 8 to manage editorial access control to different areas of a web site".