admin_post action not usable if admin access denied to user

What about (1) current_screen? action hook, or a condition for (2)
get_current_screen() in your conditional and then calling wp_redirect?

Both give you a WP_Screen object which has several parameters, including a $parent_base property that can give broader inclusion if needed, too.

Here’s the property list from the codex:

$action Any action associated with the screen. ‘add’ for *-add.php and
*-new.php screens. Empty otherwise.

$base The base type of the screen. This is typically the same as $id but with any post types and
taxonomies stripped. For example, for an $id of ‘edit-post’ the base
is ‘edit’.

$id The unique ID of the screen.

$is_network Whether the
screen is in the network admin.

$is_user Whether the screen is in the
user admin.

$parent_base The base menu parent. This is derived from
$parent_file by removing the query string and any .php extension.
$parent_file values of ‘edit.php?post_type=page’ and
‘edit.php?post_type=post’ have a $parent_base of ‘edit’.

$parent_file
The $parent_file for the screen per the admin menu system. Some
$parent_file values are ‘edit.php?post_type=page’, ‘edit.php’, and
‘options-general.php’.

$post_type The post type associated with the
screen, if any. The ‘edit.php?post_type=page’ screen has a post type
of ‘page’. The ‘edit-tags.php?taxonomy=$taxonomy&post_type=page’
screen has a post type of ‘page’.

$taxonomy The taxonomy associated
with the screen, if any. The ‘edit-tags.php?taxonomy=category’ screen
has a taxonomy of ‘category’.

Just a quick example of possible usage, not working code as is:

add_action( 'current_screen', 'my_function' );

function my_function( $current_screen ) {
     //true for anything other than page prefixed with edit.php
     if ( $current_screen->parent_base !== 'edit' ) { 
          //get user role here, then:
          if ( in_array( $user->roles ) ) {
             //send to /wp-admin/ 
            //note: for multisite I don't think admin_url() is the function you need
              wp_redirect( admin_url() ); 
          }
     }
 }

There may be a better approach for your specific case, but in general I’ve used something similar open/close access to a post_type or user profile screen without affecting ability for users to log in.