Skip to content

Allow using Ai query/subscription with ai_features token

What does this MR do and why?

This MR allows the ai_features scoped personal access tokens to be used with GraphQL queries/mutations and subscriptions that are necessary for duo chat. This ai_features scope token is documented in https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#personal-access-token-scopes and was designed to be used in our IDE extensions. Since we've recently introduced duo chat to our IDE extensions this means we also want to support duo chat with this token scope.

This change was quite a widespread change because this is the first time we've added support for token scopes in GraphQL. We had to introduce a few changes to make this work:

  1. At the top level of GraphQL queries and subscriptions we always allow ai_features scopes. This does not open up all GraphQL queries to use this because we are still validating the specific query types/mutations/fields for their individual scopes
  2. We needed to introduce the ability to override the scopes at the type/object/field level and then add ai_features for all the types and fields used in our duo chat features

How to test

Enable the :graphql_minimal_auth_methods feature flag:

Feature.enable(:graphql_minimal_auth_methods)

The following script will demonstrate:

  1. An ai_features scope token can call the duo chat API
  2. An api scope token can call the updateIssue mutation
  3. An ai_features scope token cannot call the updateIssue mutation
#api_scope_token=<GET_TOKEN>
#ai_features_scope_token=<GET_TOKEN>

curl 'http://127.0.0.1:3000/api/graphql' \
  -H 'Content-Type: application/json' \
  -H "Private-Token: $ai_features_scope_token" \
  --data-raw '{"query":"mutation {\n  aiAction(input: {chat: {content: \"Hello\"}}) {\n    clientMutationId\n    requestId\n  }\n}","variables":null}'
echo

curl 'http://127.0.0.1:3000/api/graphql' \
  -H 'Content-Type: application/json' \
  -H "Private-Token: $api_scope_token" \
  --data-raw '{"query":"mutation {\n  updateIssue(input: {description: \"Correct update!\", projectPath:\"twitter/Typeahead.Js\", iid: \"7\"}) {\n    clientMutationId\n    issue {iid}\n  }\n}","variables":null}'
echo

curl 'http://127.0.0.1:3000/api/graphql' \
  -H 'Content-Type: application/json' \
  -H "Private-Token: $ai_features_scope_token" \
  --data-raw '{"query":"mutation {\n  updateIssue(input: {description: \"Bad update!\", projectPath:\"twitter/Typeahead.Js\", iid: \"7\"}) {\n    clientMutationId\n    issue {iid}\n  }\n}","variables":null}'
echo

Additionally you can read about how to test the GraphQL subscriptions in https://gitlab.com/gitlab-org/gitlab/-/issues/455805 . But testing the duo chat functionality this way is tricky. So the easiest way to test the duo chat is to install one of the editor extensions (I was using Intellij IDEA GitLab Duo extension) and point it at your local GDK. But also this requires having all the AI stuff setup which is quite a process. But I have done this testing locally.

MR acceptance checklist

Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Screenshots or screen recordings

Screenshots are required for UI changes, and strongly recommended for all other merge requests.

Before After

How to set up and validate locally

Numbered steps to set up and validate the change are strongly suggested.

Related to #455023

Edited by Luke Duncalfe

Merge request reports