feat: Add Duo CLI admin application setting (backend)
What does this MR do and why?
Adds the duo_cli_enabled as a new instance-level AI setting to allow admins to disallow use of the non-headless Duo CLI. Puts it behind a feature flag as requested by the PM. Updates the POST /api/v4/ai/duo_workflows/workflows endpoint to check whether the client is a non-headless Duo CLI, in which case if duo_cli_enabled is false, the client receives a 403 Forbidden error (which it will handle similarly to other errors due to failed access; see [https://gitlab.com/gitlab-org/editor-extensions/gitlab-lsp/-/merge_requests/3313](feat(cli): gate Duo CLI behind duo_cli_enabled admin setting). Otherwise, existing Duo CLI behavior is unchanged.
Changes:
- Add
duo_cli_enabled_settingfeature flag (disabled by default for 19.0) - Add
duo_cli_enabledas a jsonb-backed field to theai_settingstable (default:true) - Enforce at
POST /api/v4/ai/duo_workflows/workflows: returns403whenrequires_duo_cli_enabledistrueandduo_cli_enabledisfalse, since every CLI session calls this endpoint at startup
Database query
UPDATE (.update!(duo_cli_enabled: value)):
UPDATE "ai_settings"
SET "updated_at" = NOW(), "feature_settings" = '{"duo_agent_platform_enabled":true,"duo_cli_enabled":true}'
WHERE "ai_settings"."id" = 1Query plan:
Update on ai_settings (cost=0.15..2.17 rows=0 width=0) (actual time=0.113..0.113 rows=0 loops=1)
Buffers: shared hit=5
-> Index Scan using ai_settings_pkey on ai_settings (cost=0.15..2.17 rows=1 width=46) (actual time=0.047..0.048 rows=1 loops=1)
Index Cond: (id = 1)
Buffers: shared hit=2
Planning Time: 0.157 ms
Execution Time: 0.134 msReferences
- Implements: #597833 (closed)
- LSP MR: [https://gitlab.com/gitlab-org/editor-extensions/gitlab-lsp/-/merge_requests/3313](feat(cli): gate Duo CLI behind duo_cli_enabled admin setting)
How to set up and validate locally
- Start GDK
- Enable the feature flag:
Feature.enable(:duo_cli_enabled_setting) - In Rails console:
- Check default (should be true):
Ai::Setting.instance.duo_cli_enabled - Change the setting:
Ai::Setting.instance.update!(duo_cli_enabled: false)
- Check default (should be true):
- Make a workflow creation request with
requires_duo_cli_enabled: truein the body. Withduo_cli_enabledfalse, it should return403:curl -X POST "http://gdk.test:3000/api/v4/ai/duo_workflows/workflows" \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{"requires_duo_cli_enabled": true}' - With
requires_duo_cli_enabledtrue (or the feature flag off), the same request should return a workflow response object with no error. You should be able to point Duo at your GDK (from within a project set up with Duo on your local instance) and have it work normally.
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.