diff --git a/app/graphql/types/group_type.rb b/app/graphql/types/group_type.rb
index 01b741b5a986a9b7024333e8044abb700558ed2c..0bd0f251c1a3f601aec9da51c5b6a76582fb983f 100644
--- a/app/graphql/types/group_type.rb
+++ b/app/graphql/types/group_type.rb
@@ -62,6 +62,10 @@ class GroupType < NamespaceType
           null: true,
           description: 'Indicates if a group has email notifications disabled.'
 
+    field :max_access_level, Types::AccessLevelType,
+          null: false,
+          description: 'The maximum access level of the current user in the group.'
+
     field :mentions_disabled,
           type: GraphQL::Types::Boolean,
           null: true,
@@ -375,6 +379,16 @@ def group_members_count
       end
     end
 
+    def max_access_level
+      return Gitlab::Access::NO_ACCESS if current_user.nil?
+
+      BatchLoader::GraphQL.for(object.id).batch do |group_ids, loader|
+        current_user.max_member_access_for_group_ids(group_ids).each do |group_id, max_access_level|
+          loader.call(group_id, max_access_level)
+        end
+      end
+    end
+
     private
 
     def group
diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb
index 7f49c717c786acf25eb9a7ef90e18232310bff11..aacd67e269eed1b9a6e44d2514385243a5656980 100644
--- a/app/graphql/types/project_type.rb
+++ b/app/graphql/types/project_type.rb
@@ -110,6 +110,10 @@ class ProjectType < BaseObject
       null: true,
       description: 'Indicates if the project has Large File Storage (LFS) enabled.'
 
+    field :max_access_level, Types::AccessLevelType,
+      null: false,
+      description: 'The maximum access level of the current user in the project.'
+
     field :merge_requests_ff_only_enabled, GraphQL::Types::Boolean,
       null: true,
       description: 'Indicates if no merge commits should be created and all merges should instead be ' \
@@ -823,6 +827,16 @@ def statistics_details_paths
       }
     end
 
+    def max_access_level
+      return Gitlab::Access::NO_ACCESS if current_user.nil?
+
+      BatchLoader::GraphQL.for(object.id).batch do |project_ids, loader|
+        current_user.max_member_access_for_project_ids(project_ids).each do |project_id, max_access_level|
+          loader.call(project_id, max_access_level)
+        end
+      end
+    end
+
     private
 
     def project
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index ab52f1ceb2a8c39dac54a6d891a6c681ad9ec196..0271e5bca7be13b7153ab506a9ba8d4b036eaf86 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -19444,6 +19444,7 @@ GPG signature for a signed commit.
 | <a id="groupid"></a>`id` | [`ID!`](#id) | ID of the namespace. |
 | <a id="groupistemporarystorageincreaseenabled"></a>`isTemporaryStorageIncreaseEnabled` **{warning-solid}** | [`Boolean`](#boolean) | **Deprecated** in 16.7. Feature removal, will be completely removed in 17.0. |
 | <a id="grouplfsenabled"></a>`lfsEnabled` | [`Boolean`](#boolean) | Indicates if Large File Storage (LFS) is enabled for namespace. |
+| <a id="groupmaxaccesslevel"></a>`maxAccessLevel` | [`AccessLevel!`](#accesslevel) | The maximum access level of the current user in the group. |
 | <a id="groupmentionsdisabled"></a>`mentionsDisabled` | [`Boolean`](#boolean) | Indicates if a group is disabled from getting mentioned. |
 | <a id="groupname"></a>`name` | [`String!`](#string) | Name of the namespace. |
 | <a id="grouppackagesettings"></a>`packageSettings` | [`PackageSettings`](#packagesettings) | Package settings for the namespace. |
@@ -24407,6 +24408,7 @@ Represents vulnerability finding of a security report on the pipeline.
 | <a id="projectlanguages"></a>`languages` | [`[RepositoryLanguage!]`](#repositorylanguage) | Programming languages used in the project. |
 | <a id="projectlastactivityat"></a>`lastActivityAt` | [`Time`](#time) | Timestamp of the project last activity. |
 | <a id="projectlfsenabled"></a>`lfsEnabled` | [`Boolean`](#boolean) | Indicates if the project has Large File Storage (LFS) enabled. |
+| <a id="projectmaxaccesslevel"></a>`maxAccessLevel` | [`AccessLevel!`](#accesslevel) | The maximum access level of the current user in the project. |
 | <a id="projectmergecommittemplate"></a>`mergeCommitTemplate` | [`String`](#string) | Template used to create merge commit message in merge requests. |
 | <a id="projectmergerequestsaccesslevel"></a>`mergeRequestsAccessLevel` | [`ProjectFeatureAccess`](#projectfeatureaccess) | Access level required for merge requests access. |
 | <a id="projectmergerequestsdisablecommittersapproval"></a>`mergeRequestsDisableCommittersApproval` | [`Boolean!`](#boolean) | Indicates that committers of the given merge request cannot approve. |
diff --git a/spec/graphql/resolvers/concerns/resolves_groups_spec.rb b/spec/graphql/resolvers/concerns/resolves_groups_spec.rb
index 72e86d54deaa88fb5a5bb72a8167077e17825809..06a6b8d9ada82e2d3308e10582676fe4a4497746 100644
--- a/spec/graphql/resolvers/concerns/resolves_groups_spec.rb
+++ b/spec/graphql/resolvers/concerns/resolves_groups_spec.rb
@@ -26,15 +26,16 @@
     <<~FIELDS
       containerRepositoriesCount
       customEmoji { nodes { id } }
-      fullPath
-      groupMembersCount
-      path
       dependencyProxyBlobCount
       dependencyProxyBlobs { nodes { fileName } }
       dependencyProxyImageCount
       dependencyProxyImageTtlPolicy { enabled }
       dependencyProxySetting { enabled }
       descendantGroupsCount
+      fullPath
+      groupMembersCount
+      maxAccessLevel { integerValue }
+      path
       projectsCount
     FIELDS
   end
diff --git a/spec/graphql/types/group_type_spec.rb b/spec/graphql/types/group_type_spec.rb
index 51a9476f449f8962032ca7b90e28317194d3809c..7231a1e0357dbe7019c5f3dd3b0a3b25f8e2a1f8 100644
--- a/spec/graphql/types/group_type_spec.rb
+++ b/spec/graphql/types/group_type_spec.rb
@@ -22,7 +22,7 @@
       mentions_disabled parent boards milestones group_members
       merge_requests container_repositories container_repositories_count
       packages dependency_proxy_setting dependency_proxy_manifests
-      dependency_proxy_blobs dependency_proxy_image_count
+      dependency_proxy_blobs dependency_proxy_image_count max_access_level
       dependency_proxy_blob_count dependency_proxy_total_size dependency_proxy_total_size_in_bytes
       dependency_proxy_image_prefix dependency_proxy_image_ttl_policy
       shared_runners_setting timelogs organization_state_counts organizations
diff --git a/spec/graphql/types/project_type_spec.rb b/spec/graphql/types/project_type_spec.rb
index 36d72140006717296f5215c3341be010b9336df5..f6e178f5b28b522448d426b269f75e70f03ebdf9 100644
--- a/spec/graphql/types/project_type_spec.rb
+++ b/spec/graphql/types/project_type_spec.rb
@@ -34,7 +34,7 @@
       incident_management_timeline_event incident_management_timeline_events
       container_expiration_policy service_desk_enabled service_desk_address
       issue_status_counts terraform_states alert_management_integrations
-      container_repositories container_repositories_count
+      container_repositories container_repositories_count max_access_level
       pipeline_analytics squash_read_only sast_ci_configuration
       cluster_agent cluster_agents agent_configurations ci_access_authorized_agents user_access_authorized_agents
       ci_template timelogs merge_commit_template squash_commit_template work_item_types
diff --git a/spec/requests/api/graphql/group_query_spec.rb b/spec/requests/api/graphql/group_query_spec.rb
index 1dcbc44c587f3639809331271bbeba4fe17ae64d..1b3b153ebe08b90ded512e3430961329c4373814 100644
--- a/spec/requests/api/graphql/group_query_spec.rb
+++ b/spec/requests/api/graphql/group_query_spec.rb
@@ -217,5 +217,33 @@ def group_query(group)
         expect(graphql_data['group']).to be_nil
       end
     end
+
+    describe 'maxAccessLevel' do
+      let(:current_user) { user1 }
+
+      it 'returns access level of the current user in the group' do
+        private_group.add_owner(user1)
+
+        post_graphql(group_query(private_group), current_user: current_user)
+
+        expect(graphql_data_at(:group, :maxAccessLevel, :integerValue)).to eq(Gitlab::Access::OWNER)
+      end
+
+      shared_examples 'public group in which the user has no membership' do
+        it 'returns no access' do
+          post_graphql(group_query(public_group), current_user: current_user)
+
+          expect(graphql_data_at(:group, :maxAccessLevel, :integerValue)).to eq(Gitlab::Access::NO_ACCESS)
+        end
+      end
+
+      it_behaves_like 'public group in which the user has no membership'
+
+      context 'when the user is not authenticated' do
+        let(:current_user) { nil }
+
+        it_behaves_like 'public group in which the user has no membership'
+      end
+    end
   end
 end
diff --git a/spec/requests/api/graphql/project_query_spec.rb b/spec/requests/api/graphql/project_query_spec.rb
index 2d9c6367676c2ce629445bc514b003e55c2d3b00..0c72f34efeeddb7e336a3f9a73fbabe10a83e555 100644
--- a/spec/requests/api/graphql/project_query_spec.rb
+++ b/spec/requests/api/graphql/project_query_spec.rb
@@ -401,4 +401,34 @@
       end
     end
   end
+
+  describe 'maxAccessLevel' do
+    let(:project_fields) { 'maxAccessLevel { integerValue }' }
+
+    it 'returns access level of the current user in the project' do
+      project.add_developer(current_user)
+
+      post_graphql(query, current_user: current_user)
+
+      expect(graphql_data_at(:project, :maxAccessLevel, :integerValue)).to eq(Gitlab::Access::DEVELOPER)
+    end
+
+    shared_examples 'public project in which the user has no membership' do
+      it 'returns no access' do
+        project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
+
+        post_graphql(query, current_user: current_user)
+
+        expect(graphql_data_at(:project, :maxAccessLevel, :integerValue)).to eq(Gitlab::Access::NO_ACCESS)
+      end
+    end
+
+    it_behaves_like 'public project in which the user has no membership'
+
+    context 'when the user is not authenticated' do
+      let(:current_user) { nil }
+
+      it_behaves_like 'public project in which the user has no membership'
+    end
+  end
 end