Skip to content

MCP governance

Audience: Organisation administrators.

Govern which MCP tools external clients may call, for whom (OAuth clients and role groups), with what declared purpose, and review an audit trail of allow/deny decisions.

When to use this

  • You connect DataHub to an external MCP client (e.g. Cursor, Claude Desktop, or a custom app) that speaks OAuth 2.1 with Dynamic Client Registration and PKCE.
  • You need default-deny exposure: new clients start with no tools until you attach a Tool Policy.
  • You must evidence who called which tool, when, and whether access was allowed or denied.

Setup (one-time admin steps)

  1. Roles: Ensure the right administrators have MCP governance admin (full management) or read-only audit access, via role groups.
  2. Module access: MCP governance lives under Administration in the app sidebar (not a top-level module).
  3. Tool policies: Create at least one non-default policy that lists allowed tools (or “allow all” with blocks), sets a maximum classification ceiling, and optional blocks (tools, modules, tags, prefixes).
  4. Bind policies: Attach a policy to each OAuth client and, for internal HERC, use role group bindings on the policy so JWT roles resolve to the same rules.
  5. OAuth discovery: Point external clients at your DataHub base URL so they can read /.well-known/oauth-authorization-server and use /oauth/register, /oauth/authorize, /oauth/token, /oauth/revoke, and /oauth/introspect as documented by your integration.
  6. External client config: In the MCP client, complete registration (DCR), run the browser authorize flow, and confirm the consent screen. Until a non-empty policy is bound, tool calls should be denied.

What users see

  • Admins: Overview KPIs, Tool policies, OAuth clients, and Audit under Administration → MCP governance.
  • End users: A Connected apps page under Settings lists apps they authorized; they can revoke access. The OAuth consent screen shows purpose, policy, scoped tools (summarised), and allow-once vs allow-always.

How it works (functional)

  • Single policy model for external OAuth clients and internal role groups: same shape everywhere; enforcement merges bindings for internal users.
  • /mcp accepts Bearer access tokens only. Internal HERC does not rely on cookie auth to /mcp; it loads a filtered tool list through a dedicated internal toolset API using the same policy rules.
  • Tokens are stored hashed; only the OAuth token endpoint returns plaintext tokens at issuance.
  • Audit records each tool decision with user, client (if any), tool, outcome, purpose, and timing. Old detail rows roll into monthly summaries after the retention window.

Limitations

  • One organisation per OAuth client in v1 (no multi-tenant client).
  • No federated SSO for OAuth client identities in v1.
  • No per-client rate limits beyond platform-wide API limits.
  • Webhook / SIEM fan-out of audit events is not built-in; use export and polling where available.
  • Default policies (mcp.empty, mcp.full_internal, mcp.read_only) cannot be archived or permanently deleted.

Audit & compliance

  • Retention is time-bounded at detail-row level; monthly aggregates remain for longer-term reporting.
  • Purpose is declared on the client and can be re-asserted on authorize; it appears on consent and in audit.
  • Tokens and secrets are not exposed in the admin UI or customer APIs beyond presence flags (e.g. active token).

Troubleshooting

Symptom Likely cause What to try
Client registers but all tool calls denied Client still on default-empty policy Bind a policy that allows the needed tools (or allow-all with safe blocks).
Consent shows no tools Policy allows nothing or blocks everything Edit policy allow list and classification ceiling.
Authorize redirect error redirect_uri not registered Add exact HTTPS callback URI to the client; avoid javascript: / data:.
HERC tools missing after policy change Role group binding or classification Check policy bindings for herc.read (and related groups); check max_classification.
Audit empty for external calls No traffic yet or filters too narrow Generate a test call; clear date/client filters on the audit log tab.