diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 163c6174c9dfedcf757b319146af8591d9d79285..ab992d082b89b2cf9ee095dd42caae5661535b74 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -504,6 +504,16 @@ This field returns a [connection](#connections). It accepts the
 four standard [pagination arguments](#connection-pagination-arguments):
 `before: String`, `after: String`, `first: Int`, `last: Int`.
 
+### `Query.memberRolePermissions`
+
+List of all customizable permissions.
+
+Returns [`CustomizablePermissionConnection`](#customizablepermissionconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
 ### `Query.mergeRequest`
 
 Find a merge request.
@@ -9216,6 +9226,29 @@ The edge type for [`CustomizableDashboardVisualization`](#customizabledashboardv
 | <a id="customizabledashboardvisualizationedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
 | <a id="customizabledashboardvisualizationedgenode"></a>`node` | [`CustomizableDashboardVisualization`](#customizabledashboardvisualization) | The item at the end of the edge. |
 
+#### `CustomizablePermissionConnection`
+
+The connection type for [`CustomizablePermission`](#customizablepermission).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="customizablepermissionconnectionedges"></a>`edges` | [`[CustomizablePermissionEdge]`](#customizablepermissionedge) | A list of edges. |
+| <a id="customizablepermissionconnectionnodes"></a>`nodes` | [`[CustomizablePermission]`](#customizablepermission) | A list of nodes. |
+| <a id="customizablepermissionconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
+
+#### `CustomizablePermissionEdge`
+
+The edge type for [`CustomizablePermission`](#customizablepermission).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="customizablepermissionedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
+| <a id="customizablepermissionedgenode"></a>`node` | [`CustomizablePermission`](#customizablepermission) | The item at the end of the edge. |
+
 #### `DastProfileConnection`
 
 The connection type for [`DastProfile`](#dastprofile).
@@ -15307,6 +15340,18 @@ Represents a product analytics dashboard visualization.
 | <a id="customizabledashboardvisualizationslug"></a>`slug` | [`String!`](#string) | Slug of the visualization. |
 | <a id="customizabledashboardvisualizationtype"></a>`type` | [`String!`](#string) | Type of the visualization. |
 
+### `CustomizablePermission`
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="customizablepermissionavailablefor"></a>`availableFor` | [`[String!]!`](#string) | Objects the permission is available for. |
+| <a id="customizablepermissiondescription"></a>`description` | [`String`](#string) | Description of the permission. |
+| <a id="customizablepermissionname"></a>`name` | [`String!`](#string) | Localized name of the permission. |
+| <a id="customizablepermissionrequirement"></a>`requirement` | [`String`](#string) | Requirement of the permission. |
+| <a id="customizablepermissionvalue"></a>`value` | [`String!`](#string) | Value of the permission. |
+
 ### `DastPreScanVerification`
 
 Represents a DAST Pre Scan Verification.
diff --git a/ee/app/graphql/ee/types/query_type.rb b/ee/app/graphql/ee/types/query_type.rb
index f230bd22b15c3b1b2cf301ac7da8f2b361e417f1..802b827b0be15f90208c763d9774efc1c9c87eb0 100644
--- a/ee/app/graphql/ee/types/query_type.rb
+++ b/ee/app/graphql/ee/types/query_type.rb
@@ -129,6 +129,11 @@ module QueryType
               null: true,
               description: 'Instance level google cloud logging configurations.',
               resolver: ::Resolvers::AuditEvents::Instance::GoogleCloudLoggingConfigurationsResolver
+        field :member_role_permissions,
+              ::Types::MemberRoles::CustomizablePermissionType.connection_type,
+              resolver: ::Resolvers::MemberRoles::PermissionListResolver,
+              null: true,
+              description: 'List of all customizable permissions.'
       end
 
       def vulnerability(id:)
diff --git a/ee/app/graphql/resolvers/member_roles/permission_list_resolver.rb b/ee/app/graphql/resolvers/member_roles/permission_list_resolver.rb
new file mode 100644
index 0000000000000000000000000000000000000000..27b46bd1a2bb18cf0b9d9e06108a14cb4759c46f
--- /dev/null
+++ b/ee/app/graphql/resolvers/member_roles/permission_list_resolver.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Resolvers
+  module MemberRoles
+    class PermissionListResolver < BaseResolver
+      type Types::MemberRoles::CustomizablePermissionType, null: true
+
+      def resolve
+        MemberRole::ALL_CUSTOMIZABLE_PERMISSIONS.map do |permission, definition|
+          definition.merge(value: permission)
+        end
+      end
+    end
+  end
+end
diff --git a/ee/app/graphql/types/member_roles/customizable_permission_type.rb b/ee/app/graphql/types/member_roles/customizable_permission_type.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0fe8185f7a669af98efcac8bc69074cc86501ecd
--- /dev/null
+++ b/ee/app/graphql/types/member_roles/customizable_permission_type.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+module Types
+  module MemberRoles
+    # rubocop: disable Graphql/AuthorizeTypes
+    class CustomizablePermissionType < BaseObject
+      graphql_name 'CustomizablePermission'
+
+      field :available_for, [GraphQL::Types::String], null: false,
+        description: 'Objects the permission is available for.'
+      field :description, GraphQL::Types::String, null: true, description: 'Description of the permission.'
+      field :name, GraphQL::Types::String, null: false,
+        description: 'Localized name of the permission.'
+      field :requirement, GraphQL::Types::String, null: true, description: 'Requirement of the permission.'
+      field :value, GraphQL::Types::String, null: false, description: 'Value of the permission.'
+
+      def available_for
+        result = []
+        result << :project if MemberRole::ALL_CUSTOMIZABLE_PROJECT_PERMISSIONS.include?(object[:value])
+        result << :group if MemberRole::ALL_CUSTOMIZABLE_GROUP_PERMISSIONS.include?(object[:value])
+        result
+      end
+
+      def description
+        _(object[:description])
+      end
+
+      def name
+        _(object[:value].to_s.humanize)
+      end
+    end
+    # rubocop: enable Graphql/AuthorizeTypes
+  end
+end
diff --git a/ee/app/models/members/member_role.rb b/ee/app/models/members/member_role.rb
index b47a244af576ced17efb8baa5e07eb899c3f2d4f..6108f8db722f0ea0c45b2808539c8ab3a8f67c62 100644
--- a/ee/app/models/members/member_role.rb
+++ b/ee/app/models/members/member_role.rb
@@ -4,20 +4,20 @@ class MemberRole < ApplicationRecord # rubocop:disable Gitlab/NamespacedClass
   MAX_COUNT_PER_GROUP_HIERARCHY = 10
   ALL_CUSTOMIZABLE_PERMISSIONS = {
     admin_merge_request: {
-      descripition: 'Permission to admin merge requests'
+      description: 'Allows admin access to the merge requests.'
     },
     admin_vulnerability: {
-      description: 'Permission to admin vulnerability',
+      description: 'Allows admin access to the vulnerability reports.',
       requirement: :read_vulnerability
     },
     read_code: {
-      description: 'Permission to read code'
+      description: 'Allows read-only access to the source code.'
     },
     read_dependency: {
-      description: 'Permission to read dependency'
+      description: 'Allows read-only access to the dependencies.'
     },
     read_vulnerability: {
-      description: 'Permission to read vulnerability'
+      description: 'Allows read-only access to the vulnerability reports.'
     }
   }.freeze
   ALL_CUSTOMIZABLE_PROJECT_PERMISSIONS = [
diff --git a/ee/spec/graphql/types/member_roles/customizable_permission_type_spec.rb b/ee/spec/graphql/types/member_roles/customizable_permission_type_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..725845d59bb86a40e979ae261fbc5e3d25c6bc12
--- /dev/null
+++ b/ee/spec/graphql/types/member_roles/customizable_permission_type_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['CustomizablePermission'], feature_category: :system_access do
+  include GraphqlHelpers
+
+  it { expect(described_class.graphql_name).to eq('CustomizablePermission') }
+
+  it 'has the expected fields' do
+    expected_fields = %w[availableFor description requirement name value]
+
+    expect(described_class).to include_graphql_fields(*expected_fields)
+  end
+end
diff --git a/ee/spec/graphql/types/query_type_spec.rb b/ee/spec/graphql/types/query_type_spec.rb
index 8a8c060dcb1d9a2529a094573ecf0433a29fc7d8..b8426fcd6d4a1daf351152a340667e58b0ccea6e 100644
--- a/ee/spec/graphql/types/query_type_spec.rb
+++ b/ee/spec/graphql/types/query_type_spec.rb
@@ -20,6 +20,7 @@
       :instance_security_dashboard,
       :iteration,
       :license_history_entries,
+      :member_role_permissions,
       :organization,
       :subscription_future_entries,
       :vulnerabilities,
diff --git a/ee/spec/requests/api/graphql/member_role/permissions_list_spec.rb b/ee/spec/requests/api/graphql/member_role/permissions_list_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c88292a1e2466163001d13f0c2d00ada3974e81e
--- /dev/null
+++ b/ee/spec/requests/api/graphql/member_role/permissions_list_spec.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Query.member_role_permissions', feature_category: :system_access do
+  include GraphqlHelpers
+
+  let(:fields) do
+    <<~QUERY
+      nodes {
+        availableFor
+        description
+        name
+        requirement
+        value
+      }
+    QUERY
+  end
+
+  let(:query) do
+    graphql_query_for('memberRolePermissions', fields)
+  end
+
+  before do
+    stub_const('MemberRole::ALL_CUSTOMIZABLE_PERMISSIONS',
+      {
+        admin_ability_one: {
+          description: 'Allows admin access to do something.',
+          minimal_level: Gitlab::Access::GUEST
+        },
+        admin_ability_two: {
+          description: 'Allows admin access to do something else.',
+          minimal_level: Gitlab::Access::DEVELOPER,
+          requirement: :read_ability_two
+        },
+        read_ability_two: {
+          description: 'Allows read access to do something else.',
+          minimal_level: Gitlab::Access::GUEST
+        }
+      }
+    )
+    stub_const('::MemberRole::ALL_CUSTOMIZABLE_PROJECT_PERMISSIONS',
+      [:admin_ability_one, :read_ability_two]
+    )
+    stub_const('::MemberRole::ALL_CUSTOMIZABLE_GROUP_PERMISSIONS',
+      [:admin_ability_two, :read_ability_two]
+    )
+
+    post_graphql(query)
+  end
+
+  subject { graphql_data.dig('memberRolePermissions', 'nodes') }
+
+  it_behaves_like 'a working graphql query'
+
+  it 'returns all customizable ablities' do
+    expected_result = [
+      { 'availableFor' => ['project'], 'description' => 'Allows admin access to do something.',
+        'name' => 'Admin ability one', 'requirement' => nil, 'value' => 'admin_ability_one' },
+      { 'availableFor' => %w[project group], 'description' => 'Allows read access to do something else.',
+        'name' => 'Read ability two', 'requirement' => nil, 'value' => 'read_ability_two' },
+      { 'availableFor' => ['group'], 'description' => "Allows admin access to do something else.",
+        'requirement' => 'read_ability_two', 'name' => 'Admin ability two', 'value' => 'admin_ability_two' }
+    ]
+
+    expect(subject).to match_array(expected_result)
+  end
+end