diff --git a/core/modules/user/src/Entity/Role.php b/core/modules/user/src/Entity/Role.php
index 5ecbc02..a0b709c 100644
--- a/core/modules/user/src/Entity/Role.php
+++ b/core/modules/user/src/Entity/Role.php
@@ -178,6 +178,12 @@ public function preSave(EntityStorageInterface $storage) {
       });
       $this->weight = $max + 1;
     }
+
+    if (!$this->isSyncing()) {
+      // Permissions are always ordered alphabetically to avoid conflicts in the
+      // exported configuration.
+      sort($this->permissions);
+    }
   }
 
 }
diff --git a/core/modules/user/src/Plugin/views/field/Permissions.php b/core/modules/user/src/Plugin/views/field/Permissions.php
index bd5c11d..c9d5a9f 100644
--- a/core/modules/user/src/Plugin/views/field/Permissions.php
+++ b/core/modules/user/src/Plugin/views/field/Permissions.php
@@ -75,7 +75,6 @@ public function query() {
   }
 
   public function preRender(&$values) {
-    $uids = array();
     $this->items = array();
 
     $permission_names = \Drupal::service('user.permissions')->getPermissions();
@@ -100,10 +99,8 @@ public function preRender(&$values) {
         }
       }
 
-      foreach ($uids as $uid) {
-        if (isset($this->items[$uid])) {
-          ksort($this->items[$uid]);
-        }
+      foreach ($this->items as &$permission) {
+        ksort($permission);
       }
     }
   }
diff --git a/core/modules/user/src/Tests/Update/UserUpdateOrderPermissionsTest.php b/core/modules/user/src/Tests/Update/UserUpdateOrderPermissionsTest.php
new file mode 100644
index 0000000..344cb57
--- /dev/null
+++ b/core/modules/user/src/Tests/Update/UserUpdateOrderPermissionsTest.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace Drupal\user\Tests\Update;
+
+use Drupal\system\Tests\Update\UpdatePathTestBase;
+use Drupal\user\Entity\Role;
+
+/**
+ * Tests user permissions sort upgrade path.
+ *
+ * @group Update
+ */
+class UserUpdateOrderPermissionsTest extends UpdatePathTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setDatabaseDumpFiles() {
+    $this->databaseDumpFiles = [
+      __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8-rc1.bare.standard.php.gz',
+    ];
+  }
+
+  /**
+   * Tests that permissions are ordered by machine name.
+   */
+  public function testPermissionsOrder() {
+    $authenticated = Role::load('authenticated');
+    $permissions = $authenticated->getPermissions();
+    sort($permissions);
+    $this->assertNotIdentical($permissions, $authenticated->getPermissions());
+
+    $this->runUpdates();
+    $authenticated = Role::load('authenticated');
+    $this->assertIdentical($permissions, $authenticated->getPermissions());
+  }
+
+}
diff --git a/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserRoleTest.php b/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserRoleTest.php
index a52b6a7..5393805 100644
--- a/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserRoleTest.php
+++ b/core/modules/user/tests/src/Kernel/Migrate/d6/MigrateUserRoleTest.php
@@ -38,6 +38,7 @@ protected function assertRole($id, array $permissions, $lookupId, MigrateIdMapIn
     /** @var \Drupal\user\RoleInterface $role */
     $role = Role::load($id);
     $this->assertInstanceOf(RoleInterface::class, $role);
+    sort($permissions);
     $this->assertSame($permissions, $role->getPermissions());
     $this->assertSame([[$id]], $id_map->lookupDestinationIds(['rid' => $lookupId]));
   }
@@ -67,9 +68,9 @@ protected function assertRoles(MigrateIdMapInterface $id_map) {
       // From permission table.
       'access comments',
       'access content',
+      'migrate test authenticated permission',
       'post comments',
       'skip comment approval',
-      'migrate test authenticated permission',
       // From filter_format.
       'use text format filtered_html',
     ];
diff --git a/core/modules/user/tests/src/Kernel/Migrate/d7/MigrateUserRoleTest.php b/core/modules/user/tests/src/Kernel/Migrate/d7/MigrateUserRoleTest.php
index edd5e3c..9b5a772 100644
--- a/core/modules/user/tests/src/Kernel/Migrate/d7/MigrateUserRoleTest.php
+++ b/core/modules/user/tests/src/Kernel/Migrate/d7/MigrateUserRoleTest.php
@@ -45,6 +45,7 @@ protected function assertEntity($id, $label, $original_rid) {
         ->condition('rid', $original_rid)
         ->execute()
         ->fetchCol();
+      sort($permissions);
       $this->assertIdentical($permissions, $entity->getPermissions());
     }
   }
diff --git a/core/modules/user/tests/src/Kernel/UserRoleEntityTest.php b/core/modules/user/tests/src/Kernel/UserRoleEntityTest.php
new file mode 100644
index 0000000..562ada1
--- /dev/null
+++ b/core/modules/user/tests/src/Kernel/UserRoleEntityTest.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Drupal\Tests\user\Kernel;
+
+use Drupal\KernelTests\KernelTestBase;
+use Drupal\user\Entity\Role;
+
+/**
+ * @group user
+ */
+class UserRoleEntityTest extends KernelTestBase {
+
+  public static $modules = ['system', 'user'];
+
+  public function testOrderOfPermissions() {
+    $role = Role::create(['id' => 'test_role']);
+    $role->grantPermission('b')
+      ->grantPermission('a')
+      ->grantPermission('c')
+      ->save();
+    $this->assertEquals($role->getPermissions(), ['a', 'b', 'c']);
+
+    $role->revokePermission('b')->save();
+    $this->assertEquals($role->getPermissions(), ['a', 'c']);
+
+    $role->grantPermission('b')->save();
+    $this->assertEquals($role->getPermissions(), ['a', 'b', 'c']);
+  }
+
+}
diff --git a/core/modules/user/tests/src/Kernel/Views/HandlerFieldPermissionTest.php b/core/modules/user/tests/src/Kernel/Views/HandlerFieldPermissionTest.php
index 9def2b8..c0c791f 100644
--- a/core/modules/user/tests/src/Kernel/Views/HandlerFieldPermissionTest.php
+++ b/core/modules/user/tests/src/Kernel/Views/HandlerFieldPermissionTest.php
@@ -37,9 +37,9 @@ public function testFieldPermission() {
     $expected_permissions[$this->users[2]->id()][] = t('Administer permissions');
     // View user profiles comes first, because we sort by the permission
     // machine name.
+    $expected_permissions[$this->users[3]->id()][] = t('View user information');
     $expected_permissions[$this->users[3]->id()][] = t('Administer permissions');
     $expected_permissions[$this->users[3]->id()][] = t('Administer users');
-    $expected_permissions[$this->users[3]->id()][] = t('View user information');
 
     foreach ($view->result as $index => $row) {
       $uid = $view->field['uid']->getValue($row);
diff --git a/core/modules/user/user.post_update.php b/core/modules/user/user.post_update.php
new file mode 100644
index 0000000..3f19b0c
--- /dev/null
+++ b/core/modules/user/user.post_update.php
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * @file
+ * Post update functions for User module.
+ */
+
+use Drupal\user\Entity\Role;
+
+/**
+ * Enforce order of role permissions.
+ */
+function user_post_update_enforce_order_of_permissions() {
+  $entity_save = function (Role $role) {
+    $permissions = $role->getPermissions();
+    sort($permissions);
+    if ($permissions !== $role->getPermissions()) {
+      $role->save();
+    }
+  };
+  array_map($entity_save, Role::loadMultiple());
+}
