diff --git bp-groups/bp-groups-actions.php bp-groups/bp-groups-actions.php
index 2a0ea8b..54736db 100644
--- bp-groups/bp-groups-actions.php
+++ bp-groups/bp-groups-actions.php
@@ -15,6 +15,70 @@
 if ( !defined( 'ABSPATH' ) ) exit;
 
 /**
+ * Protect access to single groups.
+ *
+ * @since BuddyPress (2.1.0)
+ */
+function bp_groups_group_access_protection() {
+	if ( ! bp_is_group() ) {
+		return;
+	}
+
+	$current_group   = groups_get_current_group();
+	$user_has_access = $current_group->user_has_access;
+	$no_access_args  = array();
+
+	if ( ! $user_has_access && 'hidden' !== $current_group->status ) {
+		// Always allow access to home and request-membership
+		if ( bp_is_current_action( 'home' ) || bp_is_current_action( 'request-membership' ) ) {
+			$user_has_access = true;
+
+		// User doesn't have access, so set up redirect args
+		} else {
+			if ( is_user_logged_in() ) {
+				$no_access_args = array(
+					'message'  => __( 'You do not have access to this group.', 'buddypress' ),
+					'root'     => bp_get_group_permalink( $current_group ) . 'home/',
+					'redirect' => false
+				);
+			}
+		}
+	}
+
+	// Protect the admin tab from non-admins
+	if ( bp_is_current_action( 'admin' ) && ! bp_is_item_admin() ) {
+		$user_has_access = false;
+		$no_access_args  = array(
+			'message'  => __( 'You are not an admin of this group.', 'buddypress' ),
+			'root'     => bp_get_group_permalink( $current_group ),
+			'redirect' => false
+		);
+	}
+
+	// Send the current value off to be filtered based on plugin-specific settings
+	$user_has_access = apply_filters( 'bp_group_user_has_access', $user_has_access );
+
+	// If user has access, we return rather than redirect
+	if ( $user_has_access ) {
+		return;
+	}
+
+	// Hidden groups should return a 404 for non-members.
+	// Unset the current group so that you're not redirected
+	// to the default group tab
+	if ( 'hidden' == $current_group->status ) {
+		buddypress()->groups->current_group = 0;
+		buddypress()->is_single_item        = false;
+		bp_do_404();
+		return;
+	} else {
+		bp_core_no_access( $no_access_args );
+	}
+
+}
+add_action( 'bp_actions', 'bp_groups_group_access_protection' );
+
+/**
  * Catch and process group creation form submissions.
  */
 function groups_action_create_group() {
diff --git bp-groups/bp-groups-classes.php bp-groups/bp-groups-classes.php
index c036b62..3fd9061 100644
--- bp-groups/bp-groups-classes.php
+++ bp-groups/bp-groups-classes.php
@@ -3010,6 +3010,11 @@ class BP_Group_Extension {
 			'display_hook'      => $this->display_hook,
 			'template_file'     => $this->template_file,
 			'screens'           => $this->get_default_screens(),
+			'access'            => array(
+				'public'  => 'anyone',
+				'private' => 'members',
+				'hidden'  => 'members',
+			),
 		) );
 
 		$this->initialized = true;
@@ -3190,7 +3195,9 @@ class BP_Group_Extension {
 			return;
 		}
 
-		if ( true === $this->enable_nav_item ) {
+		$user_has_access = $this->user_has_access();
+
+		if ( true === $this->enable_nav_item && true === $user_has_access ) {
 			bp_core_new_subnav_item( array(
 				'name'            => ! $this->nav_item_name ? $this->name : $this->nav_item_name,
 				'slug'            => $this->slug,
@@ -3199,11 +3206,12 @@ class BP_Group_Extension {
 				'position'        => $this->nav_item_position,
 				'item_css_id'     => 'nav-' . $this->slug,
 				'screen_function' => array( &$this, '_display_hook' ),
-				'user_has_access' => $this->enable_nav_item
+				'user_has_access' => $user_has_access,
 			) );
 
 			// When we are viewing the extension display page, set the title and options title
 			if ( bp_is_current_action( $this->slug ) ) {
+				add_filter( 'bp_group_user_has_access',   array( $this, 'user_has_access' ) );
 				add_action( 'bp_template_content_header', create_function( '', 'echo "' . esc_attr( $this->name ) . '";' ) );
 				add_action( 'bp_template_title',          create_function( '', 'echo "' . esc_attr( $this->name ) . '";' ) );
 			}
@@ -3223,6 +3231,54 @@ class BP_Group_Extension {
 		bp_core_load_template( apply_filters( 'bp_core_template_plugin', $this->template_file ) );
 	}
 
+	/**
+	 * Determine whether the current user has access to this tab.
+	 *
+	 * @since BuddyPress (2.1.0)
+	 *
+	 * @return bool
+	 */
+	public function user_has_access( $user_has_access ) {
+
+		if ( current_user_can( 'bp_moderate' ) ) {
+			return true;
+		}
+
+		$group = groups_get_group( array(
+			'group_id' => $this->group_id,
+		) );
+
+		// Filter based on plugin-specific settings, if set
+		$access_setting = '';
+		if ( isset( $this->params['access'][ $group->status ] ) ) {
+			$access_setting = $this->params['access'][ $group->status ];
+		}
+
+		switch ( $access_setting ) {
+			case 'admins' :
+				$user_has_access = groups_is_user_admin( bp_loggedin_user_id(), $this->group_id );
+				break;
+
+			case 'mods' :
+				$user_has_access = groups_is_user_mod( bp_loggedin_user_id(), $this->group_id );
+				break;
+
+			case 'members' :
+				$user_has_access = groups_is_user_member( bp_loggedin_user_id(), $this->group_id );
+				break;
+
+			case 'loggedin' :
+				$user_has_access = is_user_logged_in();
+				break;
+
+			case 'anyone' :
+				$user_has_access = true;
+				break;
+		}
+
+		return $user_has_access;
+	}
+
 	/** Create ************************************************************/
 
 	/**
diff --git bp-groups/bp-groups-loader.php bp-groups/bp-groups-loader.php
index 08edbff..49d06a7 100644
--- bp-groups/bp-groups-loader.php
+++ bp-groups/bp-groups-loader.php
@@ -269,47 +269,6 @@ class BP_Groups_Component extends BP_Component {
 
 		}
 
-		// Group access control
-		if ( bp_is_groups_component() && !empty( $this->current_group ) ) {
-			if ( !$this->current_group->user_has_access ) {
-
-				// Hidden groups should return a 404 for non-members.
-				// Unset the current group so that you're not redirected
-				// to the default group tab
-				if ( 'hidden' == $this->current_group->status ) {
-					$this->current_group = 0;
-					$bp->is_single_item  = false;
-					bp_do_404();
-					return;
-
-				// Skip the no_access check on home and membership request pages
-				} elseif ( !bp_is_current_action( 'home' ) && !bp_is_current_action( 'request-membership' ) ) {
-
-					// Off-limits to this user. Throw an error and redirect to the group's home page
-					if ( is_user_logged_in() ) {
-						bp_core_no_access( array(
-							'message'  => __( 'You do not have access to this group.', 'buddypress' ),
-							'root'     => bp_get_group_permalink( $bp->groups->current_group ) . 'home/',
-							'redirect' => false
-						) );
-
-					// User does not have access, and does not get a message
-					} else {
-						bp_core_no_access();
-					}
-				}
-			}
-
-			// Protect the admin tab from non-admins
-			if ( bp_is_current_action( 'admin' ) && !bp_is_item_admin() ) {
-				bp_core_no_access( array(
-					'message'  => __( 'You are not an admin of this group.', 'buddypress' ),
-					'root'     => bp_get_group_permalink( $bp->groups->current_group ),
-					'redirect' => false
-				) );
-			}
-		}
-
 		// Preconfigured group creation steps
 		$this->group_creation_steps = apply_filters( 'groups_create_group_steps', array(
 			'group-details'  => array(
diff --git bp-templates/bp-legacy/buddypress/groups/single/home.php bp-templates/bp-legacy/buddypress/groups/single/home.php
index 11dfb2e..dbfd798 100644
--- bp-templates/bp-legacy/buddypress/groups/single/home.php
+++ bp-templates/bp-legacy/buddypress/groups/single/home.php
@@ -33,23 +33,34 @@
 		 * @todo A real template hierarchy? Gasp!
 		 */
 
-		// Group is visible
-		if ( bp_group_is_visible() ) : 
-
 			// Looking at home location
 			if ( bp_is_group_home() ) :
 
-				// Use custom front if one exists
-				$custom_front = bp_locate_template( array( 'groups/single/front.php' ), false, true );
-				if     ( ! empty( $custom_front   ) ) : load_template( $custom_front, true );
+				if ( bp_group_is_visible() ) {
 
-				// Default to activity
-				elseif ( bp_is_active( 'activity' ) ) : bp_get_template_part( 'groups/single/activity' );
+					// Use custom front if one exists
+					$custom_front = bp_locate_template( array( 'groups/single/front.php' ), false, true );
+					if     ( ! empty( $custom_front   ) ) : load_template( $custom_front, true );
 
-				// Otherwise show members
-				elseif ( bp_is_active( 'members'  ) ) : bp_groups_members_template_part();
+					// Default to activity
+					elseif ( bp_is_active( 'activity' ) ) : bp_get_template_part( 'groups/single/activity' );
 
-				endif;
+					// Otherwise show members
+					elseif ( bp_is_active( 'members'  ) ) : bp_groups_members_template_part();
+
+					endif;
+
+				} else {
+
+					do_action( 'bp_before_group_status_message' ); ?>
+
+					<div id="message" class="info">
+						<p><?php bp_group_status_message(); ?></p>
+					</div>
+
+					<?php do_action( 'bp_after_group_status_message' );
+
+				}
 				
 			// Not looking at home
 			else :
@@ -76,29 +87,9 @@
 				else                                : bp_get_template_part( 'groups/single/plugins'      );
 
 				endif;
+			
 			endif;
 
-		// Group is not visible
-		elseif ( ! bp_group_is_visible() ) :
-
-			// Membership request
-			if ( bp_is_group_membership_request() ) :
-				bp_get_template_part( 'groups/single/request-membership' );
-
-			// The group is not visible, show the status message
-			else :
-
-				do_action( 'bp_before_group_status_message' ); ?>
-
-				<div id="message" class="info">
-					<p><?php bp_group_status_message(); ?></p>
-				</div>
-
-				<?php do_action( 'bp_after_group_status_message' );
-
-			endif;
-		endif;
-
 		do_action( 'bp_after_group_body' ); ?>
 
 	</div><!-- #item-body -->
