Skip to content

fix(mcp-integrations): techdocs-mcp-extras actions use service credentials instead of the caller's, bypassing catalog permissions #4485

Description

@Elesiann

Summary

The three actions in workspaces/mcp-integrations/plugins/techdocs-mcp-extras (fetch-techdocs, retrieve-techdocs-content, analyze-techdocs-coverage) ignore the credentials provided by the actions registry (action: async ({ input }) =>) and call the catalog and the techdocs backend with auth.getOwnServiceCredentials() (src/service.ts, around lines 209, 289, 346, 463 and 532 on main).

Service principals are always allowed by the permission framework, so with permission.enabled: true any authenticated MCP user can list entities and read TechDocs content that catalog.entity.read would deny them in the UI. The techdocs backend itself gates /static/docs on the caller's catalog read permission (plugins/techdocs-backend/src/service/router.ts in backstage/backstage), so the MCP path bypasses a check the rest of the product enforces. Read-only, but it breaks the assumption that MCP tools inherit the caller's RBAC.

Tasks

  • Thread credentials from the action callback (action: async ({ input, credentials }) =>) in src/actions/*.ts into the TechDocsService methods
  • Use { credentials } for catalog calls and onBehalfOf: credentials when obtaining the techdocs plugin token in src/service.ts, replacing the auth.getOwnServiceCredentials() calls (around lines 209, 289, 346, 463, 532)
  • Remove this.logger.info(credentials) in src/service.ts (around line 290), which logs the credentials object at info level
  • Update src/service.test.ts / src/plugin.integration.test.ts to assert the caller's credentials are forwarded
  • Add a patch changeset for @red-hat-developer-hub/backstage-plugin-techdocs-mcp-extras

Acceptance Criteria

  • With permission.enabled: true, an MCP caller denied catalog.entity.read on an entity gets no entity metadata and no TechDocs content for it from any of the three actions
  • Catalog and techdocs backend requests made by the plugin carry the caller's identity (onBehalfOf: credentials), not the plugin's own service credentials
  • No credentials object is written to the log
  • Behaviour for callers that are allowed is unchanged

Context

The sibling plugins software-catalog-mcp-extras and scaffolder-mcp-extras in the same workspace already forward the caller's credentials, and the workspace's own .cursor/rules/port-mcp-tool.mdc requires "credentials from action callback".

Version: @red-hat-developer-hub/backstage-plugin-techdocs-mcp-extras 0.2.6 (main); the pattern dates back to the initial import of the plugin (#1491) and is unchanged since.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions