redhat-developer / redhat-developer/rhdh-plugins

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

Open
#4,485 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
48
Forks
120
Avg merge
2d 6h
Merged PRs (30d)
337

Description

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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with workspaces/mcp-integrations/plugins/techdocs-mcp-extras/src/actions/*.ts and src/service.ts, then read src/service.test.ts and src/plugin.integration.test.ts. Trace the three actions' credential flow and existing catalog and TechDocs calls; done means caller identity is preserved, denied callers receive no protected data, credentials are not logged, tests pass, and a patch changeset is added.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
authorization, backend-api-design, security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.