diff --git a/core/modules/update/css/update.admin.theme.css b/core/modules/update/css/update.admin.theme.css
index abf0a88243..3891e864fc 100644
--- a/core/modules/update/css/update.admin.theme.css
+++ b/core/modules/update/css/update.admin.theme.css
@@ -37,7 +37,11 @@
 }
 
 .project-update__version {
-  padding: 1em 0;
+  border-bottom: 1px solid #bfbfbf;
+  padding: 0.5em 0;
+}
+.project-update__version--installed {
+  border-bottom: none;
 }
 .project-update__version-date {
   white-space: nowrap;
@@ -51,13 +55,12 @@
 }
 .project-update__version-links {
   text-align: right; /* LTR */
-  padding-right: 1em; /* LTR */
   list-style-type: none;
 }
 [dir="rtl"] .project-update__version-links {
   text-align: left;
-  padding-left: 1em;
 }
-.project-update__version--recommended-strong .project-update__version-title {
+.project-update__version--recommended-strong .project-update__version-title,
+.version-security .project-update__version-title {
   font-weight: bold;
 }
diff --git a/core/modules/update/src/UpdateProcessor.php b/core/modules/update/src/UpdateProcessor.php
index 25dfc7a004..9115357274 100644
--- a/core/modules/update/src/UpdateProcessor.php
+++ b/core/modules/update/src/UpdateProcessor.php
@@ -231,6 +231,9 @@ protected function parseXml($raw_xml) {
         foreach ($release->children() as $k => $v) {
           $data['releases'][$version][$k] = (string) $v;
         }
+        if ($release->security['covered']) {
+          $data['releases'][$version]['security_covered'] = TRUE;
+        }
         $data['releases'][$version]['terms'] = [];
         if ($release->terms) {
           foreach ($release->terms->children() as $term) {
diff --git a/core/modules/update/templates/update-project-status.html.twig b/core/modules/update/templates/update-project-status.html.twig
index 4cc9a19e8b..894379e785 100644
--- a/core/modules/update/templates/update-project-status.html.twig
+++ b/core/modules/update/templates/update-project-status.html.twig
@@ -47,24 +47,14 @@
   </span>
 </div>
 
-<div class="project-update__title">
+<div class="project-update__title clearfix">
   {%- if url -%}
     <a href="{{ url }}">{{ title }}</a>
   {%- else -%}
     {{ title }}
   {%- endif %}
-  {{ existing_version }}
-  {% if install_type == 'dev' and datestamp %}
-    <span class="project-update__version-date">({{ datestamp }})</span>
-  {% endif %}
 </div>
 
-{% if versions %}
-  {% for version in versions %}
-    {{ version }}
-  {% endfor %}
-{% endif %}
-
 {%
   set extra_classes = [
     project.status == constant('UPDATE_NOT_SECURE') ? 'project-not-secure',
@@ -83,24 +73,31 @@
     </div>
   {% endif %}
   {% set includes = includes|join(', ') %}
-  {% if disabled %}
-    {{ 'Includes:'|t }}
-    <ul>
-      <li>
-        {% trans %}
-          Enabled: {{ includes|placeholder }}
-        {% endtrans %}
-      </li>
-      <li>
-        {% set disabled = disabled|join(', ') %}
-        {% trans %}
-          Disabled: {{ disabled|placeholder }}
-        {% endtrans %}
-      </li>
-    </ul>
-  {% else %}
-    {% trans %}
-      Includes: {{ includes|placeholder }}
-    {% endtrans %}
-  {% endif %}
 </div>
+
+{% if versions %}
+  {% for version in versions %}
+    {{ version }}
+  {% endfor %}
+{% endif %}
+
+{% if disabled %}
+  {{ 'Includes:'|t }}
+  <ul>
+    <li>
+      {% trans %}
+        Enabled: {{ includes|placeholder }}
+      {% endtrans %}
+    </li>
+    <li>
+      {% set disabled = disabled|join(', ') %}
+      {% trans %}
+        Disabled: {{ disabled|placeholder }}
+      {% endtrans %}
+    </li>
+  </ul>
+{% else %}
+  {% trans %}
+    Includes: {{ includes|placeholder }}
+  {% endtrans %}
+{% endif %}
diff --git a/core/modules/update/templates/update-version.html.twig b/core/modules/update/templates/update-version.html.twig
index c21c4f0ba4..9a683e05bb 100644
--- a/core/modules/update/templates/update-version.html.twig
+++ b/core/modules/update/templates/update-version.html.twig
@@ -11,26 +11,32 @@
  *   - date: The date of the release.
  *   - download_link: The URL for the downloadable file.
  *   - release_link: The URL for the release notes.
+ * - version_type: The type of the version, possible values are 'recommended', 'security', 'latest', 'dev', 'also',
+ *  'installed'.
  *
  * @ingroup themeable
  */
 #}
 <div class="{{ attributes.class }} project-update__version"{{ attributes|without('class') }}>
   <div class="clearfix">
-    <div class="project-update__version-title layout-column layout-column--quarter">{{ title }}</div>
-    <div class="project-update__version-details layout-column layout-column--quarter">
+    <div class="project-update__version-title">{{ title }}</div>
+    <div class="project-update__version-details layout-column layout-column--three-quarter">
       <a href="{{ version.release_link }}">{{ version.version }}</a>
       <span class="project-update__version-date">({{ version.date|date('Y-M-d') }})</span>
+      {% if version.security_covered %}
+        {% trans %}
+          <small>Covered by Drupal’s <a href="https://www.drupal.org/security-advisory-policy">security advisory policy</a></small>
+        {% endtrans %}
+      {% endif %}
     </div>
-    <div class="layout-column layout-column--half">
-      <ul class="project-update__version-links">
-        <li class="project-update__download-link">
-          <a href="{{ version.download_link }}">{{ 'Download'|t }}</a>
-        </li>
-        <li class="project-update__release-notes-link">
-          <a href="{{ version.release_link }}">{{ 'Release notes'|t }}</a>
-        </li>
-      </ul>
-    </div>
+    {% if version_type != 'installed' %}
+      <div class="layout-column layout-column--quarter">
+        <ul class="project-update__version-links">
+          <li class="project-update__download-link">
+            <a href="{{ version.release_link }}">{{ 'Download'|t }}</a>
+          </li>
+        </ul>
+      </div>
+    {% endif %}
   </div>
 </div>
diff --git a/core/modules/update/tests/modules/update_test/aaa_update_test.1_0.xml b/core/modules/update/tests/modules/update_test/aaa_update_test.1_0.xml
index 82362fe846..9405cb3e38 100644
--- a/core/modules/update/tests/modules/update_test/aaa_update_test.1_0.xml
+++ b/core/modules/update/tests/modules/update_test/aaa_update_test.1_0.xml
@@ -29,6 +29,7 @@
    <term><name>Release type</name><value>New features</value></term>
    <term><name>Release type</name><value>Bug fixes</value></term>
   </terms>
+  <security>AAA is not covered!</security>
  </release>
 </releases>
 </project>
diff --git a/core/modules/update/tests/modules/update_test/bbb_update_test.1_0.xml b/core/modules/update/tests/modules/update_test/bbb_update_test.1_0.xml
index 8d705b5f96..2142c04efa 100644
--- a/core/modules/update/tests/modules/update_test/bbb_update_test.1_0.xml
+++ b/core/modules/update/tests/modules/update_test/bbb_update_test.1_0.xml
@@ -16,11 +16,11 @@
  <release>
   <name>bbb_update_test 8.x-1.0</name>
   <version>8.x-1.0</version>
-  <tag>DRUPAL-7--1-0</tag>
+  <tag>8.x-1.0</tag>
   <version_major>1</version_major>
   <version_patch>0</version_patch>
   <status>published</status>
-  <release_link>http://example.com/bbb_update_test-7-x-1-0-release</release_link>
+  <release_link>http://example.com/bbb_update_test-8-x-1-0-release</release_link>
   <download_link>http://example.com/bbb_update_test-8.x-1.0.tar.gz</download_link>
   <date>1250424521</date>
   <mdhash>b966255555d9c9b86d480ca08cfaa98e</mdhash>
@@ -29,6 +29,26 @@
    <term><name>Release type</name><value>New features</value></term>
    <term><name>Release type</name><value>Bug fixes</value></term>
   </terms>
+  <security covered="1"/>
+ </release>
+ <release>
+  <name>bbb_update_test 8.x-1.0-beta1</name>
+  <version>8.x-1.0-beta1</version>
+  <tag>8.x-1.0-beta1</tag>
+  <version_major>1</version_major>
+  <version_patch>0</version_patch>
+  <version_extra>beta1</version_extra>
+  <status>published</status>
+  <release_link>http://example.com/bbb_update_test-8-x-1-0-beta1</release_link>
+  <download_link>http://example.com/bbb_update_test-8.x-1.0-beta1.tar.gz</download_link>
+  <date>1250424521</date>
+  <mdhash>7da7b18ce17cef2122f5cbca1bfe626a</mdhash>
+  <filesize>1073751331</filesize>
+  <terms>
+   <term><name>Release type</name><value>New features</value></term>
+   <term><name>Release type</name><value>Bug fixes</value></term>
+  </terms>
+  <security>Not covered!</security>
  </release>
 </releases>
 </project>
diff --git a/core/modules/update/tests/modules/update_test/ccc_update_test.1_0.xml b/core/modules/update/tests/modules/update_test/ccc_update_test.1_0.xml
index 82764c2c33..35e1f5f4ca 100644
--- a/core/modules/update/tests/modules/update_test/ccc_update_test.1_0.xml
+++ b/core/modules/update/tests/modules/update_test/ccc_update_test.1_0.xml
@@ -29,6 +29,7 @@
    <term><name>Release type</name><value>New features</value></term>
    <term><name>Release type</name><value>Bug fixes</value></term>
   </terms>
+  <security covered="1"/>
  </release>
 </releases>
 </project>
diff --git a/core/modules/update/tests/src/Functional/UpdateContribTest.php b/core/modules/update/tests/src/Functional/UpdateContribTest.php
index 20d397cd48..ee2e2ee311 100644
--- a/core/modules/update/tests/src/Functional/UpdateContribTest.php
+++ b/core/modules/update/tests/src/Functional/UpdateContribTest.php
@@ -176,8 +176,8 @@ public function testUpdateContribOrder() {
     // Instead of just searching for 'BBB Update test' or something, we want
     // to use the full markup that starts the project entry itself, so that
     // we're really testing that the project listings are in the right order.
-    $bbb_project_link = '<div class="project-update__title"><a href="http://example.com/project/bbb_update_test">BBB Update test</a>';
-    $ccc_project_link = '<div class="project-update__title"><a href="http://example.com/project/ccc_update_test">CCC Update test</a>';
+    $bbb_project_link = '<div class="project-update__title clearfix"><a href="http://example.com/project/bbb_update_test">BBB Update test</a>';
+    $ccc_project_link = '<div class="project-update__title clearfix"><a href="http://example.com/project/ccc_update_test">CCC Update test</a>';
     $this->assertTrue(strpos($this->getRawContent(), $bbb_project_link) < strpos($this->getRawContent(), $ccc_project_link), "'BBB Update test' project is listed before the 'CCC Update test' project");
   }
 
@@ -375,7 +375,7 @@ public function testUpdateBrokenFetchURL() {
     // The other two should be listed as projects.
     $this->assertRaw(\Drupal::l(t('AAA Update test'), Url::fromUri('http://example.com/project/aaa_update_test')), 'Link to aaa_update_test project appears.');
     $this->assertNoRaw(\Drupal::l(t('BBB Update test'), Url::fromUri('http://example.com/project/bbb_update_test')), 'Link to bbb_update_test project does not appear.');
-    $this->assertRaw(\Drupal::l(t('CCC Update test'), Url::fromUri('http://example.com/project/ccc_update_test')), 'Link to bbb_update_test project appears.');
+    $this->assertRaw(\Drupal::l(t('CCC Update test'), Url::fromUri('http://example.com/project/ccc_update_test')), 'Link to ccc_update_test project appears.');
   }
 
   /**
diff --git a/core/modules/update/tests/src/Functional/UpdateCoreTest.php b/core/modules/update/tests/src/Functional/UpdateCoreTest.php
index 5cd4b10260..65822b96f2 100644
--- a/core/modules/update/tests/src/Functional/UpdateCoreTest.php
+++ b/core/modules/update/tests/src/Functional/UpdateCoreTest.php
@@ -82,8 +82,7 @@ public function testNormalUpdateAvailable() {
         $this->checkForMetaRefresh();
         $this->assertNoText(t('Security update required!'));
         $this->assertRaw(\Drupal::l("8.$minor_version.1" . $extra_version, Url::fromUri("http://example.com/drupal-8-$minor_version-1$extra_version-release")), 'Link to release appears.');
-        $this->assertRaw(\Drupal::l(t('Download'), Url::fromUri("http://example.com/drupal-8-$minor_version-1$extra_version.tar.gz")), 'Link to download appears.');
-        $this->assertRaw(\Drupal::l(t('Release notes'), Url::fromUri("http://example.com/drupal-8-$minor_version-1$extra_version-release")), 'Link to release notes appears.');
+        $this->assertRaw(\Drupal::l(t('Download'), Url::fromUri("http://example.com/drupal-8-$minor_version-1$extra_version-release")), 'Link to download appears.');
 
         switch ($minor_version) {
           case 0:
@@ -92,7 +91,7 @@ public function testNormalUpdateAvailable() {
             if ($extra_version == '') {
               $this->assertNoText(t('Up to date'));
               $this->assertText(t('Update available'));
-              $this->assertText(t('Recommended version:'));
+              $this->assertText(t('Recommended update:'));
               $this->assertNoText(t('Latest version:'));
               $this->assertRaw('warning.svg', 'Warning icon was found.');
             }
@@ -101,7 +100,7 @@ public function testNormalUpdateAvailable() {
             else {
               $this->assertText(t('Up to date'));
               $this->assertNoText(t('Update available'));
-              $this->assertNoText(t('Recommended version:'));
+              $this->assertNoText(t('Recommended update:'));
               $this->assertText(t('Latest version:'));
               $this->assertRaw('check.svg', 'Check icon was found.');
             }
@@ -112,7 +111,7 @@ public function testNormalUpdateAvailable() {
             if ($extra_version == '') {
               $this->assertNoText(t('Up to date'));
               $this->assertText(t('Update available'));
-              $this->assertText(t('Recommended version:'));
+              $this->assertText(t('Recommended update:'));
               $this->assertNoText(t('Latest version:'));
               $this->assertRaw('warning.svg', 'Warning icon was found.');
             }
@@ -121,7 +120,7 @@ public function testNormalUpdateAvailable() {
             else {
               $this->assertNoText(t('Up to date'));
               $this->assertText(t('Update available'));
-              $this->assertText(t('Recommended version:'));
+              $this->assertText(t('Recommended update:'));
               $this->assertText(t('Latest version:'));
               $this->assertRaw('warning.svg', 'Warning icon was found.');
             }
@@ -146,11 +145,10 @@ public function testMajorUpdateAvailable() {
           $this->checkForMetaRefresh();
           $this->assertNoText(t('Security update required!'));
           $this->assertRaw(\Drupal::l('9.0.0', Url::fromUri("http://example.com/drupal-9-0-0-release")), 'Link to release appears.');
-          $this->assertRaw(\Drupal::l(t('Download'), Url::fromUri("http://example.com/drupal-9-0-0.tar.gz")), 'Link to download appears.');
-          $this->assertRaw(\Drupal::l(t('Release notes'), Url::fromUri("http://example.com/drupal-9-0-0-release")), 'Link to release notes appears.');
+          $this->assertRaw(\Drupal::l(t('Download'), Url::fromUri("http://example.com/drupal-9-0-0-release")), 'Link to download appears.');
           $this->assertNoText(t('Up to date'));
           $this->assertText(t('Not supported!'));
-          $this->assertText(t('Recommended version:'));
+          $this->assertText(t('Recommended update:'));
           $this->assertNoText(t('Latest version:'));
           $this->assertRaw('error.svg', 'Error icon was found.');
         }
@@ -170,8 +168,7 @@ public function testSecurityUpdateAvailable() {
       $this->assertNoText(t('Update available'));
       $this->assertText(t('Security update required!'));
       $this->assertRaw(\Drupal::l("8.$minor_version.2", Url::fromUri("http://example.com/drupal-8-$minor_version-2-release")), 'Link to release appears.');
-      $this->assertRaw(\Drupal::l(t('Download'), Url::fromUri("http://example.com/drupal-8-$minor_version-2.tar.gz")), 'Link to download appears.');
-      $this->assertRaw(\Drupal::l(t('Release notes'), Url::fromUri("http://example.com/drupal-8-$minor_version-2-release")), 'Link to release notes appears.');
+      $this->assertRaw(\Drupal::l(t('Download'), Url::fromUri("http://example.com/drupal-8-$minor_version-2-release")), 'Link to download appears.');
       $this->assertRaw('error.svg', 'Error icon was found.');
     }
   }
diff --git a/core/modules/update/update.compare.inc b/core/modules/update/update.compare.inc
index 2ba5fdce75..9e2fce96a8 100644
--- a/core/modules/update/update.compare.inc
+++ b/core/modules/update/update.compare.inc
@@ -177,6 +177,10 @@ function update_calculate_project_update_status(&$project_data, $available) {
     }
   }
 
+  // For dev releases, existing_version looks like '8.4.0-dev', while
+  // updates.drupal.org provides '8.4.x-dev'.
+  $project_data['version_normalized'] = preg_replace('/0-dev$/', 'x-dev', $project_data['existing_version']);
+
   // If the project status is marked as something bad, there's nothing else
   // to consider.
   if (isset($available['project_status'])) {
@@ -296,6 +300,7 @@ function update_calculate_project_update_status(&$project_data, $available) {
   foreach ($available['releases'] as $version => $release) {
     // First, if this is the existing release, check a few conditions.
     if ($project_data['existing_version'] === $version) {
+      $project_data['releases'][$version] = $release;
       if (isset($release['terms']['Release type']) &&
           in_array('Insecure', $release['terms']['Release type'])) {
         $project_data['status'] = UPDATE_NOT_SECURE;
diff --git a/core/modules/update/update.install b/core/modules/update/update.install
index 4cff44c727..8eaceb9ace 100644
--- a/core/modules/update/update.install
+++ b/core/modules/update/update.install
@@ -5,6 +5,7 @@
  * Install, update, and uninstall functions for the Update Manager module.
  */
 
+use Drupal\Core\Link;
 use Drupal\Core\Url;
 
 /**
@@ -33,8 +34,26 @@ function update_requirements($phase) {
     if ($available = update_get_available(FALSE)) {
       module_load_include('inc', 'update', 'update.compare');
       $data = update_calculate_project_data($available);
-      // First, populate the requirements for core:
+
+      // Check if all projects have security advisory coverage.
+      $requirements['update_covered'] = [
+        'title' => t('Drupal.org security advisory coverage'),
+        'value' => t('Currently installed modules and themes from Drupal.org receive coverage.'),
+        'description' => t('Projects covered by Drupal’s <a href="https://www.drupal.org/security-advisory-policy">security advisory policy</a> will have <a href="https://www.drupal.org/security">security advisories</a> responsibly disclosed when vulnerabilities are reported to Drupal’s security team. Projects from Drupal.org that are not covered may have publicly disclosed vulnerabilities.'),
+      ];
+      foreach ($data as $project) {
+        // 'security_covered' boolean makes a positive assertion of coverage.
+        // 'security' string confirms there is no coverage. Check both so
+        // non-www.drupal.org projects are not false positives.
+        if (isset($project['releases'][$project['version_normalized']]) && empty($project['releases'][$project['version_normalized']]['security_covered']) && !empty($project['releases'][$project['version_normalized']]['security'])) {
+          $requirements['update_covered']['value'] = Link::createFromRoute(t('Modules and themes without security advisory coverage found'), 'update.status');
+          break;
+        }
+      }
+
+      // Populate the requirements for core:
       $requirements['update_core'] = _update_requirement_check($data['drupal'], 'core');
+
       // We don't want to check drupal a second time.
       unset($data['drupal']);
       if (!empty($data)) {
diff --git a/core/modules/update/update.module b/core/modules/update/update.module
index a7e8cc3397..07e23b4561 100644
--- a/core/modules/update/update.module
+++ b/core/modules/update/update.module
@@ -124,7 +124,7 @@ function update_help($route_name, RouteMatchInterface $route_match) {
       $output .= '<h3>' . t('Uses') . '</h3>';
       $output .= '<dl>';
       $output .= '<dt>' . t('Checking for available updates') . '</dt>';
-      $output .= '<dd>' . t('The <a href=":update-report">Available updates report</a> displays core, contributed modules, and themes for which there are new releases available for download. On the report page, you can also check manually for updates. You can configure the frequency of update checks, which are performed during cron runs, and whether notifications are sent on the <a href=":update-settings">Update Manager settings page</a>.', [':update-report' => \Drupal::url('update.status'), ':update-settings' => \Drupal::url('update.settings')]) . '</dd>';
+      $output .= '<dd>' . t('The <a href=":update-report">Available updates report</a> displays core, contributed modules, and themes for which there are new releases available for download. On the report page, you can also check manually for updates. Projects covered by Drupal’s <a href="https://www.drupal.org/security-advisory-policy">security advisory policy</a> are noted. You can configure the frequency of update checks, which are performed during cron runs, and whether notifications are sent on the <a href=":update-settings">Update Manager settings page</a>.', [':update-report' => \Drupal::url('update.status'), ':update-settings' => \Drupal::url('update.settings')]) . '</dd>';
       // Only explain the Update manager if it has not been disabled.
       if (_update_manager_access()) {
         $output .= '<dt>' . t('Performing updates through the Update page') . '</dt>';
@@ -136,7 +136,8 @@ function update_help($route_name, RouteMatchInterface $route_match) {
       return $output;
 
     case 'update.status':
-      return '<p>' . t('Here you can find information about available updates for your installed modules and themes. Note that each module or theme is part of a "project", which may or may not have the same name, and might include multiple modules or themes within it.') . '</p>';
+      return '<p>' . t('Here you can find information about available updates for your installed modules and themes. Note that each module or theme is part of a "project", which may or may not have the same name, and might include multiple modules or themes within it.') . '</p>'
+        . '<p>' . t('Projects covered by Drupal’s <a href="https://www.drupal.org/security-advisory-policy">security advisory policy</a> will have <a href="https://www.drupal.org/security">security advisories</a> responsibly disclosed when vulnerabilities are reported to Drupal’s security team. Projects from Drupal.org that are not covered may have publicly disclosed vulnerabilities.') . '</p>';
 
     case 'system.modules_list':
       if (_update_manager_access()) {
@@ -245,7 +246,12 @@ function update_theme() {
     // We are using template instead of '#type' => 'table' here to keep markup
     // out of preprocess and allow for easier changes to markup.
     'update_version' => [
-      'variables' => ['version' => NULL, 'title' => NULL, 'attributes' => []],
+      'variables' => [
+        'version' => NULL,
+        'title' => NULL,
+        'attributes' => [],
+        'version_type' => NULL,
+      ],
       'file' => 'update.report.inc',
     ],
   ];
diff --git a/core/modules/update/update.report.inc b/core/modules/update/update.report.inc
index 7b14a05852..71839ae383 100644
--- a/core/modules/update/update.report.inc
+++ b/core/modules/update/update.report.inc
@@ -8,6 +8,8 @@
 use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Template\Attribute;
 use Drupal\Core\Url;
+use Drupal\update\UpdateFetcherInterface;
+use Drupal\update\UpdateManagerInterface;
 
 /**
  * Prepares variables for project status report templates.
@@ -39,45 +41,39 @@ function template_preprocess_update_report(&$variables) {
     $variables['no_updates_message'] = _update_no_data();
   }
 
-  $rows = [];
-
+  $projects = [];
   foreach ($data as $project) {
-    $project_status = [
-      '#theme' => 'update_project_status',
-      '#project' => $project,
-    ];
-
-    // Build project rows.
-    if (!isset($rows[$project['project_type']])) {
-      $rows[$project['project_type']] = [
-        '#type' => 'table',
-        '#attributes' => ['class' => ['update']],
-      ];
-    }
-    $row_key = !empty($project['title']) ? Unicode::strtolower($project['title']) : Unicode::strtolower($project['name']);
-
-    // Add the project status row and details.
-    $rows[$project['project_type']][$row_key]['status'] = $project_status;
-
-    // Add project status class attribute to the table row.
+    // Add the project status and details.
     switch ($project['status']) {
-      case UPDATE_CURRENT:
-        $rows[$project['project_type']][$row_key]['#attributes'] = ['class' => ['color-success']];
+      case UpdateManagerInterface::CURRENT:
+        $class = 'color-success';
         break;
-      case UPDATE_UNKNOWN:
-      case UPDATE_FETCH_PENDING:
-      case UPDATE_NOT_FETCHED:
-      case UPDATE_NOT_SECURE:
-      case UPDATE_REVOKED:
-      case UPDATE_NOT_SUPPORTED:
-        $rows[$project['project_type']][$row_key]['#attributes'] = ['class' => ['color-error']];
+
+      case UpdateFetcherInterface::UNKNOWN:
+      case UpdateFetcherInterface::FETCH_PENDING:
+      case UpdateFetcherInterface::NOT_FETCHED:
+      case UpdateManagerInterface::NOT_SECURE:
+      case UpdateManagerInterface::REVOKED:
+      case UpdateManagerInterface::NOT_SUPPORTED:
+        $class = 'color-error';
         break;
-      case UPDATE_NOT_CHECKED:
-      case UPDATE_NOT_CURRENT:
+
+      case UpdateFetcherInterface::NOT_CHECKED:
+      case UpdateManagerInterface::NOT_CURRENT:
       default:
-        $rows[$project['project_type']][$row_key]['#attributes'] = ['class' => ['color-warning']];
+        $class = 'color-warning';
         break;
     }
+    $projects[$project['project_type']][Unicode::strtolower(!empty($project['title']) ? $project['title'] : $project['name'])] = [
+      '#theme' => 'admin_block',
+      '#block' => [
+        'content' => [
+          '#theme' => 'update_project_status',
+          '#project' => $project,
+        ],
+      ],
+      '#attributes' => ['class' => [$class]],
+    ];
   }
 
   $project_types = [
@@ -90,11 +86,11 @@ function template_preprocess_update_report(&$variables) {
 
   $variables['project_types'] = [];
   foreach ($project_types as $type_name => $type_label) {
-    if (!empty($rows[$type_name])) {
-      ksort($rows[$type_name]);
+    if (!empty($projects[$type_name])) {
+      ksort($projects[$type_name]);
       $variables['project_types'][] = [
         'label' => $type_label,
-        'table' => $rows[$type_name],
+        'table' => $projects[$type_name],
       ];
     }
   }
@@ -159,8 +155,9 @@ function template_preprocess_update_project_status(&$variables) {
         $versions_inner[] = [
           '#theme' => 'update_version',
           '#version' => $project['releases'][$project['recommended']],
-          '#title' => t('Recommended version:'),
+          '#title' => t('Recommended update:'),
           '#attributes' => ['class' => $version_class],
+          '#version_type' => 'recommended',
         ];
       }
 
@@ -173,6 +170,7 @@ function template_preprocess_update_project_status(&$variables) {
             '#version' => $security_update,
             '#title' => t('Security update:'),
             '#attributes' => ['class' => $security_class],
+            '#version_type' => 'security',
           ];
         }
       }
@@ -184,6 +182,7 @@ function template_preprocess_update_project_status(&$variables) {
         '#version' => $project['releases'][$project['latest_version']],
         '#title' => t('Latest version:'),
         '#attributes' => ['class' => ['version-latest']],
+        '#version_type' => 'latest',
       ];
     }
     if ($project['install_type'] == 'dev'
@@ -195,6 +194,7 @@ function template_preprocess_update_project_status(&$variables) {
         '#version' => $project['releases'][$project['dev_version']],
         '#title' => t('Development version:'),
         '#attributes' => ['class' => ['version-latest']],
+        '#version_type' => 'dev',
       ];
     }
   }
@@ -206,10 +206,22 @@ function template_preprocess_update_project_status(&$variables) {
         '#version' => $project['releases'][$also],
         '#title' => t('Also available:'),
         '#attributes' => ['class' => ['version-also-available']],
+        '#version_type' => 'also',
       ];
     }
   }
 
+  // Currently installed version.
+  if (isset($project['releases'][$project['version_normalized']])) {
+    $versions_inner[] = [
+      '#theme' => 'update_version',
+      '#version' => $project['releases'][$project['version_normalized']],
+      '#title' => t('Installed version:'),
+      '#attributes' => ['class' => ['project-update__version--installed']],
+      '#version_type' => 'installed',
+    ];
+  }
+
   if (!empty($versions_inner)) {
     $variables['versions'] = $versions_inner;
   }
diff --git a/core/themes/seven/css/components/update.admin.theme.css b/core/themes/seven/css/components/update.admin.theme.css
new file mode 100644
index 0000000000..3891e864fc
--- /dev/null
+++ b/core/themes/seven/css/components/update.admin.theme.css
@@ -0,0 +1,66 @@
+/**
+ * @file
+ * Styles used by the Update Manager module.
+ */
+
+.project-update__title {
+  font-weight: bold;
+  font-size: 110%;
+}
+.project-update__status {
+  float: right; /* LTR */
+  font-size: 110%;
+}
+[dir="rtl"] .project-update__status {
+  float: left;
+}
+.project-update__status--not-supported {
+  float: left; /* LTR */
+}
+[dir="rtl"] .project-update__status--not-supported {
+  float: right;
+}
+.project-update__status--security-error {
+  font-weight: bold;
+  color: #970f00;
+}
+
+.project-update__status-icon {
+  padding-left: 0.5em; /* LTR */
+}
+[dir="rtl"] .project-update__status-icon {
+  padding-left: 0;
+  padding-right: 0.5em;
+}
+.project-update__details {
+  padding: 1em 1em 0.25em 1em;
+}
+
+.project-update__version {
+  border-bottom: 1px solid #bfbfbf;
+  padding: 0.5em 0;
+}
+.project-update__version--installed {
+  border-bottom: none;
+}
+.project-update__version-date {
+  white-space: nowrap;
+}
+.project-update__version-details {
+  padding-right: 0.5em; /* LTR */
+}
+[dir="rtl"] .project-update__version-details {
+  padding-left: 0.5em;
+  direction: ltr; /* Version numbers should always be LTR. */
+}
+.project-update__version-links {
+  text-align: right; /* LTR */
+  list-style-type: none;
+}
+[dir="rtl"] .project-update__version-links {
+  text-align: left;
+}
+.project-update__version--recommended-strong .project-update__version-title,
+.version-security .project-update__version-title {
+  font-weight: bold;
+}
diff --git a/core/themes/seven/seven.info.yml b/core/themes/seven/seven.info.yml
index 3f0e43c025..559a06160c 100644
--- a/core/themes/seven/seven.info.yml
+++ b/core/themes/seven/seven.info.yml
@@ -42,6 +42,8 @@ libraries-override:
         assets/vendor/jquery.ui/themes/base/dialog.css: false
   classy/dialog:
     seven/seven.drupal.dialog
+  update/drupal.update.admin:
+    seven/drupal.update.admin
 libraries-extend:
   core/ckeditor:
     - seven/ckeditor-dialog
diff --git a/core/themes/seven/seven.libraries.yml b/core/themes/seven/seven.libraries.yml
index 508c0fe497..de1d1e048d 100644
--- a/core/themes/seven/seven.libraries.yml
+++ b/core/themes/seven/seven.libraries.yml
@@ -93,6 +93,12 @@ drupal.responsive-detail:
     - core/jquery.once
     - core/collapse
 
+drupal.update.admin:
+  version: VERSION
+  css:
+    theme:
+      css/components/update.admin.theme.css: {}
+
 vertical-tabs:
   version: VERSION
   css:
diff --git a/core/themes/seven/templates/update-project-status.html.twig b/core/themes/seven/templates/update-project-status.html.twig
new file mode 100644
index 0000000000..894379e785
--- /dev/null
+++ b/core/themes/seven/templates/update-project-status.html.twig
@@ -0,0 +1,103 @@
+{#
+/**
+ * @file
+ * Default theme implementation for the project status report.
+ *
+ * Available variables:
+ * - title: The project title.
+ * - url: The project url.
+ * - status: The project status.
+ *   - label: The project status label.
+ *   - attributes: HTML attributes for the project status.
+ *   - reason: The reason you should update the project.
+ *   - icon: The project status version indicator icon.
+ * - existing_version: The version of the installed project.
+ * - versions: The available versions of the project.
+ * - install_type: The type of project (e.g., dev).
+ * - datestamp: The date/time of a project version's release.
+ * - extras: HTML attributes and additional information about the project.
+ *   - attributes: HTML attributes for the extra item.
+ *   - label: The label for an extra item.
+ *   - data: The data about an extra item.
+ * - includes: The projects within the project.
+ * - disabled: The currently disabled projects in the project.
+ *
+ * @see template_preprocess_update_project_status()
+ *
+ * @ingroup themeable
+ */
+#}
+{%
+  set status_classes = [
+    project.status == constant('UPDATE_NOT_SECURE') ? 'project-update__status--security-error',
+    project.status == constant('UPDATE_REVOKED') ? 'project-update__status--revoked',
+    project.status == constant('UPDATE_NOT_SUPPORTED') ? 'project-update__status--not-supported',
+    project.status == constant('UPDATE_NOT_CURRENT') ? 'project-update__status--not-current',
+    project.status == constant('UPDATE_CURRENT') ? 'project-update__status--current',
+  ]
+%}
+<div{{ status.attributes.addClass('project-update__status', status_classes) }}>
+  {%- if status.label -%}
+    <span>{{ status.label }}</span>
+  {%- else -%}
+    {{ status.reason }}
+  {%- endif %}
+  <span class="project-update__status-icon">
+    {{ status.icon }}
+  </span>
+</div>
+
+<div class="project-update__title clearfix">
+  {%- if url -%}
+    <a href="{{ url }}">{{ title }}</a>
+  {%- else -%}
+    {{ title }}
+  {%- endif %}
+</div>
+
+{%
+  set extra_classes = [
+    project.status == constant('UPDATE_NOT_SECURE') ? 'project-not-secure',
+    project.status == constant('UPDATE_REVOKED') ? 'project-revoked',
+    project.status == constant('UPDATE_NOT_SUPPORTED') ? 'project-not-supported',
+  ]
+%}
+<div class="project-updates__details">
+  {% if extras %}
+    <div class="extra">
+      {% for extra in extras %}
+        <div{{ extra.attributes.addClass(extra_classes) }}>
+          {{ extra.label }}: {{ extra.data }}
+        </div>
+      {% endfor %}
+    </div>
+  {% endif %}
+  {% set includes = includes|join(', ') %}
+</div>
+
+{% if versions %}
+  {% for version in versions %}
+    {{ version }}
+  {% endfor %}
+{% endif %}
+
+{% if disabled %}
+  {{ 'Includes:'|t }}
+  <ul>
+    <li>
+      {% trans %}
+        Enabled: {{ includes|placeholder }}
+      {% endtrans %}
+    </li>
+    <li>
+      {% set disabled = disabled|join(', ') %}
+      {% trans %}
+        Disabled: {{ disabled|placeholder }}
+      {% endtrans %}
+    </li>
+  </ul>
+{% else %}
+  {% trans %}
+    Includes: {{ includes|placeholder }}
+  {% endtrans %}
+{% endif %}
diff --git a/core/themes/seven/templates/update-version.html.twig b/core/themes/seven/templates/update-version.html.twig
new file mode 100644
index 0000000000..9a683e05bb
--- /dev/null
+++ b/core/themes/seven/templates/update-version.html.twig
@@ -0,0 +1,42 @@
+{#
+/**
+ * @file
+ * Default theme implementation for the version display of a project.
+ *
+ * Available variables:
+ * - attributes: HTML attributes suitable for a container element.
+ * - title: The title of the project.
+ * - version:  A list of data about the latest released version, containing:
+ *   - version: The version number.
+ *   - date: The date of the release.
+ *   - download_link: The URL for the downloadable file.
+ *   - release_link: The URL for the release notes.
+ * - version_type: The type of the version, possible values are 'recommended', 'security', 'latest', 'dev', 'also',
+ *  'installed'.
+ *
+ * @ingroup themeable
+ */
+#}
+<div class="{{ attributes.class }} project-update__version"{{ attributes|without('class') }}>
+  <div class="clearfix">
+    <div class="project-update__version-title">{{ title }}</div>
+    <div class="project-update__version-details layout-column layout-column--three-quarter">
+      <a href="{{ version.release_link }}">{{ version.version }}</a>
+      <span class="project-update__version-date">({{ version.date|date('Y-M-d') }})</span>
+      {% if version.security_covered %}
+        {% trans %}
+          <small>Covered by Drupal’s <a href="https://www.drupal.org/security-advisory-policy">security advisory policy</a></small>
+        {% endtrans %}
+      {% endif %}
+    </div>
+    {% if version_type != 'installed' %}
+      <div class="layout-column layout-column--quarter">
+        <ul class="project-update__version-links">
+          <li class="project-update__download-link">
+            <a href="{{ version.release_link }}">{{ 'Download'|t }}</a>
+          </li>
+        </ul>
+      </div>
+    {% endif %}
+  </div>
+</div>
