diff --git a/doc/api/graphql/reference/gitlab_schema.graphql b/doc/api/graphql/reference/gitlab_schema.graphql
index b1f43f38e510775befacc5c78353a2f38dd7cfcc..6af179c5718a9a7b99246e8d5dc664a9598ed4ce 100644
--- a/doc/api/graphql/reference/gitlab_schema.graphql
+++ b/doc/api/graphql/reference/gitlab_schema.graphql
@@ -9499,6 +9499,11 @@ type GeoNode {
     """
     first: Int
 
+    """
+    Global ID of a specific compliance framework to return.
+    """
+    id: ComplianceManagementFrameworkID
+
     """
     Returns the last _n_ elements from the list.
     """
@@ -9715,7 +9720,7 @@ type Group {
   ): CodeCoverageActivityConnection
 
   """
-  Compliance frameworks available to projects in this namespace Available only
+  Compliance frameworks available to projects in this namespace. Available only
   when feature flag `ff_custom_compliance_frameworks` is enabled.
   """
   complianceFrameworks(
@@ -15368,7 +15373,7 @@ type Namespace {
   additionalPurchasedStorageSize: Float
 
   """
-  Compliance frameworks available to projects in this namespace Available only
+  Compliance frameworks available to projects in this namespace. Available only
   when feature flag `ff_custom_compliance_frameworks` is enabled.
   """
   complianceFrameworks(
@@ -15387,6 +15392,11 @@ type Namespace {
     """
     first: Int
 
+    """
+    Global ID of a specific compliance framework to return.
+    """
+    id: ComplianceManagementFrameworkID
+
     """
     Returns the last _n_ elements from the list.
     """
diff --git a/doc/api/graphql/reference/gitlab_schema.json b/doc/api/graphql/reference/gitlab_schema.json
index 34d80e450f4cfeca1aad1b231383aafdef48a9c0..0e72319c4b0ca0d76474361f2bfc330b23a4dbfd 100644
--- a/doc/api/graphql/reference/gitlab_schema.json
+++ b/doc/api/graphql/reference/gitlab_schema.json
@@ -26177,6 +26177,16 @@
                     "ofType": null
                   },
                   "defaultValue": null
+                },
+                {
+                  "name": "id",
+                  "description": "Global ID of a specific compliance framework to return.",
+                  "type": {
+                    "kind": "SCALAR",
+                    "name": "ComplianceManagementFrameworkID",
+                    "ofType": null
+                  },
+                  "defaultValue": null
                 }
               ],
               "type": {
@@ -26928,7 +26938,7 @@
             },
             {
               "name": "complianceFrameworks",
-              "description": "Compliance frameworks available to projects in this namespace Available only when feature flag `ff_custom_compliance_frameworks` is enabled.",
+              "description": "Compliance frameworks available to projects in this namespace. Available only when feature flag `ff_custom_compliance_frameworks` is enabled.",
               "args": [
                 {
                   "name": "after",
@@ -45542,7 +45552,7 @@
             },
             {
               "name": "complianceFrameworks",
-              "description": "Compliance frameworks available to projects in this namespace Available only when feature flag `ff_custom_compliance_frameworks` is enabled.",
+              "description": "Compliance frameworks available to projects in this namespace. Available only when feature flag `ff_custom_compliance_frameworks` is enabled.",
               "args": [
                 {
                   "name": "after",
@@ -45583,6 +45593,16 @@
                     "ofType": null
                   },
                   "defaultValue": null
+                },
+                {
+                  "name": "id",
+                  "description": "Global ID of a specific compliance framework to return.",
+                  "type": {
+                    "kind": "SCALAR",
+                    "name": "ComplianceManagementFrameworkID",
+                    "ofType": null
+                  },
+                  "defaultValue": null
                 }
               ],
               "type": {
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 439b3f8527a8bff15d6d2cd421df40db4fd41bff..720c7ca557f2d4d3fd7b297c599ccb651f390bc6 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -1579,7 +1579,7 @@ Represents an external issue.
 | `board` | Board | A single board of the group |
 | `boards` | BoardConnection | Boards of the group |
 | `codeCoverageActivities` | CodeCoverageActivityConnection | Represents the code coverage activity for this group |
-| `complianceFrameworks` | ComplianceFrameworkConnection | Compliance frameworks available to projects in this namespace Available only when feature flag `ff_custom_compliance_frameworks` is enabled. |
+| `complianceFrameworks` | ComplianceFrameworkConnection | Compliance frameworks available to projects in this namespace. Available only when feature flag `ff_custom_compliance_frameworks` is enabled. |
 | `containerRepositories` | ContainerRepositoryConnection | Container repositories of the group |
 | `containerRepositoriesCount` | Int! | Number of container repositories in the group |
 | `containsLockedProjects` | Boolean! | Includes at least one project where the repository size exceeds the limit |
@@ -2329,7 +2329,7 @@ Contains statistics about a milestone.
 | ----- | ---- | ----------- |
 | `actualRepositorySizeLimit` | Float | Size limit for repositories in the namespace in bytes |
 | `additionalPurchasedStorageSize` | Float | Additional storage purchased for the root namespace in bytes |
-| `complianceFrameworks` | ComplianceFrameworkConnection | Compliance frameworks available to projects in this namespace Available only when feature flag `ff_custom_compliance_frameworks` is enabled. |
+| `complianceFrameworks` | ComplianceFrameworkConnection | Compliance frameworks available to projects in this namespace. Available only when feature flag `ff_custom_compliance_frameworks` is enabled. |
 | `containsLockedProjects` | Boolean! | Includes at least one project where the repository size exceeds the limit |
 | `description` | String | Description of the namespace |
 | `descriptionHtml` | String | The GitLab Flavored Markdown rendering of `description` |
diff --git a/ee/app/graphql/ee/types/namespace_type.rb b/ee/app/graphql/ee/types/namespace_type.rb
index d2156496cc3a8dfee8848dc0fd2dc2c130d79e2a..e087a5d7bdc6203af65952e8a81016de3a5ed6a0 100644
--- a/ee/app/graphql/ee/types/namespace_type.rb
+++ b/ee/app/graphql/ee/types/namespace_type.rb
@@ -57,8 +57,12 @@ module NamespaceType
         field :compliance_frameworks,
               ::Types::ComplianceManagement::ComplianceFrameworkType.connection_type,
               null: true,
-              description: 'Compliance frameworks available to projects in this namespace',
-              feature_flag: :ff_custom_compliance_frameworks
+              description: 'Compliance frameworks available to projects in this namespace.',
+              feature_flag: :ff_custom_compliance_frameworks do
+                argument :id, ::Types::GlobalIDType[::ComplianceManagement::Framework],
+                         description: 'Global ID of a specific compliance framework to return.',
+                         required: false
+              end
 
         def additional_purchased_storage_size
           object.additional_purchased_storage_size.megabytes
@@ -68,12 +72,22 @@ def storage_size_limit
           object.root_storage_size.limit
         end
 
-        def compliance_frameworks
-          BatchLoader::GraphQL.for(object.id).batch(default_value: []) do |namespace_ids, loader|
-            results = ::ComplianceManagement::Framework.with_namespaces(namespace_ids)
+        def compliance_frameworks(id: nil)
+          id = ::Types::GlobalIDType[::ComplianceManagement::Framework].coerce_isolated_input(id) unless id.nil?
+          BatchLoader::GraphQL
+            .for([object.id, id&.model_id])
+            .batch(default_value: []) do |keys, loader|
+            namespace_ids = keys.map(&:first).uniq
+            by_namespace_id = keys.group_by(&:first).transform_values { |k| k.map(&:second) }
+            frameworks = ::ComplianceManagement::Framework.with_namespaces(namespace_ids)
+            frameworks.group_by(&:namespace_id).each do |ns_id, group|
+              by_namespace_id[ns_id].each do |fw_id|
+                group.each do |fw|
+                  next unless fw_id.nil? || fw_id.to_i == fw.id
 
-            results.each do |framework|
-              loader.call(framework.namespace.id) { |xs| xs << framework }
+                  loader.call([ns_id, fw_id]) { |array| array << fw }
+                end
+              end
             end
           end
         end
diff --git a/ee/changelogs/unreleased/289846-graphql-namespace-frameworks-filter-by-id.yml b/ee/changelogs/unreleased/289846-graphql-namespace-frameworks-filter-by-id.yml
new file mode 100644
index 0000000000000000000000000000000000000000..76a908fbf8e70eb8ead031a0f0c1efa5c51f0426
--- /dev/null
+++ b/ee/changelogs/unreleased/289846-graphql-namespace-frameworks-filter-by-id.yml
@@ -0,0 +1,5 @@
+---
+title: Add ID filter to Namespace -> ComplianceFramework GraphQL
+merge_request: 49108
+author:
+type: added
diff --git a/ee/spec/requests/api/graphql/namespace/compliance_frameworks_spec.rb b/ee/spec/requests/api/graphql/namespace/compliance_frameworks_spec.rb
index 84caa279a1c4dc63b1485f39b8b2d70f81854c4e..40db43da11eb5d373b6886ef3534916a7097fea2 100644
--- a/ee/spec/requests/api/graphql/namespace/compliance_frameworks_spec.rb
+++ b/ee/spec/requests/api/graphql/namespace/compliance_frameworks_spec.rb
@@ -28,8 +28,51 @@
       )
     end
 
+    context 'when querying a specific framework ID' do
+      let(:query) do
+        graphql_query_for(
+          :namespace, { full_path: namespace.full_path }, query_nodes(:compliance_frameworks, nil, args: { id: global_id_of(compliance_framework_1) })
+        )
+      end
+
+      it 'returns only a single compliance framework' do
+        post_graphql(query, current_user: current_user)
+
+        expect(graphql_data_at(:namespace, :complianceFrameworks, :nodes).map { |n| n['id'] }).to contain_exactly(global_id_of(compliance_framework_1))
+      end
+    end
+
+    context 'when querying an invalid object ID' do
+      let(:query) do
+        graphql_query_for(
+          :namespace, { full_path: namespace.full_path }, query_nodes(:compliance_frameworks, nil, args: { id: global_id_of(namespace) })
+        )
+      end
+
+      it 'returns an error message' do
+        post_graphql(query, current_user: current_user)
+
+        expect(graphql_errors).to contain_exactly(include('message' => "\"#{global_id_of(namespace)}\" does not represent an instance of ComplianceManagement::Framework"))
+      end
+    end
+
+    context 'when querying a specific framework that current_user has no access to' do
+      let(:query) do
+        graphql_query_for(
+          :namespace, { full_path: namespace.full_path }, query_nodes(:compliance_frameworks, nil, args: { id: global_id_of(create(:compliance_framework)) })
+        )
+      end
+
+      it 'does not return the framework' do
+        post_graphql(query, current_user: current_user)
+
+        expect(graphql_data_at(:namespace, :complianceFrameworks, :nodes)).to be_empty
+      end
+    end
+
     context 'when querying multiple namespaces' do
       let(:group) { create(:group) }
+      let(:sox_framework) { create(:compliance_framework, namespace: group, name: 'SOX') }
       let(:multiple_namespace_query) do
         <<~QUERY
           query {
@@ -39,26 +82,33 @@
             b: namespace(fullPath: "#{group.full_path}") {
               complianceFrameworks { nodes { id name } }
             }
+            c: namespace(fullPath: "#{group.full_path}") {
+              complianceFrameworks(id: "#{sox_framework.to_global_id}") { nodes { id name } }
+            }
           }
         QUERY
       end
 
       before do
-        create(:compliance_framework, namespace: group)
+        create(:compliance_framework, namespace: group, name: 'GDPR')
         group.add_owner(current_user)
       end
 
       it 'avoids N+1 queries' do
+        post_graphql(query, current_user: current_user)
+        post_graphql(multiple_namespace_query, current_user: current_user)
+
         query_count = ActiveRecord::QueryRecorder.new { post_graphql(query, current_user: current_user) }.count
 
-        expect { post_graphql(multiple_namespace_query, current_user: current_user) }.not_to exceed_query_limit(query_count + 4)
+        expect { post_graphql(multiple_namespace_query, current_user: current_user) }.not_to exceed_query_limit(query_count + 2)
       end
 
       it 'responds with the expected list of compliance frameworks' do
         post_graphql(multiple_namespace_query, current_user: current_user)
 
-        expect(graphql_data_at(:a, :complianceFrameworks, :nodes).map { |f| f['name'] }).to contain_exactly('Test1', 'Test2')
-        expect(graphql_data_at(:b, :complianceFrameworks, :nodes).map { |f| f['name'] }).to contain_exactly('GDPR')
+        expect(graphql_data_at(:a, :complianceFrameworks, :nodes, :name)).to contain_exactly('Test1', 'Test2')
+        expect(graphql_data_at(:b, :complianceFrameworks, :nodes, :name)).to contain_exactly('GDPR', 'SOX')
+        expect(graphql_data_at(:c, :complianceFrameworks, :nodes, :name)).to contain_exactly('SOX')
       end
     end