List the Policy Store policies on the project page
What does this MR do and why?
A project's Policy Store page now shows the security policies that apply to it — the ones authored at its organization and at the groups above it. The page is read-only: a project cannot create, edit or open a policy from here, so there is no create button and the policy names are plain text rather than links.
This also adds the Policy store entry under a project's Secure menu. It lands here rather than in the backend MR so that nothing points at the page until the page has something to show.
Details
- New client-side document
get_project_policy_store_policies.query.graphql, readingProject.policyStore.policies. No server schema change, so nothing to regenerate. app.vuepicks the query by container and derives each row's detail path fromlistPath; a project provides none, so its rows render without one.list_wrapper.vuehides the create button unless the reader both has the permission and has a path to send them to, swaps the empty-state copy when the container has no create path at all, and renders a name as plain text when the row has no detail path.- The evaluations stat is hidden on a project: its policy store records no evaluations of its own, so the count would always read zero. The query is skipped there, which also means its refetch has no observer —
retry()guards for that. - Sidebar entry added to the project Secure menu, with the same experiment and permission gate as the page itself.
Why this is needed
Projects are governed by policies they cannot see today. The organization and group levels each have a Policy Store page; a project has had no way to answer "which policies apply to me". This is the project half of https://gitlab.com/gitlab-org/gitlab/-/issues/632454, and it is the first state of this page a user can actually reach — the backend MR below adds the route and renders an empty container.
References
- https://gitlab.com/gitlab-org/gitlab/-/issues/632454
- Backend half this is stacked on: !264748 (merged)
Screenshots or screen recordings
| Before | After |
|---|---|
| N/A — no Policy store entry existed under a project's Secure menu, and the route rendered an empty container. | ![]() |
Recording (3x, URL banner) — the project page listing an inherited policy and expanding its configuration, then the same group page for contrast:
Visual verification
Re-verified after the rebase onto master, on flightjs/Flight in a GDK with the experiment enabled.
- Project page: the inherited policy is listed with its source linking back to the group, the name is plain text, there is no create button, and the only stat is Active policies.
- Expanding the row renders mode, status, rules and actions, including the Rego definition.
- Group page, for contrast: Create new policy is present, the name is a link to the detail page, and the Evaluations (last 7 days) stat is shown.
- Browser console clean on both pages — no errors, only the usual GitLab UI translation and font-preload warnings.
How to set up and validate locally
- Enable the
policy_store_experiment_enabledinstance setting and opt a root group in via its namespace setting. - Create a policy at the organization or at that group.
- Open
<project>/-/security/policy_storefor a project in that group, via Secure > Policy store. - Confirm the policy is listed, the name is not a link, there is no create button, and the only stat shown is Active policies.
- Expand a row's chevron and confirm the configuration details render.
- Confirm a project in a group that has not opted in still 404s, and that a Guest does too.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist.
