Expose duo_namespace_access_rules to top-level namespace settings
What does this MR do and why?
Expose ai_feature_rules to top-level namespace settings
Add support for managing top-level namespace access rules
This setting is feature flagged
Depends on !216915 (merged)
References
Screenshots or screen recordings
Sample response
{
"duo_namespace_access_rules": [
{
"through_namespace": {
"id": 963,
"name": "kraken",
"full_path": "gitlab-duo/kraken"
},
"features": [
"duo_classic",
"duo_agent_platform"
]
},
{
"through_namespace": {
"id": 964,
"name": "nebula",
"full_path": "gitlab-duo/nebula"
},
"features": [
"duo_agent_platform"
]
}
]
}
How to set up and validate locally
- Run GDK in SaaS mode
- With the feature flag disabled:
Feature.disable(:duo_access_through_namespaces, root_ancestor)-
Get group settings, inspect the response to verify no rules exist:
duo_namespace_access_rules: []curl 'http://gdk.test:3000/api/v4/groups/1000000' \ -H "Authorization: Bearer $GITLAB_TOKEN" \ -H 'Content-Type: application/json'
-
- With the feature flag enabled,
Feature.enable(:duo_access_through_namespaces, root_ancestor)-
Create feature access rules for the namespace, inspect the response to verify rules are added:
duo_namespace_access_rulesis updated accordinglycurl -w 'http://gdk.test:3000/api/v4/groups/1000000' \ -X 'PUT' \ -H "Authorization: Bearer $GITLAB_TOKEN" \ -H 'Content-Type: application/json' \ --data-raw '{ "duo_namespace_access_rules": [ { "through_namespace": { "id": 963 }, "features": ["duo_classic", "duo_agent_platform"] }, { "through_namespace": { "id": 964 }, "features": ["duo_agent_platform"] } ] }' -
Remove feature access rules, inspect the response to verify rules have been removed:
duo_namespace_access_rules: []curl -w 'http://gdk.test:3000/api/v4/groups/1000000' \ -X 'PUT' \ -H "Authorization: Bearer $GITLAB_TOKEN" \ -H 'Content-Type: application/json' \ --data-raw '{ "duo_namespace_access_rules": [ { "through_namespace": { "id": 963 }, "features": [] }, { "through_namespace": { "id": 964 }, "features": [] } ] }'
-
Query plan
DELETE FROM "ai_namespace_feature_access_rules"
WHERE "ai_namespace_feature_access_rules"."root_namespace_id" = 1000000
---
Delete on ai_namespace_feature_access_rules (cost=0.15..5.22 rows=0 width=0)
-> Index Scan using index_ai_nfar_on_root_namespace_on_accessible_entity on ai_namespace_feature_access_rules (cost=0.15..5.22 rows=4 width=6)
Index Cond: (root_namespace_id = 1000000)
(3 rows)
INSERT INTO "ai_namespace_feature_access_rules" ("created_at", "updated_at", "root_namespace_id", "through_namespace_id", "accessible_entity")
VALUES
('2026-01-07 12:44:12.719604', '2026-01-07 12:44:12.719604', 1000000, 103, 'duo_classic'),
('2026-01-07 12:44:12.719604', '2026-01-07 12:44:12.719604', 1000000, 103, 'duo_agent_platform')
---
gitlabhq_development=# explain INSERT INTO "ai_namespace_feature_access_rules" ("created_at","updated_at","root_namespace_id","through_namespace_id","accessible_entity") VALUES ('2026-01-07 12:44:12.719604', '2026-01-07 12:44:12.719604', 1000000, 103, 'duo_classic'), ('2026-01-07 12:44:12.719604', '2026-01-07 12:44:12.719604', 1000000, 103, 'duo_agent_platform');
QUERY PLAN
-------------------------------------------------------------------------------
Insert on ai_namespace_feature_access_rules (cost=0.00..0.03 rows=0 width=0)
-> Values Scan on "*VALUES*" (cost=0.00..0.03 rows=2 width=72)
MR 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.
Related to #583898
Edited by Eduardo Bonet