Block saving Policy Store rules with blank required config
What does this MR do and why?
The wizard let three rule shapes reach Save that the store always refuses — an empty custom Rego program, a custom program declaring a package other than governance, and an environment rule naming neither environments nor tiers. Each failed server-side, surfacing the store's 400 message in a generic page alert far from the field that caused it. This blocks all three client-side, naming the gaps where Save lives:
- The rules catalog now declares requirements as data:
required: trueand afirstStatementexpectation on the custom rule's Rego field, andrequireOneOf: ['names', 'tiers']on the environment rule (mirroringGitlab::PolicyStore::RuleTranspiler). - A new
catalog/validation.jsturns unmet declarations into human sentences; guard specs pin the declarations against typos (arequireOneOfkey must exist among the entry's fields, never be empty) and pin the shipped default template as satisfying its own field's rules, so a freshly added Custom Rule is never born blocked. ThefirstStatementparse is shared with the rego-template guard spec, so "first statement" has a single definition. - The review step lists the blockers in a warning alert titled "Complete the policy before saving", above the impact statement (which stays visible), and the Save button stays disabled until they are resolved. The blockers are computed against the static
RULEScatalog so they survive a catalog fetch failure.
Known gap, deliberately out of scope: a calendar (Freeze Window) rule still reaches Save even though the transpiler has no emitter for it yet — that emitter lands in !250203 (merged) and the surface is intentionally kept authorable in the meantime.
References
- Blank rules/actions elements refused: !250726 (merged)
- Persistence-layer rules validation: !251158 (merged)
- Issue: https://gitlab.com/gitlab-org/gitlab/-/work_items/604309
Screenshots or screen recordings
Recording (3x speed, GDK org first): add a Custom Rule (prefilled template, field marked required) → clear the Rego → the review step shows "Complete the policy before saving: Custom Rule (Rego) is missing Rego policy definition." with Save disabled → type a program opening with package mine → the blocker becomes "…must open with package governance" → fix the package → blockers gone, Save enabled, policy created.
| Before | After |
|---|---|
| Empty or wrong-package Rego saved into a server error in a page alert | Save disabled with the gaps named on the review step |
How to set up and validate locally
- Enable
security_policies_v2and thepolicy_store_experiment_enabledapplication setting (Ultimate license); for the organization surface also enableui_for_organizations. - Create a policy with a trigger and a Custom Rule, clear the prefilled Rego, and go to the Review step: the warning alert names the gap and Save is disabled.
- Type a program starting with a package other than
governance: the blocker changes to the must-open-with message. - Restore
package governance: the alert disappears and Save works. - Same with an Environment State rule and neither names nor tiers filled.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist.