Let ai_workflows tokens read Orbit status and schema in GraphQL
What does this MR do and why?
GitLab Duo Agent Platform (DAP) agents call GitLab with an OAuth token that has the ai_workflows and mcp scopes. On Orbit GraphQL this token got null with no error. GraphQL checks the token scope on each field and on each type, and the Orbit types accepted only api and read_api.
This MR opens the Orbit status fields and the Orbit schema to ai_workflows tokens. It also fixes Query.orbit.schema from !263083 (merged). That field declared ai_workflows, but its types did not, so a DAP token could not reach it.
Each opened type adds ai_workflows with the GitLab authorization_scopes idiom, as todo_type.rb does. Each opened field names the shared AI_WORKFLOW_SCOPES constant (orbit.rb):
module Types::Analytics::Orbit
AI_WORKFLOW_SCOPES = [:api, :read_api, :ai_workflows].freeze
class IndexingType < BaseObject
def self.authorization_scopes
super + [:ai_workflows]
end
field :state, IndexingStateEnum, null: true, scopes: AI_WORKFLOW_SCOPES
end
endA field stays closed until it names AI_WORKFLOW_SCOPES.
Open to ai_workflows |
Closed to ai_workflows |
|---|---|
Group.orbit, Project.orbit |
enabled, enabledAt |
indexing and all fields below it |
access, trial |
itemCounts and all fields below it |
indexingStatus |
Query.orbit.schema and all fields below it |
Query.orbit.memberGroups, groups, excludedGroups, access |
Connection edges { node } stays closed to ai_workflows tokens. Clients use nodes.
References
Related to gitlab-org/orbit/knowledge-graph#263
- Design: Orbit graph status in GraphQL.
- First MR of the graph status stack. The next MR batches
orbit.itemCounts.
Screenshots or screen recordings
This MR has no UI change. The table shows a live GDK with a DAP token made by Ai::DuoWorkflows::CreateOauthAccessTokenService, next to a read_api personal access token.
| Query | DAP token | read_api token |
|---|---|---|
group { orbit { indexing itemCounts } } |
data, no errors | data, no errors |
project { orbit { indexing itemCounts } } |
data, no errors | data, no errors |
group { orbit { enabled enabledAt indexingStatus access trial } } |
all null |
data, except access and trial for a member below Owner |
orbit { schema { nodes { nodes } edges { nodes } } } |
data, no errors | data, no errors |
orbit { schema { nodes { edges { node } } } } |
node is null |
data |
orbit { memberGroups } |
null |
data |
The Orbit CLI also passes all 12 runs with 4 token types and the --full-path, --namespace-id, and --project-id options.
How to set up and validate locally
The request specs send a real ai_workflows and mcp OAuth token. They fail on master and pass on this branch.
-
Run the specs:
bin/rspec ee/spec/requests/api/graphql/analytics/orbit/ -
The specs cover these cases:
- The CLI query for a group and for a project returns no
null. - The closed fields return
null. - An administrator token gets no
accessorexcludedGroups. - A composite identity token gets no group that its service account cannot read.
- A user who is not a member of a public group gets no status.
- A
read_usertoken getsInvalid token.
- The CLI query for a group and for a project returns no
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.