Add granular token directives to MCP-reached Duo types
What does this MR do and why?
With a fine-grained PAT, any GraphQL object type without an authorize_granular_token directive resolves to null. Once the token is passed into the MCP GraphQL tools (#631630 (closed)), list_duo_agents_and_flows and get_duo_session return no data. I found the affected types by loading each MCP query against the schema and listing every object type it reaches.
This is the second MR for #631631. The first, !261599 (merged), covers the core MCP tools (work items, notes, merge requests, commits, repository tree, wiki). This one covers the EE Duo tools. The two are independent and can merge in either order. They only both touch config/authz/graphql/authorization_todo.txt and the generated doc/auth/tokens/fine_grained_access_tokens_graphql.md.
Changes (see the implementation guide):
AiCatalogAgent,AiCatalogFlow,AiCatalogThirdPartyFlow:read_ai_catalog_itemat the user boundary.AiFoundationalChatAgent:read_ai_catalog_itemat the user boundary. It is not a database record and has no project or group.AiCatalogItemConsumer: a new raw and assignable permission,read_ai_catalog_item_consumer, at the project and group boundaries (the consumer's project or group). This matches the existingupdate_ai_catalog_item_consumeranddelete_ai_catalog_item_consumerpermissions. It is removed fromconfig/authz/permissions/definitions_todo.txt.AiCatalogItemConsumerPermissions:skip_reason: :parent_authorizes, because it is only reachable through the consumer.DuoWorkflowEvent:read_duo_workflowat the user boundary, matchingDuoWorkflow. The type directive covers every path to events:DuoWorkflow.latestCheckpoint,Project.duoWorkflowEvents, the rootQuery.duoWorkflowEventsand theworkflowEventsUpdatedsubscription.- The todo lines for all seven types are removed and the docs are regenerated.
- Specs: request specs for each directive and boundary, including the MCP combination. A consumer in one project for an item owned by another project returns the item when the token has
read_ai_catalog_item_consumeron the project plus user-levelread_ai_catalog_item. Without the user-level permission it returns the consumer withitemnull.
Design decision for reviewers
The catalog item types use the user boundary instead of the owning project. list_duo_agents_and_flows reads each consumer's item, and that item usually belongs to a different catalog project than the one the token is scoped to. Foundational items have no project at all. A project boundary would return the consumers with item: null.
AiCatalogSkill, added recently, uses a project boundary. This MR leaves it unchanged, and the two could be aligned in a follow-up. I would like feedback on whether the user boundary is the right choice here.
Out of scope
The SecurityScanProfileAttach and vulnerabilitiesSeverityOverride mutations, used by the MCP security tools, are not covered. Both take arrays of IDs (projectIds/groupIds, vulnerabilityIds), and Gitlab::Graphql::Authz::BoundaryExtractor cannot yet resolve a boundary from an array argument. They need framework support first and will be handled separately.
References
- Part of #631631
- Parent: #630327
- Token passthrough: #631630 (closed)
- First MR: !261599 (merged)
- Directive docs: https://docs.gitlab.com/development/permissions/granular_access/graphql_implementation_guide/
Screenshots or screen recordings
Not applicable, this MR only changes the backend.
How to set up and validate locally
-
Create a fine-grained personal access token in the UI (User settings > Personal access tokens > Fine-grained) with "AI catalog item consumer: Read" for a project that has enabled AI catalog agents or flows, plus "AI catalog item: Read" at the user level.
-
Run this query against
/api/graphqlwith the token:query { aiCatalogConfiguredItems(projectId: "gid://gitlab/Project/1") { nodes { id enabled item { id name } } } }On master the
nodeslist is empty. With this MR it returns each consumer with its item. -
Remove the user-level "AI catalog item: Read" permission from the token and run the query again. The consumers are returned with
item: null.
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.