diff --git a/app/assets/javascripts/access_tokens/components/access_token_table_app.vue b/app/assets/javascripts/access_tokens/components/access_token_table_app.vue
index ff421eb3ec33a8fee2b392c8b05a3216df00f3be..cb71eedae7554e13720ef322fe6c3983db635583 100644
--- a/app/assets/javascripts/access_tokens/components/access_token_table_app.vue
+++ b/app/assets/javascripts/access_tokens/components/access_token_table_app.vue
@@ -12,7 +12,6 @@ import DomElementListener from '~/vue_shared/components/dom_element_listener.vue
 import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
 import HelpIcon from '~/vue_shared/components/help_icon/help_icon.vue';
 import UserDate from '~/vue_shared/components/user_date.vue';
-import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
 import { EVENT_SUCCESS, FIELDS, INITIAL_PAGE, PAGE_SIZE } from './constants';
 
 /**
@@ -38,7 +37,6 @@ export default {
   directives: {
     GlTooltip: GlTooltipDirective,
   },
-  mixins: [glFeatureFlagsMixin()],
   lastUsedHelpLink: helpPagePath('/user/profile/personal_access_tokens.md', {
     anchor: 'view-the-time-at-and-ips-where-a-token-was-last-used',
   }),
@@ -95,10 +93,6 @@ export default {
         ignoredFields.push('role');
       }
 
-      if (!this.glFeatures.patIp) {
-        ignoredFields.push('lastUsedIps');
-      }
-
       const fields = FIELDS.filter(({ key }) => !ignoredFields.includes(key));
 
       // Remove the sortability of the columns if backend pagination is on.
diff --git a/app/controllers/user_settings/personal_access_tokens_controller.rb b/app/controllers/user_settings/personal_access_tokens_controller.rb
index 55579bc2d8c0c7c0a9720faecc4028336e945f01..d764e0ac7410b647672287b617d7ac8dce1e5da0 100644
--- a/app/controllers/user_settings/personal_access_tokens_controller.rb
+++ b/app/controllers/user_settings/personal_access_tokens_controller.rb
@@ -8,9 +8,6 @@ class PersonalAccessTokensController < ApplicationController
     feature_category :system_access
 
     before_action :check_personal_access_tokens_enabled
-    before_action do
-      push_frontend_feature_flag(:pat_ip, current_user)
-    end
     prepend_before_action(only: [:index]) { authenticate_sessionless_user!(:ics) }
 
     def index
diff --git a/app/services/personal_access_tokens/last_used_service.rb b/app/services/personal_access_tokens/last_used_service.rb
index 1c479b1db1f3ea08bd12a7aa8496e921367f9f41..70cd218102b1016315e7176b234eb7e9bdaf1857 100644
--- a/app/services/personal_access_tokens/last_used_service.rb
+++ b/app/services/personal_access_tokens/last_used_service.rb
@@ -63,7 +63,6 @@ def update_pat_ip
     end
 
     def last_used_ip_needs_update?
-      return false unless Feature.enabled?(:pat_ip, @personal_access_token.user)
       return false unless Gitlab::IpAddressState.current
       return true if @personal_access_token.last_used_at.nil?
 
diff --git a/config/feature_flags/gitlab_com_derisk/pat_ip.yml b/config/feature_flags/gitlab_com_derisk/pat_ip.yml
deleted file mode 100644
index bc1d46553818bf6b277c46fc5f958531b3f640e3..0000000000000000000000000000000000000000
--- a/config/feature_flags/gitlab_com_derisk/pat_ip.yml
+++ /dev/null
@@ -1,9 +0,0 @@
----
-name: pat_ip
-feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/428577
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/161076
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/428577
-milestone: '17.8'
-group: group::authentication
-type: gitlab_com_derisk
-default_enabled: false
diff --git a/db/docs/personal_access_token_last_used_ips.yml b/db/docs/personal_access_token_last_used_ips.yml
index 6471bbc11e9ea2310f17a46e10af73cfbd939eec..c0d4ab0d6cef9b10dcde9dd2fff665f84d0a4333 100644
--- a/db/docs/personal_access_token_last_used_ips.yml
+++ b/db/docs/personal_access_token_last_used_ips.yml
@@ -4,7 +4,7 @@ feature_categories:
   - system_access
 description: Keeps the data for last used IP addresses for personal access tokens
 introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/161076
-milestone: '17.8'
+milestone: '17.9'
 gitlab_schema: gitlab_main_cell
 sharding_key:
-  organization_id: organizations
\ No newline at end of file
+organization_id: organizations
diff --git a/db/migrate/20241112103518_add_personal_access_token_last_used_ips_table.rb b/db/migrate/20241112103518_add_personal_access_token_last_used_ips_table.rb
index e9f59d5550681b83283c9d2245eefbfaebe2c4eb..1c9a60a1060f66954cf11aa758fdc5039c5211c7 100644
--- a/db/migrate/20241112103518_add_personal_access_token_last_used_ips_table.rb
+++ b/db/migrate/20241112103518_add_personal_access_token_last_used_ips_table.rb
@@ -3,7 +3,7 @@
 class AddPersonalAccessTokenLastUsedIpsTable < Gitlab::Database::Migration[2.2]
   INDEX_NAME = 'idx_pat_last_used_ips_on_pat_id'
 
-  milestone '17.8'
+  milestone '17.9'
 
   def up
     create_table :personal_access_token_last_used_ips do |t|
diff --git a/doc/user/profile/personal_access_tokens.md b/doc/user/profile/personal_access_tokens.md
index 4427f85c985e047e46ca0dffe87aec94165da94f..6d8c7409439514aff330d64f429deb700ad5ee8b 100644
--- a/doc/user/profile/personal_access_tokens.md
+++ b/doc/user/profile/personal_access_tokens.md
@@ -166,6 +166,7 @@ To disable the enterprise users' personal access tokens:
 > - In GitLab 16.0 and earlier, token usage information is updated every 24 hours.
 > - The frequency of token usage information updates [changed](https://gitlab.com/gitlab-org/gitlab/-/issues/410168) in GitLab 16.1 from 24 hours to 10 minutes.
 > - Ability to view IP addresses [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/428577) in GitLab 17.8 [with a flag](../../administration/feature_flags.md) named `pat_ip`. Disabled by default.
+> - In GitLab 17.9, the `pat_ip` feature flag was removed and the ability to view IP addresses was enabled.
 
 Token usage information is updated every 10 minutes. GitLab considers a token used when the token is used to:
 
diff --git a/spec/frontend/access_tokens/components/access_token_table_app_spec.js b/spec/frontend/access_tokens/components/access_token_table_app_spec.js
index 570a83d4028ef3edb1882cdbab439bfe158c9474..2e2938872b1d60a8387bc2ca782d26272448a0d2 100644
--- a/spec/frontend/access_tokens/components/access_token_table_app_spec.js
+++ b/spec/frontend/access_tokens/components/access_token_table_app_spec.js
@@ -59,9 +59,6 @@ describe('~/access_tokens/components/access_token_table_app', () => {
         initialActiveAccessTokens: defaultActiveAccessTokens,
         noActiveTokensMessage,
         showRole,
-        glFeatures: {
-          patIp: true,
-        },
         ...props,
       },
     });
diff --git a/spec/services/personal_access_tokens/last_used_service_spec.rb b/spec/services/personal_access_tokens/last_used_service_spec.rb
index e17cbc581b7765281007fc63f8bc81e90d3271b0..25b45940c4ec2e6c68f022c74b707636ad32dfeb 100644
--- a/spec/services/personal_access_tokens/last_used_service_spec.rb
+++ b/spec/services/personal_access_tokens/last_used_service_spec.rb
@@ -45,25 +45,6 @@
         end
       end
 
-      context 'when PAT IP feature flag is disabled' do
-        let(:current_ip_address) { '127.0.0.1' }
-
-        before do
-          stub_feature_flags(pat_ip: false)
-        end
-
-        it "does not update the personal access token's last used ips" do
-          allow(Gitlab::IpAddressState).to receive(:current).and_return(current_ip_address)
-
-          expect { service_execution }.not_to change { personal_access_token.last_used_ips.count }
-          expect(
-            Authn::PersonalAccessTokenLastUsedIp
-              .where(personal_access_token_id: personal_access_token.id, ip_address: Gitlab::IpAddressState.current)
-              .exists?
-          ).to be_falsy
-        end
-      end
-
       context 'when the personal access token was used more than 1 minute ago', :freeze_time do
         let(:current_ip_address) { '::1' }
         let(:personal_access_token) { create(:personal_access_token, last_used_at: 2.minutes.ago) }