Add last_used_ips to project_access_tokens and group_access_token
Title: Expose last_used_ips on project and group access token API responses extends: https://gitlab.com/gitlab-org/gitlab/-/work_items/428577 Type: Feature / API enhancement Labels (suggest): ~"group::authentication" ~"Category:System Access" ~"feature" ~"backend" ~"API" Body: ## Problem The public REST API responses for project and group access tokens omit `last_used_ips`, even though: 1. The data is already collected — project and group access tokens are `PersonalAccessToken` rows owned by `project_bot` users (see `app/models/personal_access_token.rb`), and the `last_used_ips` association is populated identically to personal tokens. 2. The GitLab web UI already surfaces "Last Used IPs" for these tokens via the internal `ProjectAccessTokenSerializer` / `GroupAccessTokenSerializer`, both of which inherit from `AccessTokenEntityBase < API::Entities::PersonalAccessTokenWithLastUsedIps`. 3. The public REST entity `API::Entities::ResourceAccessToken` (`lib/api/entities/resource_access_token.rb`) inherits from the IP-less `API::Entities::PersonalAccessToken` instead. As a result, programmatic auditors cannot see the same information that admins see in the UI. 4. GraphQL has no `ProjectAccessToken` / `GroupAccessToken` types at all, so the REST API is the only path for programmatic access. ## Use case We run an internal auditor (`repo-scanner audit`) that flags unmanaged or stale access tokens across our GitLab projects and groups. We'd like to additionally flag tokens last used from IP ranges outside our trusted infrastructure (e.g. outside GCP/runner CIDR ranges) so an unexpected egress can be detected early. Today this is impossible without scraping internal Rails routes or reading the database directly. ## Proposal Change `API::Entities::ResourceAccessToken` to inherit from `API::Entities::PersonalAccessTokenWithLastUsedIps`. This is a one-line change that adds `last_used_ips: [...]` to the responses of: - `GET /projects/:id/access_tokens` - `GET /projects/:id/access_tokens/:token_id` - `POST /projects/:id/access_tokens/:token_id/rotate` - `GET /groups/:id/access_tokens` - `GET /groups/:id/access_tokens/:token_id` - `POST /groups/:id/access_tokens/:token_id/rotate` No model changes, no migrations, no new endpoints. Field shape and semantics match the existing personal access tokens implementation. ## Backwards compatibility Additive only — adds a single new field to existing JSON responses. No existing field changes type or is removed. Clients that ignore unknown fields are unaffected.
task