Skip to content

Enforce scoped auth for EPCIS MCP tools#39

Open
zsculac wants to merge 7 commits intomainfrom
feat/epcis-auth
Open

Enforce scoped auth for EPCIS MCP tools#39
zsculac wants to merge 7 commits intomainfrom
feat/epcis-auth

Conversation

@zsculac
Copy link
Contributor

@zsculac zsculac commented Feb 27, 2026

Add withRequiredMcpScope support in @dkg/plugins and apply it to EPCIS MCP handlers while preserving the standard mcp.registerTool flow. Expand integration tests and documentation to cover MCP transport scope plus tool-level epcis.read/epcis.write requirements.

Add withRequiredMcpScope support in @dkg/plugins and apply it to EPCIS MCP handlers while preserving the standard mcp.registerTool flow. Expand integration tests and documentation to cover MCP transport scope plus tool-level epcis.read/epcis.write requirements.

Made-with: Cursor
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR adds EPCIS scope enforcement across API and MCP, plus new integration coverage, but there is a security-critical fail-open path in the new MCP scope guard. The test suite moves in the right direction, yet key newly-guarded read paths are still untested and a couple of assertions are too weak to catch real regressions. Maintainability in the touched auth boundary is somewhat worsened by duplicating EPCIS route-scope mapping outside the plugin, which increases drift risk.

},
},
async (input) => {
withRequiredMcpScope("epcis.read", async (input) => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Bug: This introduces a new auth boundary for epcis-track-item, but the new integration tests do not verify its scope behavior (they only exercise epcis-query, epcis-capture, and epcis-capture-status). Add regression tests for epcis-track-item with mcp-only, read-only, and write-only tokens to prevent silent authorization regressions.

github-actions[bot]

This comment was marked as off-topic.

github-actions[bot]

This comment was marked as off-topic.

github-actions[bot]

This comment was marked as off-topic.

github-actions[bot]

This comment was marked as off-topic.

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR adds EPCIS scope enforcement primitives and a strong integration test matrix for read/write authorization across HTTP and MCP paths. The extraction of route constants and reusable scope-guard helpers improves maintainability in the touched EPCIS/plugin areas. I did not find a clear runtime blocker in the changed auth logic, but there are two reliability/maintainability gaps in the integration test setup that should be fixed before merge. Overall direction is good, with minor cleanup needed to keep tests deterministic and dependency wiring explicit.

import { authorized, createOAuthPlugin } from "@dkg/plugin-oauth";
import dkgEssentialsPlugin from "@dkg/plugin-dkg-essentials";
import createFsBlobStorage from "@dkg/plugin-dkg-essentials/createFsBlobStorage";
import epcisPlugin, { applyEpcisHttpScopeGuards } from "@dkg/plugin-epcis";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Issue: @dkg/plugin-epcis is imported here but not declared in apps/agent/package.json; add it as a dependency/devDependency so this workspace can run tests reliably in isolated installs and keeps the dependency graph explicit.


const actualPort = (server.address() as any)?.port || port;
const url = `http://localhost:${actualPort}`;
process.env.EXPO_PUBLIC_MCP_URL = url;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Issue: This mutates process.env.EXPO_PUBLIC_MCP_URL globally without restoring it in cleanup, which can make later tests order-dependent. Save the previous value before setting it and restore/delete it in the returned cleanup function.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant