Add expires_at argument to personalAccessTokenRotate mutation

What does this MR do and why?

Add optional expires_at argument to allow specifying custom expiration dates when rotating personal access tokens (PAT). If not provided, the new token inherits the original token's expiration date. This behavior (new token expires_at == rotated token's expires_at) matches the current behavior of PAT rotation.

References

Screenshots or screen recordings

Before After

How to set up and validate locally

  1. Login with any user
  2. Create a personal access token for the user with an expiration date.
  3. Get the global ID of the created personal access token
    $ rails c
    > PersonalAccessToken.last.to_global_id.to_s
    => "gid://gitlab/PersonalAccessToken/<id>"
  4. Enable granular_personal_access_tokens feature flag
  5. Go to http://localhost:3000/-/graphql-explorer and run the following mutation
    mutation {
      personalAccessTokenRotate(input: { id: "gid://gitlab/PersonalAccessToken/<id>" }) {
        token
        errors
      }
    }
  6. Verify that the new token's expires_at is equal to the rotated token's expires_at
    $ rails c
    > PersonalAccessToken.last.expires_at == PersonalAccessToken.find(<id>).expires_at
    => true
  7. Go to http://localhost:3000/-/graphql-explorer and run the following mutation on the new token
    mutation {
      personalAccessTokenRotate(input: { id: "gid://gitlab/PersonalAccessToken/<new-token-id>", expiresAt: "2026-05-01" }) {
        token
        errors
      }
    }
  8. Verify that the new token's expires_at is equal to provided value
    $ rails c
    > PersonalAccessToken.last.expires_at
    => Fri, 01 May 2026

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Eugie Limpin

Merge request reports

Loading