Author environment policy rules as names and tiers
What does this MR do and why?
The Policy Store editor's Environment State rule authored a single free-text environment key, but the rule transpiler (gitlab-policy-store gem) reads exactly names and tiers from the rule's value, both arrays of strings, and refuses the rule when neither yields one. Every environment rule authored in the UI was therefore rejected on save with rule 0: environment rule requires at least one of names or tiers — the rule was unauthorable.
This MR replaces the field with the two the transpiler reads:
names: a free-form token list (newtoken_listfield type in the editor's GenericConfig, rendered withGlTokenSelector) for exact environment names.tiers: a badge selector over the five deployment tiers.
The old field's placeholder also promised glob patterns (prod-*) that the compiled Rego never supported; the new copy states the values match verbatim, and that when names and tiers are both set the environment must match both (the compiled conditions are conjunctive).
References
Found while triaging the Policy Store experiment on staging (policies could not be created from the wizard). No tracked issue yet.
Screenshots or screen recordings
| Before | After |
|---|---|
![]() |
![]() |
Before: one free-text Environment field whose value nothing read; every save failed with environment rule requires at least one of names or tiers. After: an Environment names token list and an Environment tiers badge selector; saving succeeds.
How to set up and validate locally
-
Enable the experiment in a Rails console:
Feature.enable(:security_policies_v2) ApplicationSetting.current.update!(policy_store_experiment_enabled: true) group = Group.find_by_full_path('<your-root-group>') group.namespace_settings.update!(policy_store_experiment_enabled: true) -
As an instance administrator, open
Secure > Policy store > Create new policyon the opted-in group. -
Name the policy, add the Deployment trigger, open the Rules tab, and add Environment State.
-
Type an environment name (for example
canary) into Environment names and press Enter; click a tier badge (for exampleproduction). -
Continue through Next > Next > Save policy. The save succeeds (
201onPOST /api/v4/organizations/:id/security/policy_store); before this change the same flow always failed withrule 0: environment rule requires at least one of names or tiers. -
Fetch the stored policy and confirm the compiled Rego carries membership sets for both fields:
curl --header "PRIVATE-TOKEN: <admin-token>" "http://gdk.test:3000/api/v4/organizations/1/security/policy_store"The environment rule's
regocontainsinput.environment.name in {"canary"}andinput.environment.tier in {"production"}.

