Reset legacy 'gl' instance token prefix

What does this MR do and why?

instance_token_prefix defaulted to gl between 2025-02-27 (4156bc0c) and 2025-05-11 (36c2cc83), before being intentionally changed to ''. That default was written into application_settings.token_prefixes on any instance that saved its application settings during that window, even with the feature flag diabled.

The stale value has no effect today, but once custom_prefix_for_all_token_types is enabled, it composes the token prefix as <instance_prefix>-<type_prefix>, so every newly generated token comes out as gl-glpat-… (and equivalent for other token types) even though no administrator configured a prefix. It also overrides a configured custom PAT prefix without indication. The feature flag has not been enabled yet, so no token has ever been issued with a gl- prefix. This makes clearing the stale value safe.

This MR:

  1. Makes Authn::TokenField::PrefixHelper.instance_prefix treat a stored gl as unset (returns ''), so gl- is never prepended, regardless of whether the data migration below has run yet.
  2. Rejects setting instance_token_prefix to gl going forward in ApplicationSetting, but only when the value is being changed (if: :instance_token_prefix_changed?), so instances that still have gl persisted can keep saving other settings without being blocked. This avoids confusion in the future.
  3. Adds a regular data migration that resets persisted gl values back to ''. It runs as a regular migration so it executes before the applying code on every upgrade path. down is a no-op: a reset row is indistinguishable from an intentionally empty one, and the old gl must not (and cannot) be restored, because we don't know if the the previous value was empty or gl.

🛠️ with ❤️ at Siemens

References

How to set up and validate locally

  1. Reproduce a legacy instance in bin/rails console:
  s = ApplicationSetting.current
  s.update_column(:token_prefixes, s.token_prefixes.merge('instance_token_prefix' => 'gl'))
  Feature.enable(:custom_prefix_for_all_token_types)
  1. Confirm the stored gl is treated as unset: Authn::TokenField::PrefixHelper.instance_prefix returns , and a newly created personal access token has the prefix glpat-xyz123..., not gl-glpat-xyz123....
  2. You can confirm unrelated settings still can be saved while gl is in the database by changing any other setting in the general admin view.
  3. Confirm setting the prefix to gl is now rejected:
  ApplicationSetting.current.update(instance_token_prefix: 'gl')
  # => false, error: "is reserved and cannot be used"
  1. Run the migration and confirm the stored value is cleared:
  bin/rails db:migrate

  ApplicationSetting.current.reload.instance_token_prefix
  # => ""

MR acceptance checklist

MR Checklist ( @nwittstruck)

Related to #608221 (closed)

Edited by Nicholas Wittstruck

Merge request reports

Loading
Loading