What a GitLab token can be depends on which GitLab you ask
Access levels arrive in GitLab releases, so validating them without knowing the version gets you a plausible error at the wrong time.
GitLab adds access levels between releases.
Planner showed up in 17.7 and Security Manager in 18.11, and if you ask a 17.5 instance for either one you get a rejection from GitLab with no particular explanation.
That is a bad place to find out, because by then Vault has accepted the role, stored it, and the failure happens later when somebody asks for a token.
So we validate the access level against the GitLab we are actually talking to, rather than against a list of everything GitLab has ever supported.
var accessLevelMinVersionByTokenType = map[Type]map[AccessLevel]string{ TypeProject: { AccessLevelGuestPermissions: "0.0", AccessLevelDeveloperPermissions: "0.0", AccessLevelMaintainerPermissions: "0.0", AccessLevelPlannerPermissions: "17.7", AccessLevelSecurityManagerPermissions: "18.11", }, TypePersonal: nil,}0.0 means it has always worked inside the range the plugin supports, and a version string means you need at least that.
The nil is the other half, and I took a while to see that it belonged in the same table.
A personal access token has no access level at all, and neither does a service account token, so the right answer there isn’t a list of permitted values, it’s that the field doesn’t apply and a non-empty value is an error.
Two different failures, one table.
The same thing happens with scopes, because those arrive in releases too, so we give them the same treatment.
Supporting a new GitLab release is usually a line in a map, and what the plugin refuses to do changes with the version it’s pointed at rather than with the version of the plugin you installed.