diff --git a/core/modules/jsonapi/tests/src/Functional/RoleTest.php b/core/modules/jsonapi/tests/src/Functional/RoleTest.php
index a511613225..623127194b 100644
--- a/core/modules/jsonapi/tests/src/Functional/RoleTest.php
+++ b/core/modules/jsonapi/tests/src/Functional/RoleTest.php
@@ -53,6 +53,7 @@ protected function createEntity() {
     $role = Role::create([
       'id' => 'llama',
       'label' => 'Llama',
+      'description' => '',
     ]);
     $role->save();

@@ -88,6 +89,7 @@ protected function getExpectedDocument() {
           'status' => TRUE,
           'dependencies' => [],
           'label' => 'Llama',
+          'description' => '',
           'is_admin' => NULL,
           'permissions' => [],
           'drupal_internal__id' => 'llama',
diff --git a/core/modules/user/config/install/user.role.anonymous.yml b/core/modules/user/config/install/user.role.anonymous.yml
index c89e023b03..89d3b8a966 100644
--- a/core/modules/user/config/install/user.role.anonymous.yml
+++ b/core/modules/user/config/install/user.role.anonymous.yml
@@ -6,3 +6,4 @@ label: 'Anonymous user'
 weight: 0
 is_admin: false
 permissions: {  }
+description: 'The role given to users that are not logged in.'
diff --git a/core/modules/user/config/install/user.role.authenticated.yml b/core/modules/user/config/install/user.role.authenticated.yml
index 5da2abdd93..f07fdaf40b 100644
--- a/core/modules/user/config/install/user.role.authenticated.yml
+++ b/core/modules/user/config/install/user.role.authenticated.yml
@@ -6,3 +6,4 @@ label: 'Authenticated user'
 weight: 1
 is_admin: false
 permissions: {  }
+description: 'The basic role given to logged in users.'
diff --git a/core/modules/user/config/schema/user.schema.yml b/core/modules/user/config/schema/user.schema.yml
index 2f9bda44f2..5fef84536c 100644
--- a/core/modules/user/config/schema/user.schema.yml
+++ b/core/modules/user/config/schema/user.schema.yml
@@ -113,6 +113,9 @@ user.role.*:
     label:
       type: label
       label: 'Label'
+    description:
+      type: text
+      label: 'Description'
     weight:
       type: integer
       label: 'User role weight'
diff --git a/core/modules/user/src/Entity/Role.php b/core/modules/user/src/Entity/Role.php
index 97b0155719..2a1ed0a4f4 100644
--- a/core/modules/user/src/Entity/Role.php
+++ b/core/modules/user/src/Entity/Role.php
@@ -48,6 +48,7 @@
  *     "weight",
  *     "is_admin",
  *     "permissions",
+ *     "description",
  *   }
  * )
  */
@@ -67,6 +68,13 @@ class Role extends ConfigEntityBase implements RoleInterface {
    */
   protected $label;

+  /**
+   * A brief description of this role.
+   *
+   * @var string
+   */
+  public $description;
+
   /**
    * The weight of this role in administrative listings.
    *
@@ -113,6 +121,21 @@ public function setWeight($weight) {
     return $this;
   }

+  /**
+   * {@inheritdoc}
+   */
+  public function getDescription() {
+    return $this->description;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setDescription($description) {
+    $this->description = $description;
+    return $this;
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/core/modules/user/src/RoleForm.php b/core/modules/user/src/RoleForm.php
index 34aa98e8fc..3e78173a11 100644
--- a/core/modules/user/src/RoleForm.php
+++ b/core/modules/user/src/RoleForm.php
@@ -16,7 +16,9 @@ class RoleForm extends EntityForm {
    * {@inheritdoc}
    */
   public function form(array $form, FormStateInterface $form_state) {
+    /** @var \Drupal\role\RoleInterface $entity */
     $entity = $this->entity;
+
     $form['label'] = [
       '#type' => 'textfield',
       '#title' => $this->t('Role name'),
@@ -37,6 +39,12 @@ public function form(array $form, FormStateInterface $form_state) {
         'exists' => ['\Drupal\user\Entity\Role', 'load'],
       ],
     ];
+    $form['description'] = [
+      '#type' => 'textarea',
+      '#title' => $this->t('Description'),
+      '#default_value' => $entity->getDescription(),
+      '#description' => $this->t('The description for this role.'),
+    ];
     $form['weight'] = [
       '#type' => 'value',
       '#value' => $entity->getWeight(),
@@ -49,10 +57,13 @@ public function form(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function save(array $form, FormStateInterface $form_state) {
+
+    /** @var RoleInterface $entity */
     $entity = $this->entity;

     // Prevent leading and trailing spaces in role names.
     $entity->set('label', trim($entity->label()));
+    $entity->setDescription($entity->getDescription());
     $status = $entity->save();

     $edit_link = $this->entity->toLink($this->t('Edit'), 'edit-form')->toString();
diff --git a/core/modules/user/src/RoleInterface.php b/core/modules/user/src/RoleInterface.php
index 3c9425f644..0fa95b410b 100644
--- a/core/modules/user/src/RoleInterface.php
+++ b/core/modules/user/src/RoleInterface.php
@@ -97,4 +97,22 @@ public function getWeight();
    */
   public function setWeight($weight);

+  /**
+   * Returns the description.
+   *
+   * @return string
+   *   The description.
+   */
+  public function getDescription();
+
+  /**
+   * Sets the description to the given value.
+   *
+   * @param string $description
+   *   The desired description.
+   *
+   * @return $this
+   */
+  public function setDescription($description);
+
 }
diff --git a/core/modules/user/src/RoleListBuilder.php b/core/modules/user/src/RoleListBuilder.php
index d864a550d0..6ec35fb6bc 100644
--- a/core/modules/user/src/RoleListBuilder.php
+++ b/core/modules/user/src/RoleListBuilder.php
@@ -63,7 +63,8 @@ public function getFormId() {
    * {@inheritdoc}
    */
   public function buildHeader() {
-    $header['label'] = t('Name');
+    $header['label'] = $this->t('Name');
+    $header['description'] = $this->t('Description');
     return $header + parent::buildHeader();
   }

@@ -72,6 +73,9 @@ public function buildHeader() {
    */
   public function buildRow(EntityInterface $entity) {
     $row['label'] = $entity->label();
+    $row['description'] = [
+      '#markup' => $entity->getDescription(),
+    ];
     return $row + parent::buildRow($entity);
   }

diff --git a/core/modules/user/tests/src/Functional/Rest/RoleResourceTestBase.php b/core/modules/user/tests/src/Functional/Rest/RoleResourceTestBase.php
index 0c12f123ce..8f67549b87 100644
--- a/core/modules/user/tests/src/Functional/Rest/RoleResourceTestBase.php
+++ b/core/modules/user/tests/src/Functional/Rest/RoleResourceTestBase.php
@@ -36,6 +36,7 @@ protected function createEntity() {
     $role = Role::create([
       'id' => 'llama',
       'label' => 'Llama',
+      'description' => '',
     ]);
     $role->save();

@@ -52,6 +53,7 @@ protected function getExpectedNormalizedEntity() {
       'langcode' => 'en',
       'status' => TRUE,
       'dependencies' => [],
+      'description' => '',
       'id' => 'llama',
       'label' => 'Llama',
       'is_admin' => NULL,
diff --git a/core/modules/user/tests/src/Functional/RoleListBuilderTest.php b/core/modules/user/tests/src/Functional/RoleListBuilderTest.php
new file mode 100644
index 0000000000..28f475cef3
--- /dev/null
+++ b/core/modules/user/tests/src/Functional/RoleListBuilderTest.php
@@ -0,0 +1,57 @@
+<?php
+
+namespace Drupal\Tests\user\Functional;
+
+use Drupal\Tests\BrowserTestBase;
+use Drupal\user\Entity\Role;
+
+/**
+ * Tests for the RolesListBuilder.
+ *
+ * @group user
+ * @see \Drupal\user\RoleListBuilder
+ */
+class RoleListBuilderTest extends BrowserTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = [
+    'user',
+  ];
+
+  /**
+   * Ensures the rows of the list are built correctly.
+   */
+  public function testListBuilder() {
+
+    // Create a role to view.
+    /** @var \Drupal\user\RoleInterface $role */
+    $role = Role::create([
+      'id' => 'role_1',
+      'label' => 'My Role',
+      'description' => 'Lorem ipsum',
+    ]);
+    $role->save();
+
+    // Log in as an administrator.
+    $admin = $this->createUser([], NULL, TRUE);
+    $this->drupalLogin($admin);
+
+    $this->drupalGet('/admin/people/roles');
+
+    $this->assertSession()->pageTextContains('Name');
+    $this->assertSession()->pageTextContains('Description');
+
+    // Check that the role values are displayed correctly.
+    $this->assertSession()->pageTextContains($role->label());
+    $this->assertSession()->pageTextContains($role->getDescription());
+
+  }
+
+}
diff --git a/core/modules/user/tests/src/Functional/Update/AddUserRoleDescriptionTest.php b/core/modules/user/tests/src/Functional/Update/AddUserRoleDescriptionTest.php
new file mode 100644
index 0000000000..9e5baf5ebe
--- /dev/null
+++ b/core/modules/user/tests/src/Functional/Update/AddUserRoleDescriptionTest.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace Drupal\Tests\user\Functional\Update;
+
+use Drupal\FunctionalTests\Update\UpdatePathTestBase;
+
+/**
+ * Ensures description is added to user role configurations.
+ *
+ * @group Update
+ */
+class AddUserRoleDescriptionTest extends UpdatePathTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setDatabaseDumpFiles() {
+    $this->databaseDumpFiles = [
+      __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.8.0.bare.standard.php.gz',
+    ];
+  }
+
+  /**
+   * Ensures description is added to user role configurations.
+   */
+  public function testUpdate() {
+    $anonymous_user_role_description = \Drupal::config('user.role.anonymous')->get('description');
+    $authenticated_user_role_description = \Drupal::config('user.role.authenticated')->get('description');
+    $this->assertNull($anonymous_user_role_description, 'Description does not exist for anonymous user role.');
+    $this->assertNull($authenticated_user_role_description, 'Description does not exist for authenticated user role.');
+
+    $this->runUpdates();
+
+    $anonymous_user_role_description = \Drupal::config('user.role.anonymous')->get('description');
+    $authenticated_user_role_description = \Drupal::config('user.role.authenticated')->get('description');
+    $this->assertEquals('The role given to users that are not logged in.', $anonymous_user_role_description, 'Description has been added for anonymous user role.');
+    $this->assertEquals('The basic role given to logged in users.', $authenticated_user_role_description, 'Description has been added for authenticated user role.');
+  }
+
+}
diff --git a/core/modules/user/tests/src/Kernel/UserRoleEntityTest.php b/core/modules/user/tests/src/Kernel/UserRoleEntityTest.php
index 5d85147ca1..104783f8ba 100644
--- a/core/modules/user/tests/src/Kernel/UserRoleEntityTest.php
+++ b/core/modules/user/tests/src/Kernel/UserRoleEntityTest.php
@@ -6,8 +6,13 @@
 use Drupal\user\Entity\Role;

 /**
+ * Tests for the Role entity.
+ *
  * @group user
+ *
  * @coversDefaultClass \Drupal\user\Entity\Role
+ *
+ * @see \Drupal\user\Entity\Role
  */
 class UserRoleEntityTest extends KernelTestBase {

@@ -46,4 +51,21 @@ public function testGrantingNonExistentPermission() {
       ->save();
   }

+  /**
+   * Tests the setting and getting of a roles descriptions.
+   *
+   * @covers ::getDescription
+   * @covers ::setDescription
+   */
+  public function testRoleDescription() {
+    /** @var \Drupal\user\Entity\RoleInterface $role */
+    $role = Role::create(['id' => 'test_role']);
+
+    $description = 'Lorem ipsum.';
+    $role->setDescription($description);
+
+    $this->assertEquals($role->getDescription(), $description);
+
+  }
+
 }
diff --git a/core/modules/user/user.post_update.php b/core/modules/user/user.post_update.php
index 14662df8ef..a969da5958 100644
--- a/core/modules/user/user.post_update.php
+++ b/core/modules/user/user.post_update.php
@@ -47,3 +47,19 @@ function user_post_update_update_roles(&$sandbox = NULL) {
     );
   }
 }
+
+/**
+ * Adds description to user role configurations.
+ */
+function user_post_update_add_user_role_description() {
+  $config_factory = \Drupal::configFactory();
+
+  if (!$config_factory->getEditable('user.role.anonymous')->isNew()) {
+    $config_factory->getEditable('user.role.anonymous')
+      ->set('description', 'The role given to users that are not logged in.')
+      ->save(TRUE);
+  }
+
+  if (!$config_factory->getEditable('user.role.authenticated')->isNew()) {
+  $config_factory->getEditable('user.role.authenticated')
+    ->set('description', 'The basic role given to logged in users.')
+    ->save(TRUE);
+  }
+
+  if (!$config_factory->getEditable('user.role.administrator')->isNew()) {
+  $config_factory->getEditable('user.role.administrator')
+    ->set('description', 'The role given to admin users.')
+    ->save(TRUE);
+  }
+
+}
diff --git a/core/profiles/demo_umami/config/install/user.role.administrator.yml b/core/profiles/demo_umami/config/install/user.role.administrator.yml
index e5453b725d..66c58bf43c 100644
--- a/core/profiles/demo_umami/config/install/user.role.administrator.yml
+++ b/core/profiles/demo_umami/config/install/user.role.administrator.yml
@@ -6,3 +6,4 @@ label: Administrator
 weight: 2
 is_admin: true
 permissions: {  }
+description: 'The role given to admin users.'
diff --git a/core/profiles/demo_umami/config/install/user.role.anonymous.yml b/core/profiles/demo_umami/config/install/user.role.anonymous.yml
index 820b8454fb..929f07caca 100644
--- a/core/profiles/demo_umami/config/install/user.role.anonymous.yml
+++ b/core/profiles/demo_umami/config/install/user.role.anonymous.yml
@@ -19,3 +19,4 @@ permissions:
   - 'search content'
   - 'use text format restricted_html'
   - 'view media'
+description: 'The role given to users that are not logged in.'
diff --git a/core/profiles/demo_umami/config/install/user.role.authenticated.yml b/core/profiles/demo_umami/config/install/user.role.authenticated.yml
index 8334961e2c..a30a4421e4 100644
--- a/core/profiles/demo_umami/config/install/user.role.authenticated.yml
+++ b/core/profiles/demo_umami/config/install/user.role.authenticated.yml
@@ -21,3 +21,4 @@ permissions:
   - 'search content'
   - 'use text format basic_html'
   - 'view media'
+description: 'The basic role given to logged in users.'
diff --git a/core/profiles/demo_umami/config/install/user.role.author.yml b/core/profiles/demo_umami/config/install/user.role.author.yml
index c9d34695e6..478cb7bed3 100644
--- a/core/profiles/demo_umami/config/install/user.role.author.yml
+++ b/core/profiles/demo_umami/config/install/user.role.author.yml
@@ -55,3 +55,4 @@ permissions:
   - 'view page revisions'
   - 'view recipe revisions'
   - 'view the administration theme'
+description: 'The role given to content authors.'
diff --git a/core/profiles/demo_umami/config/install/user.role.editor.yml b/core/profiles/demo_umami/config/install/user.role.editor.yml
index 40d5f651ee..674e9ebb58 100644
--- a/core/profiles/demo_umami/config/install/user.role.editor.yml
+++ b/core/profiles/demo_umami/config/install/user.role.editor.yml
@@ -68,3 +68,4 @@ permissions:
   - 'view page revisions'
   - 'view recipe revisions'
   - 'view the administration theme'
+description: 'The role given to content editors.'
diff --git a/core/profiles/standard/config/install/user.role.administrator.yml b/core/profiles/standard/config/install/user.role.administrator.yml
index ca48a58b4e..ee2de3c24c 100644
--- a/core/profiles/standard/config/install/user.role.administrator.yml
+++ b/core/profiles/standard/config/install/user.role.administrator.yml
@@ -6,3 +6,4 @@ label: Administrator
 weight: 3
 is_admin: true
 permissions: {  }
+description: 'The role given to admin users.'
diff --git a/core/profiles/standard/config/install/user.role.anonymous.yml b/core/profiles/standard/config/install/user.role.anonymous.yml
index 5674329ecf..27ede5312d 100644
--- a/core/profiles/standard/config/install/user.role.anonymous.yml
+++ b/core/profiles/standard/config/install/user.role.anonymous.yml
@@ -19,3 +19,4 @@ permissions:
   - 'access site-wide contact form'
   - 'search content'
   - 'use text format restricted_html'
+description: 'The role given to users that are not logged in.'
diff --git a/core/profiles/standard/config/install/user.role.authenticated.yml b/core/profiles/standard/config/install/user.role.authenticated.yml
index 2442711ddc..1adb6c45d3 100644
--- a/core/profiles/standard/config/install/user.role.authenticated.yml
+++ b/core/profiles/standard/config/install/user.role.authenticated.yml
@@ -23,3 +23,4 @@ permissions:
   - 'search content'
   - 'skip comment approval'
   - 'use text format basic_html'
+description: 'The basic role given to logged in users.'
diff --git a/core/profiles/standard/config/install/user.role.content_editor.yml b/core/profiles/standard/config/install/user.role.content_editor.yml
index 3e35418178..430842d9ab 100644
--- a/core/profiles/standard/config/install/user.role.content_editor.yml
+++ b/core/profiles/standard/config/install/user.role.content_editor.yml
@@ -43,3 +43,4 @@ permissions:
   - 'view all revisions'
   - 'view own unpublished content'
   - 'view the administration theme'
+description: 'The role given to content editors.'
diff --git a/core/tests/fixtures/config_install/multilingual.tar.gz b/core/tests/fixtures/config_install/multilingual.tar.gz
index 28e83ae926..18cf99e8ca 100644
--- a/core/tests/fixtures/config_install/multilingual.tar.gz
+++ b/core/tests/fixtures/config_install/multilingual.tar.gz
@@ -1,129 +1,127 @@