Change post status based on user role

I’m then trying to figure out how to change the post status once their
subscription is up

function downgrade_user_role( $entry, $subscription_id, $transaction_id, $new_payment_amount ) {
    $user = GFUserData::get_user_by_entry_id( $entry['id'] );
    $user->set_role( 'subscriber' );
    global $wpdb;
    $wpdb->query( $wpdb->prepare(
      "UPDATE $wpdb->posts SET post_status="draft" WHERE post_author = %d
       AND post_status IN ('publish', 'future')",
       $user->ID
    ) );
}
add_action( 'gform_authorizenet_subscription_canceled', 'downgrade_user_role', 10, 4 );

Another option would be to only include the posts by certain user
roles in the query but haven’t been able to find a way to do that
either.

function exclude_subscribers_posts( $query ) {
  if ( is_admin() || ! is_main_query() ) return;
  $subscribers = get_users( array('role'=>'subscriber', 'fields'=>'ID') );
  if ( $subscribers ) {
     $subscribers = implode(',', array_map('intval', $subscribers));
     global $wpdb;
     $exclude = $wpdb->get_col(
       "SELECT ID FROM $wpdb->posts WHERE post_author IN ($subscribers)"
     );
     if ( empty($exclude) ) return $query;
     $include = (array) $query->get('post__in');
     if ( $include ) {
       $query->set('post__in', array_diff( $include, $exclude) );
     } else {
       $query->set('post__not_in', $exclude);
     }
  }
}
add_action('pre_get_posts','exclude_subscribers_posts');

Consider that:

  1. Option 1 is faster and run once
  2. Option 2 is slower, and run on every (main) query

For these reasons option 1 is much better, use option 2 only if you absolutely can’t use option 1 for any reason.