How can I create an entity reference field to list a subset of roles? I want to provide a field in a node to lists a subset of available roles. These roles could be used to decide how the node would be displayed to users with the roles selected here.

Is there a way to create an entity reference field of entity type user role? If yes, how can I restrict the field to display only certain roles? The usual way is to create a view with entity reference display and add conditions in the view to restrict the options. Is it possible to create a view of type user role?
Two parts to check here.


Is it possible to reference user role (a config entity) 
Is there a way to restrict the available roles in the field level.


reg #1, yes! the out-of-box Drupal core allows creating an entity reference field with the target entity as a user role.



For #2, there is no easy way as the only way to restrict the available option(in core) is via views, but unfortunately, we can create views of the content entities. However, we can add a reference handler with config (as below) to restrict the available roles.

&lt;?php

namespace Drupal\mymodule\Plugin\EntityReferenceSelection;

use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection;
use Drupal\Core\Form\FormStateInterface;

/**
 * Provide configuration to select specific roles to reference.
 *
 * @EntityReferenceSelection(
 *   id = "default:user_role",
 *   label = @Translation("Role selection"),
 *   entity_types = {"user_role"},
 *   group = "default",
 *   weight = 1
 * )
 */
class RoleSelection extends DefaultSelection {

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildConfigurationForm($form, $form_state);
    $configuration = $this-&gt;getConfiguration();
    $entity_type_id = $configuration['target_type'];
    $storage = $this-&gt;entityTypeManager-&gt;getStorage($entity_type_id);

    $options = array_map(function ($entity) {
      /** @var \Drupal\Core\Entity\EntityInterface $entity */
      return $entity-&gt;label();
    }, $storage-&gt;loadMultiple());

    $form['target_roles'] = [
      '#type' =&gt; 'checkboxes',
      '#title' =&gt; $this-&gt;t('Allowed roles'),
      '#options' =&gt; $options,
      '#default_value' =&gt; isset($configuration['target_roles']) ? (array) $configuration['target_roles'] : [],
      '#multiple' =&gt; TRUE,
    ];
    return $form;
  }
    /**
   * {@inheritDoc}
   */
  protected function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
    $configuration = $this-&gt;getConfiguration();
    $target_type = $configuration['target_type'] ?: [];
    $entity_type = $this-&gt;entityTypeManager-&gt;getDefinition($target_type);
    $query = parent::buildEntityQuery($match, $match_operator);

    // Add condition, if set of roles selected.
    if (isset( $configuration['target_roles'])) {
      $query-&gt;condition($entity_type-&gt;getKey('id'), $configuration['target_roles'], 'IN');
    }
    return $query;
  }

}


Here is the field settings page:
 

and here is the final output: