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_setting feature flag (disabled by default for 19.0)
  • Add duo_cli_enabled as a jsonb-backed field to the ai_settings table (default: true)
  • Enforce at POST /api/v4/ai/duo_workflows/workflows: returns 403 when requires_duo_cli_enabled is true and duo_cli_enabled is false, 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" = 1

Query 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 ms

References

  • 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

  1. Start GDK
  2. Enable the feature flag: Feature.enable(:duo_cli_enabled_setting)
  3. 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)
  4. Make a workflow creation request with requires_duo_cli_enabled: true in the body. With duo_cli_enabled false, it should return 403:
    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}'
  5. With requires_duo_cli_enabled true (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.

Edited by Anna Springfield

Merge request reports

Loading