diff --git includes/VersioncontrolRepository.php includes/VersioncontrolRepository.php
index 517fa63..18c1b8d 100644
--- includes/VersioncontrolRepository.php
+++ includes/VersioncontrolRepository.php
@@ -99,6 +99,7 @@ abstract class VersioncontrolRepository implements VersioncontrolEntityInterface
    * The current plugin types(array keys) are:
    * - author_mapper
    * - committer_mapper
+   * - auth_handler
    *
    * @var array
    */
@@ -476,6 +477,19 @@ abstract class VersioncontrolRepository implements VersioncontrolEntityInterface
     return new $class_name();
   }
 
+  public function getAuthHandler() {
+    if (!isset($this->pluginInstances['auth_handler'])) {
+      // If no plugin is set, use the free-for-all plugin
+      if (empty($this->plugins['auth_handler'])) {
+        // FIXME temporarily writing to a db-recorded field like this is very hacky
+        $this->plugins['auth_handler'] = 'ffa';
+      }
+      $this->pluginInstances['auth_handler'] = $this->getPluginClass('auth_handler', 'vcs_auth', 'handler');
+      $this->pluginInstances['auth_handler']->setRepository($this);
+    }
+    return $this->pluginInstances['auth_handler'];
+  }
+
   public function getAuthorMapper() {
     if (!isset($this->pluginInstances['author_mapper'])) {
       // if no plugin is set, just directly register FALSE for the instance
diff --git includes/interfaces.inc includes/interfaces.inc
index 64a32d0..b9e600f 100644
--- includes/interfaces.inc
+++ includes/interfaces.inc
@@ -203,4 +203,22 @@ interface VersioncontrolUserMapperInterface {
    *   Either a uid (int), or FALSE if the mapping failed.
    */
   public function mapCommitter(VersioncontrolOperation $commit);
+}
+
+interface VersioncontrolAuthHandlerInterface {
+  public function setRepository(VersioncontrolRepository $repository);
+  /**
+   * Determine whether this user has any access at all to the repository.
+   *
+   * Implementing code should always check this first to get around having to
+   * do more complex checks.
+   */
+  public function authAccess($uid);
+  public function authBranchCreate($uid);
+  public function authBranchDelete($uid, VersioncontrolBranch $branch);
+  public function authBranchUpdate($uid, VersioncontrolBranch $branch);
+  public function authTagCreate($uid);
+  public function authTagDelete($uid, VersioncontrolTag $tag);
+  public function authTagUpdate($uid, VersioncontrolTag $tag);
+  public function getErrorMessages();
 }
\ No newline at end of file
diff --git includes/plugins/vcs_auth/VersioncontrolAuthHandlerFFA.class.php includes/plugins/vcs_auth/VersioncontrolAuthHandlerFFA.class.php
new file mode 100644
index 0000000..4578f79
--- /dev/null
+++ includes/plugins/vcs_auth/VersioncontrolAuthHandlerFFA.class.php
@@ -0,0 +1,32 @@
+<?php
+
+class VersioncontrolAuthHandlerFFA implements VersioncontrolAuthHandlerInterface {
+  public function setRepository(VersioncontrolRepository $repository) {}
+
+  public function authAccess($uid) {
+    return TRUE;
+  }
+
+  public function authBranchCreate($uid) {
+    return TRUE;
+  }
+  public function authBranchDelete($uid, VersioncontrolBranch $branch) {
+    return TRUE;
+  }
+  public function authBranchUpdate($uid, VersioncontrolBranch $branch) {
+    return TRUE;
+  }
+  public function authTagCreate($uid) {
+    return TRUE;
+  }
+  public function authTagDelete($uid, VersioncontrolTag $tag) {
+    return TRUE;
+  }
+  public function authTagUpdate($uid, VersioncontrolTag $tag) {
+    return TRUE;
+  }
+
+  public function getErrorMessages() {
+    return NULL;
+  }
+}
\ No newline at end of file
diff --git includes/plugins/vcs_auth/VersioncontrolAuthHandlerMappedAccounts.class.php includes/plugins/vcs_auth/VersioncontrolAuthHandlerMappedAccounts.class.php
new file mode 100644
index 0000000..658763e
--- /dev/null
+++ includes/plugins/vcs_auth/VersioncontrolAuthHandlerMappedAccounts.class.php
@@ -0,0 +1,249 @@
+<?php
+
+class VersioncontrolAuthHandlerMappedAccounts implements VersioncontrolAuthHandlerInterface {
+  /**
+   * The repository this plugin is working with.
+   *
+   * @var VersioncontrolRepository
+   */
+  protected $repository;
+
+  /**
+   * The Drupal user this plugin is working with.
+   */
+  protected $user;
+
+  protected $userData = array();
+
+  protected $built = FALSE;
+
+  protected $userMasks = array();
+
+  /**
+   * An array of error message strings, to be formatted by sprintf when
+   * VersioncontrolAuthHandlerMappedAccounts::getErrorMessages is called.
+   *
+   * @var array
+   */
+  protected $errors = array();
+
+  const DENY  = 0;
+  const GRANT = 1;
+  const ALL   = 2;
+
+  public function setRepository(VersioncontrolRepository $repository) {
+    if ($this->repository instanceof VersioncontrolRepository && $this->repository !== $repository) {
+      throw new Exception('Cannot attach different repositories to a single VersioncontrolAuthHandlerMappedAccounts instance. Instanciate a new object.', E_RECOVERABLE_ERROR);
+    }
+
+    $this->repository = $repository;
+    $this->build();
+  }
+
+  protected function build() {
+    if ($this->built) {
+      return; // already built, bail out
+    }
+    if (!$this->repository instanceof VersioncontrolRepository) {
+      throw new Exception('Cannot build the account mapper object until a repository has been attached.');
+    }
+
+    // Retrieve the base auth data
+    $this->userData = db_select('versioncontrol_auth_account', 'base')
+      ->fields('base')
+      ->condition('repo_id', $this->repository->repo_id)
+      ->execute()
+      ->fetchAllAssoc('uid', PDO::FETCH_ASSOC);
+
+    foreach ($this->userData as &$data) {
+      $data['per-label-auth'] = array();
+    }
+
+    // Retrieve the extended per-label auth data
+    $label_data = db_select('versioncontrol_auth_account_label', 'base')
+      ->fields('base')
+      ->condition('repo_id', $this->repository->repo_id)
+      ->execute();
+
+    foreach ($label_data as $row) {
+      $labeldata = array(
+        'update' => $row->update,
+        'delete' => $row->delete,
+      );
+      $this->userData[$row->uid]['per-label-auth'][$row->label_id] = $labeldata;
+    }
+
+    $this->built = TRUE;
+  }
+
+  public function authAccess($uid) {
+    $this->build();
+    if (empty($this->userData[$uid]) || empty($this->userData[$uid]['access'])) {
+      // No account is registered, or access is set to 0 on the account
+      $this->errors[] = t('User does not have access to this repository.');
+      return FALSE;
+    }
+    return TRUE;
+  }
+
+  protected function baseAuth($uid) {
+    $this->build();
+    if (empty($this->userData[$uid])) {
+      // If no record of the user, deny.
+      return self::DENY;
+    }
+    else {
+      return (int) $this->userData[$uid]['access'];
+    }
+  }
+
+  public function authBranchCreate($uid) {
+    $base = $this->baseAuth($uid);
+    if ($base == self::DENY) {
+      // Zero access, deny.
+      return FALSE;
+    }
+    else if ($base == self::ALL) {
+      // User has super cow powers, say yes.
+      return TRUE;
+    }
+
+    return $this->userData[$uid]['branch_create'] == self::GRANT;
+  }
+
+  public function authBranchDelete($uid, VersioncontrolBranch $branch) {
+    return $this->authLabel($uid, $branch, 'delete');
+  }
+
+  public function authBranchUpdate($uid, VersioncontrolBranch $branch) {
+    return $this->authLabel($uid, $branch, 'update');
+  }
+  public function authTagCreate($uid) {
+    $base = $this->baseAuth($uid);
+    if ($base == self::DENY) {
+      // Zero access, deny.
+      return FALSE;
+    }
+    else if ($base == self::ALL) {
+      // User has super cow powers, say yes.
+      return TRUE;
+    }
+
+    return $this->userData[$uid]['tag_create'] == self::GRANT;
+  }
+  public function authTagDelete($uid, VersioncontrolTag $tag) {
+    return $this->authLabel($uid, $tag, 'delete');
+  }
+  public function authTagUpdate($uid, VersioncontrolTag $tag) {
+    return $this->authLabel($uid, $tag, 'update');
+  }
+
+  protected function authLabel($uid, VersioncontrolEntity $label, $op) {
+    $base = $this->baseAuth($uid);
+    switch ($base) {
+      case self::DENY:
+        // Zero access, deny.
+        return FALSE;
+      case self::ALL:
+        // User has super cow powers, say yes.
+        return TRUE;
+    }
+
+    $type = $label instanceof VersioncontrolTag ? 'tag' : 'branch';
+
+    switch ($this->userData[$uid][$type . '_' . $op]) {
+      case self::DENY:
+        // User has no perms for this op on this label type
+        return FALSE;
+      case self::ALL:
+        // User has all perms for this op on this label type
+        return TRUE;
+    }
+
+    // If we get this far, then we're doing a label-specific perm check.
+    return $this->userData[$uid]['per-label-auth'][$label->label_id][$op] == self::GRANT;
+  }
+
+  public function getErrorMessages() {
+    return $this->errors;
+  }
+
+  public function setUserData($uid, $data) {
+    $this->userData[$uid] = $data;
+  }
+
+  /**
+   * Retrieve the data representing a particular user's permission set, or the
+   * entire set of permissions that have been set up for this repository.
+   *
+   * @param int $uid
+   *   The uid for which to
+   * @return mixed
+   *   An array of perm data for the requested user, or an array of such arrays
+   *   keyed on uid. If an invalid user is requested, returns FALSE.
+   */
+  public function getUserData($uid = NULL) {
+    if (is_null($uid)) {
+      return $this->userData;
+    }
+    else {
+      return empty($this->userData[$uid]) ? FALSE : $this->userData[$uid];
+    }
+  }
+
+  /**
+   * Save all auth information for the attached repository into the db.
+   *
+   * This operates by simply blowing away all data and rewriting it with mass
+   * inserts, making it more performant overall but also leaving a very, very
+   * small window during which auths may fail because the data is unavailable.
+   */
+  public function save() {
+    if (!isset($this->repository)) {
+      throw new Exception('Cannot save auth data without a repository to attach to.', E_ERROR);
+    }
+    db_delete('versioncontrol_auth_account')
+      ->condition('repo_id', $this->repository->repo_id);
+    db_delete('versioncontrol_auth_account_label')
+      ->condition('repo_id', $this->repository->repo_id);
+
+    // Prepare values
+    $base_values = array();
+    $per_label_values = array();
+    foreach ($this->userData as $uid => $data) {
+      $data['uid'] = $uid;
+      $data['repo_id'] = $this->repository->repo_id;
+
+      foreach ($data['per-label-auth'] as $label_id => $label_data) {
+        $label_data['uid'] = $uid;
+        $label_data['repo_id'] = $this->repository->repo_id;
+        $label_data['label_id'] = $label_id;
+
+        $per_label_values[] = $label_data;
+      }
+
+      unset($data['per-label-auth']);
+      $base_values[] = $data;
+    }
+
+    // Perform base insert
+    $fields = array('uid', 'repo_id', 'access', 'branch_create',
+      'branch_update', 'branch_delete', 'tag_create', 'tag_update',
+      'tag_delete');
+
+    $insert = db_insert('versioncontrol_auth_account')->fields($fields);
+
+    foreach ($base_values as $record) {
+      $insert->values($record);
+    }
+    $insert->execute();
+
+    $fields = array('uid', 'repo_id', 'label_id', 'update', 'delete');
+    $insert = db_insert('versioncontrol_auth_account_label')->fields($fields);
+
+    foreach ($per_label_values as $record) {
+      $insert->values($record);
+    }
+    $insert->execute();
+  }
+}
\ No newline at end of file
diff --git includes/plugins/vcs_auth/account.inc includes/plugins/vcs_auth/account.inc
new file mode 100644
index 0000000..bb01820
--- /dev/null
+++ includes/plugins/vcs_auth/account.inc
@@ -0,0 +1,8 @@
+<?php
+
+$plugin = array(
+  'title' => t('Free For All (unrestricted write access)'),
+  'handler' => array(
+    'class' => 'VersioncontrolAuthHandlerMappedAccounts',
+  ),
+);
diff --git includes/plugins/vcs_auth/ffa.inc includes/plugins/vcs_auth/ffa.inc
new file mode 100644
index 0000000..f31414b
--- /dev/null
+++ includes/plugins/vcs_auth/ffa.inc
@@ -0,0 +1,8 @@
+<?php
+
+$plugin = array(
+  'title' => t('Free For All (unrestricted write access)'),
+  'handler' => array(
+    'class' => 'VersioncontrolAuthHandlerFFA',
+  ),
+);
\ No newline at end of file
diff --git tests/VersioncontrolAccountAuthPlugin.test tests/VersioncontrolAccountAuthPlugin.test
new file mode 100644
index 0000000..51ec12a
--- /dev/null
+++ tests/VersioncontrolAccountAuthPlugin.test
@@ -0,0 +1,182 @@
+<?php
+// $Id$
+/**
+ * @file
+ * Unit test ensuring the parent of the 'account' family of auth plugins behaves
+ * correctly.
+ */
+require_once drupal_get_path('module', 'versioncontrol') . '/tests/VersioncontrolTestCase.test';
+
+class VersioncontrolAccountAuthPlugin extends VersioncontrolTestCase {
+
+  protected $repos    = array();
+  protected $tags     = array();
+  protected $branches = array();
+
+  /**
+   * Implementation of getInfo().
+   */
+  public static function getInfo() {
+    return array(
+      'name' => t('Versioncontrol account authentication plugin testing'),
+      'description' => t("Test the base 'account' auth plugin's CRUD and authorization logic."),
+      'group' => t('Version Control'),
+    );
+  }
+
+  /**
+   * Implementation of setUp().
+   */
+  function setUp() {
+    $this->useBackends = self::BACKENDS_ALL;
+    parent::setUp();
+
+    // Create and login the admin user
+    $admin_user = $this->drupalCreateUser(array('administer version control systems'));
+    $this->drupalLogin($admin_user);
+
+    $repo_data = array(
+      'plugins' => array(
+        'auth_handler' => 'account'
+      ),
+    );
+
+    foreach ($this->backends as $backend_machine_name => $backend) {
+      $repo = $this->versioncontrolCreateRepository($backend_machine_name, $repo_data);
+      $this->repos[$backend_machine_name] = $repo;
+      // add some more dummy data related to each repo
+      $label_default_data = array('repo_id' => $repo->repo_id);
+      $this->branches[$repo->repo_id][0] = $this->versioncontrolCreateBranch($backend_machine_name, $label_default_data);
+      $this->branches[$repo->repo_id][1] = $this->versioncontrolCreateBranch($backend_machine_name, $label_default_data);
+      $this->branches[$repo->repo_id][2] = $this->versioncontrolCreateBranch($backend_machine_name, $label_default_data);
+      $this->branches[$repo->repo_id][3] = $this->versioncontrolCreateBranch($backend_machine_name, $label_default_data);
+      $this->tags[$repo->repo_id][0] = $this->versioncontrolCreateTag($backend_machine_name, $label_default_data);
+      $this->tags[$repo->repo_id][1] = $this->versioncontrolCreateTag($backend_machine_name, $label_default_data);
+      $this->tags[$repo->repo_id][2] = $this->versioncontrolCreateTag($backend_machine_name, $label_default_data);
+      $this->tags[$repo->repo_id][3] = $this->versioncontrolCreateTag($backend_machine_name, $label_default_data);
+    }
+  }
+
+  /**
+   * Helper to get user data.
+   */
+  protected function getMappedAccountsAuthPluginUserData($repo_id) {
+      return array(
+        'access' => VersioncontrolAuthHandlerMappedAccounts::GRANT,
+        'branch_create' => VersioncontrolAuthHandlerMappedAccounts::DENY,
+        'branch_update' => VersioncontrolAuthHandlerMappedAccounts::GRANT,
+        'branch_delete' => VersioncontrolAuthHandlerMappedAccounts::GRANT,
+        'tag_create' => VersioncontrolAuthHandlerMappedAccounts::DENY,
+        'tag_update' => VersioncontrolAuthHandlerMappedAccounts::GRANT,
+        'tag_delete' => VersioncontrolAuthHandlerMappedAccounts::GRANT,
+        'per-label-auth' => array(
+          $this->branches[$repo_id][0]->label_id => array(
+            'update' => VersioncontrolAuthHandlerMappedAccounts::GRANT,
+            'delete' => VersioncontrolAuthHandlerMappedAccounts::GRANT,
+          ),
+          $this->branches[$repo_id][1]->label_id => array(
+            'update' => VersioncontrolAuthHandlerMappedAccounts::GRANT,
+            'delete' => VersioncontrolAuthHandlerMappedAccounts::DENY,
+          ),
+          $this->branches[$repo_id][2]->label_id => array(
+            'update' => VersioncontrolAuthHandlerMappedAccounts::DENY,
+            'delete' => VersioncontrolAuthHandlerMappedAccounts::GRANT,
+          ),
+          $this->branches[$repo_id][3]->label_id => array(
+            'update' => VersioncontrolAuthHandlerMappedAccounts::DENY,
+            'delete' => VersioncontrolAuthHandlerMappedAccounts::DENY,
+          ),
+          $this->tags[$repo_id][0]->label_id => array(
+            'update' => VersioncontrolAuthHandlerMappedAccounts::GRANT,
+            'delete' => VersioncontrolAuthHandlerMappedAccounts::GRANT,
+          ),
+          $this->tags[$repo_id][1]->label_id => array(
+            'update' => VersioncontrolAuthHandlerMappedAccounts::GRANT,
+            'delete' => VersioncontrolAuthHandlerMappedAccounts::DENY,
+          ),
+          $this->tags[$repo_id][2]->label_id => array(
+            'update' => VersioncontrolAuthHandlerMappedAccounts::DENY,
+            'delete' => VersioncontrolAuthHandlerMappedAccounts::GRANT,
+          ),
+          $this->tags[$repo_id][3]->label_id => array(
+            'update' => VersioncontrolAuthHandlerMappedAccounts::DENY,
+            'delete' => VersioncontrolAuthHandlerMappedAccounts::DENY,
+          ),
+        ),
+      );
+  }
+
+  public function testMappedAccountsAuthPluginCrud() {
+    foreach ($this->repos as $repo) {
+      // Manually instantiate the plugin for the create portion
+      $class_name = ctools_plugin_load_class('versioncontrol', 'vcs_auth', 'account', 'handler');
+      $authplug = new $class_name();
+      $authplug->setRepository($repo);
+
+      // Add one auth account row
+      $super_user = $this->drupalCreateUser();
+      $super_user_data = $this->getMappedAccountsAuthPluginUserData($repo->repo_id);
+      $authplug->setUserData($super_user->uid, $super_user_data);
+      $authplug->save();
+
+      // Now load the plugin using the provided method and retrieve the user data,
+      // ensure it's what we sent in
+      $db_authplug = $repo->getAuthHandler();
+      $db_data = $db_authplug->getUserData($super_user->uid);
+      $at_input = array_diff($super_user_data, $db_data);
+      $this->assertTrue(empty($at_input), 'Authentication account database data is included on provided data');
+      // add uid for the comparison(db info autoreturns it, but we set it at setUserData() not in the array passed)
+      $super_user_data['uid'] = $super_user->uid;
+      $at_db = array_diff($db_data, $super_user_data);
+      $this->assertTrue(empty($at_db), 'Authentication account provided data is included on database data');
+
+      // Now try test  logic
+      $authplug = $repo->getAuthHandler();
+      $branches = $repo->loadBranches(array(
+        $this->branches[$repo->repo_id][0]->label_id,
+        $this->branches[$repo->repo_id][1]->label_id,
+        $this->branches[$repo->repo_id][2]->label_id,
+        $this->branches[$repo->repo_id][3]->label_id,
+      ));
+      $tags = $repo->loadTags(array(
+        $this->tags[$repo->repo_id][0]->label_id,
+        $this->tags[$repo->repo_id][1]->label_id,
+        $this->tags[$repo->repo_id][2]->label_id,
+        $this->tags[$repo->repo_id][3]->label_id,
+      ));
+      // global
+      $this->assertTrue($authplug->authAccess($super_user->uid), 'global auth validate correctly');
+      // branches
+      $this->assertFalse($authplug->authBranchCreate($super_user->uid), 'branch create validate correctly');
+      $this->assertFalse($authplug->authTagCreate($super_user->uid), 'tag create validate correctly');
+      $this->assertTrue($authplug->authBranchUpdate($super_user->uid, $this->branches[$repo->repo_id][0]), 'granular branch update validate correctly');
+      $this->assertTrue($authplug->authBranchDelete($super_user->uid, $this->branches[$repo->repo_id][0]), 'granular branch delete validate correctly');
+      $this->assertTrue($authplug->authBranchUpdate($super_user->uid, $this->branches[$repo->repo_id][1]), 'granular branch update validate correctly');
+      $this->assertFalse($authplug->authBranchDelete($super_user->uid, $this->branches[$repo->repo_id][1]), 'granular branch delete validate correctly');
+      $this->assertFalse($authplug->authBranchUpdate($super_user->uid, $this->branches[$repo->repo_id][2]), 'granular branch update validate correctly');
+      $this->assertTrue($authplug->authBranchDelete($super_user->uid, $this->branches[$repo->repo_id][2]), 'granular branch delete validate correctly');
+      $this->assertFalse($authplug->authBranchUpdate($super_user->uid, $this->branches[$repo->repo_id][3]), 'granular branch update validate correctly');
+      $this->assertFalse($authplug->authBranchDelete($super_user->uid, $this->branches[$repo->repo_id][3]), 'granular branch delete validate correctly');
+      // tags
+      $this->assertTrue($authplug->authTagUpdate($super_user->uid, $this->tags[$repo->repo_id][0]), 'granular tag update validate correctly');
+      $this->assertTrue($authplug->authTagDelete($super_user->uid, $this->tags[$repo->repo_id][0]), 'granular tag delete validate correctly');
+      $this->assertTrue($authplug->authTagUpdate($super_user->uid, $this->tags[$repo->repo_id][1]), 'granular tag update validate correctly');
+      $this->assertFalse($authplug->authTagDelete($super_user->uid, $this->tags[$repo->repo_id][1])
+      $this->assertFalse($authplug->authTagUpdate($super_user->uid, $this->tags[$repo->repo_id][2]), 'granular tag update validate correctly');
+      $this->assertTrue($authplug->authTagDelete($super_user->uid, $this->tags[$repo->repo_id][2]), 'granular tag delete validate correctly');
+      $this->assertFalse($authplug->authTagUpdate($super_user->uid, $this->tags[$repo->repo_id][3]), 'granular tag update validate correctly');
+      $this->assertFalse($authplug->authTagDelete($super_user->uid, $this->tags[$repo->repo_id][3]), 'granular tag delete validate correctly');
+    }
+  }
+
+  public function testAuthLogic() {
+    foreach ($this->repos as $repo) {
+      $this->doAuthLogicTest($repo);
+    }
+  }
+
+  public function doAuthLogicTest(VersioncontrolRepository $repo) {
+    $authplug = $repo->getAuthHandler();
+  }
+
+}
diff --git tests/VersioncontrolTestCase.test tests/VersioncontrolTestCase.test
index b04f8a5..7ee9d22 100644
--- tests/VersioncontrolTestCase.test
+++ tests/VersioncontrolTestCase.test
@@ -121,4 +121,69 @@ abstract class VersioncontrolTestCase extends DrupalWebTestCase {
       $this->testBackend = versioncontrol_get_backends('test');
     }
   }
+
+  /**
+   * Create a dummy backend, insert it in the database, and return it for use.
+   *
+   * This uses a fake path that doesn't point to any real repository, so
+   * anything that actually tries to interact with the underlying repo will
+   * fail.
+   *
+   * @param string $backend_name
+   * @param array  $data
+   */
+  public function versioncontrolCreateRepository($backend_name = 'test', $data = array()) {
+    static $i = 0;
+    $default_data = array(
+      'name' => 'test_repo_' . ++$i,
+      'vcs' => $backend_name,
+      'root' => '/fake/path/to/repo',
+      'update_method' => 0,
+      'updated' => 0,
+      'locked' => 0,
+      'data' => array(),
+      'plugins' => array(),
+    );
+    $default_plugins = array(
+      'auth_handler' => 'ffa',
+    );
+
+    $data = array_merge_recursive($default_data, $data);
+    foreach ($default_plugins as $plugin_slot => $default_plugin) {
+      if (empty($data['plugins'][$plugin_slot])) {
+        $data['plugins'][$plugin_slot] = $default_plugin;
+      }
+    }
+    $backend = $this->backends[$backend_name];
+    $repo = $backend->buildEntity('repo', $data);
+    $repo->insert();
+
+    return $repo;
+  }
+
+  public function versioncontrolCreateLabel($type, $backend_name = 'test', $data = array()) {
+    $default_data = array(
+      'name' => $this->randomName(32),
+    );
+    $data += $default_data;
+
+    $backend = $this->backends[$backend_name];
+    if (!isset($data['repo_id'])) {
+      $repo = $this->versioncontrolCreateRepository($backend_name);
+      $data['repo_id'] = $repo->repo_id;
+    }
+    $label = $backend->buildEntity($type, $data);
+    $label->insert();
+
+    return $label;
+  }
+
+  public function versioncontrolCreateBranch($backend_name = 'test', $data = array()) {
+    return $this->versioncontrolCreateLabel('branch', $backend_name, $data);
+  }
+
+  public function versioncontrolCreateTag($backend_name = 'test', $data = array()) {
+    return $this->versioncontrolCreateLabel('tag', $backend_name, $data);
+  }
+
 }
diff --git versioncontrol.install versioncontrol.install
index 4af381d..0eed54a 100644
--- versioncontrol.install
+++ versioncontrol.install
@@ -402,6 +402,115 @@ function versioncontrol_schema() {
     'primary key' => array('uid', 'repo_id'),
   );
 
+  $schema['versioncontrol_auth_account'] = array(
+    'description' => 'ACL table, used by the VersioncontrolAuthHandlerMappedAccounts family of plugins, that stores ACL data on a per-uid/per-repo basis.',
+    'fields' => array(
+      'uid' => array(
+        'description' => 'Foreign key to {users}.uid; uniquely identifies a Drupal user to whom this ACL data applies.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'repo_id' => array(
+        'description' => 'Foreign key to {versioncontrol_repositories}.repo_id; identifies the repository to which this ACL data applies.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'access' => array(
+        'type' => 'int',
+        'description' => 'Base, global access to the repository. 0 indicates no access (disabled/inactive account; acts as a global deny), 1 indicates some level of access, 2 indicates global access (overrides granular access).',
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'branch_create' => array(
+        'type' => 'int',
+        'description' => 'Grant user access to create branches in the repository.',
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'branch_update' => array(
+        'type' => 'int',
+        'description' => 'Grant user access to update/write to any branch in the repository. 1 is global access, 0 defers to individual branch perms.',
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'branch_delete' => array(
+        'type' => 'int',
+        'description' => 'Grant user access to delete any branch in the repository. 1 is global access, 0 defers to individual branch perms.',
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'tag_create' => array(
+        'type' => 'int',
+        'description' => 'Grant user access to create tags in the repository.',
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'tag_update' => array(
+        'type' => 'int',
+        'description' => 'Grant user access to update/modify any tag in the repository. 1 is global access, 0 defers to individual tag perms.',
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'tag_delete' => array(
+        'type' => 'int',
+        'description' => 'Grant user access to delete tags in the repository. 0 is no access, 1 is some access, 2 can delete all tags.',
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'primary key' => array('repo_id', 'uid'),
+  );
+  $schema['versioncontrol_auth_account_label'] = array(
+    'description' => '',
+    'fields' => array(
+      'uid' => array(
+        'description' => 'Foreign key to {users}.uid; uniquely identifies a Drupal user to whom this ACL data applies.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'repo_id' => array(
+        'description' => 'Foreign key to {versioncontrol_repositories}.repo_id; identifies the repository to which this ACL data applies.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'label_id' => array(
+        'description' => 'Foreign key to {versioncontrol_labels}.label_id; identifies the label (branch or tag) to which this ACL data applies.',
+        'type' => 'serial',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'update' => array(
+        'type' => 'int',
+        'description' => 'Grant user access to update/modify this label.',
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'delete' => array(
+        'type' => 'int',
+        'description' => 'Grant user access to delete this label.',
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'primary key' => array('repo_id', 'uid', 'label_id'),
+    'indexes' => array(
+      'label_id' => array('label_id'),
+    ),
+  );
+
   return $schema;
 }
 
@@ -857,3 +966,128 @@ function versioncontrol_update_6308() {
   db_add_field($ret, 'versioncontrol_repositories', 'plugins', $plugins);
   return $ret;
 }
+
+/**
+ * Remove the defunct versioncontrol_accounts table and replace it with ones
+ * driven by auth plugins, specifically the
+ * VersioncontrolAuthHandlerMappedAccounts family of plugins.
+ */
+function versioncontrol_update_6309() {
+  $ret = array();
+
+  $account_table = array(
+    'description' => 'ACL table, used by the VersioncontrolAuthHandlerMappedAccounts family of plugins, that stores ACL data on a per-uid/per-repo basis.',
+    'fields' => array(
+      'uid' => array(
+        'description' => 'Foreign key to {users}.uid; uniquely identifies a Drupal user to whom this ACL data applies.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'repo_id' => array(
+        'description' => 'Foreign key to {versioncontrol_repositories}.repo_id; identifies the repository to which this ACL data applies.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'access' => array(
+        'type' => 'int',
+        'description' => 'Base, global access to the repository. 0 indicates no access (disabled/inactive account; acts as a global deny), 1 indicates some level of access, 2 indicates global access (overrides granular access).',
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'branch_create' => array(
+        'type' => 'int',
+        'description' => 'Grant user access to create branches in the repository.',
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'branch_update' => array(
+        'type' => 'int',
+        'description' => 'Grant user access to update/write to any branch in the repository. 1 is global access, 0 defers to individual branch perms.',
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'branch_delete' => array(
+        'type' => 'int',
+        'description' => 'Grant user access to delete any branch in the repository. 1 is global access, 0 defers to individual branch perms.',
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'tag_create' => array(
+        'type' => 'int',
+        'description' => 'Grant user access to create tags in the repository.',
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'tag_update' => array(
+        'type' => 'int',
+        'description' => 'Grant user access to update/modify any tag in the repository. 1 is global access, 0 defers to individual tag perms.',
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'tag_delete' => array(
+        'type' => 'int',
+        'description' => 'Grant user access to delete tags in the repository. 0 is no access, 1 is some access, 2 can delete all tags.',
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'primary key' => array('repo_id', 'uid'),
+  );
+
+  db_create_table($ret, 'versioncontrol_auth_account', $account_table);
+
+  $auth_label_table = array(
+    'description' => '',
+    'fields' => array(
+      'uid' => array(
+        'description' => 'Foreign key to {users}.uid; uniquely identifies a Drupal user to whom this ACL data applies.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'repo_id' => array(
+        'description' => 'Foreign key to {versioncontrol_repositories}.repo_id; identifies the repository to which this ACL data applies.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'label_id' => array(
+        'description' => 'Foreign key to {versioncontrol_labels}.label_id; identifies the label (branch or tag) to which this ACL data applies.',
+        'type' => 'serial',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'update' => array(
+        'type' => 'int',
+        'description' => 'Grant user access to update/modify this label.',
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'delete' => array(
+        'type' => 'int',
+        'description' => 'Grant user access to delete this label.',
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'primary key' => array('repo_id', 'uid', 'label_id'),
+    'indexes' => array(
+      'label_id' => array('label_id'),
+    ),
+  );
+
+  db_create_table($ret, 'versioncontrol_auth_account_label', $auth_label_table);
+
+  return $ret;
+}
