Let fine-grained tokens read AiCatalog versions and MCP servers
What does this MR do and why?
Without an authorize_granular_token directive, a fine-grained personal access token gets no data from seven catalog types. Each now declares one and leaves authorization_todo.txt:
AiCatalogAgentVersion,AiCatalogFlowVersionandAiCatalogThirdPartyFlowVersiontakeread_ai_catalog_itemon the user, as their items do.AiCatalogSkillVersion, the fourth version type, already declares it on its project.AiCatalogMcpServertakesread_ai_catalog_mcp_serveron the user, the ability it already checks, from a new Read assignable permission next to Create, Update and Block. A token that reads catalog items does not read the MCP servers: an agent version'smcpServersand the MCP server mutations'mcpServerneed this permission too. No token held it before, so none needs migrating.AiCatalogMcpTooltakesread_ai_catalog_itemon the user, the permissionQuery.aiCatalogBuiltInToolschecks for the built-in tools. The type carries it becauseQuery.aiCatalogMcpToolsis non-null.AiCatalogMcpToolIconandAiFoundationalChatAgentFlowConfig, returned only below a type that checksread_ai_catalog_item, declare it withparent_authorizes:.
It also declares parent_authorizes: :read_ai_catalog_item on AiCatalogItemPermissions, which !267273 (merged) left as a skip: its four parents check that permission, so no token changes. This is a follow-up promised in !269587 (comment 4204222716), and the domain in one MR, as agreed in !267273 (comment 4195231927).
References
Closes #639842
Related to #593878
I found this while working on gitlab-mcp-server.
Screenshots or screen recordings
No UI change.
How to set up and validate locally
-
As an organization member, with the
mcp_clientandai_catalog_mcp_serversflags on and a public agent whose latest version uses an MCP server, run with a fine-grained token that holdsread_ai_catalog_itemandread_ai_catalog_mcp_serveron the user:query { aiCatalogItem(id: "<agent global ID>") { latestVersion { ... on AiCatalogAgentVersion { systemPrompt mcpServers { nodes { name } } } } } aiCatalogMcpTools { nodes { name icons { src } } } } -
On master
latestVersionand every node ofaiCatalogMcpToolsarenull; on this branch both return data. -
Drop
read_ai_catalog_mcp_server:mcpServersis empty. Dropread_ai_catalog_itemtoo: the item and the tools are gone.
Checks I ran (Ruby 3.3.11)
The changed request specs post aiCatalogItemVersions, aiCatalogMcpServer, aiCatalogMcpTools and aiFoundationalChatAgents with a fine-grained token, with and without the permission.
- With master's types, the changed specs give 137 examples, 18 failures: the 8 new type checks and 10 of the new request examples (the others, such as the legacy token cases, pass on both). With the previous version of this MR, where
read_ai_catalog_itemgrantedread_ai_catalog_mcp_server, the two newmcpServersexamples fail. - On this branch, the changed specs and the existing MCP server specs: 207 examples, 0 failures, 17 pending (the shared examples' cases that apply only to a project or group boundary).
gitlab:permissions:validate, RuboCop, the commit linter and Danger's linters pass; bothcompile_docstasks leave the committed docs unchanged. Left to the pipeline: Ruby 3.4 and the FOSS run.
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.