← All KB Checks
HIGHScriptOnlyCheck

MCP / Action Fabric Exposure Scope Too Broad

nowisor-ai-mcp-exposure-scope··Source on GitHub →

MCP / Action Fabric Exposure Scope Too Broad

This page describes the nowisor-ai-mcp-exposure-scope check from the nowisor Instance Scan Pack v1.2.0 (ai-agent-security group, spec AIG-007). The check flags write-capable tool packages on the inbound agent surface, and OAuth clients with no bounded token lifetime.

What this finding means

Your inbound agent surface grants more than it needs. Two independent questions, evaluated and reported separately:

This complements rather than duplicates the ungoverned-inbound-agent check. That check asks who is connected and whether they are catalogued. This asks how much the connection can do. An agent can be perfectly registered, owned and reviewed and still hold a write-everything package on a non-expiring client - which is the more common real-world failure, because registration is a governance task somebody owns and scope minimisation is not.

The two questions are independent: one can be answerable while the other is not, and the check reports N/A per question rather than guessing at a schema that differs across releases.

Why it matters for your compliance

NIS2 Article 21(2)(i) access control and 21(2)(d) supply chain security both apply: an external agent with write tools is a supplier with write access.

ISO 27001 A.8.2 (privileged access rights) is the operative control - MCP tool packages are privileged grants in everything but name.

DORA Article 9(4)(c) limits access to approved functions; a blanket write grant approves every function at once.

OWASP LLM06:2025 (Excessive Agency) names the pattern exactly, and LLM03:2025 (Supply Chain) covers the external-party dimension.

The attack path

Over-granting is the default, not the exception. Tool packages are assembled to make an integration work, then never narrowed. Nobody revisits a working integration to remove capabilities it is not using - which is precisely why the permission-vs-usage correlation exists, and why this configuration check is the cheap first pass.

Non-expiring credentials outlive their justification. A client issued for a three-month pilot keeps authenticating for years. The pilot ends, the owner moves on, and the access remains - held by a party outside your instance, against tools that can write.

The blast radius is external. Unlike an over-privileged internal account, an inbound agent's credential lives in someone else's system, subject to someone else's security posture. Compromise there is compromise here, and you will not see it happen.

How to fix it

For broad tool grants:

  1. Reduce each package to the narrowest set that satisfies the use case. Prefer read-only tools wherever they serve - a summarisation agent does not need write tools.
  2. Where a write tool is genuinely required, scope it to specific tables rather than granting a blanket operation.

For OAuth clients without expiry:

  1. Set a bounded token lifetime and a rotation schedule.
  2. Revoke clients whose project has ended.

Run this alongside the ungoverned-inbound check: register first, then minimise. Narrowing the scope of an agent nobody owns solves half a problem.

How this check stays honest

Every check in the ai-agent-security group is enumeration-driven: table and field names are resolved from sys_db_object and sys_dictionary on your instance, never asserted from a hardcoded list. The sn_aia namespace is paid-SKU gated and cannot be verified against a ServiceNow developer instance, so asserting its identifiers from documentation alone would risk exactly the fabricated-identifier problem this codebase audits for.

Two consequences you will see in the output:

All detection is read-only. No record contents are inspected or transmitted.