diff --git a/core/lib/Drupal/Core/Entity/EntityPublishedTrait.php b/core/lib/Drupal/Core/Entity/EntityPublishedTrait.php
index 871aceb..59fddd5 100644
--- a/core/lib/Drupal/Core/Entity/EntityPublishedTrait.php
+++ b/core/lib/Drupal/Core/Entity/EntityPublishedTrait.php
@@ -33,8 +33,7 @@ public static function publishedBaseFieldDefinitions(EntityTypeInterface $entity
     }
 
     return [$entity_type->getKey('published') => BaseFieldDefinition::create('boolean')
-      ->setLabel(new TranslatableMarkup('Publishing status'))
-      ->setDescription(new TranslatableMarkup('A boolean indicating the published state.'))
+      ->setLabel(new TranslatableMarkup('Published'))
       ->setRevisionable(TRUE)
       ->setTranslatable(TRUE)
       ->setDefaultValue(TRUE)];
diff --git a/core/modules/book/config/optional/core.entity_form_display.node.book.default.yml b/core/modules/book/config/optional/core.entity_form_display.node.book.default.yml
index 58aba45..b1db6d1 100644
--- a/core/modules/book/config/optional/core.entity_form_display.node.book.default.yml
+++ b/core/modules/book/config/optional/core.entity_form_display.node.book.default.yml
@@ -33,6 +33,13 @@ content:
     weight: 15
     region: content
     third_party_settings: {  }
+  status:
+    type: boolean_checkbox
+    settings:
+      display_label: true
+    weight: 120
+    region: content
+    third_party_settings: {  }
   sticky:
     type: boolean_checkbox
     settings:
diff --git a/core/modules/book/tests/src/Functional/BookTest.php b/core/modules/book/tests/src/Functional/BookTest.php
index 66edec9..e52e484 100644
--- a/core/modules/book/tests/src/Functional/BookTest.php
+++ b/core/modules/book/tests/src/Functional/BookTest.php
@@ -741,8 +741,8 @@ public function testBookNavigationBlockOnUnpublishedBook() {
     $this->drupalPlaceBlock('book_navigation', ['block_mode' => 'book pages']);
 
     // Unpublish book node.
-    $edit = [];
-    $this->drupalPostForm('node/' . $this->book->id() . '/edit', $edit, t('Save and unpublish'));
+    $edit = ['status[value]' => FALSE];
+    $this->drupalPostForm('node/' . $this->book->id() . '/edit', $edit, t('Save'));
 
     // Test node page.
     $this->drupalGet('node/' . $this->book->id());
diff --git a/core/modules/comment/tests/src/Functional/CommentStatusFieldAccessTest.php b/core/modules/comment/tests/src/Functional/CommentStatusFieldAccessTest.php
index 504b3ba..e208c71 100644
--- a/core/modules/comment/tests/src/Functional/CommentStatusFieldAccessTest.php
+++ b/core/modules/comment/tests/src/Functional/CommentStatusFieldAccessTest.php
@@ -86,14 +86,14 @@ public function testCommentStatusFieldAccessStatus() {
     $assert->fieldNotExists('comment[0][status]');
     $this->submitForm([
       'title[0][value]' => 'Node 1',
-    ], t('Save and publish'));
+    ], t('Save'));
     $assert->fieldExists('subject[0][value]');
     $this->drupalLogin($this->commentAdmin);
     $this->drupalGet('node/add/article');
     $assert->fieldExists('comment[0][status]');
     $this->submitForm([
       'title[0][value]' => 'Node 2',
-    ], t('Save and publish'));
+    ], t('Save'));
     $assert->fieldExists('subject[0][value]');
   }
 
diff --git a/core/modules/content_moderation/content_moderation.module b/core/modules/content_moderation/content_moderation.module
index 7345e93..44a4270 100644
--- a/core/modules/content_moderation/content_moderation.module
+++ b/core/modules/content_moderation/content_moderation.module
@@ -15,6 +15,8 @@
 use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Core\Session\AccountInterface;
@@ -193,6 +195,28 @@ function content_moderation_node_access(NodeInterface $node, $operation, Account
 }
 
 /**
+ * Implements hook_entity_field_access().
+ */
+function content_moderation_entity_field_access($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
+  if ($items && $operation === 'edit') {
+    /** @var \Drupal\content_moderation\ModerationInformationInterface $moderation_info */
+    $moderation_info = Drupal::service('content_moderation.moderation_information');
+
+    $entity_type = \Drupal::entityTypeManager()->getDefinition($field_definition->getTargetEntityTypeId());
+
+    $entity = $items->getEntity();
+
+    // Deny edit access to the published field if the entity is being moderated.
+    if ($entity_type->hasKey('published') && $moderation_info->isModeratedEntity($entity) && $entity->moderation_state && $field_definition->getName() == $entity_type->getKey('published')) {
+      return AccessResult::forbidden();
+    }
+  }
+
+  return AccessResult::neutral();
+
+}
+
+/**
  * Implements hook_theme().
  */
 function content_moderation_theme() {
diff --git a/core/modules/content_moderation/src/Tests/ModerationStateNodeTest.php b/core/modules/content_moderation/src/Tests/ModerationStateNodeTest.php
index 49eee6d..4bce3a6 100644
--- a/core/modules/content_moderation/src/Tests/ModerationStateNodeTest.php
+++ b/core/modules/content_moderation/src/Tests/ModerationStateNodeTest.php
@@ -63,7 +63,7 @@ public function testCreatingContent() {
     // Create a new node.
     $this->drupalPostForm('node/add/moderated_content', [
       'title[0][value]' => 'non-moderated content',
-    ], t('Save and publish'));
+    ], t('Save'));
 
     $node = $this->getNodeByTitle('non-moderated content');
     if (!$node) {
diff --git a/core/modules/content_moderation/src/Tests/ModerationStateNodeTypeTest.php b/core/modules/content_moderation/src/Tests/ModerationStateNodeTypeTest.php
index 099b4dc..5c494da 100644
--- a/core/modules/content_moderation/src/Tests/ModerationStateNodeTypeTest.php
+++ b/core/modules/content_moderation/src/Tests/ModerationStateNodeTypeTest.php
@@ -19,10 +19,10 @@ public function testNotModerated() {
     $this->assertText('The content type Not moderated has been added.');
     $this->grantUserPermissionToCreateContentOfType($this->adminUser, 'not_moderated');
     $this->drupalGet('node/add/not_moderated');
-    $this->assertRaw('Save as unpublished');
+    $this->assertRaw('Save');
     $this->drupalPostForm(NULL, [
       'title[0][value]' => 'Test',
-    ], t('Save and publish'));
+    ], t('Save'));
     $this->assertText('Not moderated Test has been created.');
   }
 
@@ -39,7 +39,7 @@ public function testEnablingOnExistingContent() {
     $this->drupalGet('node/add/not_moderated');
     $this->drupalPostForm(NULL, [
       'title[0][value]' => 'Test',
-    ], t('Save and publish'));
+    ], t('Save'));
     $this->assertText('Not moderated Test has been created.');
 
     // Now enable moderation state, ensuring all the expected links and tabs are
diff --git a/core/modules/content_moderation/tests/src/Functional/NodeAccessTest.php b/core/modules/content_moderation/tests/src/Functional/NodeAccessTest.php
index 2d52421..c3315e3 100644
--- a/core/modules/content_moderation/tests/src/Functional/NodeAccessTest.php
+++ b/core/modules/content_moderation/tests/src/Functional/NodeAccessTest.php
@@ -15,7 +15,7 @@ class NodeAccessTest extends ModerationStateTestBase {
   protected function setUp() {
     parent::setUp();
     $this->drupalLogin($this->adminUser);
-    $this->createContentTypeFromUi('Moderated content', 'moderated_content', TRUE);
+    $this->createContentTypeFromUi('Moderated content', 'moderated_content', FALSE);
     $this->grantUserPermissionToCreateContentOfType($this->adminUser, 'moderated_content');
   }
 
@@ -25,8 +25,20 @@ protected function setUp() {
   public function testPageAccess() {
     $this->drupalLogin($this->adminUser);
 
+    // Access the node form before moderation is enabled, the publication state
+    // should now be visible.
+    $this->drupalGet('node/add/moderated_content');
+    $this->assertSession()->fieldExists('Published');
+
+    // Now enable the workflow.
+    $this->enableModerationThroughUi('moderated_content', 'editorial');
+
+    // Access that the status field is no longer visible.
+    $this->drupalGet('node/add/moderated_content');
+    $this->assertSession()->fieldNotExists('Published');
+
     // Create a node to test with.
-    $this->drupalPostForm('node/add/moderated_content', [
+    $this->drupalPostForm(NULL, [
       'title[0][value]' => 'moderated content',
     ], t('Save and Create New Draft'));
     $node = $this->getNodeByTitle('moderated content');
diff --git a/core/modules/content_translation/src/Tests/ContentTranslationLanguageChangeTest.php b/core/modules/content_translation/src/Tests/ContentTranslationLanguageChangeTest.php
index bb9b223..04bd023 100644
--- a/core/modules/content_translation/src/Tests/ContentTranslationLanguageChangeTest.php
+++ b/core/modules/content_translation/src/Tests/ContentTranslationLanguageChangeTest.php
@@ -73,12 +73,12 @@ public function testLanguageChange() {
     $edit = [
       'title[0][value]' => 'english_title',
     ];
-    $this->drupalPostForm(NULL, $edit, t('Save and publish'));
+    $this->drupalPostForm(NULL, $edit, t('Save'));
 
     // Create a translation in French.
     $this->clickLink('Translate');
     $this->clickLink('Add');
-    $this->drupalPostForm(NULL, [], t('Save and keep published (this translation)'));
+    $this->drupalPostForm(NULL, [], t('Save (this translation)'));
     $this->clickLink('Translate');
 
     // Edit English translation.
@@ -90,7 +90,7 @@ public function testLanguageChange() {
       'files[field_image_field_0]' => $images->uri,
     ];
     $this->drupalPostForm(NULL, $edit, t('Upload'));
-    $this->drupalPostForm(NULL, ['field_image_field[0][alt]' => 'alternative_text'], t('Save and keep published (this translation)'));
+    $this->drupalPostForm(NULL, ['field_image_field[0][alt]' => 'alternative_text'], t('Save (this translation)'));
 
     // Check that the translation languages are correct.
     $node = $this->getNodeByTitle('english_title');
@@ -109,13 +109,13 @@ public function testTitleDoesNotChangesOnChangingLanguageWidgetAndTriggeringAjax
       'title[0][value]' => 'english_title',
       'test_field_only_en_fr' => 'node created',
     ];
-    $this->drupalPostForm(NULL, $edit, t('Save and publish'));
+    $this->drupalPostForm(NULL, $edit, t('Save'));
     $this->assertEqual('node created', \Drupal::state()->get('test_field_only_en_fr'));
 
     // Create a translation in French.
     $this->clickLink('Translate');
     $this->clickLink('Add');
-    $this->drupalPostForm(NULL, [], t('Save and keep published (this translation)'));
+    $this->drupalPostForm(NULL, [], t('Save (this translation)'));
     $this->clickLink('Translate');
 
     // Edit English translation.
@@ -137,7 +137,7 @@ public function testTitleDoesNotChangesOnChangingLanguageWidgetAndTriggeringAjax
       'langcode[0][value]' => 'en',
       'field_image_field[0][alt]' => 'alternative_text'
     ];
-    $this->drupalPostForm(NULL, $edit, t('Save and keep published (this translation)'));
+    $this->drupalPostForm(NULL, $edit, t('Save (this translation)'));
 
     // Check that the translation languages are correct.
     $node = $this->getNodeByTitle('english_title');
diff --git a/core/modules/field/tests/src/Functional/EntityReference/EntityReferenceXSSTest.php b/core/modules/field/tests/src/Functional/EntityReference/EntityReferenceXSSTest.php
index 46986ec..b161ed6 100644
--- a/core/modules/field/tests/src/Functional/EntityReference/EntityReferenceXSSTest.php
+++ b/core/modules/field/tests/src/Functional/EntityReference/EntityReferenceXSSTest.php
@@ -62,7 +62,7 @@ public function testEntityReferenceXSS() {
       'title[0][value]' => $this->randomString(),
       'entity_reference_test' => $referenced_node->id()
     ];
-    $this->drupalPostForm(NULL, $edit, 'Save and publish');
+    $this->drupalPostForm(NULL, $edit, 'Save');
     $this->assertEscaped($referenced_node->getTitle());
 
     // Test the options_buttons type.
diff --git a/core/modules/file/src/Tests/FileFieldAnonymousSubmissionTest.php b/core/modules/file/src/Tests/FileFieldAnonymousSubmissionTest.php
index b59b1ba..66d87cd 100644
--- a/core/modules/file/src/Tests/FileFieldAnonymousSubmissionTest.php
+++ b/core/modules/file/src/Tests/FileFieldAnonymousSubmissionTest.php
@@ -138,7 +138,7 @@ protected function doTestNodeWithFileWithoutTitle() {
       $label = 'Save';
     }
     else {
-      $label = 'Save and publish';
+      $label = 'Save';
     }
     $this->drupalPostForm(NULL, $edit, $label);
     $this->assertResponse(200);
diff --git a/core/modules/file/src/Tests/FileFieldDisplayTest.php b/core/modules/file/src/Tests/FileFieldDisplayTest.php
index 1b7e534..db9b7dc 100644
--- a/core/modules/file/src/Tests/FileFieldDisplayTest.php
+++ b/core/modules/file/src/Tests/FileFieldDisplayTest.php
@@ -77,7 +77,7 @@ public function testNodeDisplay() {
 
     // Turn the "display" option off and check that the file is no longer displayed.
     $edit = [$field_name . '[0][display]' => FALSE];
-    $this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save'));
 
     $this->assertNoRaw($default_output, 'Field is hidden when "display" option is unchecked.');
 
@@ -87,7 +87,7 @@ public function testNodeDisplay() {
       $field_name . '[0][description]' => $description,
       $field_name . '[0][display]' => TRUE,
     ];
-    $this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save'));
     $this->assertText($description);
 
     // Ensure the filename in the link's title attribute is escaped.
@@ -167,7 +167,7 @@ public function testDescToggle() {
       'title[0][value]' => $title,
       'files[field_' . $field_name . '_0]' => drupal_realpath($file->uri),
     ];
-    $this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish'));
+    $this->drupalPostForm('node/add/' . $type_name, $edit, t('Save'));
     $node = $this->drupalGetNodeByTitle($title);
     $this->drupalGet('node/' . $node->id() . '/edit');
     $this->assertText(t('The description may be used as the label of the link to the file.'));
diff --git a/core/modules/file/src/Tests/FileFieldRevisionTest.php b/core/modules/file/src/Tests/FileFieldRevisionTest.php
index 7de496f..7b7b4d3 100644
--- a/core/modules/file/src/Tests/FileFieldRevisionTest.php
+++ b/core/modules/file/src/Tests/FileFieldRevisionTest.php
@@ -63,7 +63,7 @@ public function testRevisions() {
 
     // Save a new version of the node without any changes.
     // Check that the file is still the same as the previous revision.
-    $this->drupalPostForm('node/' . $nid . '/edit', ['revision' => '1'], t('Save and keep published'));
+    $this->drupalPostForm('node/' . $nid . '/edit', ['revision' => '1'], t('Save'));
     $node_storage->resetCache([$nid]);
     $node = $node_storage->load($nid);
     $node_file_r3 = File::load($node->{$field_name}->target_id);
diff --git a/core/modules/file/src/Tests/FileFieldTestBase.php b/core/modules/file/src/Tests/FileFieldTestBase.php
index 73cc96a..b7b90d7 100644
--- a/core/modules/file/src/Tests/FileFieldTestBase.php
+++ b/core/modules/file/src/Tests/FileFieldTestBase.php
@@ -227,7 +227,7 @@ public function uploadNodeFiles(array $files, $field_name, $nid_or_type, $new_re
         $edit[$name][] = $file_path;
       }
     }
-    $this->drupalPostForm("node/$nid/edit", $edit, t('Save and keep published'));
+    $this->drupalPostForm("node/$nid/edit", $edit, t('Save'));
 
     return $nid;
   }
@@ -243,7 +243,7 @@ public function removeNodeFile($nid, $new_revision = TRUE) {
     ];
 
     $this->drupalPostForm('node/' . $nid . '/edit', [], t('Remove'));
-    $this->drupalPostForm(NULL, $edit, t('Save and keep published'));
+    $this->drupalPostForm(NULL, $edit, t('Save'));
   }
 
   /**
@@ -256,7 +256,7 @@ public function replaceNodeFile($file, $field_name, $nid, $new_revision = TRUE)
     ];
 
     $this->drupalPostForm('node/' . $nid . '/edit', [], t('Remove'));
-    $this->drupalPostForm(NULL, $edit, t('Save and keep published'));
+    $this->drupalPostForm(NULL, $edit, t('Save'));
   }
 
   /**
diff --git a/core/modules/file/src/Tests/FileFieldValidateTest.php b/core/modules/file/src/Tests/FileFieldValidateTest.php
index 5ddcdde..422bf68 100644
--- a/core/modules/file/src/Tests/FileFieldValidateTest.php
+++ b/core/modules/file/src/Tests/FileFieldValidateTest.php
@@ -29,7 +29,7 @@ public function testRequired() {
     // Try to post a new node without uploading a file.
     $edit = [];
     $edit['title[0][value]'] = $this->randomMachineName();
-    $this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish'));
+    $this->drupalPostForm('node/add/' . $type_name, $edit, t('Save'));
     $this->assertRaw(t('@title field is required.', ['@title' => $field->getLabel()]), 'Node save failed when required file field was empty.');
 
     // Create a new node with the uploaded file.
@@ -50,7 +50,7 @@ public function testRequired() {
     // Try to post a new node without uploading a file in the multivalue field.
     $edit = [];
     $edit['title[0][value]'] = $this->randomMachineName();
-    $this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish'));
+    $this->drupalPostForm('node/add/' . $type_name, $edit, t('Save'));
     $this->assertRaw(t('@title field is required.', ['@title' => $field->getLabel()]), 'Node save failed when required multiple value file field was empty.');
 
     // Create a new node with the uploaded file into the multivalue field.
diff --git a/core/modules/file/src/Tests/FileFieldWidgetTest.php b/core/modules/file/src/Tests/FileFieldWidgetTest.php
index ddfd8f4..ad47d77 100644
--- a/core/modules/file/src/Tests/FileFieldWidgetTest.php
+++ b/core/modules/file/src/Tests/FileFieldWidgetTest.php
@@ -121,7 +121,7 @@ public function testSingleValuedWidget() {
       $this->assertTrue(isset($label[0]), 'Label for upload found.');
 
       // Save the node and ensure it does not have the file.
-      $this->drupalPostForm(NULL, [], t('Save and keep published'));
+      $this->drupalPostForm(NULL, [], t('Save'));
       $node_storage->resetCache([$nid]);
       $node = $node_storage->load($nid);
       $this->assertTrue(empty($node->{$field_name}->target_id), 'File was successfully removed from the node.');
@@ -238,8 +238,7 @@ public function testMultiValuedWidget() {
       $this->assertNoFieldByXPath('//input[@type="submit"]', t('Remove'), format_string('After removing all files, there is no "Remove" button displayed (JSMode=%type).', ['%type' => $type]));
 
       // Save the node and ensure it does not have any files.
-      $this->drupalPostForm(NULL, ['title[0][value]' => $this->randomMachineName()], t('Save and publish'));
-      $matches = [];
+      $this->drupalPostForm(NULL, ['title[0][value]' => $this->randomMachineName()], t('Save'));
       preg_match('/node\/([0-9]+)/', $this->getUrl(), $matches);
       $nid = $matches[1];
       $node_storage->resetCache([$nid]);
@@ -368,7 +367,7 @@ public function testPrivateFileComment() {
     $edit = [
       'title[0][value]' => $this->randomMachineName(),
     ];
-    $this->drupalPostForm('node/add/article', $edit, t('Save and publish'));
+    $this->drupalPostForm('node/add/article', $edit, t('Save'));
     $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
 
     // Add a comment with a file.
@@ -402,7 +401,8 @@ public function testPrivateFileComment() {
 
     // Unpublishes node.
     $this->drupalLogin($this->adminUser);
-    $this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save and unpublish'));
+    $edit = ['status[value]' => FALSE];
+    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
 
     // Ensures normal user can no longer download the file.
     $this->drupalLogin($user);
diff --git a/core/modules/file/src/Tests/FilePrivateTest.php b/core/modules/file/src/Tests/FilePrivateTest.php
index 3c9776f..7ecd485 100644
--- a/core/modules/file/src/Tests/FilePrivateTest.php
+++ b/core/modules/file/src/Tests/FilePrivateTest.php
@@ -72,10 +72,10 @@ public function testPrivateFile() {
     // Attempt to reuse the file when editing a node.
     $edit = [];
     $edit['title[0][value]'] = $this->randomMachineName();
-    $this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish'));
+    $this->drupalPostForm('node/add/' . $type_name, $edit, t('Save'));
     $new_node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
     $edit[$field_name . '[0][fids]'] = $node_file->id();
-    $this->drupalPostForm('node/' . $new_node->id() . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $new_node->id() . '/edit', $edit, t('Save'));
     // Make sure the form submit failed - we stayed on the edit form.
     $this->assertUrl('node/' . $new_node->id() . '/edit');
     // Check that we got the expected constraint form error.
@@ -86,7 +86,7 @@ public function testPrivateFile() {
     $edit = [];
     $edit['title[0][value]'] = $this->randomMachineName();
     $edit[$field_name . '[0][fids]'] = $node_file->id();
-    $this->drupalPostForm('node/add/' . $type_name, $edit, t('Save and publish'));
+    $this->drupalPostForm('node/add/' . $type_name, $edit, t('Save'));
     $new_node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
     $this->assertTrue(empty($new_node), 'Node was not created.');
     $this->assertUrl('node/add/' . $type_name);
diff --git a/core/modules/filter/tests/src/Functional/FilterHooksTest.php b/core/modules/filter/tests/src/Functional/FilterHooksTest.php
index c799460..5ff4a8a 100644
--- a/core/modules/filter/tests/src/Functional/FilterHooksTest.php
+++ b/core/modules/filter/tests/src/Functional/FilterHooksTest.php
@@ -60,7 +60,7 @@ public function testFilterHooks() {
     $edit['title[0][value]'] = $title;
     $edit['body[0][value]'] = $this->randomMachineName(32);
     $edit['body[0][format]'] = $format_id;
-    $this->drupalPostForm("node/add/{$type->id()}", $edit, t('Save and publish'));
+    $this->drupalPostForm("node/add/{$type->id()}", $edit, t('Save'));
     $this->assertText(t('@type @title has been created.', ['@type' => $type_name, '@title' => $title]));
 
     // Disable the text format.
diff --git a/core/modules/forum/config/optional/core.entity_form_display.node.forum.default.yml b/core/modules/forum/config/optional/core.entity_form_display.node.forum.default.yml
index 6773d32..965a691 100644
--- a/core/modules/forum/config/optional/core.entity_form_display.node.forum.default.yml
+++ b/core/modules/forum/config/optional/core.entity_form_display.node.forum.default.yml
@@ -42,6 +42,13 @@ content:
     weight: 15
     region: content
     third_party_settings: {  }
+  status:
+    type: boolean_checkbox
+    settings:
+      display_label: true
+    weight: 120
+    region: content
+    third_party_settings: {  }
   sticky:
     type: boolean_checkbox
     settings:
diff --git a/core/modules/forum/tests/src/Functional/ForumBlockTest.php b/core/modules/forum/tests/src/Functional/ForumBlockTest.php
index 6c412b7..2914e94 100644
--- a/core/modules/forum/tests/src/Functional/ForumBlockTest.php
+++ b/core/modules/forum/tests/src/Functional/ForumBlockTest.php
@@ -170,7 +170,7 @@ protected function createForumTopics($count = 5) {
       ];
 
       // Create the forum topic, preselecting the forum ID via a URL parameter.
-      $this->drupalPostForm('node/add/forum', $edit, t('Save and publish'), ['query' => ['forum_id' => 1]]);
+      $this->drupalPostForm('node/add/forum', $edit, t('Save'), ['query' => ['forum_id' => 1]]);
       $topics[] = $title;
     }
 
diff --git a/core/modules/forum/tests/src/Functional/ForumIndexTest.php b/core/modules/forum/tests/src/Functional/ForumIndexTest.php
index 53c8364..38adb72 100644
--- a/core/modules/forum/tests/src/Functional/ForumIndexTest.php
+++ b/core/modules/forum/tests/src/Functional/ForumIndexTest.php
@@ -44,7 +44,7 @@ public function testForumIndexStatus() {
     $this->drupalGet("forum/$tid");
     $this->clickLink(t('Add new @node_type', ['@node_type' => 'Forum topic']));
     $this->assertUrl('node/add/forum', ['query' => ['forum_id' => $tid]]);
-    $this->drupalPostForm(NULL, $edit, t('Save and publish'));
+    $this->drupalPostForm(NULL, $edit, t('Save'));
 
     // Check that the node exists in the database.
     $node = $this->drupalGetNodeByTitle($title);
@@ -71,7 +71,8 @@ public function testForumIndexStatus() {
 
 
     // Unpublish the node.
-    $this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save and unpublish'));
+    $edit = ['status[value]' => FALSE];
+    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
     $this->drupalGet('node/' . $node->id());
     $this->assertText(t('Access denied'), 'Unpublished node is no longer accessible.');
 
diff --git a/core/modules/image/src/Tests/ImageFieldDisplayTest.php b/core/modules/image/src/Tests/ImageFieldDisplayTest.php
index 9c105c1..8061526 100644
--- a/core/modules/image/src/Tests/ImageFieldDisplayTest.php
+++ b/core/modules/image/src/Tests/ImageFieldDisplayTest.php
@@ -282,7 +282,7 @@ public function testImageFieldSettings() {
       $field_name . '[0][alt]' => $image['#alt'],
       $field_name . '[0][title]' => $image['#title'],
     ];
-    $this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save'));
     $default_output = str_replace("\n", NULL, $renderer->renderRoot($image));
     $this->assertRaw($default_output, 'Image displayed using user supplied alt and title attributes.');
 
@@ -292,7 +292,7 @@ public function testImageFieldSettings() {
       $field_name . '[0][alt]' => $this->randomMachineName($test_size),
       $field_name . '[0][title]' => $this->randomMachineName($test_size),
     ];
-    $this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save'));
     $schema = $field->getFieldStorageDefinition()->getSchema();
     $this->assertRaw(t('Alternative text cannot be longer than %max characters but is currently %length characters long.', [
       '%max' => $schema['columns']['alt']['length'],
@@ -314,9 +314,9 @@ public function testImageFieldSettings() {
     $edit = [
       'files[' . $field_name . '_1][]' => drupal_realpath($test_image->uri),
     ];
-    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
     // Add the required alt text.
-    $this->drupalPostForm(NULL, [$field_name . '[1][alt]' => $alt], t('Save and keep published'));
+    $this->drupalPostForm(NULL, [$field_name . '[1][alt]' => $alt], t('Save'));
     $this->assertText(format_string('Article @title has been updated.', ['@title' => $node->getTitle()]));
 
     // Assert ImageWidget::process() calls FieldWidget::process().
diff --git a/core/modules/image/src/Tests/ImageFieldTestBase.php b/core/modules/image/src/Tests/ImageFieldTestBase.php
index eec7f7b..c023917 100644
--- a/core/modules/image/src/Tests/ImageFieldTestBase.php
+++ b/core/modules/image/src/Tests/ImageFieldTestBase.php
@@ -90,10 +90,10 @@ public function uploadNodeImage($image, $field_name, $type, $alt = '') {
       'title[0][value]' => $this->randomMachineName(),
     ];
     $edit['files[' . $field_name . '_0]'] = drupal_realpath($image->uri);
-    $this->drupalPostForm('node/add/' . $type, $edit, t('Save and publish'));
+    $this->drupalPostForm('node/add/' . $type, $edit, t('Save'));
     if ($alt) {
       // Add alt text.
-      $this->drupalPostForm(NULL, [$field_name . '[0][alt]' => $alt], t('Save and publish'));
+      $this->drupalPostForm(NULL, [$field_name . '[0][alt]' => $alt], t('Save'));
     }
 
     // Retrieve ID of the newly created node from the current URL.
diff --git a/core/modules/image/src/Tests/ImageFieldValidateTest.php b/core/modules/image/src/Tests/ImageFieldValidateTest.php
index 7e5ee9b..e429d0b 100644
--- a/core/modules/image/src/Tests/ImageFieldValidateTest.php
+++ b/core/modules/image/src/Tests/ImageFieldValidateTest.php
@@ -119,7 +119,7 @@ public function testRequiredAttributes() {
     $edit = [
       'title[0][value]' => $this->randomMachineName(),
     ];
-    $this->drupalPostForm('node/add/article', $edit, t('Save and publish'));
+    $this->drupalPostForm('node/add/article', $edit, t('Save'));
 
     $this->assertNoText(t('Alternative text field is required.'));
     $this->assertNoText(t('Title field is required.'));
@@ -132,7 +132,7 @@ public function testRequiredAttributes() {
     $edit = [
       'title[0][value]' => $this->randomMachineName(),
     ];
-    $this->drupalPostForm('node/add/article', $edit, t('Save and publish'));
+    $this->drupalPostForm('node/add/article', $edit, t('Save'));
 
     $this->assertNoText(t('Alternative text field is required.'));
     $this->assertNoText(t('Title field is required.'));
diff --git a/core/modules/inline_form_errors/tests/src/FunctionalJavascript/FormErrorHandlerCKEditorTest.php b/core/modules/inline_form_errors/tests/src/FunctionalJavascript/FormErrorHandlerCKEditorTest.php
index 3ee24b4..37fa7ff 100644
--- a/core/modules/inline_form_errors/tests/src/FunctionalJavascript/FormErrorHandlerCKEditorTest.php
+++ b/core/modules/inline_form_errors/tests/src/FunctionalJavascript/FormErrorHandlerCKEditorTest.php
@@ -87,7 +87,7 @@ public function testFragmentLink() {
     // Only enter a title in the node add form and leave the body field empty.
     $edit = ['edit-title-0-value' => 'Test inline form error with CKEditor'];
 
-    $this->submitForm($edit, 'Save and publish');
+    $this->submitForm($edit, 'Save');
 
     // Add a bottom margin to the title field to be sure the body field is not
     // visible. PhantomJS runs with a resolution of 1024x768px.
diff --git a/core/modules/language/tests/src/Functional/LanguageNegotiationUrlTest.php b/core/modules/language/tests/src/Functional/LanguageNegotiationUrlTest.php
index 8472ff7..07ae85d 100644
--- a/core/modules/language/tests/src/Functional/LanguageNegotiationUrlTest.php
+++ b/core/modules/language/tests/src/Functional/LanguageNegotiationUrlTest.php
@@ -70,7 +70,7 @@ public function testDomain() {
       'title[0][value]' => 'Test',
       'path[0][alias]' => '/eng/test',
     ];
-    $this->drupalPostForm('node/add/article', $nodeValues, $this->t('Save and publish'));
+    $this->drupalPostForm('node/add/article', $nodeValues, $this->t('Save'));
     $this->assertSession()->statusCodeEquals(200);
   }
 
diff --git a/core/modules/menu_ui/menu_ui.module b/core/modules/menu_ui/menu_ui.module
index cffccde..41e7a86 100644
--- a/core/modules/menu_ui/menu_ui.module
+++ b/core/modules/menu_ui/menu_ui.module
@@ -352,11 +352,7 @@ function menu_ui_form_node_form_alter(&$form, FormStateInterface $form_state) {
     '#description' => t('Menu links with lower weights are displayed before links with higher weights.'),
   ];
 
-  foreach (array_keys($form['actions']) as $action) {
-    if ($action != 'preview' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
-      $form['actions'][$action]['#submit'][] = 'menu_ui_form_node_form_submit';
-    }
-  }
+  $form['actions']['submit']['#submit'][] = 'menu_ui_form_node_form_submit';
 }
 
 /**
diff --git a/core/modules/menu_ui/src/Tests/MenuNodeTest.php b/core/modules/menu_ui/src/Tests/MenuNodeTest.php
index 3f1bba0..25764ba 100644
--- a/core/modules/menu_ui/src/Tests/MenuNodeTest.php
+++ b/core/modules/menu_ui/src/Tests/MenuNodeTest.php
@@ -133,37 +133,6 @@ public function testMenuNodeFormWidget() {
     // Assert that there is no link for the node.
     $this->drupalGet('test-page');
     $this->assertNoLink($node_title);
-
-    // Use not only the save button, but also the two special buttons:
-    // 'Save and publish' as well as 'Save and keep published'.
-    // These buttons just appear for 'administer nodes' users.
-    $admin_user = $this->drupalCreateUser([
-      'access administration pages',
-      'administer content types',
-      'administer nodes',
-      'administer menu',
-      'create page content',
-      'edit any page content',
-    ]);
-    $this->drupalLogin($admin_user);
-    foreach (['Save and unpublish' => FALSE, 'Save and keep unpublished' => FALSE, 'Save and publish' => TRUE, 'Save and keep published' => TRUE] as $submit => $visible) {
-      $edit = [
-        'menu[enabled]' => 1,
-        'menu[title]' => $node_title,
-      ];
-      $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, $submit);
-      // Assert that the link exists.
-      $this->drupalGet('test-page');
-      if ($visible) {
-        $this->assertLink($node_title, 0, 'Found a menu link after submitted with ' . $submit);
-      }
-      else {
-        $this->assertNoLink($node_title, 'Found no menu link after submitted with ' . $submit);
-      }
-    }
-
-    // Log back in as normal user.
-    $this->drupalLogin($this->editor);
     // Edit the node and create a menu link.
     $edit = [
       'menu[enabled]' => 1,
diff --git a/core/modules/node/node.install b/core/modules/node/node.install
index 4e2c240..c8967ce 100644
--- a/core/modules/node/node.install
+++ b/core/modules/node/node.install
@@ -6,6 +6,7 @@
  */
 
 use Drupal\Core\Database\Database;
+use Drupal\Core\Entity\Entity\EntityFormDisplay;
 use Drupal\Core\Field\BaseFieldDefinition;
 use Drupal\user\RoleInterface;
 
@@ -246,3 +247,24 @@ function node_update_8301() {
   $entity_type->set('entity_keys', $keys);
   $definition_update_manager->updateEntityType($entity_type);
 }
+
+/**
+ * Load all form displays for nodes, add status with these settings, save.
+ */
+function node_update_8400() {
+  $query = \Drupal::entityQuery('entity_form_display')->condition('targetEntityType', 'node');
+  $ids = $query->execute();
+  $form_displays = EntityFormDisplay::loadMultiple($ids);
+
+  // Assign status settings for each 'node' target entity types with 'default'
+  // form mode.
+  foreach ($form_displays as $id => $form_display) {
+    /** @var \Drupal\Core\Entity\Display\EntityDisplayInterface $form_display */
+    $form_display->setComponent('status', [
+      'type' => 'boolean_checkbox',
+      'settings' => [
+        'display_label' => TRUE,
+      ],
+    ])->save();
+  }
+}
diff --git a/core/modules/node/src/Entity/Node.php b/core/modules/node/src/Entity/Node.php
index c11a188..6c2095f 100644
--- a/core/modules/node/src/Entity/Node.php
+++ b/core/modules/node/src/Entity/Node.php
@@ -405,6 +405,16 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
       ])
       ->setDisplayConfigurable('form', TRUE);
 
+    $fields['status']
+      ->setDisplayOptions('form', [
+        'type' => 'boolean_checkbox',
+        'settings' => [
+          'display_label' => TRUE,
+        ],
+        'weight' => 120,
+      ])
+      ->setDisplayConfigurable('form', TRUE);
+
     $fields['created'] = BaseFieldDefinition::create('created')
       ->setLabel(t('Authored on'))
       ->setDescription(t('The time that the node was created.'))
diff --git a/core/modules/node/src/NodeForm.php b/core/modules/node/src/NodeForm.php
index 203c2e6..1aca4f1 100644
--- a/core/modules/node/src/NodeForm.php
+++ b/core/modules/node/src/NodeForm.php
@@ -86,7 +86,10 @@ public function form(array $form, FormStateInterface $form_state) {
     $node = $this->entity;
 
     if ($this->operation == 'edit') {
-      $form['#title'] = $this->t('<em>Edit @type</em> @title', ['@type' => node_get_type_label($node), '@title' => $node->label()]);
+      $form['#title'] = $this->t('<em>Edit @type</em> @title', [
+        '@type' => node_get_type_label($node),
+        '@title' => $node->label()
+      ]);
     }
 
     // Changed must be sent to the client, for later overwrite error checking.
@@ -99,6 +102,13 @@ public function form(array $form, FormStateInterface $form_state) {
 
     $form['advanced']['#attributes']['class'][] = 'entity-meta';
 
+    $form['footer'] = [
+      '#type' => 'container',
+      '#weight' => 99,
+      'status' => $form['status'],
+    ];
+    unset($form['status']);
+
     // Node author information for administrators.
     $form['author'] = [
       '#type' => 'details',
@@ -147,8 +157,6 @@ public function form(array $form, FormStateInterface $form_state) {
 
     $form['#attached']['library'][] = 'node/form';
 
-    $form['#entity_builders']['update_status'] = '::updateStatus';
-
     return $form;
   }
 
@@ -183,59 +191,6 @@ protected function actions(array $form, FormStateInterface $form_state) {
 
     $element['submit']['#access'] = $preview_mode != DRUPAL_REQUIRED || $form_state->get('has_been_previewed');
 
-    // If saving is an option, privileged users get dedicated form submit
-    // buttons to adjust the publishing status while saving in one go.
-    // @todo This adjustment makes it close to impossible for contributed
-    //   modules to integrate with "the Save operation" of this form. Modules
-    //   need a way to plug themselves into 1) the ::submit() step, and
-    //   2) the ::save() step, both decoupled from the pressed form button.
-    if ($element['submit']['#access'] && \Drupal::currentUser()->hasPermission('administer nodes')) {
-      // isNew | prev status » default   & publish label             & unpublish label
-      // 1     | 1           » publish   & Save and publish          & Save as unpublished
-      // 1     | 0           » unpublish & Save and publish          & Save as unpublished
-      // 0     | 1           » publish   & Save and keep published   & Save and unpublish
-      // 0     | 0           » unpublish & Save and keep unpublished & Save and publish
-
-      // Add a "Publish" button.
-      $element['publish'] = $element['submit'];
-      // If the "Publish" button is clicked, we want to update the status to "published".
-      $element['publish']['#published_status'] = TRUE;
-      $element['publish']['#dropbutton'] = 'save';
-      if ($node->isNew()) {
-        $element['publish']['#value'] = t('Save and publish');
-      }
-      else {
-        $element['publish']['#value'] = $node->isPublished() ? t('Save and keep published') : t('Save and publish');
-      }
-      $element['publish']['#weight'] = 0;
-
-      // Add a "Unpublish" button.
-      $element['unpublish'] = $element['submit'];
-      // If the "Unpublish" button is clicked, we want to update the status to "unpublished".
-      $element['unpublish']['#published_status'] = FALSE;
-      $element['unpublish']['#dropbutton'] = 'save';
-      if ($node->isNew()) {
-        $element['unpublish']['#value'] = t('Save as unpublished');
-      }
-      else {
-        $element['unpublish']['#value'] = !$node->isPublished() ? t('Save and keep unpublished') : t('Save and unpublish');
-      }
-      $element['unpublish']['#weight'] = 10;
-
-      // If already published, the 'publish' button is primary.
-      if ($node->isPublished()) {
-        unset($element['unpublish']['#button_type']);
-      }
-      // Otherwise, the 'unpublish' button is primary and should come first.
-      else {
-        unset($element['publish']['#button_type']);
-        $element['unpublish']['#weight'] = -10;
-      }
-
-      // Remove the "Save" button.
-      $element['submit']['#access'] = FALSE;
-    }
-
     $element['preview'] = [
       '#type' => 'submit',
       '#access' => $preview_mode != DRUPAL_DISABLED && ($node->access('create') || $node->access('update')),
diff --git a/core/modules/node/src/Tests/NodeEditFormTest.php b/core/modules/node/src/Tests/NodeEditFormTest.php
index ed8b34a..6900858 100644
--- a/core/modules/node/src/Tests/NodeEditFormTest.php
+++ b/core/modules/node/src/Tests/NodeEditFormTest.php
@@ -98,7 +98,7 @@ public function testNodeEdit() {
     $edit['title[0][value]'] = $this->randomMachineName(8);
     $edit[$body_key] = $this->randomMachineName(16);
     $edit['revision'] = TRUE;
-    $this->drupalPostForm(NULL, $edit, t('Save and keep published'));
+    $this->drupalPostForm(NULL, $edit, t('Save'));
 
     // Ensure that the node revision has been created.
     $revised_node = $this->drupalGetNodeByTitle($edit['title[0][value]'], TRUE);
@@ -124,12 +124,21 @@ public function testNodeEdit() {
     $edit['created[0][value][date]'] = $this->randomMachineName(8);
     // Get the current amount of open details elements.
     $open_details_elements = count($this->cssSelect('details[open="open"]'));
-    $this->drupalPostForm(NULL, $edit, t('Save and keep published'));
+    $this->drupalPostForm(NULL, $edit, t('Save'));
     // The node author details must be open.
     $this->assertRaw('<details class="node-form-author js-form-wrapper form-wrapper" data-drupal-selector="edit-author" id="edit-author" open="open">');
     // Only one extra details element should now be open.
     $open_details_elements++;
     $this->assertEqual(count($this->cssSelect('details[open="open"]')), $open_details_elements, 'Exactly one extra open &lt;details&gt; element found.');
+
+    // Edit the same node, save it and verify it's unpublished after unchecking
+    // the 'Published' boolean_checkbox and clicking 'Save'.
+    $this->drupalGet("node/" . $node->id() . "/edit");
+    $edit = ['status[value]' => FALSE];
+    $this->drupalPostForm(NULL, $edit, t('Save'));
+    $this->nodeStorage->resetCache([$node->id()]);
+    $node = $this->nodeStorage->load($node->id());
+    $this->assertFalse($node->isPublished(), 'Node is unpublished');
   }
 
   /**
@@ -143,7 +152,7 @@ public function testNodeEditAuthoredBy() {
     $edit = [];
     $edit['title[0][value]'] = $this->randomMachineName(8);
     $edit[$body_key] = $this->randomMachineName(16);
-    $this->drupalPostForm('node/add/page', $edit, t('Save and publish'));
+    $this->drupalPostForm('node/add/page', $edit, t('Save'));
 
     // Check that the node was authored by the currently logged in user.
     $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
@@ -172,7 +181,7 @@ public function testNodeEditAuthoredBy() {
     $this->drupalLogin($this->adminUser);
 
     // Save the node without making any changes.
-    $this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save and keep published'));
+    $this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save'));
     $this->nodeStorage->resetCache([$node->id()]);
     $node = $this->nodeStorage->load($node->id());
     $this->assertIdentical($this->webUser->id(), $node->getOwner()->id());
@@ -184,7 +193,7 @@ public function testNodeEditAuthoredBy() {
 
     // Check that saving the node without making any changes keeps the proper
     // author ID.
-    $this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save and keep published'));
+    $this->drupalPostForm('node/' . $node->id() . '/edit', [], t('Save'));
     $this->nodeStorage->resetCache([$node->id()]);
     $node = $this->nodeStorage->load($node->id());
     $this->assertIdentical($this->webUser->id(), $node->getOwner()->id());
@@ -203,13 +212,13 @@ protected function checkVariousAuthoredByValues(NodeInterface $node, $form_eleme
     $edit = [
       $form_element_name => 'invalid-name',
     ];
-    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
     $this->assertRaw(t('There are no entities matching "%name".', ['%name' => 'invalid-name']));
 
     // Change the authored by field to an empty string, which should assign
     // authorship to the anonymous user (uid 0).
     $edit[$form_element_name] = '';
-    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
     $this->nodeStorage->resetCache([$node->id()]);
     $node = $this->nodeStorage->load($node->id());
     $uid = $node->getOwnerId();
@@ -228,7 +237,7 @@ protected function checkVariousAuthoredByValues(NodeInterface $node, $form_eleme
     // Change the authored by field to another user's name (that is not
     // logged in).
     $edit[$form_element_name] = $this->webUser->getUsername();
-    $this->drupalPostForm(NULL, $edit, t('Save and keep published'));
+    $this->drupalPostForm(NULL, $edit, t('Save'));
     $this->nodeStorage->resetCache([$node->id()]);
     $node = $this->nodeStorage->load($node->id());
     $this->assertIdentical($node->getOwnerId(), $this->webUser->id(), 'Node authored by normal user.');
diff --git a/core/modules/node/src/Tests/NodeFormButtonsTest.php b/core/modules/node/src/Tests/NodeFormButtonsTest.php
deleted file mode 100644
index ed2bb8f..0000000
--- a/core/modules/node/src/Tests/NodeFormButtonsTest.php
+++ /dev/null
@@ -1,135 +0,0 @@
-<?php
-
-namespace Drupal\node\Tests;
-
-/**
- * Tests all the different buttons on the node form.
- *
- * @group node
- */
-class NodeFormButtonsTest extends NodeTestBase {
-
-  use AssertButtonsTrait;
-
-  /**
-   * A normal logged in user.
-   *
-   * @var \Drupal\user\UserInterface
-   */
-  protected $webUser;
-
-  /**
-   * A user with permission to bypass access content.
-   *
-   * @var \Drupal\user\UserInterface
-   */
-  protected $adminUser;
-
-  protected function setUp() {
-    parent::setUp();
-
-    // Create a user that has no access to change the state of the node.
-    $this->webUser = $this->drupalCreateUser(['create article content', 'edit own article content']);
-    // Create a user that has access to change the state of the node.
-    $this->adminUser = $this->drupalCreateUser(['administer nodes', 'bypass node access']);
-  }
-
-  /**
-   * Tests that the right buttons are displayed for saving nodes.
-   */
-  public function testNodeFormButtons() {
-    $node_storage = $this->container->get('entity.manager')->getStorage('node');
-    // Log in as administrative user.
-    $this->drupalLogin($this->adminUser);
-
-    // Verify the buttons on a node add form.
-    $this->drupalGet('node/add/article');
-    $this->assertButtons([t('Save and publish'), t('Save as unpublished')]);
-
-    // Save the node and assert it's published after clicking
-    // 'Save and publish'.
-    $edit = ['title[0][value]' => $this->randomString()];
-    $this->drupalPostForm('node/add/article', $edit, t('Save and publish'));
-
-    // Get the node.
-    $node_1 = $node_storage->load(1);
-    $this->assertTrue($node_1->isPublished(), 'Node is published');
-
-    // Verify the buttons on a node edit form.
-    $this->drupalGet('node/' . $node_1->id() . '/edit');
-    $this->assertButtons([t('Save and keep published'), t('Save and unpublish')]);
-
-    // Save the node and verify it's still published after clicking
-    // 'Save and keep published'.
-    $this->drupalPostForm(NULL, $edit, t('Save and keep published'));
-    $node_storage->resetCache([1]);
-    $node_1 = $node_storage->load(1);
-    $this->assertTrue($node_1->isPublished(), 'Node is published');
-
-    // Save the node and verify it's unpublished after clicking
-    // 'Save and unpublish'.
-    $this->drupalPostForm('node/' . $node_1->id() . '/edit', $edit, t('Save and unpublish'));
-    $node_storage->resetCache([1]);
-    $node_1 = $node_storage->load(1);
-    $this->assertFalse($node_1->isPublished(), 'Node is unpublished');
-
-    // Verify the buttons on an unpublished node edit screen.
-    $this->drupalGet('node/' . $node_1->id() . '/edit');
-    $this->assertButtons([t('Save and keep unpublished'), t('Save and publish')]);
-
-    // Create a node as a normal user.
-    $this->drupalLogout();
-    $this->drupalLogin($this->webUser);
-
-    // Verify the buttons for a normal user.
-    $this->drupalGet('node/add/article');
-    $this->assertButtons([t('Save')], FALSE);
-
-    // Create the node.
-    $edit = ['title[0][value]' => $this->randomString()];
-    $this->drupalPostForm('node/add/article', $edit, t('Save'));
-    $node_2 = $node_storage->load(2);
-    $this->assertTrue($node_2->isPublished(), 'Node is published');
-
-    // Log in as an administrator and unpublish the node that just
-    // was created by the normal user.
-    $this->drupalLogout();
-    $this->drupalLogin($this->adminUser);
-    $this->drupalPostForm('node/' . $node_2->id() . '/edit', [], t('Save and unpublish'));
-    $node_storage->resetCache([2]);
-    $node_2 = $node_storage->load(2);
-    $this->assertFalse($node_2->isPublished(), 'Node is unpublished');
-
-    // Log in again as the normal user, save the node and verify
-    // it's still unpublished.
-    $this->drupalLogout();
-    $this->drupalLogin($this->webUser);
-    $this->drupalPostForm('node/' . $node_2->id() . '/edit', [], t('Save'));
-    $node_storage->resetCache([2]);
-    $node_2 = $node_storage->load(2);
-    $this->assertFalse($node_2->isPublished(), 'Node is still unpublished');
-    $this->drupalLogout();
-
-    // Set article content type default to unpublished. This will change the
-    // the initial order of buttons and/or status of the node when creating
-    // a node.
-    $fields = \Drupal::entityManager()->getFieldDefinitions('node', 'article');
-    $fields['status']->getConfig('article')
-      ->setDefaultValue(FALSE)
-      ->save();
-
-    // Verify the buttons on a node add form for an administrator.
-    $this->drupalLogin($this->adminUser);
-    $this->drupalGet('node/add/article');
-    $this->assertButtons([t('Save as unpublished'), t('Save and publish')]);
-
-    // Verify the node is unpublished by default for a normal user.
-    $this->drupalLogout();
-    $this->drupalLogin($this->webUser);
-    $edit = ['title[0][value]' => $this->randomString()];
-    $this->drupalPostForm('node/add/article', $edit, t('Save'));
-    $node_3 = $node_storage->load(3);
-    $this->assertFalse($node_3->isPublished(), 'Node is unpublished');
-  }
-
-}
diff --git a/core/modules/node/src/Tests/NodeTranslationUITest.php b/core/modules/node/src/Tests/NodeTranslationUITest.php
index a01c4d5..92623c7 100644
--- a/core/modules/node/src/Tests/NodeTranslationUITest.php
+++ b/core/modules/node/src/Tests/NodeTranslationUITest.php
@@ -99,7 +99,9 @@ public function testPublishedStatusNoFields() {
       'source' => $default_langcode,
       'target' => $langcode
     ], ['language' => $language]);
-    $this->drupalPostForm($add_url, $this->getEditValues($values, $langcode), t('Save and unpublish (this translation)'));
+    $edit = $this->getEditValues($values, $langcode);
+    $edit['status[value]'] = FALSE;
+    $this->drupalPostForm($add_url, $edit, t('Save (this translation)'));
 
     $storage->resetCache([$this->entityId]);
     $entity = $storage->load($this->entityId);
@@ -139,18 +141,6 @@ protected function getNewEntityValues($langcode) {
   /**
    * {@inheritdoc}
    */
-  protected function getFormSubmitAction(EntityInterface $entity, $langcode) {
-    if ($entity->getTranslation($langcode)->isPublished()) {
-      return t('Save and keep published') . $this->getFormSubmitSuffix($entity, $langcode);
-    }
-    else {
-      return t('Save and keep unpublished') . $this->getFormSubmitSuffix($entity, $langcode);
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   protected function doTestPublishedStatus() {
     $storage = $this->container->get('entity_type.manager')
       ->getStorage($this->entityTypeId);
@@ -158,18 +148,18 @@ protected function doTestPublishedStatus() {
     $entity = $storage->load($this->entityId);
     $languages = $this->container->get('language_manager')->getLanguages();
 
-    $actions = [
-      t('Save and keep published'),
-      t('Save and unpublish'),
+    $statuses = [
+      TRUE,
+      FALSE,
     ];
 
-    foreach ($actions as $index => $action) {
+    foreach ($statuses as $index => $value) {
       // (Un)publish the node translations and check that the translation
       // statuses are (un)published accordingly.
       foreach ($this->langcodes as $langcode) {
         $options = ['language' => $languages[$langcode]];
         $url = $entity->urlInfo('edit-form', $options);
-        $this->drupalPostForm($url, [], $action . $this->getFormSubmitSuffix($entity, $langcode), $options);
+        $this->drupalPostForm($url, ['status[value]' => $value], t('Save') . $this->getFormSubmitSuffix($entity, $langcode), $options);
       }
       $storage->resetCache([$this->entityId]);
       $entity = $storage->load($this->entityId);
diff --git a/core/modules/node/src/Tests/Update/NodeUpdateTest.php b/core/modules/node/src/Tests/Update/NodeUpdateTest.php
index b8b30be..0111606 100644
--- a/core/modules/node/src/Tests/Update/NodeUpdateTest.php
+++ b/core/modules/node/src/Tests/Update/NodeUpdateTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\node\Tests\Update;
 
+use Drupal\Core\Entity\Entity\EntityFormDisplay;
 use Drupal\system\Tests\Update\UpdatePathTestBase;
 
 /**
@@ -38,4 +39,29 @@ public function testPublishedEntityKey() {
     $this->assertEqual('status', $entity_type->getKey('published'));
   }
 
+  /**
+   * Tests that the node entity form has the status checkbox.
+   *
+   * @see node_update_8302()
+   */
+  public function testStatusCheckbox() {
+    // Run updates.
+    $this->runUpdates();
+
+    $query = \Drupal::entityQuery('entity_form_display')
+      ->condition('targetEntityType', 'node');
+    $ids = $query->execute();
+    $form_displays = EntityFormDisplay::loadMultiple($ids);
+
+    /**
+     * @var string $id
+     * @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display
+     */
+    foreach ($form_displays as $id => $form_display) {
+      $component = $form_display->getComponent('status');
+      $this->assertEqual('boolean_checkbox', $component['type']);
+      $this->assertEqual(['display_label' => TRUE], $component['settings']);
+    }
+  }
+
 }
diff --git a/core/modules/node/tests/src/Functional/NodeRevisionsUiBypassAccessTest.php b/core/modules/node/tests/src/Functional/NodeRevisionsUiBypassAccessTest.php
index a3a575d..186b694 100644
--- a/core/modules/node/tests/src/Functional/NodeRevisionsUiBypassAccessTest.php
+++ b/core/modules/node/tests/src/Functional/NodeRevisionsUiBypassAccessTest.php
@@ -67,7 +67,7 @@ public function testDisplayRevisionTab() {
 
     // Uncheck the create new revision checkbox and save the node.
     $edit = ['revision' => FALSE];
-    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, 'Save and keep published');
+    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, 'Save');
 
     $this->assertUrl($node->toUrl());
     $this->assertNoLink(t('Revisions'));
@@ -78,7 +78,7 @@ public function testDisplayRevisionTab() {
 
     // Submit the form without changing the checkbox.
     $edit = [];
-    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, 'Save and keep published');
+    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, 'Save');
 
     $this->assertUrl($node->toUrl());
     $this->assertLink(t('Revisions'));
diff --git a/core/modules/node/tests/src/Functional/NodeRevisionsUiTest.php b/core/modules/node/tests/src/Functional/NodeRevisionsUiTest.php
index cc364cd..a437e4a 100644
--- a/core/modules/node/tests/src/Functional/NodeRevisionsUiTest.php
+++ b/core/modules/node/tests/src/Functional/NodeRevisionsUiTest.php
@@ -55,7 +55,7 @@ public function testNodeFormSaveWithoutRevision() {
 
     // Uncheck the create new revision checkbox and save the node.
     $edit = ['revision' => FALSE];
-    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
 
     // Load the node again and check the revision is the same as before.
     $node_storage->resetCache([$node->id()]);
@@ -68,7 +68,7 @@ public function testNodeFormSaveWithoutRevision() {
 
     // Submit the form without changing the checkbox.
     $edit = [];
-    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
 
     // Load the node again and check the revision is different from before.
     $node_storage->resetCache([$node->id()]);
diff --git a/core/modules/options/tests/src/Functional/OptionsFieldUITest.php b/core/modules/options/tests/src/Functional/OptionsFieldUITest.php
index 836740d..e29a1d0 100644
--- a/core/modules/options/tests/src/Functional/OptionsFieldUITest.php
+++ b/core/modules/options/tests/src/Functional/OptionsFieldUITest.php
@@ -328,7 +328,7 @@ public function testNodeDisplay() {
     $edit = [
       $this->fieldName => '1',
     ];
-    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
 
     // Check the node page and see if the values are correct.
     $file_formatters = ['list_default', 'list_key'];
diff --git a/core/modules/search/src/Tests/SearchConfigSettingsFormTest.php b/core/modules/search/src/Tests/SearchConfigSettingsFormTest.php
index 191e0cf..cc77f2b 100644
--- a/core/modules/search/src/Tests/SearchConfigSettingsFormTest.php
+++ b/core/modules/search/src/Tests/SearchConfigSettingsFormTest.php
@@ -47,7 +47,7 @@ protected function setUp() {
     // also needs the word "pizza" so we can use it as the search keyword.
     $body_key = 'body[0][value]';
     $edit[$body_key] = \Drupal::l($node->label(), $node->urlInfo()) . ' pizza sandwich';
-    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
 
     $this->container->get('plugin.manager.search')->createInstance('node_search')->updateIndex();
     search_update_totals();
diff --git a/core/modules/system/src/Tests/Menu/BreadcrumbTest.php b/core/modules/system/src/Tests/Menu/BreadcrumbTest.php
index 64c8c15..39303ff 100644
--- a/core/modules/system/src/Tests/Menu/BreadcrumbTest.php
+++ b/core/modules/system/src/Tests/Menu/BreadcrumbTest.php
@@ -206,7 +206,7 @@ public function testBreadCrumbs() {
     $edit = [
       'menu[menu_parent]' => $link->getMenuName() . ':' . $link->getPluginId(),
     ];
-    $this->drupalPostForm('node/' . $parent->id() . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $parent->id() . '/edit', $edit, t('Save'));
     $expected = [
       "node" => $link->getTitle(),
     ];
@@ -227,7 +227,7 @@ public function testBreadCrumbs() {
     $edit = [
       'field_tags[target_id]' => implode(',', array_keys($tags)),
     ];
-    $this->drupalPostForm('node/' . $parent->id() . '/edit', $edit, t('Save and keep published'));
+    $this->drupalPostForm('node/' . $parent->id() . '/edit', $edit, t('Save'));
 
     // Put both terms into a hierarchy Drupal » Breadcrumbs. Required for both
     // the menu links and the terms itself, since taxonomy_term_page() resets
diff --git a/core/modules/system/src/Tests/Update/UpdatePathRC1TestBaseFilledTest.php b/core/modules/system/src/Tests/Update/UpdatePathRC1TestBaseFilledTest.php
index 09cc586..9ee6d0c 100644
--- a/core/modules/system/src/Tests/Update/UpdatePathRC1TestBaseFilledTest.php
+++ b/core/modules/system/src/Tests/Update/UpdatePathRC1TestBaseFilledTest.php
@@ -117,7 +117,7 @@ public function testUpdatedSite() {
     $this->assertText('Test Article - New title');
     $this->assertText('Test 1');
     $this->assertRaw('0.01');
-    $this->drupalPostForm('node/8/edit', [], 'Save and keep published (this translation)');
+    $this->drupalPostForm('node/8/edit', [], 'Save (this translation)');
     $this->assertResponse(200);
     $this->drupalGet('node/8/edit', ['language' => $spanish]);
     $this->assertText('Test title Spanish');
diff --git a/core/modules/system/src/Tests/Update/UpdatePathTestBaseFilledTest.php b/core/modules/system/src/Tests/Update/UpdatePathTestBaseFilledTest.php
index fe62340..3c5aab0 100644
--- a/core/modules/system/src/Tests/Update/UpdatePathTestBaseFilledTest.php
+++ b/core/modules/system/src/Tests/Update/UpdatePathTestBaseFilledTest.php
@@ -117,7 +117,7 @@ public function testUpdatedSite() {
     $this->assertText('Test Article - New title');
     $this->assertText('Test 1');
     $this->assertRaw('0.01');
-    $this->drupalPostForm('node/8/edit', [], 'Save and keep published (this translation)');
+    $this->drupalPostForm('node/8/edit', [], 'Save (this translation)');
     $this->assertResponse(200);
     $this->drupalGet('node/8/edit', ['language' => $spanish]);
     $this->assertText('Test title Spanish');
diff --git a/core/modules/taxonomy/tests/src/Functional/LegacyTest.php b/core/modules/taxonomy/tests/src/Functional/LegacyTest.php
index 2894715..ac8e82d 100644
--- a/core/modules/taxonomy/tests/src/Functional/LegacyTest.php
+++ b/core/modules/taxonomy/tests/src/Functional/LegacyTest.php
@@ -60,7 +60,7 @@ public function testTaxonomyLegacyNode() {
     $edit['created[0][value][time]'] = $date->format('H:i:s');
     $edit['body[0][value]'] = $this->randomMachineName();
     $edit['field_tags[target_id]'] = $this->randomMachineName();
-    $this->drupalPostForm('node/add/article', $edit, t('Save and publish'));
+    $this->drupalPostForm('node/add/article', $edit, t('Save'));
     // Checks that the node has been saved.
     $node = $this->drupalGetNodeByTitle($edit['title[0][value]']);
     $this->assertEqual($node->getCreatedTime(), $date->getTimestamp(), 'Legacy node was saved with the right date.');
diff --git a/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml b/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml
index c94e36e..9082f2d 100644
--- a/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml
+++ b/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml
@@ -66,6 +66,13 @@ content:
     weight: 15
     region: content
     third_party_settings: {  }
+  status:
+    type: boolean_checkbox
+    settings:
+      display_label: true
+    weight: 120
+    region: content
+    third_party_settings: {  }
   sticky:
     type: boolean_checkbox
     settings:
diff --git a/core/profiles/standard/config/install/core.entity_form_display.node.page.default.yml b/core/profiles/standard/config/install/core.entity_form_display.node.page.default.yml
index 0b7ffd1..682f1a5 100644
--- a/core/profiles/standard/config/install/core.entity_form_display.node.page.default.yml
+++ b/core/profiles/standard/config/install/core.entity_form_display.node.page.default.yml
@@ -40,6 +40,13 @@ content:
     weight: 15
     region: content
     third_party_settings: {  }
+  status:
+    type: boolean_checkbox
+    settings:
+      display_label: true
+    weight: 120
+    region: content
+    third_party_settings: {  }
   sticky:
     type: boolean_checkbox
     settings:
diff --git a/core/themes/seven/templates/node-edit-form.html.twig b/core/themes/seven/templates/node-edit-form.html.twig
new file mode 100644
index 0000000..a289901
--- /dev/null
+++ b/core/themes/seven/templates/node-edit-form.html.twig
@@ -0,0 +1,30 @@
+{#
+/**
+ * @file
+ * Theme override for a node edit form.
+ *
+ * Two column template for the node add/edit form.
+ *
+ * This template will be used when a node edit form specifies 'node_edit_form'
+ * as its #theme callback.  Otherwise, by default, node add/edit forms will be
+ * themed by form.html.twig.
+ *
+ * Available variables:
+ * - form: The node add/edit form.
+ *
+ * @see seven_form_node_form_alter()
+ */
+#}
+<div class="layout-node-form clearfix">
+    <div class="layout-region layout-region-node-main">
+        {{ form|without('advanced', 'footer', 'actions') }}
+    </div>
+    <div class="layout-region layout-region-node-secondary">
+        {{ form.advanced }}
+    </div>
+    <div class="layout-region layout-region-node-footer">
+        <hr/>
+        {{ form.footer }}
+        {{ form.actions }}
+    </div>
+</div>
