diff --git a/core/lib/Drupal/Core/Entity/EntityAccessController.php b/core/lib/Drupal/Core/Entity/EntityAccessController.php
index f20ef9c..8fb13b0 100644
--- a/core/lib/Drupal/Core/Entity/EntityAccessController.php
+++ b/core/lib/Drupal/Core/Entity/EntityAccessController.php
@@ -286,6 +286,12 @@ public function fieldAccess($operation, FieldDefinitionInterface $field_definiti
     // Get the default access restriction that lives within this field.
     $default = $items ? $items->defaultAccess($operation, $account) : TRUE;
 
+    // Get the default access restriction as specified by the access controller.
+    $entity_default = $this->checkFieldAccess($operation, $field_definition, $account, $items);
+
+    // Combine default access, denying access wins.
+    $default = $default && $entity_default;
+
     // Invoke hook and collect grants/denies for field access from other
     // modules. Our default access flag is masked under the ':default' key.
     $grants = array(':default' => $default);
@@ -315,4 +321,26 @@ public function fieldAccess($operation, FieldDefinitionInterface $field_definiti
     return FALSE;
   }
 
+  /**
+   * Default field access as determined by this access controller.
+   *
+   * @param string $operation
+   *   The operation access should be checked for.
+   *   Usually one of "view" or "edit".
+   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
+   *   The field definition.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The user session for which to check access.
+   * @param \Drupal\Core\Field\FieldItemListInterface $items
+   *   (optional) The field values for which to check access, or NULL if access
+   *   is checked for the field definition, without any specific value
+   *   available. Defaults to NULL.
+   *
+   * @return bool
+   *   TRUE if access is allowed, FALSE otherwise.
+   */
+  protected function checkFieldAccess($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
+    return TRUE;
+  }
+
 }
diff --git a/core/modules/node/src/NodeAccessController.php b/core/modules/node/src/NodeAccessController.php
index ab38a26..420f22b 100644
--- a/core/modules/node/src/NodeAccessController.php
+++ b/core/modules/node/src/NodeAccessController.php
@@ -11,6 +11,8 @@
 use Drupal\Core\Database\Query\SelectInterface;
 use Drupal\Core\Entity\EntityControllerInterface;
 use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Entity\EntityAccessController;
 use Drupal\Core\Entity\EntityInterface;
@@ -131,6 +133,21 @@ protected function checkCreateAccess(AccountInterface $account, array $context,
   /**
    * {@inheritdoc}
    */
+  protected function checkFieldAccess($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
+    $administrative_fields = array('uid', 'status', 'created', 'promote', 'sticky', 'revision_log');
+    $read_only_fields = array('changed', 'revision_timestamp', 'revision_uid');
+    if ($operation == 'edit' && in_array($field_definition->getName(), $administrative_fields)) {
+      return $account->hasPermission('administer nodes');
+    }
+    if ($operation == 'edit' && in_array($field_definition->getName(), $read_only_fields)) {
+      return FALSE;
+    }
+    return parent::checkFieldAccess($operation, $field_definition, $account, $items);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function acquireGrants(NodeInterface $node) {
     $grants = $this->moduleHandler->invokeAll('node_access_records', array($node));
     // Let modules alter the grants.
diff --git a/core/modules/node/src/NodeAdministrativeField.php b/core/modules/node/src/NodeAdministrativeField.php
new file mode 100644
index 0000000..1067396
--- /dev/null
+++ b/core/modules/node/src/NodeAdministrativeField.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * @file
+ * Contains \Drupal\node\NodeAdministrativeField.
+ */
+
+
+namespace Drupal\node;
+
+use Drupal\Core\Field\FieldItemList;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\node\Entity\Node;
+
+
+/**
+ * Status field of node.
+ */
+class NodeAdministrativeField extends FieldItemList {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultAccess($operation = 'view', AccountInterface $account = NULL) {
+
+    if (!isset($account)) {
+      $account = \Drupal::currentUser();
+    }
+
+    if ($operation == 'view') {
+      // If access to the node itself is granted the fields value may be viewed.
+      return TRUE;
+    }
+    // Edit operation: only grant access to administrative users.
+    if ($account->hasPermission('bypass node access') || $account->hasPermission('administer nodes')) {
+      return TRUE;
+    }
+    return FALSE;
+  }
+}
diff --git a/core/modules/node/src/Tests/NodeFieldAccessTest.php b/core/modules/node/src/Tests/NodeFieldAccessTest.php
new file mode 100644
index 0000000..3797747
--- /dev/null
+++ b/core/modules/node/src/Tests/NodeFieldAccessTest.php
@@ -0,0 +1,134 @@
+<?php
+/**
+ * @file
+ * Contains \Drupal\node\Tests\NodeFieldAccessTest.
+ */
+
+namespace Drupal\node\Tests;
+
+use Drupal\Component\Utility\String;
+use Drupal\Core\Annotation\Action;
+use Drupal\node\Entity\Node;
+use Drupal\system\Tests\Entity\EntityUnitTestBase;
+
+/**
+ * Tests node field level access.
+ *
+ * @group node
+ */
+class NodeFieldAccessTest extends EntityUnitTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('node');
+
+  /**
+   * Fields that only users with administer nodes permissions can change.
+   *
+   * @var array
+   */
+  protected $administrativeFields = array(
+    'status',
+    'promote',
+    'sticky',
+    'created',
+    'uid',
+    'revision_log',
+  );
+
+  /**
+   * These fields are automatically managed and can not be changed by any user.
+   *
+   * @var array
+   */
+  protected $readOnlyFields = array('changed', 'revision_uid', 'revision_timestamp');
+
+  /**
+   * Test permissions on nodes status field.
+   */
+  function testAccessToAdministrativeFields() {
+
+    // A all mighty user.
+    $chuck_norris = $this->createUser(array(), array('bypass node access'));
+
+    // An administrator user.
+    $content_admin_user = $this->createUser(array(), array('administer nodes'));
+
+    // Two different editor users.
+    $page_creator_user = $this->createUser(array(), array('create page content', 'edit own page content', 'delete own page content'));
+    $page_manager_user = $this->createUser(array(), array('create page content', 'edit any page content', 'delete any page content'));
+
+    // An unprivileged user.
+    $page_unrelated_user = $this->createUser(array(), array('access content'));
+
+    // List of all users
+    $test_users = array(
+      $chuck_norris,
+      $content_admin_user,
+      $page_creator_user,
+      $page_manager_user,
+      $page_unrelated_user,
+    );
+
+    // Create three "Basic pages". One is owned by our test-user
+    // "page_creator", one by "page_manager", and one by someone else.
+    $node1 = Node::create(array(
+      'title' => $this->randomName(8),
+      'uid' => $page_creator_user->id(),
+      'type' => 'page',
+    ));
+    $node2 = Node::create(array(
+      'title' => $this->randomName(8),
+      'uid' => $page_manager_user->id(),
+      'type' => 'page',
+    ));
+    $node3 = Node::create(array(
+      'title' => $this->randomName(8),
+      'uid' => $chuck_norris->id(),
+      'type' => 'page',
+    ));
+
+    foreach ($this->administrativeFields as $field) {
+
+      // Checks on view operations.
+      foreach ($test_users as $account) {
+        $may_view = $node1->{$field}->access('view', $account);
+        $this->assertTrue($may_view, String::format('Any user may view the field @name.', array('@name' => $field)));
+      }
+
+      // Checks on edit operations.
+      $may_update = $node1->{$field}->access('edit', $page_creator_user);
+      $this->assertFalse($may_update, String::format('Users with permission "edit own page content" is not allowed to the field @name.', array('@name' => $field)));
+      $may_update = $node2->{$field}->access('edit', $page_creator_user);
+      $this->assertFalse($may_update, String::format('Users with permission "edit own page content" is not allowed to the field @name.', array('@name' => $field)));
+      $may_update = $node2->{$field}->access('edit', $page_manager_user);
+      $this->assertFalse($may_update, String::format('Users with permission "edit any page content" is not allowed to the field @name.', array('@name' => $field)));
+      $may_update = $node1->{$field}->access('edit', $page_manager_user);
+      $this->assertFalse($may_update, String::format('Users with permission "edit any page content" is not allowed to the field @name.', array('@name' => $field)));
+      $may_update = $node2->{$field}->access('edit', $page_unrelated_user);
+      $this->assertFalse($may_update, String::format('Users not having permission "edit any page content" is not allowed to the field @name.', array('@name' => $field)));
+      $may_update = $node1->{$field}->access('edit', $chuck_norris) && $node3->status->access('edit', $chuck_norris);
+      $this->assertTrue($may_update, String::format('Users with permission "bypass node access" may edit @name fields on all nodes.', array('@name' => $field)));
+      $may_update = $node1->{$field}->access('edit', $content_admin_user) && $node3->status->access('edit', $content_admin_user);
+      $this->assertTrue($may_update, String::format('Users with permission "administer nodes" may edit @name fields on all nodes.', array('@name' => $field)));
+    }
+
+    foreach ($this->readOnlyFields as $field) {
+      // Check view operation.
+      foreach ($test_users as $account) {
+        $may_view = $node1->{$field}->access('view', $account);
+        $this->assertTrue($may_view, String::format('Any user may view the field @name.', array('@name' => $field)));
+      }
+
+      // Check edit operation.
+      foreach ($test_users as $account) {
+        $may_view = $node1->{$field}->access('edit', $account);
+        $this->assertFalse($may_view, String::format('No user is not allowed to edit the field @name.', array('@name' => $field)));
+      }
+    }
+  }
+
+}
