diff --git a/app/assets/javascripts/pages/groups/settings/access_tokens/index.js b/app/assets/javascripts/pages/groups/settings/access_tokens/index.js
index 6e0b6c78e2896b21ec0542bed6ed91bd63e48b80..1211cad7d1d494b059ac8539d9bae8b14ea14b29 100644
--- a/app/assets/javascripts/pages/groups/settings/access_tokens/index.js
+++ b/app/assets/javascripts/pages/groups/settings/access_tokens/index.js
@@ -8,7 +8,4 @@ import {
 initAccessTokenTableApp();
 initExpiresAtField();
 initNewAccessTokenApp();
-
-if (gon.features.retainResourceAccessTokenUserAfterRevoke) {
-  initInactiveAccessTokenTableApp();
-}
+initInactiveAccessTokenTableApp();
diff --git a/app/assets/javascripts/pages/projects/settings/access_tokens/index.js b/app/assets/javascripts/pages/projects/settings/access_tokens/index.js
index 6e0b6c78e2896b21ec0542bed6ed91bd63e48b80..1211cad7d1d494b059ac8539d9bae8b14ea14b29 100644
--- a/app/assets/javascripts/pages/projects/settings/access_tokens/index.js
+++ b/app/assets/javascripts/pages/projects/settings/access_tokens/index.js
@@ -8,7 +8,4 @@ import {
 initAccessTokenTableApp();
 initExpiresAtField();
 initNewAccessTokenApp();
-
-if (gon.features.retainResourceAccessTokenUserAfterRevoke) {
-  initInactiveAccessTokenTableApp();
-}
+initInactiveAccessTokenTableApp();
diff --git a/app/controllers/concerns/access_tokens_actions.rb b/app/controllers/concerns/access_tokens_actions.rb
index ce43fb2e7675b20334811206fd6b2c7bdb736e8b..8f7ed09b00610630784a3861a85ad30c8a9353e5 100644
--- a/app/controllers/concerns/access_tokens_actions.rb
+++ b/app/controllers/concerns/access_tokens_actions.rb
@@ -8,9 +8,6 @@ module AccessTokensActions
     before_action -> { check_permission(:destroy_resource_access_tokens) }, only: [:revoke]
     before_action -> { check_permission(:manage_resource_access_tokens) }, only: [:rotate]
     before_action -> { check_permission(:create_resource_access_tokens) }, only: [:create]
-    before_action do
-      push_frontend_feature_flag(:retain_resource_access_token_user_after_revoke, resource.root_ancestor)
-    end
   end
 
   # rubocop:disable Gitlab/ModuleWithInstanceVariables
@@ -72,8 +69,6 @@ def rotate
   end
 
   def inactive
-    return render_404 unless Feature.enabled?(:retain_resource_access_token_user_after_revoke, resource.root_ancestor)
-
     tokens = inactive_access_tokens.page(page)
     add_pagination_headers(tokens)
 
@@ -102,9 +97,7 @@ def set_index_vars
 
     @scopes = Gitlab::Auth.available_scopes_for(resource)
     @active_access_tokens, @active_access_tokens_size = active_access_tokens
-    if Feature.enabled?(:retain_resource_access_token_user_after_revoke, resource.root_ancestor) # rubocop:disable Style/GuardClause
-      @inactive_access_tokens_size = inactive_access_tokens.size
-    end
+    @inactive_access_tokens_size = inactive_access_tokens.size
   end
   # rubocop:enable Gitlab/ModuleWithInstanceVariables
 
diff --git a/app/services/personal_access_tokens/rotate_service.rb b/app/services/personal_access_tokens/rotate_service.rb
index d39da4f8992c3bd490a5fcbbbbbb08aa1a66c750..e8dae3a5dd58d1a6bc401b6739f33ab586a5c2ce 100644
--- a/app/services/personal_access_tokens/rotate_service.rb
+++ b/app/services/personal_access_tokens/rotate_service.rb
@@ -58,17 +58,11 @@ def valid_access_level?
     def update_bot_membership(target_user, expires_at)
       return if target_user.human?
 
-      if resource && Feature.enabled?(:retain_resource_access_token_user_after_revoke, resource.root_ancestor)
-        # Tokens created before the feature flag is enabled will have an
-        # expiring membership. We must explicitly set it to nil to
-        # - stop the membership from expiring on its old expiry date
-        # - retain the membership when this token does eventually expire
-        #   or get revoked.
-        #
-        # Applies only to resource (group and project) access tokens
-        # not personal access tokens.
-        expires_at = nil
-      end
+      # Related to https://gitlab.com/gitlab-org/gitlab/-/issues/514328
+      # We must retain bot user membership after it became inactive
+      # because currently it is the only way to identify to which
+      # group/project access token belongs to.
+      expires_at = nil # rubocop:disable Lint/ShadowedArgument -- https://gitlab.com/gitlab-org/gitlab/-/issues/514328
 
       target_user.members.update(expires_at: expires_at)
     end
diff --git a/app/services/resource_access_tokens/create_service.rb b/app/services/resource_access_tokens/create_service.rb
index 493b02707ff247539f0dfd4e5b05a83c4cd94a12..dd46123d0c799f95968590857165a311b848d56d 100644
--- a/app/services/resource_access_tokens/create_service.rb
+++ b/app/services/resource_access_tokens/create_service.rb
@@ -114,11 +114,7 @@ def default_scopes
     end
 
     def create_membership(resource, user, access_level)
-      if Feature.enabled?(:retain_resource_access_token_user_after_revoke, resource.root_ancestor)
-        resource.add_member(user, access_level)
-      else
-        resource.add_member(user, access_level, expires_at: pat_expiration)
-      end
+      resource.add_member(user, access_level)
     end
 
     def pat_expiration
diff --git a/app/services/resource_access_tokens/revoke_service.rb b/app/services/resource_access_tokens/revoke_service.rb
index 04aa73b0568e0596a35f78bf35e73ad227490cba..844a485bc8653be8b64d95f77fd5b00253978449 100644
--- a/app/services/resource_access_tokens/revoke_service.rb
+++ b/app/services/resource_access_tokens/revoke_service.rb
@@ -19,15 +19,9 @@ def execute
 
       access_token.revoke!
 
-      success_message = "Access token #{access_token.name} has been revoked"
-      unless Feature.enabled?(:retain_resource_access_token_user_after_revoke, resource.root_ancestor)
-        destroy_bot_user
-        success_message += " and the bot user has been scheduled for deletion"
-      end
-
       log_event
 
-      success("#{success_message}.")
+      success("Access token #{access_token.name} has been revoked.")
     rescue StandardError => error
       log_error("Failed to revoke access token for #{bot_user.name}: #{error.message}")
       error(error.message)
@@ -37,10 +31,6 @@ def execute
 
     attr_reader :current_user, :access_token, :bot_user, :resource
 
-    def destroy_bot_user
-      DeleteUserWorker.perform_async(current_user.id, bot_user.id, skip_authorization: true, reason_for_deletion: "Access token revoked")
-    end
-
     def can_destroy_token?
       %w[project group].include?(resource.class.name.downcase) && can?(current_user, :destroy_resource_access_tokens, resource)
     end
diff --git a/app/views/groups/settings/access_tokens/index.html.haml b/app/views/groups/settings/access_tokens/index.html.haml
index cd873a9503ee93e5834e3f4484146c1629d55655..47b0c34c03f20941ee0188ce11d9fbfdc981c298 100644
--- a/app/views/groups/settings/access_tokens/index.html.haml
+++ b/app/views/groups/settings/access_tokens/index.html.haml
@@ -51,10 +51,9 @@
       - c.with_body do
         #js-access-token-table-app{ data: { access_token_type: type, access_token_type_plural: type_plural, backend_pagination: 'true', initial_active_access_tokens: @active_access_tokens.to_json, no_active_tokens_message: _('This group has no active access tokens.'), show_role: true } }
 
-    - if Feature.enabled?(:retain_resource_access_token_user_after_revoke, @group.root_ancestor)
-      .gl-mt-5
-        = render ::Layouts::CrudComponent.new(_('Inactive group access tokens'),
-          icon: 'token',
-          count: @inactive_access_tokens_size) do |c|
-          - c.with_body do
-            #js-inactive-access-token-table-app{ data: { no_inactive_tokens_message: _('This group has no inactive access tokens.'), pagination_url: inactive_group_settings_access_tokens_url(@group, format: :json) } }
+    .gl-mt-5
+      = render ::Layouts::CrudComponent.new(_('Inactive group access tokens'),
+        icon: 'token',
+        count: @inactive_access_tokens_size) do |c|
+        - c.with_body do
+          #js-inactive-access-token-table-app{ data: { no_inactive_tokens_message: _('This group has no inactive access tokens.'), pagination_url: inactive_group_settings_access_tokens_url(@group, format: :json) } }
diff --git a/app/views/projects/settings/access_tokens/index.html.haml b/app/views/projects/settings/access_tokens/index.html.haml
index 5924152522f6184d93fa377f7b691bd8217fca60..e0537b2ff3aefdd0d7d1f144ff6c2b7b3e3a04ba 100644
--- a/app/views/projects/settings/access_tokens/index.html.haml
+++ b/app/views/projects/settings/access_tokens/index.html.haml
@@ -38,10 +38,9 @@
       - c.with_body do
         #js-access-token-table-app{ data: { access_token_type: type, access_token_type_plural: type_plural, backend_pagination: 'true', initial_active_access_tokens: @active_access_tokens.to_json, no_active_tokens_message: _('This project has no active access tokens.'), show_role: true } }
 
-    - if Feature.enabled?(:retain_resource_access_token_user_after_revoke, @project.root_ancestor)
-      .gl-mt-5
-        = render ::Layouts::CrudComponent.new(_('Inactive project access tokens'),
-          icon: 'token',
-          count: @inactive_access_tokens_size) do |c|
-          - c.with_body do
-            #js-inactive-access-token-table-app{ data: { no_inactive_tokens_message: _('This project has no inactive access tokens.'), pagination_url: inactive_project_settings_access_tokens_url(@project, format: :json) } }
+    .gl-mt-5
+      = render ::Layouts::CrudComponent.new(_('Inactive project access tokens'),
+        icon: 'token',
+        count: @inactive_access_tokens_size) do |c|
+        - c.with_body do
+          #js-inactive-access-token-table-app{ data: { no_inactive_tokens_message: _('This project has no inactive access tokens.'), pagination_url: inactive_project_settings_access_tokens_url(@project, format: :json) } }
diff --git a/config/feature_flags/beta/retain_resource_access_token_user_after_revoke.yml b/config/feature_flags/beta/retain_resource_access_token_user_after_revoke.yml
deleted file mode 100644
index 04da64070ba87a56970f0f3c4e116e5e8d2c9057..0000000000000000000000000000000000000000
--- a/config/feature_flags/beta/retain_resource_access_token_user_after_revoke.yml
+++ /dev/null
@@ -1,9 +0,0 @@
----
-name: retain_resource_access_token_user_after_revoke
-feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/462217
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/157130
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/468606
-milestone: '17.2'
-group: group::authentication
-type: beta
-default_enabled: false
diff --git a/doc/user/project/settings/project_access_tokens.md b/doc/user/project/settings/project_access_tokens.md
index 4b3621fd43961f280cb222b1fda1170b1e66ff01..ebb9a563de7a4e4ffbc164ebe460cb4110d62b14 100644
--- a/doc/user/project/settings/project_access_tokens.md
+++ b/doc/user/project/settings/project_access_tokens.md
@@ -186,10 +186,8 @@ Your expired access tokens are listed in the [inactive project access tokens tab
 
 ## Bot users for projects
 
-> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/462217) in GitLab 17.2 [with a flag](../../../administration/feature_flags.md) named `retain_resource_access_token_user_after_revoke`. Disabled by default. When enabled new bot users are made members with no expiry date and, when the token is later revoked or expires, the bot user is retained. It is not deleted and its records are not moved to the Ghost User.
-
-FLAG:
-The behavior of the bot user after the project access token is revoked is controlled by a feature flag. For more information, see the history.
+> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/462217) in GitLab 17.2 [with a flag](../../../administration/feature_flags.md) named `retain_resource_access_token_user_after_revoke`. Disabled by default. When enabled new bot users are made members with no expiry date and, when the token is later revoked or expires, the bot user is retained for 30 days.
+> - Inactive bot users retention is [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/462217) in GitLab 17.9. Feature flag `retain_resource_access_token_user_after_revoke` removed.
 
 Bot users for projects are [GitLab-created non-billable users](../../../subscriptions/self_managed/index.md#billable-users).
 Each time you create a project access token, a bot user is created and added to the project.
@@ -206,15 +204,15 @@ API calls made with a project access token are associated with the corresponding
 
 Bot users for projects:
 
-- Are included in a project's member list but cannot be modified. The membership expires when the token expires.
+- Are included in a project's member list but cannot be modified.
 - Cannot be added to any other project.
 - Can have a maximum role of Owner for a project. For more information, see
   [Create a project access token](../../../api/project_access_tokens.md#create-a-project-access-token).
 
 When the project access token is [revoked](#revoke-or-rotate-a-project-access-token):
 
-- The bot user is deleted.
-- All records are moved to a system-wide user with the username [Ghost User](../../profile/account/delete_account.md#associated-records).
+- The bot user is retained for 30 days.
+- After 30 days the bot user is deleted. All records are moved to a system-wide user with the username [Ghost User](../../profile/account/delete_account.md#associated-records).
 
 See also [Bot users for groups](../../group/settings/group_access_tokens.md#bot-users-for-groups).
 
diff --git a/ee/spec/requests/admin/credentials_controller_spec.rb b/ee/spec/requests/admin/credentials_controller_spec.rb
index fdd69e334d7910c81e2fe19147cfbfa5360b4ecf..76662d88aa13c5111c9ea841f09ab61d381d85d3 100644
--- a/ee/spec/requests/admin/credentials_controller_spec.rb
+++ b/ee/spec/requests/admin/credentials_controller_spec.rb
@@ -205,26 +205,6 @@
         expect(response).to redirect_to(admin_credentials_path)
         expect(flash[:notice]).to eq "Access token #{group_access_token.name} has been revoked."
       end
-
-      context 'when retain_bot_user feature flag is disabled' do
-        before do
-          stub_feature_flags(retain_resource_access_token_user_after_revoke: false)
-        end
-
-        it :aggregate_failures do
-          put admin_credential_resource_revoke_path(credential_id: project_access_token.id, resource_id: project.id, resource_type: 'Project')
-
-          expect(response).to redirect_to(admin_credentials_path)
-          expect(flash[:notice]).to eq "Access token #{project_access_token.name} has been revoked and the bot user has been scheduled for deletion."
-        end
-
-        it :aggregate_failures do
-          put admin_credential_resource_revoke_path(credential_id: group_access_token.id, resource_id: group.id, resource_type: 'Group')
-
-          expect(response).to redirect_to(admin_credentials_path)
-          expect(flash[:notice]).to eq "Access token #{group_access_token.name} has been revoked and the bot user has been scheduled for deletion."
-        end
-      end
     end
 
     shared_examples_for 'displays the flash error message' do
diff --git a/spec/factories/personal_access_tokens.rb b/spec/factories/personal_access_tokens.rb
index f4e0036da98a524df47f97245642bc9a656d5e02..d3cd1b0c91873d18c8e3e2b2d0bdcb92d9a24ff5 100644
--- a/spec/factories/personal_access_tokens.rb
+++ b/spec/factories/personal_access_tokens.rb
@@ -54,11 +54,7 @@
     end
 
     after(:create) do |token, evaluator|
-      if Feature.enabled?(:retain_resource_access_token_user_after_revoke, evaluator.resource.root_ancestor)
-        evaluator.resource.add_member(token.user, evaluator.access_level)
-      else
-        evaluator.resource.add_member(token.user, evaluator.access_level, expires_at: token.expires_at)
-      end
+      evaluator.resource.add_member(token.user, evaluator.access_level)
     end
 
     trait :with_rotated_token do
diff --git a/spec/lib/authn/tokens/personal_access_token_spec.rb b/spec/lib/authn/tokens/personal_access_token_spec.rb
index da7d9a4764c71fe6d11beed4e03a49a1d318c185..8c508059975a910ed14d847fdc9127315cfbc3de 100644
--- a/spec/lib/authn/tokens/personal_access_token_spec.rb
+++ b/spec/lib/authn/tokens/personal_access_token_spec.rb
@@ -3,21 +3,6 @@
 require 'spec_helper'
 
 RSpec.describe Authn::Tokens::PersonalAccessToken, feature_category: :system_access do
-  shared_examples 'resource access token' do
-    before do
-      stub_feature_flags(retain_resource_access_token_user_after_revoke: false)
-    end
-
-    it 'also deletes the bot', :enable_admin_mode do
-      expect(DeleteUserWorker).to receive(:perform_async).with(
-        admin.id, bot.id,
-        skip_authorization: true, reason_for_deletion: "Access token revoked"
-      )
-
-      expect(token.revoke!(admin).status).to eq(:success)
-    end
-  end
-
   let_it_be(:user) { create(:user) }
   let_it_be(:admin) { create(:admin) }
   let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
@@ -43,7 +28,9 @@
       let_it_be(:project_member) { create(:project_member, source: create(:project), user: bot) }
       let_it_be(:plaintext) { create(:personal_access_token, user: bot).token }
 
-      it_behaves_like 'resource access token'
+      it 'successfully revokes the token', :enable_admin_mode do
+        expect(token.revoke!(admin).status).to eq(:success)
+      end
     end
 
     context 'when the token is a group access token' do
@@ -51,7 +38,9 @@
       let_it_be(:group_member) { create(:group_member, source: create(:group), user: bot) }
       let_it_be(:plaintext) { create(:personal_access_token, user: bot).token }
 
-      it_behaves_like 'resource access token'
+      it 'successfully revokes the token', :enable_admin_mode do
+        expect(token.revoke!(admin).status).to eq(:success)
+      end
     end
   end
 
diff --git a/spec/requests/api/resource_access_tokens_spec.rb b/spec/requests/api/resource_access_tokens_spec.rb
index bd073173874be9edd04c1fa67a09b0e63a548d7b..fb5e839a3a90b24d9e131dc19934108ae79b8d45 100644
--- a/spec/requests/api/resource_access_tokens_spec.rb
+++ b/spec/requests/api/resource_access_tokens_spec.rb
@@ -277,43 +277,6 @@
       end
 
       context "when the user has valid permissions" do
-        context "when retain bot user ff is disabled" do
-          before do
-            stub_feature_flags(retain_resource_access_token_user_after_revoke: false)
-          end
-
-          it "deletes the #{source_type} access token from the #{source_type}" do
-            delete_token
-
-            expect(response).to have_gitlab_http_status(:no_content)
-            expect(token.reload).to be_revoked
-            expect(
-              Users::GhostUserMigration.where(user: project_bot, initiator_user: user)
-            ).to be_exists
-          end
-
-          context "when using #{source_type} access token to DELETE other #{source_type} access token" do
-            let_it_be(:other_project_bot) { create(:user, :project_bot) }
-            let_it_be(:other_token) { create(:personal_access_token, user: other_project_bot) }
-            let_it_be(:token_id) { other_token.id }
-
-            before do
-              resource.add_maintainer(other_project_bot)
-            end
-
-            it "deletes the #{source_type} access token from the #{source_type}" do
-              delete_token
-
-              expect(response).to have_gitlab_http_status(:no_content)
-              expect(token.reload).not_to be_revoked
-              expect(other_token.reload).to be_revoked
-              expect(
-                Users::GhostUserMigration.where(user: other_project_bot, initiator_user: user)
-              ).to be_exists
-            end
-          end
-        end
-
         it "deletes the #{source_type} access token from the #{source_type}" do
           delete_token
 
diff --git a/spec/services/group_access_tokens/rotate_service_spec.rb b/spec/services/group_access_tokens/rotate_service_spec.rb
index b37ea73a045aaf01e8099a1cda9ad13cef23309c..9e25d696cd9b86131a9743cf44f260b193d79105 100644
--- a/spec/services/group_access_tokens/rotate_service_spec.rb
+++ b/spec/services/group_access_tokens/rotate_service_spec.rb
@@ -21,23 +21,6 @@
         expect(new_token.user).to eq(token.user)
         expect(bot_user_membership.reload.expires_at).to be_nil
       end
-
-      context 'when retain_resource_access_token_user_after_revoke FF is disabled' do
-        before do
-          stub_feature_flags(retain_resource_access_token_user_after_revoke: false)
-        end
-
-        it 'rotates the token and sets the bot user expires at', :freeze_time do
-          expect(response).to be_success
-
-          new_token = response.payload[:personal_access_token]
-
-          expect(new_token.token).not_to eq(token.token)
-          expect(new_token.expires_at).to eq(1.week.from_now.to_date)
-          expect(new_token.user).to eq(token.user)
-          expect(bot_user_membership.reload.expires_at).to eq(new_token.expires_at)
-        end
-      end
     end
 
     shared_examples_for 'fails to rotate the token' do
diff --git a/spec/services/project_access_tokens/rotate_service_spec.rb b/spec/services/project_access_tokens/rotate_service_spec.rb
index 90ab1cf857c910f68e057ccb8fe44e90837c69d7..ed85da123d3b1a131dd5cc456857c9947e18593a 100644
--- a/spec/services/project_access_tokens/rotate_service_spec.rb
+++ b/spec/services/project_access_tokens/rotate_service_spec.rb
@@ -136,19 +136,6 @@
               response
               expect(bot_user_membership.reload.expires_at).to be_nil
             end
-
-            context 'when retain_resource_access_token_user_after_revoke FF is disabled' do
-              before do
-                stub_feature_flags(retain_resource_access_token_user_after_revoke: false)
-              end
-
-              it 'updates membership expires at' do
-                response
-
-                new_token = response.payload[:personal_access_token]
-                expect(bot_user_membership.reload.expires_at).to eq(new_token.expires_at)
-              end
-            end
           end
         end
 
diff --git a/spec/services/resource_access_tokens/create_service_spec.rb b/spec/services/resource_access_tokens/create_service_spec.rb
index 341c8adc87e0afbeea017259c2336d1142095dcc..5ad28cdcbc5d36cd19a805b4400dfa4d100080a4 100644
--- a/spec/services/resource_access_tokens/create_service_spec.rb
+++ b/spec/services/resource_access_tokens/create_service_spec.rb
@@ -234,22 +234,6 @@
               expect(resource.members.find_by(user_id: project_bot.id).expires_at).to be_nil
             end
 
-            context 'when retain_resource_access_token_user_after_revoke is disabled' do
-              before do
-                stub_feature_flags(retain_resource_access_token_user_after_revoke: false)
-              end
-
-              it 'project bot membership expires when PAT expires' do
-                response = subject
-                access_token = response.payload[:access_token]
-                project_bot = access_token.user
-
-                expect(resource.members.find_by(user_id: project_bot.id).expires_at).to eq(
-                  max_pat_access_token_lifetime.to_date
-                )
-              end
-            end
-
             context 'when require_personal_access_token_expiry is set to false' do
               before do
                 stub_application_setting(require_personal_access_token_expiry: false)
@@ -281,20 +265,6 @@
 
               expect(resource.members.find_by(user_id: project_bot.id).expires_at).to be_nil
             end
-
-            context 'when retain_resource_access_token_user_after_revoke is disabled' do
-              before do
-                stub_feature_flags(retain_resource_access_token_user_after_revoke: false)
-              end
-
-              it 'sets the project bot to expire on the same day as the token' do
-                response = subject
-                access_token = response.payload[:access_token]
-                project_bot = access_token.user
-
-                expect(resource.members.find_by(user_id: project_bot.id).expires_at).to eq(access_token.expires_at)
-              end
-            end
           end
 
           context 'when invalid scope is passed' do
diff --git a/spec/services/resource_access_tokens/revoke_service_spec.rb b/spec/services/resource_access_tokens/revoke_service_spec.rb
index 96ac7ef7dc7ae1d71a2b1631acedf40d1102f53b..e8035e198a3786f000204d227e748beeda7bbcdd 100644
--- a/spec/services/resource_access_tokens/revoke_service_spec.rb
+++ b/spec/services/resource_access_tokens/revoke_service_spec.rb
@@ -36,37 +36,6 @@
 
         expect(Gitlab::AppLogger).to have_received(:info).with("PROJECT ACCESS TOKEN REVOCATION: revoked_by: #{user.username}, project_id: #{resource.id}, token_user: #{resource_bot.name}, token_id: #{access_token.id}")
       end
-
-      context 'with retain user feature flag disabled' do
-        before do
-          stub_feature_flags(retain_resource_access_token_user_after_revoke: false)
-        end
-
-        it { expect(subject.message).to eq("Access token #{access_token.name} has been revoked and the bot user has been scheduled for deletion.") }
-
-        it 'calls delete user worker' do
-          expect(DeleteUserWorker).to receive(:perform_async).with(
-            user.id, resource_bot.id,
-            skip_authorization: true, reason_for_deletion: "Access token revoked"
-          )
-
-          subject
-        end
-
-        it 'removes membership of bot user' do
-          subject
-
-          expect(resource.reload).not_to have_user(resource_bot)
-        end
-
-        it 'initiates user removal' do
-          subject
-
-          expect(
-            Users::GhostUserMigration.where(user: resource_bot, initiator_user: user)
-          ).to be_exists
-        end
-      end
     end
 
     shared_examples 'rollback revoke steps' do
diff --git a/spec/support/shared_examples/features/access_tokens_shared_examples.rb b/spec/support/shared_examples/features/access_tokens_shared_examples.rb
index ac6de78edce0b6e62ffaaca953f84511056c17b7..723ba30495c704627dc657e46f54fbff33fe004f 100644
--- a/spec/support/shared_examples/features/access_tokens_shared_examples.rb
+++ b/spec/support/shared_examples/features/access_tokens_shared_examples.rb
@@ -133,17 +133,6 @@ def inactive_access_tokens
     find("[data-testid='inactive-access-tokens']")
   end
 
-  context 'when feature flag is disabled' do
-    before do
-      stub_feature_flags(retain_resource_access_token_user_after_revoke: false)
-    end
-
-    it 'does not show inactive tokens' do
-      visit resource_settings_access_tokens_path
-      expect(page).to have_no_selector("[data-testid='inactive-access-tokens']")
-    end
-  end
-
   it 'allows revocation of an active token' do
     visit resource_settings_access_tokens_path
     accept_gl_confirm(button_text: 'Revoke') { click_on 'Revoke' }
diff --git a/spec/support/shared_examples/requests/access_tokens_controller_shared_examples.rb b/spec/support/shared_examples/requests/access_tokens_controller_shared_examples.rb
index 686e969f6e9188f656600108355325029eb4d131..f135d29d53241f64e1f396917c2fc5873164f468 100644
--- a/spec/support/shared_examples/requests/access_tokens_controller_shared_examples.rb
+++ b/spec/support/shared_examples/requests/access_tokens_controller_shared_examples.rb
@@ -35,18 +35,6 @@
     expect(assigns(:inactive_access_tokens_size)).to eq(3)
   end
 
-  context 'when retain_resource_access_token_user_after_revoke FF is disabled' do
-    before do
-      stub_feature_flags(retain_resource_access_token_user_after_revoke: false)
-    end
-
-    it 'does not retrieve count of inactive access tokens' do
-      get_access_tokens
-
-      expect(assigns(:inactive_access_tokens_size)).to be_nil
-    end
-  end
-
   it 'returns for json response list of active access tokens' do
     get_access_tokens_json
 
@@ -123,14 +111,6 @@ def expect_header(header_name, header_val)
     create(:personal_access_token, user: access_token_user)
   end
 
-  context 'when retain_resource_access_token_user_after_revoke FF is disabled' do
-    before do
-      stub_feature_flags(retain_resource_access_token_user_after_revoke: false)
-    end
-
-    it { expect(subject).to have_gitlab_http_status(:not_found) }
-  end
-
   it 'returns list of inactive access tokens' do
     get_inactive_access_tokens
 
@@ -232,44 +212,6 @@ def created_token
 end
 
 RSpec.shared_examples 'PUT resource access tokens available' do
-  context "when retain bot user ff is disabled" do
-    before do
-      stub_feature_flags(retain_resource_access_token_user_after_revoke: false)
-    end
-
-    it 'revokes the token' do
-      subject
-      expect(resource_access_token.reload).to be_revoked
-    end
-
-    it 'calls delete user worker' do
-      expect(DeleteUserWorker).to receive(:perform_async).with(
-        user.id,
-        access_token_user.id,
-        skip_authorization: true, reason_for_deletion: "Access token revoked"
-      )
-
-      subject
-    end
-
-    it 'removes membership of bot user' do
-      subject
-
-      resource_bots = if resource.is_a?(Project)
-                        resource.bots
-                      elsif resource.is_a?(Group)
-                        User.bots.id_in(resource.all_group_members.non_invite.pluck(:user_id))
-                      end
-
-      expect(resource_bots).not_to include(access_token_user)
-    end
-
-    it 'creates GhostUserMigration records to handle migration in a worker' do
-      expect { subject }.to(
-        change { Users::GhostUserMigration.count }.from(0).to(1))
-    end
-  end
-
   it 'revokes the token' do
     subject
     expect(resource_access_token.reload).to be_revoked