diff --git a/modules/authcache_ajax/authcache_ajax.module b/modules/authcache_ajax/authcache_ajax.module
index 8869e81..fb61538 100644
--- a/modules/authcache_ajax/authcache_ajax.module
+++ b/modules/authcache_ajax/authcache_ajax.module
@@ -5,9 +5,9 @@
  */
 
 /**
- * Implements hook_authcache_enum_key_properties().
+ * Implements hook_authcache_enum_key_property_info().
  */
-function authcache_ajax_authcache_enum_key_properties() {
+function authcache_ajax_authcache_enum_key_property_info() {
   return array(
     'ajax' => array(
       'name' => t('Browser is capable of issuing Ajax requests'),
diff --git a/modules/authcache_enum/authcache_enum.api.php b/modules/authcache_enum/authcache_enum.api.php
index 12a898d..cda52eb 100644
--- a/modules/authcache_enum/authcache_enum.api.php
+++ b/modules/authcache_enum/authcache_enum.api.php
@@ -25,14 +25,28 @@ function hook_authcache_enum_anonymous_keys_alter(&$keys) {
 /**
  * Return information about key properties.
  *
+ * This hook is kept for backwards compatibility reasons, but will be removed
+ * in the future. Use hook_authcache_enum_key_property_info() instead.
+ *
+ * @deprecated
+ * @see hook_authcache_enum_key_property_info()
+ */
+function hook_authcache_enum_key_properties() {
+}
+
+/**
+ * Return information about key properties.
+ *
  * @return array
  *   An associative array of key-value pairs. Where keys are the names of
  *   key properties and values are associative arrays of the following
  *   structure:
  *   - name: The translated human readable property name
  *   - choices: An array of all possible values for this property
+ *
+ * @see hook_authcache_enum_key_property_info_alter()
  */
-function hook_authcache_enum_key_properties() {
+function hook_authcache_enum_key_property_info() {
   return array(
     'js' => array(
       'name' => t('Browser supports JavaScript'),
@@ -42,11 +56,19 @@ function hook_authcache_enum_key_properties() {
 }
 
 /**
- * Modify available keys and property info records.
+ * Modify the key properties used for authcache key enumeration.
+ *
+ * @see hook_authcache_enum_key_property_info().
+ */
+function hook_authcache_enum_key_property_info_alter(&$property_info) {
+}
+
+/**
+ * Modify available keys and property records.
  *
- * @param array &$properties_info
+ * @param array &$properties
  *   An associative array where keys correspond to authcache keys and values
  *   represent the property record the key is derived from.
  */
-function hook_authcache_enum_key_properties_alter(&$properties_info) {
+function hook_authcache_enum_key_properties_alter(&$properties) {
 }
diff --git a/modules/authcache_enum/authcache_enum.module b/modules/authcache_enum/authcache_enum.module
index 443f15d..7062c16 100644
--- a/modules/authcache_enum/authcache_enum.module
+++ b/modules/authcache_enum/authcache_enum.module
@@ -12,7 +12,7 @@
  * values represent the property record the key is derived from.
  *
  * A nested structure containing information about key properties is
- * returned by implementations of hook_authcache_enum_key_properties:
+ * returned by implementations of hook_authcache_enum_key_property_info:
  *
  * @code
  * $properties_info = array(
@@ -82,7 +82,12 @@ function authcache_enum_user_keys() {
   $info = &drupal_static(__FUNCTION__);
 
   if (!isset($info)) {
-    $properties_info = module_invoke_all('authcache_enum_key_properties');
+    $properties_info = module_invoke_all('authcache_enum_key_property_info');
+
+    // Invoke hook_authcache_enum_key_properties() for backwards compatibility.
+    $properties_info += module_invoke_all('authcache_enum_key_properties');
+
+    drupal_alter('authcache_enum_key_property_info', $properties_info);
 
     $sets = array();
     foreach ($properties_info as $key => $definition) {
@@ -179,9 +184,9 @@ function authcache_enum_authcache_enum_anonymous_keys() {
 }
 
 /**
- * Implements hook_authcache_enum_key_properties().
+ * Implements hook_authcache_enum_key_property_info().
  */
-function authcache_enum_authcache_enum_key_properties() {
+function authcache_enum_authcache_enum_key_property_info() {
   global $base_root;
 
   $func = variable_get('authcache_enum_role_combine', '_authcache_enum_default_role_combine');
diff --git a/modules/authcache_enum/lib/Drupal/authcache_enum/Tests/AuthcacheEnumKeysTestCase.php b/modules/authcache_enum/lib/Drupal/authcache_enum/Tests/AuthcacheEnumKeysTestCase.php
index d822c7e..22c2634 100644
--- a/modules/authcache_enum/lib/Drupal/authcache_enum/Tests/AuthcacheEnumKeysTestCase.php
+++ b/modules/authcache_enum/lib/Drupal/authcache_enum/Tests/AuthcacheEnumKeysTestCase.php
@@ -150,6 +150,103 @@ class AuthcacheEnumKeysTestCase extends \DrupalWebTestCase {
       $rid2 => $rid2,
     ));
 
+    // Data for hook_authcache_enum_key_property_info().
+    $custom_property_info = array(
+      'js' => array(
+        'name' => t('Browser supports JavaScript'),
+        'choices' => array(TRUE, FALSE),
+      ),
+    );
+
+    // Data for hook_authcache_enum_key_property_info_alter().
+    // Remove roles and customize choices on base_root property.
+    $base_roots = array(
+      'http://www.' . $this->randomName(6) . '.com',
+      'http://www.' . $this->randomName(7) . '.com',
+    );
+    $property_info_alter = array(
+      'delete' => array(
+        'roles' => TRUE,
+      ),
+      'insert' => array(
+        'base_root' => array(
+          'name' => t('The root URL of the host, excluding the path'),
+          'choices' => $base_roots,
+        ),
+      ),
+    );
+
+    $expect_properties = array(
+      array(
+        'base_root' => $base_roots[0],
+        'js' => FALSE,
+      ),
+      array(
+        'base_root' => $base_roots[0],
+        'js' => TRUE,
+      ),
+      array(
+        'base_root' => $base_roots[1],
+        'js' => FALSE,
+      ),
+      array(
+        'base_root' => $base_roots[1],
+        'js' => TRUE,
+      ),
+    );
+
+    $user_keys = array_map('authcache_user_key', $expect_properties);
+    $expect_alter = array_combine($user_keys, $expect_properties);
+    ksort($expect_alter);
+
+    $expect_keys = $user_keys;
+    $expect_keys[] = $base_root;
+
+    $infostub = $this->stubmod->hook('authcache_enum_key_property_info', $custom_property_info);
+    $infoalterstub = $this->stubmod->hook('authcache_enum_key_property_info_alter', $property_info_alter);
+    $keyalterstub = $this->stubmod->hook('authcache_enum_key_properties_alter');
+
+    $result = authcache_enum_keys();
+
+    $this->assertStub($infostub, \HookStub::once());
+
+    $default_property_info = authcache_enum_authcache_enum_key_property_info();
+    $this->assertStub($infoalterstub, \HookStub::once());
+    $this->assertStub($infoalterstub, \HookStub::args(array(
+      $default_property_info + $custom_property_info,
+      NULL,
+      NULL,
+      NULL,
+    )));
+
+    $this->assertStub($keyalterstub, \HookStub::once());
+    $this->assertStub($keyalterstub, \HookStub::args(array(
+      $expect_alter,
+      NULL,
+      NULL,
+      NULL,
+    )));
+
+    sort($result);
+    sort($expect_keys);
+    $this->assertEqual($expect_keys, $result);
+  }
+
+  /**
+   * Test deprecated authenticated key customization.
+   */
+  public function testDeprecatedCustomAuthenticatedKeys() {
+    global $base_root;
+
+    $rid1 = (int) $this->drupalCreateRole(array());
+    $rid2 = (int) $this->drupalCreateRole(array());
+    variable_set('authcache_roles', array(
+      DRUPAL_ANONYMOUS_RID => DRUPAL_ANONYMOUS_RID,
+      DRUPAL_AUTHENTICATED_RID => DRUPAL_AUTHENTICATED_RID,
+      $rid1 => $rid1,
+      $rid2 => $rid2,
+    ));
+
     $property_info = array(
       'js' => array(
         'name' => t('Browser supports JavaScript'),
diff --git a/modules/authcache_enum/tests/authcache_enum_test.module b/modules/authcache_enum/tests/authcache_enum_test.module
index 4d26b68..d8ddd92 100644
--- a/modules/authcache_enum/tests/authcache_enum_test.module
+++ b/modules/authcache_enum/tests/authcache_enum_test.module
@@ -33,7 +33,24 @@ function authcache_enum_test_authcache_enum_key_properties() {
 /**
  * Implements hook_authcache_enum_key_properties_alter()
  */
-function authcache_enum_test_authcache_enum_key_properties_alter(&$properties_info) {
-  ksort($properties_info);
+function authcache_enum_test_authcache_enum_key_properties_alter(&$properties) {
+  ksort($properties);
   return HookStub::record(__FUNCTION__, func_get_args());
 }
+
+/**
+ * Implements hook_authcache_enum_key_property_info()
+ */
+function authcache_enum_test_authcache_enum_key_property_info() {
+  return HookStub::record(__FUNCTION__, func_get_args());
+}
+
+/**
+ * Implements hook_authcache_enum_key_property_info_alter()
+ */
+function authcache_enum_test_authcache_enum_key_property_info_alter(&$property_info) {
+  if (($alter = HookStub::record(__FUNCTION__, func_get_args()))) {
+    $property_info = array_diff_key($property_info, $alter['delete']);
+    $property_info = $alter['insert'] + $property_info;
+  }
+}
diff --git a/modules/authcache_esi/authcache_esi.module b/modules/authcache_esi/authcache_esi.module
index d3851e0..68f88e8 100644
--- a/modules/authcache_esi/authcache_esi.module
+++ b/modules/authcache_esi/authcache_esi.module
@@ -5,9 +5,9 @@
  */
 
 /**
- * Implements hook_authcache_enum_key_properties().
+ * Implements hook_authcache_enum_key_property_info().
  */
-function authcache_esi_authcache_enum_key_properties() {
+function authcache_esi_authcache_enum_key_property_info() {
   return array(
     'esi' => array(
       'name' => t('Request issued by ESI enabled reverse proxy'),
