diff --git a/app/graphql/mutations/ci/job_token_scope/add_group_or_project.rb b/app/graphql/mutations/ci/job_token_scope/add_group_or_project.rb
index b52ac2f301ec4c39656a5123f3a7e31f95d9f818..b7d28c8b12ba5f1d95ab2ca168e2dc63984ea629 100644
--- a/app/graphql/mutations/ci/job_token_scope/add_group_or_project.rb
+++ b/app/graphql/mutations/ci/job_token_scope/add_group_or_project.rb
@@ -18,6 +18,13 @@ class AddGroupOrProject < BaseMutation
           required: true,
           description: 'Group or project to be added to the CI job token scope.'
 
+        argument :default_permissions, GraphQL::Types::Boolean,
+          required: false,
+          default_value: true,
+          experiment: { milestone: '17.8' },
+          description: 'Indicates whether default permissions are enabled (true) or fine-grained permissions are ' \
+            'enabled (false).'
+
         argument :job_token_policies, [Types::Ci::JobTokenScope::PoliciesEnum],
           required: false,
           default_value: [],
@@ -36,16 +43,16 @@ class AddGroupOrProject < BaseMutation
           null: true,
           description: "CI job token's access scope."
 
-        def resolve(args)
-          project = authorized_find!(args[:project_path])
-
-          target = find_target_path(args[:target_path])
-
-          args.delete(:job_token_policies) unless Feature.enabled?(:add_policies_to_ci_job_token, project)
+        def resolve(project_path:, target_path:, default_permissions:, job_token_policies:)
+          project = authorized_find!(project_path)
+          target = find_target_path(target_path)
+          policies_enabled = Feature.enabled?(:add_policies_to_ci_job_token, project)
+          # Use default permissions if policies feature isn't enabled.
+          default = policies_enabled ? default_permissions : true
 
           result = ::Ci::JobTokenScope::AddGroupOrProjectService
             .new(project, current_user)
-            .execute(target, policies: args[:job_token_policies])
+            .execute(target, default_permissions: default, policies: job_token_policies)
 
           if result.success?
             {
diff --git a/app/graphql/mutations/ci/job_token_scope/update_job_token_policies.rb b/app/graphql/mutations/ci/job_token_scope/update_job_token_policies.rb
index ab53c09cde788bbacefe9ff289327387c3d00906..d5f9bf37b3f9ecdf865b8e0097ade9dd046d9afc 100644
--- a/app/graphql/mutations/ci/job_token_scope/update_job_token_policies.rb
+++ b/app/graphql/mutations/ci/job_token_scope/update_job_token_policies.rb
@@ -18,6 +18,11 @@ class UpdateJobTokenPolicies < BaseMutation
           required: true,
           description: 'Group or project that the CI job token targets.'
 
+        argument :default_permissions, GraphQL::Types::Boolean,
+          required: true,
+          description: 'Indicates whether default permissions are enabled (true) or fine-grained permissions are ' \
+            'enabled (false).'
+
         argument :job_token_policies, [Types::Ci::JobTokenScope::PoliciesEnum],
           required: true,
           description: 'List of policies added to the CI job token scope.'
@@ -28,7 +33,7 @@ class UpdateJobTokenPolicies < BaseMutation
           experiment: { milestone: '17.6' },
           description: "Allowlist entry for the CI job token's access scope."
 
-        def resolve(project_path:, target_path:, job_token_policies:)
+        def resolve(project_path:, target_path:, default_permissions:, job_token_policies:)
           project = authorized_find!(project_path)
           target = find_target_using_path(target_path)
 
@@ -38,7 +43,7 @@ def resolve(project_path:, target_path:, job_token_policies:)
 
           result = ::Ci::JobTokenScope::UpdatePoliciesService
             .new(project, current_user)
-            .execute(target, job_token_policies)
+            .execute(target, default_permissions, job_token_policies)
 
           if result.success?
             {
diff --git a/app/graphql/types/ci/job_token_scope/allowlist_entry_type.rb b/app/graphql/types/ci/job_token_scope/allowlist_entry_type.rb
index 3e976ef69193516c301a11f90ac8b5e8b1131f7d..c05927a79738c8c853825f0c9f944ae4e1603e64 100644
--- a/app/graphql/types/ci/job_token_scope/allowlist_entry_type.rb
+++ b/app/graphql/types/ci/job_token_scope/allowlist_entry_type.rb
@@ -25,6 +25,11 @@ class AllowlistEntryType < BaseObject
           null: true,
           description: 'Direction of access. Defaults to INBOUND.'
 
+        field :default_permissions,
+          GraphQL::Types::Boolean,
+          description: 'Indicates whether default permissions are enabled (true) or fine-grained permissions are ' \
+            'enabled (false).'
+
         field :job_token_policies,
           [Types::Ci::JobTokenScope::PoliciesEnum],
           null: true,
@@ -63,6 +68,10 @@ def direction
           end
         end
 
+        def default_permissions
+          Feature.enabled?(:add_policies_to_ci_job_token, object.source_project) ? object.default_permissions : true
+        end
+
         def job_token_policies
           return unless Feature.enabled?(:add_policies_to_ci_job_token, object.source_project)
 
diff --git a/app/models/ci/job_token/allowlist.rb b/app/models/ci/job_token/allowlist.rb
index c5248823d567f0aa54d661e116c0d9926c3f3160..2a4ec179b8c8481000e36c91c05cbc773f4bfc72 100644
--- a/app/models/ci/job_token/allowlist.rb
+++ b/app/models/ci/job_token/allowlist.rb
@@ -30,25 +30,29 @@ def groups
         ::Group.id_in(group_links.pluck(:target_group_id))
       end
 
-      def add!(target_project, user:, policies: [])
+      def add!(target_project, user:, default_permissions: true, policies: [])
         job_token_policies = add_policies_to_ci_job_token_enabled ? policies : []
+        default_permissions = add_policies_to_ci_job_token_enabled ? default_permissions : true
 
         Ci::JobToken::ProjectScopeLink.create!(
           source_project: @source_project,
           direction: @direction,
           target_project: target_project,
           added_by: user,
+          default_permissions: default_permissions,
           job_token_policies: job_token_policies
         )
       end
 
-      def add_group!(target_group, user:, policies: [])
+      def add_group!(target_group, user:, default_permissions: true, policies: [])
         job_token_policies = add_policies_to_ci_job_token_enabled ? policies : []
+        default_permissions = add_policies_to_ci_job_token_enabled ? default_permissions : true
 
         Ci::JobToken::GroupScopeLink.create!(
           source_project: @source_project,
           target_group: target_group,
           added_by: user,
+          default_permissions: default_permissions,
           job_token_policies: job_token_policies
         )
       end
diff --git a/app/services/ci/job_token_scope/add_group_or_project_service.rb b/app/services/ci/job_token_scope/add_group_or_project_service.rb
index 6b816cbc4dc80f66c68775e306881398fa6b990e..9d0fc40159a610eb63544347dcd590f0794c3ee9 100644
--- a/app/services/ci/job_token_scope/add_group_or_project_service.rb
+++ b/app/services/ci/job_token_scope/add_group_or_project_service.rb
@@ -5,13 +5,15 @@ module JobTokenScope
     class AddGroupOrProjectService < ::BaseService
       include EditScopeValidations
 
-      def execute(target, policies: [])
+      def execute(target, default_permissions: true, policies: [])
         validate_target_exists!(target)
 
         if target.is_a?(::Group)
-          ::Ci::JobTokenScope::AddGroupService.new(project, current_user).execute(target, policies: policies)
+          ::Ci::JobTokenScope::AddGroupService.new(project, current_user).execute(target,
+            default_permissions: default_permissions, policies: policies)
         else
-          ::Ci::JobTokenScope::AddProjectService.new(project, current_user).execute(target, policies: policies)
+          ::Ci::JobTokenScope::AddProjectService.new(project, current_user).execute(target,
+            default_permissions: default_permissions, policies: policies)
         end
 
       rescue EditScopeValidations::NotFoundError => e
diff --git a/app/services/ci/job_token_scope/add_group_service.rb b/app/services/ci/job_token_scope/add_group_service.rb
index 2ab8493212e3da3892b5276c39d8c1609c3afd69..05a89a523eaac686d41201480be9d66963d259e1 100644
--- a/app/services/ci/job_token_scope/add_group_service.rb
+++ b/app/services/ci/job_token_scope/add_group_service.rb
@@ -5,11 +5,11 @@ module JobTokenScope
     class AddGroupService < ::BaseService
       include EditScopeValidations
 
-      def execute(target_group, policies: [])
+      def execute(target_group, default_permissions: true, policies: [])
         validate_source_project_and_target_group_access!(project, target_group, current_user)
 
         link = allowlist
-          .add_group!(target_group, policies: policies, user: current_user)
+          .add_group!(target_group, default_permissions: default_permissions, policies: policies, user: current_user)
 
         ServiceResponse.success(payload: { group_link: link })
 
diff --git a/app/services/ci/job_token_scope/add_project_service.rb b/app/services/ci/job_token_scope/add_project_service.rb
index 0c9f37f732224b7400d1a58a0ae1c720b1880896..b1dfa1b5ccd4040421910d61f3490f7db07b7f74 100644
--- a/app/services/ci/job_token_scope/add_project_service.rb
+++ b/app/services/ci/job_token_scope/add_project_service.rb
@@ -5,11 +5,11 @@ module JobTokenScope
     class AddProjectService < ::BaseService
       include EditScopeValidations
 
-      def execute(target_project, policies: [], direction: :inbound)
+      def execute(target_project, default_permissions: true, policies: [], direction: :inbound)
         validate_source_project_and_target_project_access!(project, target_project, current_user)
 
         link = allowlist(direction)
-          .add!(target_project, policies: policies, user: current_user)
+          .add!(target_project, default_permissions: default_permissions, policies: policies, user: current_user)
 
         ServiceResponse.success(payload: { project_link: link })
 
diff --git a/app/services/ci/job_token_scope/update_policies_service.rb b/app/services/ci/job_token_scope/update_policies_service.rb
index 8cad91deb0de03fb2e333d90e66a04bb4abcfeb6..2f9d7b4787b138b0c4e37bee6ee4c98524527d40 100644
--- a/app/services/ci/job_token_scope/update_policies_service.rb
+++ b/app/services/ci/job_token_scope/update_policies_service.rb
@@ -5,7 +5,7 @@ module JobTokenScope
     class UpdatePoliciesService < ::BaseService
       include EditScopeValidations
 
-      def execute(target, policies)
+      def execute(target, default_permissions, policies)
         return unless Feature.enabled?(:add_policies_to_ci_job_token, project)
 
         validate_target_exists!(target)
@@ -15,7 +15,7 @@ def execute(target, policies)
 
         return error_link_not_found unless link
 
-        if link.update(job_token_policies: policies)
+        if link.update(default_permissions: default_permissions, job_token_policies: policies)
           ServiceResponse.success(payload: link)
         else
           error_updating(link)
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 36492cc22e38249df47e0bb3d23fc41f8796170b..a03a2862e42c990107953210d54734f0a0a93927 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -3134,6 +3134,7 @@ Input type: `CiJobTokenScopeAddGroupOrProjectInput`
 | Name | Type | Description |
 | ---- | ---- | ----------- |
 | <a id="mutationcijobtokenscopeaddgrouporprojectclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationcijobtokenscopeaddgrouporprojectdefaultpermissions"></a>`defaultPermissions` **{warning-solid}** | [`Boolean`](#boolean) | **Deprecated:** **Status**: Experiment. Introduced in GitLab 17.8. |
 | <a id="mutationcijobtokenscopeaddgrouporprojectjobtokenpolicies"></a>`jobTokenPolicies` **{warning-solid}** | [`[CiJobTokenScopePolicies!]`](#cijobtokenscopepolicies) | **Deprecated:** **Status**: Experiment. Introduced in GitLab 17.5. |
 | <a id="mutationcijobtokenscopeaddgrouporprojectprojectpath"></a>`projectPath` | [`ID!`](#id) | Project that the CI job token scope belongs to. |
 | <a id="mutationcijobtokenscopeaddgrouporprojecttargetpath"></a>`targetPath` | [`ID!`](#id) | Group or project to be added to the CI job token scope. |
@@ -3225,6 +3226,7 @@ Input type: `CiJobTokenScopeUpdatePoliciesInput`
 | Name | Type | Description |
 | ---- | ---- | ----------- |
 | <a id="mutationcijobtokenscopeupdatepoliciesclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationcijobtokenscopeupdatepoliciesdefaultpermissions"></a>`defaultPermissions` | [`Boolean!`](#boolean) | Indicates whether default permissions are enabled (true) or fine-grained permissions are enabled (false). |
 | <a id="mutationcijobtokenscopeupdatepoliciesjobtokenpolicies"></a>`jobTokenPolicies` | [`[CiJobTokenScopePolicies!]!`](#cijobtokenscopepolicies) | List of policies added to the CI job token scope. |
 | <a id="mutationcijobtokenscopeupdatepoliciesprojectpath"></a>`projectPath` | [`ID!`](#id) | Project that the CI job token scope belongs to. |
 | <a id="mutationcijobtokenscopeupdatepoliciestargetpath"></a>`targetPath` | [`ID!`](#id) | Group or project that the CI job token targets. |
@@ -20496,6 +20498,7 @@ Represents an allowlist entry for the CI_JOB_TOKEN.
 | ---- | ---- | ----------- |
 | <a id="cijobtokenscopeallowlistentryaddedby"></a>`addedBy` | [`UserCore`](#usercore) | User that added the entry. |
 | <a id="cijobtokenscopeallowlistentrycreatedat"></a>`createdAt` | [`Time!`](#time) | When the entry was created. |
+| <a id="cijobtokenscopeallowlistentrydefaultpermissions"></a>`defaultPermissions` | [`Boolean`](#boolean) | Indicates whether default permissions are enabled (true) or fine-grained permissions are enabled (false). |
 | <a id="cijobtokenscopeallowlistentrydirection"></a>`direction` | [`String`](#string) | Direction of access. Defaults to INBOUND. |
 | <a id="cijobtokenscopeallowlistentryjobtokenpolicies"></a>`jobTokenPolicies` **{warning-solid}** | [`[CiJobTokenScopePolicies!]`](#cijobtokenscopepolicies) | **Introduced** in GitLab 17.5. **Status**: Experiment. List of policies for the entry. |
 | <a id="cijobtokenscopeallowlistentrysourceproject"></a>`sourceProject` | [`Project!`](#project) | Project that owns the allowlist entry. |
diff --git a/ee/app/services/ee/ci/job_token_scope/add_group_service.rb b/ee/app/services/ee/ci/job_token_scope/add_group_service.rb
index 29d1df3df1044634da4b0965703156505001df84..b0d3bc68068a1bf7ec36d98d324d3202df5f57aa 100644
--- a/ee/app/services/ee/ci/job_token_scope/add_group_service.rb
+++ b/ee/app/services/ee/ci/job_token_scope/add_group_service.rb
@@ -7,21 +7,22 @@ module AddGroupService
         extend ::Gitlab::Utils::Override
 
         override :execute
-        def execute(target_group, policies: [])
+        def execute(target_group, default_permissions: true, policies: [])
           super.tap do |response|
-            audit(project, target_group, current_user, policies) if response.success?
+            audit(project, target_group, current_user, default_permissions, policies) if response.success?
           end
         end
 
         private
 
-        def audit(scope, target, author, policies)
+        def audit(scope, target, author, default_permissions, policies)
           audit_message =
             "Group #{target.full_path} was added to list of allowed groups for #{scope.full_path}"
           event_name = 'secure_ci_job_token_group_added'
 
           if ::Feature.enabled?(:add_policies_to_ci_job_token, scope) && policies.present?
-            audit_message += ", with job token permissions: #{policies.join(', ')}"
+            audit_message += ", with default permissions: #{default_permissions}, " \
+              "job token policies: #{policies.join(', ')}"
           end
 
           audit_context = {
diff --git a/ee/app/services/ee/ci/job_token_scope/add_project_service.rb b/ee/app/services/ee/ci/job_token_scope/add_project_service.rb
index ae6920ba5da4faebd1a9542e8878241575a1fd77..2be230a96d051559328923e2c16ff1d89e642148 100644
--- a/ee/app/services/ee/ci/job_token_scope/add_project_service.rb
+++ b/ee/app/services/ee/ci/job_token_scope/add_project_service.rb
@@ -7,21 +7,25 @@ module AddProjectService
         extend ::Gitlab::Utils::Override
 
         override :execute
-        def execute(target_project, policies: [], direction: :inbound)
+        def execute(target_project, default_permissions: true, policies: [], direction: :inbound)
           super.tap do |response|
-            audit(project, target_project, current_user, policies) if direction == :inbound && response.success?
+            if direction == :inbound && response.success?
+              audit(project, target_project, current_user, default_permissions,
+                policies)
+            end
           end
         end
 
         private
 
-        def audit(scope, target, author, policies)
+        def audit(scope, target, author, default_permissions, policies)
           audit_message =
             "Project #{target.full_path} was added to inbound list of allowed projects for #{scope.full_path}"
           event_name = 'secure_ci_job_token_project_added'
 
           if ::Feature.enabled?(:add_policies_to_ci_job_token, scope) && policies.present?
-            audit_message += ", with job token permissions: #{policies.join(', ')}"
+            audit_message += ", with default permissions: #{default_permissions}, " \
+              "job token policies: #{policies.join(', ')}"
           end
 
           audit_context = {
diff --git a/ee/app/services/ee/ci/job_token_scope/remove_group_service.rb b/ee/app/services/ee/ci/job_token_scope/remove_group_service.rb
index ca2faf5ebffd9c3b00344866ec4e0825b7f77a19..204239e698d48ccb0cdc70125a38f884f147d09c 100644
--- a/ee/app/services/ee/ci/job_token_scope/remove_group_service.rb
+++ b/ee/app/services/ee/ci/job_token_scope/remove_group_service.rb
@@ -21,7 +21,7 @@ def audit(scope, target, author, policies)
           event_name = 'secure_ci_job_token_group_removed'
 
           if ::Feature.enabled?(:add_policies_to_ci_job_token, scope) && policies.present?
-            audit_message += ", with job token permissions: #{policies.join(', ')}"
+            audit_message += ", with job token policies: #{policies.join(', ')}"
           end
 
           audit_context = {
diff --git a/ee/app/services/ee/ci/job_token_scope/remove_project_service.rb b/ee/app/services/ee/ci/job_token_scope/remove_project_service.rb
index 30ad7c14d1154095aad0315e73e0d462425a6a49..aa5aef5ae64050b7131330d161df85708d10ed14 100644
--- a/ee/app/services/ee/ci/job_token_scope/remove_project_service.rb
+++ b/ee/app/services/ee/ci/job_token_scope/remove_project_service.rb
@@ -23,7 +23,7 @@ def audit(scope, target, author, policies)
           event_name = 'secure_ci_job_token_project_removed'
 
           if ::Feature.enabled?(:add_policies_to_ci_job_token, scope) && policies.present?
-            audit_message += ", with job token permissions: #{policies.join(', ')}"
+            audit_message += ", with job token policies: #{policies.join(', ')}"
           end
 
           audit_context = {
diff --git a/ee/app/services/ee/ci/job_token_scope/update_policies_service.rb b/ee/app/services/ee/ci/job_token_scope/update_policies_service.rb
index 6f0544e59fb6c541e9041ad2474469d834e83fb3..e29d45f7cadd3bf195c67cc4db2c9fcf37abf1c5 100644
--- a/ee/app/services/ee/ci/job_token_scope/update_policies_service.rb
+++ b/ee/app/services/ee/ci/job_token_scope/update_policies_service.rb
@@ -7,17 +7,17 @@ module UpdatePoliciesService
         extend ::Gitlab::Utils::Override
 
         override :execute
-        def execute(target, policies)
+        def execute(target, default_permissions, policies)
           super.tap do |response|
-            audit(project, target, current_user, policies) if response.success?
+            audit(project, target, current_user, default_permissions, policies) if response.success?
           end
         end
 
         private
 
-        def audit(scope, target, author, policies)
+        def audit(scope, target, author, default_permissions, policies)
           audit_message =
-            "CI job token policies updated to: #{policies.join(', ')}"
+            "CI job token updated to default permissions: #{default_permissions}, policies: #{policies.join(', ')}"
 
           event_name = 'secure_ci_job_token_policies_updated'
 
diff --git a/ee/spec/graphql/ee/mutations/ci/job_token_scope/add_group_or_project_spec.rb b/ee/spec/graphql/ee/mutations/ci/job_token_scope/add_group_or_project_spec.rb
index 92b086f568d6f712e080de95ec8f5ba7218909ba..5cb7bc37d5b629b83627cf4f2fc834289b32c73a 100644
--- a/ee/spec/graphql/ee/mutations/ci/job_token_scope/add_group_or_project_spec.rb
+++ b/ee/spec/graphql/ee/mutations/ci/job_token_scope/add_group_or_project_spec.rb
@@ -33,8 +33,8 @@
       {
         project_path: project.full_path,
         target_path: target.full_path,
-        job_token_policies: policies,
-        direction: :inbound
+        default_permissions: false,
+        job_token_policies: policies
       }
     end
 
@@ -51,7 +51,7 @@
 
       let(:expected_audit_message) do
         "Group #{target_group_path} was added to list of allowed groups for #{project_path}, " \
-          "with job token permissions: read_containers, read_packages"
+          "with default permissions: false, job token policies: read_containers, read_packages"
       end
 
       let(:event_name) { 'secure_ci_job_token_group_added' }
@@ -104,7 +104,7 @@
 
       let(:expected_audit_message) do
         "Project #{target_project_path} was added to inbound list of allowed projects for #{project_path}, " \
-          "with job token permissions: read_containers, read_packages"
+          "with default permissions: false, job token policies: read_containers, read_packages"
       end
 
       let(:event_name) { 'secure_ci_job_token_project_added' }
diff --git a/ee/spec/graphql/ee/mutations/ci/job_token_scope/remove_group_spec.rb b/ee/spec/graphql/ee/mutations/ci/job_token_scope/remove_group_spec.rb
index 57ecd73105c225118701ba4ac512bfa569da8ba1..d2a761a91c172dbdee2ecd49ae70e4a419e39f8f 100644
--- a/ee/spec/graphql/ee/mutations/ci/job_token_scope/remove_group_spec.rb
+++ b/ee/spec/graphql/ee/mutations/ci/job_token_scope/remove_group_spec.rb
@@ -51,7 +51,7 @@
       context 'when user removes target group to the job token scope' do
         let(:expected_audit_message) do
           "Group #{target_group_path} was removed from list of allowed groups for #{project_path}, " \
-            "with job token permissions: read_containers, read_packages"
+            "with job token policies: read_containers, read_packages"
         end
 
         let(:event_name) { 'secure_ci_job_token_group_removed' }
diff --git a/ee/spec/graphql/ee/mutations/ci/job_token_scope/remove_project_spec.rb b/ee/spec/graphql/ee/mutations/ci/job_token_scope/remove_project_spec.rb
index 20db1a312ed9a2fd5cab123a02f507a1cea653e0..e86b1047cb3c0967ea8c4210c0e53f880b11d317 100644
--- a/ee/spec/graphql/ee/mutations/ci/job_token_scope/remove_project_spec.rb
+++ b/ee/spec/graphql/ee/mutations/ci/job_token_scope/remove_project_spec.rb
@@ -59,7 +59,7 @@
 
       let(:expected_audit_message) do
         "Project #{target_project_path} was removed from inbound list of allowed projects for #{project_path}, " \
-          "with job token permissions: read_containers, read_packages"
+          "with job token policies: read_containers, read_packages"
       end
 
       let(:event_name) { 'secure_ci_job_token_project_removed' }
diff --git a/ee/spec/services/ee/ci/job_token_scope/add_group_service_spec.rb b/ee/spec/services/ee/ci/job_token_scope/add_group_service_spec.rb
index be3884a5a6fe3155962a4e0765a3baf5abe6a60b..b905c24cba46feecdb6948da97b487586987af33 100644
--- a/ee/spec/services/ee/ci/job_token_scope/add_group_service_spec.rb
+++ b/ee/spec/services/ee/ci/job_token_scope/add_group_service_spec.rb
@@ -10,12 +10,14 @@
 
   let_it_be(:policies) { %w[read_containers read_packages] }
 
-  subject(:service_result) { described_class.new(project, current_user).execute(target_group, policies: policies) }
+  subject(:service_result) do
+    described_class.new(project, current_user).execute(target_group, default_permissions: false, policies: policies)
+  end
 
   describe '#execute' do
     let(:expected_audit_message) do
       "Group #{target_group.full_path} was added to list of allowed groups for #{project.full_path}, " \
-        "with job token permissions: read_containers, read_packages"
+        "with default permissions: false, job token policies: read_containers, read_packages"
     end
 
     let(:audit_event) do
diff --git a/ee/spec/services/ee/ci/job_token_scope/add_project_service_spec.rb b/ee/spec/services/ee/ci/job_token_scope/add_project_service_spec.rb
index ce33ee00f39f703afa53890742b7aa0b669d46af..e01b676383f1c0af81fdccfbb0cd972a681172dc 100644
--- a/ee/spec/services/ee/ci/job_token_scope/add_project_service_spec.rb
+++ b/ee/spec/services/ee/ci/job_token_scope/add_project_service_spec.rb
@@ -13,14 +13,15 @@
   let_it_be(:direction) { :inbound }
 
   subject(:service_result) do
-    described_class.new(project, current_user).execute(target_project, policies: policies, direction: direction)
+    described_class.new(project, current_user).execute(target_project, default_permissions: false, policies: policies,
+      direction: direction)
   end
 
   describe '#execute' do
     context 'when the direction is inbound' do
       let(:expected_audit_message) do
         "Project #{target_project.full_path} was added to inbound list of allowed projects for #{project.full_path}, " \
-          "with job token permissions: read_containers, read_packages"
+          "with default permissions: false, job token policies: read_containers, read_packages"
       end
 
       let(:audit_event) do
diff --git a/ee/spec/services/ee/ci/job_token_scope/remove_group_service_spec.rb b/ee/spec/services/ee/ci/job_token_scope/remove_group_service_spec.rb
index dbe43c999f5f0e329688402078e49330a826aa7e..d330fc2c03f9d776f9cfd9a5ee537749eadb06f0 100644
--- a/ee/spec/services/ee/ci/job_token_scope/remove_group_service_spec.rb
+++ b/ee/spec/services/ee/ci/job_token_scope/remove_group_service_spec.rb
@@ -23,7 +23,7 @@
   describe '#execute' do
     let(:expected_audit_message) do
       "Group #{target_group.full_path} was removed from list of allowed groups for #{project.full_path}, " \
-        "with job token permissions: read_containers, read_packages"
+        "with job token policies: read_containers, read_packages"
     end
 
     let(:audit_event) do
diff --git a/ee/spec/services/ee/ci/job_token_scope/remove_project_service_spec.rb b/ee/spec/services/ee/ci/job_token_scope/remove_project_service_spec.rb
index 5cd8f249d62d068835866b817c07c86d2cea73b9..f0655e5620b53f756988cc1c35e1156901768d3c 100644
--- a/ee/spec/services/ee/ci/job_token_scope/remove_project_service_spec.rb
+++ b/ee/spec/services/ee/ci/job_token_scope/remove_project_service_spec.rb
@@ -29,7 +29,7 @@
 
       let(:expected_audit_message) do
         "Project #{target_project.full_path} was removed from inbound list of allowed projects " \
-          "for #{project.full_path}, with job token permissions: read_containers, read_packages"
+          "for #{project.full_path}, with job token policies: read_containers, read_packages"
       end
 
       let(:audit_event) do
diff --git a/ee/spec/services/ee/ci/job_token_scope/update_policies_service_spec.rb b/ee/spec/services/ee/ci/job_token_scope/update_policies_service_spec.rb
index ba07f2b18c85e7113ace76ef33a7c46d3b1d18ba..f21fd8aa6285321a784cf82c9b4aa5e2bb1d4ee2 100644
--- a/ee/spec/services/ee/ci/job_token_scope/update_policies_service_spec.rb
+++ b/ee/spec/services/ee/ci/job_token_scope/update_policies_service_spec.rb
@@ -8,10 +8,11 @@
 
   let_it_be(:current_user) { create(:user, maintainer_of: project, developer_of: target_project) }
 
+  let(:default_permissions) { false }
   let(:policies) { %w[read_containers read_packages] }
 
   subject(:service_result) do
-    described_class.new(project, current_user).execute(target_project, policies)
+    described_class.new(project, current_user).execute(target_project, default_permissions, policies)
   end
 
   describe '#execute' do
@@ -20,6 +21,7 @@
         create(:ci_job_token_project_scope_link,
           source_project: project,
           target_project: target_project,
+          default_permissions: true,
           job_token_policies: %w[read_containers read_packages],
           direction: :inbound
         )
@@ -31,7 +33,7 @@
           author: current_user,
           scope: project,
           target: target_project,
-          message: 'CI job token policies updated to: read_containers, read_packages'
+          message: 'CI job token updated to default permissions: false, policies: read_containers, read_packages'
         }
       end
 
@@ -42,6 +44,7 @@
 
         expect(link.source_project).to eq(project)
         expect(link.target_project).to eq(target_project)
+        expect(link.default_permissions).to be(default_permissions)
         expect(link.job_token_policies).to eq(policies)
       end
 
diff --git a/spec/graphql/mutations/ci/job_token_scope/add_group_or_project_spec.rb b/spec/graphql/mutations/ci/job_token_scope/add_group_or_project_spec.rb
index 86385bfcd0c0be48bfedfd9a3b810a5b67815ae0..d4c1ee16ee5ac1778c7d38fa76e6e4f41acf8adf 100644
--- a/spec/graphql/mutations/ci/job_token_scope/add_group_or_project_spec.rb
+++ b/spec/graphql/mutations/ci/job_token_scope/add_group_or_project_spec.rb
@@ -39,7 +39,12 @@
       let(:policies) { %w[read_containers read_packages] }
 
       let(:mutation_args) do
-        { project_path: project.full_path, target_path: target_project_path, job_token_policies: policies }
+        {
+          project_path: project.full_path,
+          target_path: target_project_path,
+          default_permissions: false,
+          job_token_policies: policies
+        }
       end
 
       it_behaves_like 'when user is not logged in'
@@ -64,6 +69,7 @@
             expect(project_link.source_project).to eq(project)
             expect(project_link.target_project).to eq(target_project)
             expect(project_link.added_by).to eq(current_user)
+            expect(project_link.default_permissions).to be(false)
             expect(project_link.job_token_policies).to eq(policies)
           end
 
@@ -99,7 +105,12 @@
       let(:policies) { %w[read_containers read_packages] }
 
       let(:mutation_args) do
-        { project_path: project.full_path, target_path: target_group_path, job_token_policies: policies }
+        {
+          project_path: project.full_path,
+          target_path: target_group_path,
+          default_permissions: false,
+          job_token_policies: policies
+        }
       end
 
       it_behaves_like 'when user is not logged in'
@@ -124,6 +135,7 @@
             expect(group_link.source_project).to eq(project)
             expect(group_link.target_group).to eq(target_group)
             expect(group_link.added_by).to eq(current_user)
+            expect(group_link.default_permissions).to be(false)
             expect(group_link.job_token_policies).to eq(policies)
           end
 
diff --git a/spec/graphql/types/ci/job_token_scope/allowlist_entry_type_spec.rb b/spec/graphql/types/ci/job_token_scope/allowlist_entry_type_spec.rb
index 790a46050b04d3267eb420306c2c1efcc8593b3e..58dd4cd18b2690b8fbd776ec00b45521c05d8a8f 100644
--- a/spec/graphql/types/ci/job_token_scope/allowlist_entry_type_spec.rb
+++ b/spec/graphql/types/ci/job_token_scope/allowlist_entry_type_spec.rb
@@ -10,6 +10,7 @@
       source_project
       target
       direction
+      default_permissions
       job_token_policies
       added_by
       created_at
diff --git a/spec/models/ci/job_token/allowlist_spec.rb b/spec/models/ci/job_token/allowlist_spec.rb
index c08020a5380afba7f4afc2f76d7cdbd17665d91d..0c840818ae7f71fcbf2cc58804787758263b9a02 100644
--- a/spec/models/ci/job_token/allowlist_spec.rb
+++ b/spec/models/ci/job_token/allowlist_spec.rb
@@ -68,8 +68,23 @@
     let_it_be(:added_project) { create(:project) }
     let_it_be(:user) { create(:user) }
     let_it_be(:policies) { %w[read_containers read_packages] }
+    let_it_be(:default_permissions) { false }
 
-    subject(:add_project) { allowlist.add!(added_project, policies: policies, user: user) }
+    subject(:add_project) do
+      allowlist.add!(added_project, default_permissions: default_permissions, policies: policies, user: user)
+    end
+
+    [true, false].each do |d|
+      context "with default permissions #{d}" do
+        let_it_be(:default_permissions) { d }
+
+        it "sets default permissions to #{d}" do
+          project_link = add_project
+
+          expect(project_link.default_permissions).to eq(default_permissions)
+        end
+      end
+    end
 
     [:inbound, :outbound].each do |d|
       context "with #{d}" do
@@ -97,6 +112,7 @@
             expect(project_link.added_by_id).to eq(user.id)
             expect(project_link.source_project_id).to eq(source_project.id)
             expect(project_link.target_project_id).to eq(added_project.id)
+            expect(project_link.default_permissions).to be(true)
             expect(project_link.job_token_policies).to eq([])
           end
         end
@@ -108,8 +124,23 @@
     let_it_be(:added_group) { create(:group) }
     let_it_be(:user) { create(:user) }
     let_it_be(:policies) { %w[read_containers read_packages] }
+    let_it_be(:default_permissions) { false }
 
-    subject(:add_group) { allowlist.add_group!(added_group, policies: policies, user: user) }
+    subject(:add_group) do
+      allowlist.add_group!(added_group, default_permissions: default_permissions, policies: policies, user: user)
+    end
+
+    [true, false].each do |d|
+      context "with default permissions #{d}" do
+        let_it_be(:default_permissions) { d }
+
+        it "sets default permissions to #{d}" do
+          group_link = add_group
+
+          expect(group_link.default_permissions).to eq(default_permissions)
+        end
+      end
+    end
 
     it 'adds the group scope link' do
       group_link = add_group
@@ -133,6 +164,7 @@
         expect(group_link.added_by_id).to eq(user.id)
         expect(group_link.source_project_id).to eq(source_project.id)
         expect(group_link.target_group_id).to eq(added_group.id)
+        expect(group_link.default_permissions).to be(true)
         expect(group_link.job_token_policies).to eq([])
       end
     end
diff --git a/spec/requests/api/graphql/ci/job_token_scope/allowlist_query_spec.rb b/spec/requests/api/graphql/ci/job_token_scope/allowlist_query_spec.rb
index 3778d47c06ac2fe91d7b667c9cf9f8c30d52e8b4..484bc7637f75fe14d99528f894078099e10d8e92 100644
--- a/spec/requests/api/graphql/ci/job_token_scope/allowlist_query_spec.rb
+++ b/spec/requests/api/graphql/ci/job_token_scope/allowlist_query_spec.rb
@@ -34,6 +34,7 @@
                 addedBy {
                   username
                 }
+                defaultPermissions
                 jobTokenPolicies
                 direction
               }
@@ -52,6 +53,7 @@
                 addedBy {
                   username
                 }
+                defaultPermissions
                 jobTokenPolicies
                 direction
               }
@@ -70,6 +72,7 @@
         {
           'addedBy' => { 'username' => current_user.username },
           'direction' => 'inbound',
+          'defaultPermissions' => false,
           'jobTokenPolicies' => ['READ_CONTAINERS'],
           'sourceProject' => { 'fullPath' => project.full_path },
           'target' => { 'fullPath' => target_group_1.full_path }
@@ -85,6 +88,7 @@
         {
           'addedBy' => { 'username' => current_user.username },
           'direction' => 'outbound',
+          'defaultPermissions' => false,
           'jobTokenPolicies' => ['READ_CONTAINERS'],
           'sourceProject' => { 'fullPath' => project.full_path },
           'target' => { 'fullPath' => target_project_2.full_path }
@@ -92,6 +96,7 @@
         {
           'addedBy' => { 'username' => current_user.username },
           'direction' => 'inbound',
+          'defaultPermissions' => false,
           'jobTokenPolicies' => ['READ_CONTAINERS'],
           'sourceProject' => { 'fullPath' => project.full_path },
           'target' => { 'fullPath' => target_project_1.full_path }
@@ -138,6 +143,7 @@
           :ci_job_token_project_scope_link,
           source_project: project,
           target_project: target_project_1,
+          default_permissions: false,
           job_token_policies: %w[read_containers],
           added_by: current_user,
           direction: :inbound
@@ -147,6 +153,7 @@
           :ci_job_token_project_scope_link,
           source_project: project,
           target_project: target_project_2,
+          default_permissions: false,
           job_token_policies: %w[read_containers],
           added_by: current_user,
           direction: :outbound
@@ -157,6 +164,7 @@
           source_project: project,
           target_group: target_group_1,
           added_by: current_user,
+          default_permissions: false,
           job_token_policies: %w[read_containers]
         )
       end
@@ -180,6 +188,14 @@
           expect(allowlist.dig('projectsAllowlist', 'nodes', 0, 'jobTokenPolicies')).to be_nil
           expect(allowlist.dig('projectsAllowlist', 'nodes', 1, 'jobTokenPolicies')).to be_nil
         end
+
+        it 'returns default permissions as true', :aggregate_failures do
+          post_graphql(query, current_user: current_user)
+
+          expect(allowlist.dig('groupsAllowlist', 'nodes', 0, 'defaultPermissions')).to be(true)
+          expect(allowlist.dig('projectsAllowlist', 'nodes', 0, 'defaultPermissions')).to be(true)
+          expect(allowlist.dig('projectsAllowlist', 'nodes', 1, 'defaultPermissions')).to be(true)
+        end
       end
 
       it 'avoids N+1 queries', :use_sql_query_cache do
diff --git a/spec/requests/api/graphql/mutations/ci/job_token_scope/update_job_token_policies_spec.rb b/spec/requests/api/graphql/mutations/ci/job_token_scope/update_job_token_policies_spec.rb
index acecd77b2443db464435a418bff5f205658a211b..101428e322e4361ab37f0e9280884a8c7a72b073 100644
--- a/spec/requests/api/graphql/mutations/ci/job_token_scope/update_job_token_policies_spec.rb
+++ b/spec/requests/api/graphql/mutations/ci/job_token_scope/update_job_token_policies_spec.rb
@@ -13,6 +13,7 @@
     {
       project_path: project.full_path,
       target_path: target_path,
+      default_permissions: true,
       job_token_policies: policies
     }
   end
@@ -33,6 +34,7 @@
               fullPath
             }
           }
+          defaultPermissions
           jobTokenPolicies
         }
       QL
@@ -74,6 +76,7 @@
             :ci_job_token_project_scope_link,
             source_project: project,
             target_project: target_project,
+            default_permissions: false,
             job_token_policies: %w[read_containers],
             direction: :inbound
           )
@@ -88,6 +91,7 @@
             'fullPath')).to eq(project.full_path)
           expect(mutation_response.dig('ciJobTokenScopeAllowlistEntry', 'target',
             'fullPath')).to eq(target_project.full_path)
+          expect(mutation_response.dig('ciJobTokenScopeAllowlistEntry', 'defaultPermissions')).to be(true)
           expect(mutation_response.dig('ciJobTokenScopeAllowlistEntry', 'jobTokenPolicies')).to eq(policies)
         end
 
@@ -152,6 +156,7 @@
             :ci_job_token_group_scope_link,
             source_project: project,
             target_group: target_group,
+            default_permissions: false,
             job_token_policies: %w[read_containers]
           )
         end
@@ -165,6 +170,7 @@
             'fullPath')).to eq(project.full_path)
           expect(mutation_response.dig('ciJobTokenScopeAllowlistEntry', 'target',
             'fullPath')).to eq(target_group.full_path)
+          expect(mutation_response.dig('ciJobTokenScopeAllowlistEntry', 'defaultPermissions')).to be(true)
           expect(mutation_response.dig('ciJobTokenScopeAllowlistEntry', 'jobTokenPolicies')).to eq(policies)
         end
 
diff --git a/spec/services/ci/job_token_scope/add_group_or_project_service_spec.rb b/spec/services/ci/job_token_scope/add_group_or_project_service_spec.rb
index 8fbc181dfee6922aa9828e048792b8cf1c554baf..2e494f1828e91e69c4d65476244f8f517d67e012 100644
--- a/spec/services/ci/job_token_scope/add_group_or_project_service_spec.rb
+++ b/spec/services/ci/job_token_scope/add_group_or_project_service_spec.rb
@@ -11,7 +11,9 @@
 
   let(:response_success) { ServiceResponse.success }
 
-  subject(:service_execute) { described_class.new(source_project, current_user).execute(target, policies: policies) }
+  subject(:service_execute) do
+    described_class.new(source_project, current_user).execute(target, default_permissions: false, policies: policies)
+  end
 
   describe '#execute' do
     context 'when group is a target to add' do
@@ -26,7 +28,7 @@
 
       it 'calls AddGroupService to add a target' do
         expect(add_group_service_double)
-          .to receive(:execute).with(target, policies: policies)
+          .to receive(:execute).with(target, default_permissions: false, policies: policies)
           .and_return(response_success)
 
         expect(service_execute).to eq(response_success)
@@ -46,7 +48,7 @@
 
       it 'calls AddProjectService to add a target' do
         expect(add_project_service_double)
-          .to receive(:execute).with(target, policies: policies)
+          .to receive(:execute).with(target, default_permissions: false, policies: policies)
           .and_return(response_success)
 
         expect(service_execute).to eq(response_success)
diff --git a/spec/services/ci/job_token_scope/add_group_service_spec.rb b/spec/services/ci/job_token_scope/add_group_service_spec.rb
index b6e087a25d23c40f8f46d4d9211ef05ac78c649c..0309b7e4a869365fc1b6eff10169acac67301487 100644
--- a/spec/services/ci/job_token_scope/add_group_service_spec.rb
+++ b/spec/services/ci/job_token_scope/add_group_service_spec.rb
@@ -21,6 +21,7 @@
       expect(group_link.source_project).to eq(project)
       expect(group_link.target_group).to eq(target_group)
       expect(group_link.added_by).to eq(current_user)
+      expect(group_link.default_permissions).to eq(default_permissions)
       expect(group_link.job_token_policies).to eq(policies)
     end
 
@@ -39,13 +40,16 @@
         expect(group_link.source_project).to eq(project)
         expect(group_link.target_group).to eq(target_group)
         expect(group_link.added_by).to eq(current_user)
+        expect(group_link.default_permissions).to be(true)
         expect(group_link.job_token_policies).to eq([])
       end
     end
   end
 
   describe '#execute' do
-    subject(:result) { service.execute(target_group, policies: policies) }
+    subject(:result) { service.execute(target_group, default_permissions: default_permissions, policies: policies) }
+
+    let(:default_permissions) { false }
 
     it_behaves_like 'editable group job token scope' do
       context 'when user has permissions on source and target groups' do
@@ -56,6 +60,12 @@
 
         it_behaves_like 'adds group'
 
+        context 'when default_permissions is set to true' do
+          let(:default_permissions) { true }
+
+          it_behaves_like 'adds group'
+        end
+
         context 'when token scope is disabled' do
           before do
             project.ci_cd_settings.update!(job_token_scope_enabled: false)
diff --git a/spec/services/ci/job_token_scope/add_project_service_spec.rb b/spec/services/ci/job_token_scope/add_project_service_spec.rb
index 55815e2852a829b968d5b40234f479a51cb11b41..13e0cf12192333f6681462cf8567425ca48ab78a 100644
--- a/spec/services/ci/job_token_scope/add_project_service_spec.rb
+++ b/spec/services/ci/job_token_scope/add_project_service_spec.rb
@@ -20,6 +20,7 @@
       expect(project_link.source_project).to eq(project)
       expect(project_link.target_project).to eq(target_project)
       expect(project_link.added_by).to eq(current_user)
+      expect(project_link.default_permissions).to eq(default_permissions)
       expect(project_link.job_token_policies).to eq(policies)
     end
 
@@ -38,13 +39,16 @@
         expect(project_link.source_project).to eq(project)
         expect(project_link.target_project).to eq(target_project)
         expect(project_link.added_by).to eq(current_user)
+        expect(project_link.default_permissions).to be(true)
         expect(project_link.job_token_policies).to eq([])
       end
     end
   end
 
   describe '#execute' do
-    subject(:result) { service.execute(target_project, policies: policies) }
+    subject(:result) { service.execute(target_project, default_permissions: default_permissions, policies: policies) }
+
+    let(:default_permissions) { false }
 
     it_behaves_like 'editable job token scope' do
       context 'when user has permissions on source and target projects' do
@@ -57,6 +61,12 @@
 
         it_behaves_like 'adds project'
 
+        context 'when default_permissions is set to true' do
+          let(:default_permissions) { true }
+
+          it_behaves_like 'adds project'
+        end
+
         context 'when token scope is disabled' do
           before do
             project.ci_cd_settings.update!(job_token_scope_enabled: false)
diff --git a/spec/services/ci/job_token_scope/update_policies_service_spec.rb b/spec/services/ci/job_token_scope/update_policies_service_spec.rb
index cbcbba5f1e004f3f34a7319cca50ad3c05f23802..bd333b17f5710e475e48c953f0d1d077a5bc7d30 100644
--- a/spec/services/ci/job_token_scope/update_policies_service_spec.rb
+++ b/spec/services/ci/job_token_scope/update_policies_service_spec.rb
@@ -9,7 +9,7 @@
   let_it_be(:target_group) { create(:group, :private) }
 
   subject(:execute) do
-    described_class.new(project, current_user).execute(target, policies)
+    described_class.new(project, current_user).execute(target, default_permissions, policies)
   end
 
   describe '#execute' do
@@ -78,11 +78,13 @@
           :ci_job_token_project_scope_link,
           source_project: project,
           target_project: target_project,
+          default_permissions: true,
           job_token_policies: %w[read_containers],
           direction: :inbound
         )
       end
 
+      let(:default_permissions) { false }
       let(:policies) { %w[read_containers read_packages] }
 
       it_behaves_like 'when user is not logged in'
@@ -106,6 +108,7 @@
 
             expect(project_link.source_project).to eq(project)
             expect(project_link.target_project).to eq(target_project)
+            expect(project_link.default_permissions).to be(false)
             expect(project_link.job_token_policies).to eq(%w[read_containers read_packages])
           end
 
@@ -132,10 +135,12 @@
           :ci_job_token_group_scope_link,
           source_project: project,
           target_group: target_group,
+          default_permissions: true,
           job_token_policies: %w[read_containers]
         )
       end
 
+      let(:default_permissions) { false }
       let(:policies) { %w[read_containers read_packages] }
 
       it_behaves_like 'when user is not logged in'
@@ -159,6 +164,7 @@
 
             expect(group_link.source_project).to eq(project)
             expect(group_link.target_group).to eq(target_group)
+            expect(group_link.default_permissions).to be(false)
             expect(group_link.job_token_policies).to eq(%w[read_containers read_packages])
           end