diff --git a/api-ref/source/baremetal-api-v1-drivers.inc b/api-ref/source/baremetal-api-v1-drivers.inc
index b7d8518140..c680aa0ec3 100644
--- a/api-ref/source/baremetal-api-v1-drivers.inc
+++ b/api-ref/source/baremetal-api-v1-drivers.inc
@@ -49,6 +49,9 @@ List drivers
 
 Lists all drivers.
 
+.. versionadded:: 1.77
+  Added ``fields`` selector to query for particular fields.
+
 Normal response codes: 200
 
 Request
@@ -58,6 +61,7 @@ Request
 
     - type: driver_type
     - detail: driver_detail
+    - fields: fields
 
 Response Parameters
 -------------------
@@ -125,6 +129,9 @@ Show driver details
 
 Shows details for a driver.
 
+.. versionadded:: 1.77
+  Added ``fields`` selector to query for particular fields.
+
 Normal response codes: 200
 
 Request
@@ -133,6 +140,7 @@ Request
 .. rest_parameters:: parameters.yaml
 
    - driver_name: driver_ident
+   - fields: fields
 
 Response Parameters
 -------------------
diff --git a/doc/source/contributor/webapi-version-history.rst b/doc/source/contributor/webapi-version-history.rst
index 6d6b715c78..c83cf2698c 100644
--- a/doc/source/contributor/webapi-version-history.rst
+++ b/doc/source/contributor/webapi-version-history.rst
@@ -2,6 +2,13 @@
 REST API Version History
 ========================
 
+1.77
+----------------------
+Add a fields selector to the the Drivers list:
+* ``GET /v1/drivers?fields=``
+Also add a fields selector to the the Driver detail:
+* ``GET /v1/drivers/{driver_name}?fields=``
+
 1.76 (Xena, ?)
 ----------------------
 Add endpoints for changing boot mode and secure boot state of node
diff --git a/ironic/api/controllers/v1/driver.py b/ironic/api/controllers/v1/driver.py
index 9027e4638d..2775ed284b 100644
--- a/ironic/api/controllers/v1/driver.py
+++ b/ironic/api/controllers/v1/driver.py
@@ -81,7 +81,8 @@ def hide_fields_in_newer_versions(driver):
         driver.pop('enabled_bios_interfaces', None)
 
 
-def convert_with_links(name, hosts, detail=False, interface_info=None):
+def convert_with_links(name, hosts, detail=False, interface_info=None,
+                       fields=None, sanitize=True):
     """Convert driver/hardware type info to a dict.
 
     :param name: name of a hardware type.
@@ -90,6 +91,8 @@ def convert_with_links(name, hosts, detail=False, interface_info=None):
                     the 'type' field and default/enabled interfaces fields.
     :param interface_info: optional list of dicts of hardware interface
                             info.
+    :param fields: list of fields to preserve, or ``None`` to preserve default
+    :param sanitize: boolean,  sanitize driver
     :returns: dict representing the driver object.
     """
     driver = {
@@ -143,16 +146,35 @@ def convert_with_links(name, hosts, detail=False, interface_info=None):
                 driver[enabled_key] = list(enabled)
 
     hide_fields_in_newer_versions(driver)
+
+    if not sanitize:
+        return driver
+
+    driver_sanitize(driver, fields)
+
     return driver
 
 
-def list_convert_with_links(hardware_types, detail=False):
+def driver_sanitize(driver, fields=None):
+    if fields is not None:
+        api_utils.sanitize_dict(driver, fields)
+        api_utils.check_for_invalid_fields(fields, driver)
+
+
+def _check_allow_driver_fields(fields):
+    if (fields is not None and api.request.version.minor
+            < api.controllers.v1.versions.MINOR_77_DRIVER_FIELDS_SELECTOR):
+        raise exception.NotAcceptable()
+
+
+def list_convert_with_links(hardware_types, detail=False, fields=None):
     """Convert drivers and hardware types to an API-serializable object.
 
     :param hardware_types: dict mapping hardware type names to conductor
                             hostnames.
     :param detail: boolean, whether to include detailed info, such as
                     the 'type' field and default/enabled interfaces fields.
+    :param fields: list of fields to preserve, or ``None`` to preserve default
     :returns: an API-serializable driver collection object.
     """
     drivers = []
@@ -177,7 +199,8 @@ def list_convert_with_links(hardware_types, detail=False):
             convert_with_links(htname,
                                list(hardware_types[htname]),
                                detail=detail,
-                               interface_info=interface_info))
+                               interface_info=interface_info,
+                               fields=fields))
     return collection
 
 
@@ -294,16 +317,22 @@ class DriversController(rest.RestController):
 
     @METRICS.timer('DriversController.get_all')
     @method.expose()
-    @args.validate(type=args.string, detail=args.boolean)
-    def get_all(self, type=None, detail=None):
+    @args.validate(type=args.string, detail=args.boolean,
+                   fields=args.string_list)
+    def get_all(self, type=None, detail=None, fields=None):
         """Retrieve a list of drivers."""
         # FIXME(tenbrae): formatting of the auto-generated REST API docs
         #              will break from a single-line doc string.
         #              This is a result of a bug in sphinxcontrib-pecanwsme
         # https://github.com/dreamhost/sphinxcontrib-pecanwsme/issues/8
+        if fields and detail:
+            raise exception.InvalidParameterValue(
+                "Can not specify ?detail=True and fields in the same request.")
+
         api_utils.check_policy('baremetal:driver:get')
         api_utils.check_allow_driver_detail(detail)
         api_utils.check_allow_filter_driver_type(type)
+        _check_allow_driver_fields(fields)
         if type not in (None, 'classic', 'dynamic'):
             raise exception.Invalid(_(
                 '"type" filter must be one of "classic" or "dynamic", '
@@ -315,12 +344,13 @@ class DriversController(rest.RestController):
             # NOTE(dtantsur): we don't support classic drivers starting with
             # the Rocky release.
             hw_type_dict = {}
-        return list_convert_with_links(hw_type_dict, detail=detail)
+        return list_convert_with_links(hw_type_dict, detail=detail,
+                                       fields=fields)
 
     @METRICS.timer('DriversController.get_one')
     @method.expose()
-    @args.validate(driver_name=args.string)
-    def get_one(self, driver_name):
+    @args.validate(driver_name=args.string, fields=args.string_list)
+    def get_one(self, driver_name, fields=None):
         """Retrieve a single driver."""
         # NOTE(russell_h): There is no way to make this more efficient than
         # retrieving a list of drivers using the current sqlalchemy schema, but
@@ -328,11 +358,13 @@ class DriversController(rest.RestController):
         # choose to expose below it.
         api_utils.check_policy('baremetal:driver:get')
 
+        _check_allow_driver_fields(fields)
+
         hw_type_dict = api.request.dbapi.get_active_hardware_type_dict()
         for name, hosts in hw_type_dict.items():
             if name == driver_name:
                 return convert_with_links(name, list(hosts),
-                                          detail=True)
+                                          detail=True, fields=fields)
 
         raise exception.DriverNotFound(driver_name=driver_name)
 
diff --git a/ironic/api/controllers/v1/versions.py b/ironic/api/controllers/v1/versions.py
index 9cd890e8f8..0489b1dbe4 100644
--- a/ironic/api/controllers/v1/versions.py
+++ b/ironic/api/controllers/v1/versions.py
@@ -114,6 +114,7 @@ BASE_VERSION = 1
 # v1.74: Add bios registry to /v1/nodes/{node}/bios/{setting}
 # v1.75: Add boot_mode, secure_boot fields to node object.
 # v1.76: Add support for changing boot_mode and secure_boot state
+# v1.77: Add fields selector to drivers list and driver detail.
 
 MINOR_0_JUNO = 0
 MINOR_1_INITIAL_VERSION = 1
@@ -192,6 +193,7 @@ MINOR_73_DEPLOY_UNDEPLOY_VERBS = 73
 MINOR_74_BIOS_REGISTRY = 74
 MINOR_75_NODE_BOOT_MODE = 75
 MINOR_76_NODE_CHANGE_BOOT_MODE = 76
+MINOR_77_DRIVER_FIELDS_SELECTOR = 77
 
 # When adding another version, update:
 # - MINOR_MAX_VERSION
@@ -199,7 +201,7 @@ MINOR_76_NODE_CHANGE_BOOT_MODE = 76
 #   explanation of what changed in the new version
 # - common/release_mappings.py, RELEASE_MAPPING['master']['api']
 
-MINOR_MAX_VERSION = MINOR_76_NODE_CHANGE_BOOT_MODE
+MINOR_MAX_VERSION = MINOR_77_DRIVER_FIELDS_SELECTOR
 
 # String representations of the minor and maximum versions
 _MIN_VERSION_STRING = '{}.{}'.format(BASE_VERSION, MINOR_1_INITIAL_VERSION)
diff --git a/ironic/common/release_mappings.py b/ironic/common/release_mappings.py
index cd86488df5..2baad9af34 100644
--- a/ironic/common/release_mappings.py
+++ b/ironic/common/release_mappings.py
@@ -371,7 +371,7 @@ RELEASE_MAPPING = {
         }
     },
     'master': {
-        'api': '1.76',
+        'api': '1.77',
         'rpc': '1.55',
         'objects': {
             'Allocation': ['1.1'],
diff --git a/ironic/tests/unit/api/controllers/v1/test_driver.py b/ironic/tests/unit/api/controllers/v1/test_driver.py
index b991ac7af9..6bf04297ff 100644
--- a/ironic/tests/unit/api/controllers/v1/test_driver.py
+++ b/ironic/tests/unit/api/controllers/v1/test_driver.py
@@ -274,6 +274,77 @@ class TestListDrivers(base.BaseApiTest):
         response = self.get_json('/drivers/nope', expect_errors=True)
         self.assertEqual(http_client.NOT_FOUND, response.status_int)
 
+    def test_drivers_collection_custom_fields(self):
+        self.register_fake_conductors()
+        fields = "name,hosts"
+        data = self.get_json('/drivers?fields=%s' % fields,
+                             headers={api_base.Version.string: '1.77'})
+        for data_driver in data['drivers']:
+            self.assertCountEqual(['name', 'hosts', 'links'], data_driver)
+
+    def test_get_one_custom_fields(self):
+        self.register_fake_conductors()
+        driver = self.hw1
+        fields = "name,hosts"
+        data = self.get_json('/drivers/%s?fields=%s' % (driver, fields),
+                             headers={api_base.Version.string: '1.77'})
+        self.assertCountEqual(['name', 'hosts', 'links'], data)
+
+    def test_get_custom_fields_invalid_api_version(self):
+        self.register_fake_conductors()
+        driver = self.hw1
+        fields = "name,hosts"
+
+        response = self.get_json('/drivers?fields=%s' % fields,
+                                 headers={api_base.Version.string: '1.76'},
+                                 expect_errors=True)
+        self.assertEqual('application/json', response.content_type)
+        self.assertEqual(http_client.NOT_ACCEPTABLE, response.status_int)
+
+        response = self.get_json('/drivers/%s?fields=%s' % (driver, fields),
+                                 headers={api_base.Version.string: '1.76'},
+                                 expect_errors=True)
+        self.assertEqual('application/json', response.content_type)
+        self.assertEqual(http_client.NOT_ACCEPTABLE, response.status_int)
+
+    def test_drivers_collection_custom_fields_with_detail_true(self):
+        self.register_fake_conductors()
+        fields = "name,hosts"
+        response = self.get_json('/drivers?detail=true&fields=%s' % fields,
+                                 headers={api_base.Version.string: '1.77'},
+                                 expect_errors=True)
+        self.assertEqual('application/json', response.content_type)
+        self.assertEqual(http_client.BAD_REQUEST, response.status_int)
+
+    def test_drivers_collection_custom_fields_with_detail_false(self):
+        self.register_fake_conductors()
+        fields = "name,hosts"
+        data = self.get_json('/drivers?fields=%s&detail=false' % fields,
+                             headers={api_base.Version.string: '1.77'})
+        for data_driver in data['drivers']:
+            self.assertCountEqual(['name', 'hosts', 'links'], data_driver)
+
+    def test_drivers_collection_invalid_custom_fields(self):
+        self.register_fake_conductors()
+        fields = "name,invalid"
+        response = self.get_json('/drivers?fields=%s' % fields,
+                                 headers={api_base.Version.string: '1.77'},
+                                 expect_errors=True)
+        self.assertEqual(http_client.BAD_REQUEST, response.status_int)
+        self.assertEqual('application/json', response.content_type)
+        self.assertIn('invalid', response.json['error_message'])
+
+    def test_get_one_invalid_custom_fields(self):
+        self.register_fake_conductors()
+        driver = self.hw1
+        fields = "name,invalid"
+        response = self.get_json('/drivers/%s?fields=%s' % (driver, fields),
+                                 headers={api_base.Version.string: '1.77'},
+                                 expect_errors=True)
+        self.assertEqual(http_client.BAD_REQUEST, response.status_int)
+        self.assertEqual('application/json', response.content_type)
+        self.assertIn('invalid', response.json['error_message'])
+
     def _test_links(self, public_url=None):
         cfg.CONF.set_override('public_endpoint', public_url, 'api')
         self.register_fake_conductors()
diff --git a/releasenotes/notes/add-driver-api-fields-selector-36f12259f01b0f7a.yaml b/releasenotes/notes/add-driver-api-fields-selector-36f12259f01b0f7a.yaml
new file mode 100644
index 0000000000..ca5e45bc99
--- /dev/null
+++ b/releasenotes/notes/add-driver-api-fields-selector-36f12259f01b0f7a.yaml
@@ -0,0 +1,9 @@
+---
+features:
+  - |
+    Adds support for fields selector in driver api.
+    See `story 1674775
+    <https://storyboard.openstack.org/#!/story/1674775>`_.
+
+    * ``GET /v1/drivers?fields=...``
+    * ``GET /v1/drivers/{driver_name}?fields=...``