diff --git a/core/modules/user/lib/Drupal/user/Tests/UserAccessAlterTest.php b/core/modules/user/lib/Drupal/user/Tests/UserAccessAlterTest.php
new file mode 100644
index 0000000..d897ff5
--- /dev/null
+++ b/core/modules/user/lib/Drupal/user/Tests/UserAccessAlterTest.php
@@ -0,0 +1,54 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\user\Tests\UserAccessAlterTest.
+ */
+
+namespace Drupal\user\Tests;
+
+use Drupal\simpletest\WebTestBase;
+
+class UserAccessAlterTest extends WebTestBase {
+  protected $web_user;
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('user_access_alter_test');
+
+  public static function getInfo() {
+    return array(
+      'name' => 'User access alter',
+      'description' => 'Verify that user access can be altered via code.',
+      'group' => 'User'
+    );
+  }
+
+  function setUp() {
+    parent::setUp();
+    variable_set('date_default_timezone', 'America/Los_Angeles');
+    module_enable(array('user_access_alter_test'));
+    $this->web_user = $this->drupalCreateUser();
+  }
+
+  /**
+   * Change user permissions and check user_access().
+   */
+  function testUserAccessChanges() {
+    // Unaltered permission.
+    $this->drupalLogin($this->web_user);
+    $account = $this->web_user;
+    $this->assertFalse(user_access('user lives in santiago', $account), 'User does not have altered permission.');
+
+    $this->web_user->timezone = 'America/Santiago';
+    $this->web_user->save();
+    drupal_static_reset('user_access');
+    $account = $this->web_user;
+
+    // Altered permission.
+    $this->assertTrue(user_access('user lives in santiago', $account), 'User has an altered permission.');
+  }
+}
diff --git a/core/modules/user/tests/user_access_alter_test/user_access_alter_test.info b/core/modules/user/tests/user_access_alter_test/user_access_alter_test.info
new file mode 100644
index 0000000..aae9b63
--- /dev/null
+++ b/core/modules/user/tests/user_access_alter_test/user_access_alter_test.info
@@ -0,0 +1,6 @@
+name = "User access alter tests"
+description = "Support module for user access alter testing."
+package = Testing
+version = VERSION
+core = 8.x
+hidden = TRUE
diff --git a/core/modules/user/tests/user_access_alter_test/user_access_alter_test.module b/core/modules/user/tests/user_access_alter_test/user_access_alter_test.module
new file mode 100644
index 0000000..a573b77
--- /dev/null
+++ b/core/modules/user/tests/user_access_alter_test/user_access_alter_test.module
@@ -0,0 +1,18 @@
+<?php
+
+/**
+ * @file
+ * Module to help test hook_user_access_alter().
+ */
+
+/**
+ * Implements user_access_alter().
+ *
+ * Adds a permission 'user lives in santiago'.
+ */
+function user_access_alter_test_user_access_alter(array &$permissions, $account) {
+  // Add permission if a user has the America/Santiago timezone.
+  if (isset($account->timezone) && $account->timezone == 'America/Santiago') {
+    $permissions['user lives in santiago'] = TRUE;
+  }
+}
diff --git a/core/modules/user/tests/user_form_test.info b/core/modules/user/tests/user_form_test/user_form_test.info
similarity index 100%
rename from core/modules/user/tests/user_form_test.info
rename to core/modules/user/tests/user_form_test/user_form_test.info
diff --git a/core/modules/user/tests/user_form_test.module b/core/modules/user/tests/user_form_test/user_form_test.module
similarity index 100%
rename from core/modules/user/tests/user_form_test.module
rename to core/modules/user/tests/user_form_test/user_form_test.module
diff --git a/core/modules/user/user.api.php b/core/modules/user/user.api.php
index 648cc0f..c6926aa 100644
--- a/core/modules/user/user.api.php
+++ b/core/modules/user/user.api.php
@@ -195,6 +195,29 @@ function hook_user_format_name_alter(&$name, $account) {
 }
 
 /**
+ * Alter user_access() for a user.
+ *
+ * Called by user_access() to allow modules to alter user_access() permissions.
+ * Can be used to modify existing user access or create alternative or additional
+ * user access schemes. This hook is only invoked once per user as a result of
+ * user_access() being cached.
+ *
+ * @param array $permissions
+ *   An associative array of permissions user_access() validates as true.
+ *
+ * @param object $account
+ *   The account object to which user access permissions apply.
+ *
+ * @see user_access()
+ */
+function hook_user_access_alter(array &$permissions, $account) {
+  // Add a permission if a user has the America/Santiago timezone.
+  if (isset($account->timezone) && $account->timezone == 'America/Santiago') {
+    $permissions['user lives in santiago'] = TRUE;
+  }
+}
+
+/**
  * Add mass user operations.
  *
  * This hook enables modules to inject custom operations into the mass operations
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 68b45ea..321cefb 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -466,6 +466,7 @@ function user_access($string, $account = NULL) {
     foreach ($role_permissions as $one_role) {
       $perms += $one_role;
     }
+    drupal_alter('user_access', $perms, $account);
     $perm[$account->uid] = $perms;
   }
 
