diff --git includes/VersioncontrolRepository.php includes/VersioncontrolRepository.php
index fbc8e36..81bbb25 100644
--- includes/VersioncontrolRepository.php
+++ includes/VersioncontrolRepository.php
@@ -499,6 +499,25 @@ 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'])) {
+//        $this->plugins['auth_handler'] = 'ffa';
+//      }
+//      $this->pluginInstances['auth_handler'] = $this->getPluginClass('auth_handler', 'authorization', 'handler');
+//    }
+//    return $this->pluginInstances['auth_handler'];
+
+    if (empty($this->plugins['auth_handler'])) {
+      $this->plugins['auth_handler'] = 'ffa';
+    }
+    // Spinning off new object instances is probably better than local caching
+    $obj = $this->getPluginClass('auth_handler', 'vcs_auth', 'handler');
+    $obj->setRepository($this);
+    return $obj;
+  }
+
   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 d8dc55d..8565f2d 100644
--- includes/interfaces.inc
+++ includes/interfaces.inc
@@ -241,4 +241,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(object $user);
+  public function authBranchCreate(object $user, VersioncontrolBranch $branch);
+  public function authBranchDelete(object $user, VersioncontrolBranch $branch);
+  public function authBranchUpdate(object $user, VersioncontrolBranch $branch);
+  public function authTagCreate(object $user, VersioncontrolTag $tag);
+  public function authTagDelete(object $user, VersioncontrolTag $tag);
+  public function authTagUpdate(object $user, 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..3e0a683
--- /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(object $user) {
+    return TRUE;
+  }
+
+  public function authBranchCreate(object $user, VersioncontrolBranch $branch) {
+    return TRUE;
+  }
+  public function authBranchDelete(object $user, VersioncontrolBranch $branch) {
+    return TRUE;
+  }
+  public function authBranchUpdate(object $user, VersioncontrolBranch $branch) {
+    return TRUE;
+  }
+  public function authTagCreate(object $user, VersioncontrolTag $tag) {
+    return TRUE;
+  }
+  public function authTagDelete(object $user, VersioncontrolTag $tag) {
+    return TRUE;
+  }
+  public function authTagUpdate(object $user, 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..20f3422
--- /dev/null
+++ includes/plugins/vcs_auth/VersioncontrolAuthHandlerMappedAccounts.class.php
@@ -0,0 +1,96 @@
+<?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 $repoSet = FALSE;
+  protected $built = FALSE;
+
+  /**
+   * 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 LIMITED = 2;
+
+  public function setRepository(VersioncontrolRepository $repository) {
+    if ($this->repoSet && $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->repoSet = TRUE;
+    $this->build();
+  }
+
+  protected function build() {
+    if ($this->built) {
+      return; // already built, bail out
+    }
+    if (empty($this->repoSet)) {
+      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')
+      ->fields('base')
+      ->condition('repo_id', $this->repository->repo_id)
+      ->execute()
+      ->fetchAllAssoc('uid');
+
+    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')
+      ->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(object $user) {
+    $this->build();
+    if (empty($this->userData[$user->uid]) || empty($this->userData[$user->uid]['access'])) {
+      // No account is registered, or access is set to 0 on the account
+      $this->errors[] = t('%name does not have access to this repository.', array('name' => $user->name));
+      return FALSE;
+    }
+    return TRUE;
+  }
+
+  public function authBranchCreate(object $user, VersioncontrolBranch $branch);
+  public function authBranchDelete(object $user, VersioncontrolBranch $branch);
+  public function authBranchUpdate(object $user, VersioncontrolBranch $branch);
+  public function authTagCreate(object $user, VersioncontrolTag $tag);
+  public function authTagDelete(object $user, VersioncontrolTag $tag);
+  public function authTagUpdate(object $user, VersioncontrolTag $tag);
+  public function getErrorMessages();
+}
\ 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..22449f5
--- /dev/null
+++ includes/plugins/vcs_auth/account.inc
@@ -0,0 +1,9 @@
+<?php
+
+$plugin = array(
+  'title' => t('Free For All (unrestricted write access)'),
+  'handler' => array(
+    'class' => 'VersioncontrolAuthHandlerMappedAccounts',
+    'file' => 'VersioncontrolAuthHandlerMappedAccounts.class.php',
+  ),
+);
diff --git includes/plugins/vcs_auth/ffa.inc includes/plugins/vcs_auth/ffa.inc
new file mode 100644
index 0000000..a5a3169
--- /dev/null
+++ includes/plugins/vcs_auth/ffa.inc
@@ -0,0 +1,9 @@
+<?php
+
+$plugin = array(
+  'title' => t('Free For All (unrestricted write access)'),
+  'handler' => array(
+    'class' => 'VersioncontrolAuthHandlerFFA',
+    'file' => 'VersioncontrolAuthHandlerFFA.class.php',
+  ),
+);
\ No newline at end of file
diff --git versioncontrol.install versioncontrol.install
index fbe527b..71282be 100644
--- versioncontrol.install
+++ versioncontrol.install
@@ -371,36 +371,113 @@ function versioncontrol_schema() {
     'primary key' => array('repo_id'),
   );
 
-  $schema['versioncontrol_accounts'] = array(
-    'description' =>
-      'Association table of VCS account usernames (in a specific repository) to Drupal user ids. A Drupal user can be associated to multiple VCS accounts. Ideally, multiple VCS accounts per repository should be possible too, but clumsy array data structures and assumptions in the admin interface (elsewhere, too? don\'t know) currently make it necessary to restrict the number of VCS accounts to a maximum of 1 per repository and Drupal user.',
+  $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' => 'The {users}.uid of the Drupal user associated with the VCS-specific username in {versioncontrol_accounts}.username.',
+        '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,
+      ),
+      'update_any_branch' => 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,
       ),
+      'delete_any_branch' => 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,
+      ),
+      'update_any_tag' => 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,
+      ),
+      'delete_any_tag' => array(
+        'type' => 'int',
+        'description' => 'Grant user access to delete any tag in the repository. 1 is global access, 0 defers to individual tag perms.',
+        '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 (referring to {versioncontrol_repositories}.repo_id) for the repository that contains the VCS account.',
+        '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,
       ),
-      'vcs_username' => array(
-        'description' => 'VCS-specific username of the VCS account associated with the Drupal user in {versioncontrol_accounts}.uid.',
-        'type' => 'varchar',
-        'length' => 64,
+      'delete' => array(
+        'type' => 'int',
+        'description' => 'Grant user access to delete this label.',
+        'size' => 'tiny',
         'not null' => TRUE,
-        'default' => '',
+        'default' => 0,
       ),
     ),
-    'unique keys' => array(
-      'repo_id_username' => array('repo_id', 'vcs_username'),
+    'primary key' => array('repo_id', 'uid', 'label_id'),
+    'indexes' => array(
+      'label_id' => array('label_id'),
     ),
-    'primary key' => array('uid', 'repo_id'),
   );
 
   return $schema;
@@ -858,3 +935,130 @@ 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();
+
+  db_drop_table($ret, 'versioncontrol_accounts');
+
+  $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,
+      ),
+      'update_any_branch' => 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,
+      ),
+      'delete_any_branch' => 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,
+      ),
+      'update_any_tag' => 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,
+      ),
+      'delete_any_tag' => array(
+        'type' => 'int',
+        'description' => 'Grant user access to delete any tag in the repository. 1 is global access, 0 defers to individual tag perms.',
+        '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;
+}
\ No newline at end of file
