 .../Drupal/Core/Cache/Context/AccountPermissionsCacheContext.php    | 6 +++++-
 core/lib/Drupal/Core/Cache/Context/UserRolesCacheContext.php        | 2 +-
 core/modules/node/src/Cache/NodeAccessGrantsCacheContext.php        | 5 +++++
 3 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/core/lib/Drupal/Core/Cache/Context/AccountPermissionsCacheContext.php b/core/lib/Drupal/Core/Cache/Context/AccountPermissionsCacheContext.php
index 2f1681c..4fda3fb 100644
--- a/core/lib/Drupal/Core/Cache/Context/AccountPermissionsCacheContext.php
+++ b/core/lib/Drupal/Core/Cache/Context/AccountPermissionsCacheContext.php
@@ -57,7 +57,11 @@ public function getContext() {
    */
   public function getCacheableMetadata() {
     $cacheable_metadata = new CacheableMetadata();
-    $tags = [];
+
+    // The permissions hash changes when:
+    // - a user is updated to have different roles;
+    $tags = ['user:' . $this->user->id()];
+    // - a role is updated to have different permissions.
     foreach ($this->user->getRoles() as $rid) {
       $tags[] = "config:user.role.$rid";
     }
diff --git a/core/lib/Drupal/Core/Cache/Context/UserRolesCacheContext.php b/core/lib/Drupal/Core/Cache/Context/UserRolesCacheContext.php
index 1181634..3b16c77 100644
--- a/core/lib/Drupal/Core/Cache/Context/UserRolesCacheContext.php
+++ b/core/lib/Drupal/Core/Cache/Context/UserRolesCacheContext.php
@@ -51,7 +51,7 @@ public function getContext($role = NULL) {
    * {@inheritdoc}
    */
   public function getCacheableMetadata($role = NULL) {
-    return new CacheableMetadata();
+    return (new CacheableMetadata())->setCacheTags(['user:' . $this->user->id()]);
   }
 
 }
diff --git a/core/modules/node/src/Cache/NodeAccessGrantsCacheContext.php b/core/modules/node/src/Cache/NodeAccessGrantsCacheContext.php
index d304bf7..767d286 100644
--- a/core/modules/node/src/Cache/NodeAccessGrantsCacheContext.php
+++ b/core/modules/node/src/Cache/NodeAccessGrantsCacheContext.php
@@ -93,6 +93,11 @@ public function getCacheableMetadata($operation = NULL) {
       return $cacheable_metadata;
     }
 
+    // The node grants may change if the user is updated. (The max-age is set to
+    // zero below, but sites may override this cache context, and change it to a
+    // non-zero value. In such cases, this cache tag is needed for correctness.)
+    $cacheable_metadata->setCacheTags(['user:' . $this->user->id()]);
+
     // If the site is using node grants, this cache context can not be
     // optimized.
     return $cacheable_metadata->setCacheMaxAge(0);
