diff --git a/core/includes/config.inc b/core/includes/config.inc
index b4a0666..5935b3c 100644
--- a/core/includes/config.inc
+++ b/core/includes/config.inc
@@ -100,7 +100,7 @@ function config($name) {
 }
 
 /**
- * Returns a list of differences between configuration storages.
+ * Returns config sync actions using the contents of the source storage.
  *
  * @param Drupal\Core\Config\StorageInterface $source_storage
  *   The storage to synchronize configuration from.
@@ -108,8 +108,8 @@ function config($name) {
  *   The storage to synchronize configuration to.
  *
  * @return array|bool
- *   An assocative array containing the differences between source and target
- *   storage, or FALSE if there are no differences.
+ *   An associative array containing config sync actions to import the config
+ *   from source storage to the target storage, or FALSE if there are none.
  */
 function config_sync_get_changes(StorageInterface $source_storage, StorageInterface $target_storage) {
   // Config entities maintain 'manifest' files that list the objects they
@@ -163,6 +163,51 @@ function config_sync_get_changes(StorageInterface $source_storage, StorageInterf
 }
 
 /**
+ * Returns a list of differences between configuration storages.
+ *
+ * @param Drupal\Core\Config\StorageInterface $source_storage
+ *   The storage to synchronize configuration from.
+ * @param Drupal\Core\Config\StorageInterface $target_storage
+ *   The storage to synchronize configuration to.
+ *
+ * @return array|bool
+ *   An assocative array containing the differences between source and target
+ *   storage, or FALSE if there are no differences.
+ */
+function config_compare_storage_contents(StorageInterface $source_storage, StorageInterface $target_storage) {
+  // Config entities maintain 'manifest' files that list the objects they
+  // are currently handling. Each file is a simple indexed array of config
+  // object names. In order to generate a list of objects that have been
+  // created or deleted we need to open these files in both the source and
+  // target storage, generate an array of the objects, and compare them.
+  $active_config = $source_storage->listAll();
+  $target_config = $target_storage->listAll();
+
+
+  $config_changes = array(
+    'create' => array_diff($target_config, $active_config),
+    'change' => array(),
+    'delete' => array_diff($active_config, $target_config),
+  );
+
+
+  foreach (array_intersect($active_config, $target_config) as $name) {
+    $source_config_data = $source_storage->read($name);
+    $target_config_data = $target_storage->read($name);
+    if ($source_config_data !== $target_config_data) {
+      $config_changes['change'][] = $name;
+    }
+  }
+
+  // Do not trigger subsequent synchronization operations if there are no
+  // changes in any category.
+  if (empty($config_changes['create']) && empty($config_changes['change']) && empty($config_changes['delete'])) {
+    return FALSE;
+  }
+  return $config_changes;
+}
+
+/**
  * Writes an array of config file changes from a source storage to a target storage.
  *
  * @param array $config_changes
@@ -200,6 +245,7 @@ function config_sync_changes(array $config_changes, StorageInterface $source_sto
 function config_import() {
   // Retrieve a list of differences between staging and the active configuration.
   $source_storage = drupal_container()->get('config.storage.staging');
+  $snapshot_storage = drupal_container()->get('config.storage.snapshot');
   $target_storage = drupal_container()->get('config.storage');
 
   $config_changes = config_sync_get_changes($source_storage, $target_storage);
@@ -220,6 +266,7 @@ function config_import() {
   try {
     $remaining_changes = config_import_invoke_owner($config_changes, $source_storage, $target_storage);
     config_sync_changes($remaining_changes, $source_storage, $target_storage);
+    config_import_create_snapshot($target_storage, $snapshot_storage);
   }
   catch (ConfigException $e) {
     watchdog_exception('config_import', $e);
@@ -231,6 +278,21 @@ function config_import() {
 }
 
 /**
+ * Creates a configuration snapshot following a successful import.
+ *
+ * @param Drupal\Core\Config\StorageInterface $source_storage
+ *   The storage to synchronize configuration from.
+ * @param Drupal\Core\Config\StorageInterface $target_storage
+ *   The storage to synchronize configuration to.
+ */
+function config_import_create_snapshot(StorageInterface $source_storage, StorageInterface $snapshot_storage) {
+  $snapshot_storage->deleteAll();
+  foreach ($source_storage->listAll() as $name) {
+    $snapshot_storage->write($name, $source_storage->read($name));
+  }
+}
+
+/**
  * Invokes MODULE_config_import() callbacks for configuration changes.
  *
  * @param array $config_changes
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index ec5ec0e..81c11a9 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -1839,6 +1839,11 @@ function install_finished(&$install_state) {
   // Will also trigger indexing of profile-supplied content or feeds.
   drupal_cron_run();
 
+  // Save a snapshot of the intially installed configuration.
+  $active = drupal_container()->get('config.storage');
+  $snapshot = drupal_container()->get('config.storage.snapshot');
+  config_import_create_snapshot($active, $snapshot);
+
   return $output;
 }
 
diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php
index 035f282..0711b37 100644
--- a/core/lib/Drupal/Core/CoreBundle.php
+++ b/core/lib/Drupal/Core/CoreBundle.php
@@ -61,6 +61,12 @@ public function build(ContainerBuilder $container) {
       ->register('config.storage.staging', 'Drupal\Core\Config\FileStorage')
       ->addArgument(config_get_config_directory(CONFIG_STAGING_DIRECTORY));
 
+    // Register import snapshot configuration storage.
+    $container
+      ->register('config.storage.snapshot', 'Drupal\Core\Config\DatabaseStorage')
+      ->addArgument(new Reference('database'))
+      ->addArgument('config_snapshot');
+
     // Register the typed configuration data manager.
     $container->register('config.typed', 'Drupal\Core\Config\TypedConfigManager')
       ->addArgument(new Reference('config.storage'));
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigImportTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigImportTest.php
index 1c39242..1aa1e91 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigImportTest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigImportTest.php
@@ -19,7 +19,7 @@ class ConfigImportTest extends DrupalUnitTestBase {
    *
    * @var array
    */
-  public static $modules = array('config_test');
+  public static $modules = array('config_test', 'system');
 
   public static function getInfo() {
     return array(
@@ -32,6 +32,8 @@ public static function getInfo() {
   function setUp() {
     parent::setUp();
 
+    $this->installSchema('system', 'config_snapshot');
+
     config_install_default_config('module', 'config_test');
     // Installing config_test's default configuration pollutes the global
     // variable being used for recording hook invocations by this test already,
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigSnapshotTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigSnapshotTest.php
new file mode 100644
index 0000000..272ddfd
--- /dev/null
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigSnapshotTest.php
@@ -0,0 +1,86 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\config\Tests\ConfigSnapshotTest.
+ */
+
+namespace Drupal\config\Tests;
+
+use Drupal\simpletest\DrupalUnitTestBase;
+
+/**
+ * Tests config snapshot creation and updating.
+ */
+class ConfigSnapshotTest extends DrupalUnitTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('config_test', 'system');
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Snapshot functionality',
+      'description' => 'Config snapshot creation and updating.',
+      'group' => 'Configuration',
+    );
+  }
+
+  public function setUp() {
+    parent::setUp();
+    $this->installSchema('system', 'config_snapshot');
+  }
+
+  /**
+   * Tests config snapshot creation and updating.
+   */
+  function testSnapshot() {
+    $active = $this->container->get('config.storage');
+    $staging = $this->container->get('config.storage.staging');
+    $snapshot = $this->container->get('config.storage.snapshot');
+    $config_name = 'config_test.system';
+    $config_key = 'foo';
+    $new_data = 'foobar';
+
+    // Verify that we have an initial snapshot that matches the active
+    // configuration. This has to be true as no config should be installed.
+    $this->assertFalse(config_sync_get_changes($snapshot, $active));
+
+    // Install the default config.
+    config_install_default_config('module', 'config_test');
+    // Although we have imported config this has not affected the snapshot.
+    $this->assertTrue(config_compare_storage_contents($snapshot, $active));
+
+    // Update the config snapshot.
+    config_import_create_snapshot($active, $snapshot);
+
+    // The snapshot and active config should now contain the same config
+    // objects.
+    $this->assertFalse(config_compare_storage_contents($snapshot, $active));
+
+    // Change a configuration value in staging.
+    $staging_data = config($config_name)->get();
+    $staging_data[$config_key] = $new_data;
+    $staging->write($config_name, $staging_data);
+
+    // Verify that active and snapshot match, and that staging doesn't match
+    // either of them.
+    $this->assertFalse(config_compare_storage_contents($snapshot, $active));
+    $this->assertTrue(config_compare_storage_contents($snapshot, $staging));
+    $this->assertTrue(config_compare_storage_contents($staging, $active));
+
+    // Import changed data from staging to active.
+    config_import();
+
+    // Verify changed config was properly imported.
+    $this->assertIdentical(config($config_name)->get($config_key), $new_data);
+
+    // Verify that a new snapshot was created which and that it matches
+    // the active config.
+    $this->assertFalse(config_compare_storage_contents($snapshot, $active));
+  }
+
+}
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index cfc9a4e..7f621d4 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -1205,6 +1205,26 @@ function system_schema() {
     ),
   );
 
+  $schema['config_snapshot'] = array(
+    'description' => 'Stores a snapshot of the last imported configuration.',
+    'fields' => array(
+      'name' => array(
+        'description' => 'The identifier for the config object (the name of the file, minus the file extension).',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'data' => array(
+        'description' => 'The raw data for this configuration object.',
+        'type' => 'blob',
+        'not null' => TRUE,
+        'size' => 'big',
+      ),
+    ),
+    'primary key' => array('name'),
+  );
+
   return $schema;
 }
 
@@ -2095,6 +2115,33 @@ function system_update_8048() {
 }
 
 /**
+ * Create the 'config_snapshot' table.
+ */
+function system_update_8049() {
+  $table = array(
+    'description' => 'Stores a snapshot of the last imported configuration.',
+    'fields' => array(
+      'name' => array(
+        'description' => 'The identifier for the config object (the name of the file, minus the file extension).',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'data' => array(
+        'description' => 'The raw data for this configuration object.',
+        'type' => 'blob',
+        'not null' => TRUE,
+        'size' => 'big',
+      ),
+    ),
+    'primary key' => array('name'),
+  );
+
+  db_create_table('config_snapshot', $table);
+}
+
+/**
  * @} End of "defgroup updates-7.x-to-8.x".
  * The next series of updates should start at 9000.
  */
