Allow groups to manage their own policy store policies
What does this MR do and why?
Group owners need to author and manage policies scoped to their group without requiring organization-level access. Previously, all policy store operations required an organization container, which meant only organization owners could manage policies.
By accepting either an Organization or a Group as the authorization container, group owners gain self-service policy management while staying isolated from organization-wide policies and other groups' policies. The namespace_id filter ensures a group surface only sees policies stamped with its own namespace, preventing cross-group information leakage.
This is the first of four MRs splitting the group-scoped policy store access work from !252678 (closed), focusing on the authorization substrate without REST endpoints or frontend changes.
Related work items
- MR 2: Group REST CRUD endpoints - #627173 (closed) (depends on this MR)
- MR 3: Editor/detail frontend group-scoping - #627174 (depends on MR 2)
- MR 4: GraphQL resolver group support - #627175 (depends on this MR, independent of MR 2/3)
Database
Query:
SELECT "govern_policies".* FROM "govern_policies" WHERE "govern_policies"."organization_id" = 1 AND "govern_policies"."lifecycle_state" = 0 AND "govern_policies"."trigger_type" = 0 AND ("govern_policies"."namespace_id" IS NULL OR "govern_policies"."namespace_id" IN (9970)) ORDER BY "govern_policies"."id" ASC LIMIT 101;Plan:
Limit (cost=0.14..3.16 rows=1 width=274) (actual time=0.061..0.062 rows=1 loops=1)
Buffers: shared hit=8
I/O Timings: read=0.000 write=0.000
-> Index Scan using index_govern_policies_on_org_trigger_lifecycle_and_id on public.govern_policies (cost=0.14..3.16 rows=1 width=274) (actual time=0.059..0.060 rows=1 loops=1)
Index Cond: ((govern_policies.organization_id = 1) AND (govern_policies.trigger_type = 0) AND (govern_policies.lifecycle_state = 0))
Index Searches: 1
Filter: ((govern_policies.namespace_id IS NULL) OR (govern_policies.namespace_id = 9970))
Buffers: shared hit=8
I/O Timings: read=0.000 write=0.000
Settings: work_mem = '100MB', random_page_cost = '1.5', seq_page_cost = '4', effective_cache_size = '338688MB', jit = 'off'
Query ID: -7147391647233298789Statistics:
Time: 0.718 ms
- planning: 0.614 ms
- execution: 0.104 ms
- I/O read: 0.000 ms
- I/O write: 0.000 ms
Shared buffers:
- hits: 8 (~64.00 KiB) from the buffer pool
- reads: 0 from the OS file cache, including disk I/O
- dirtied: 0
- writes: 0MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.