How do I create a cache context in Drupal 8 that varies on user/node field data?
A cache key is not the right solution as dynamic_page_cache won't vary on the right things.

What you do is:

You create a custom cache context (see core.services.yml for many examples), which itself is dependent on the [route] and [user] cache context (as it needs to check the node).

e.g. cookies:[cookie_name] is a good example. (https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Cache%21Context%21CookiesCacheContext.php/class/CookiesCacheContext/8.1.x)

In that way you can have indeed a:

caneditnode:[entity_id]

Whenever this cache context is used, your handler is checked and needs to return the right information based on the given Context.

If caneditnode is given as cache context without context it could just throw an Exception or fallback to ['user', 'route'] as that is what it depends on.

In getCacheableMetadata you would just return the node cacheable metadata and the user.roles.

See https://api.drupal.org/api/drupal/core%21core.services.yml/service/cache_context.user.permissions/8.1.x for an example of a cache context, which itself depends on other data, which can be invalidated.