Problem/Motivation

A client that uploads a file over an API gets back a /system/files/… URL. When the field is gated, that URL returns 403 for every account without the bypass permission, and nothing tells the caller why or what to do next. The same is true for an operator who asks "is the gate real on this site?": the answer lives in the status report and the settings form.

The module already has bounded services that answer these questions: FileGateResolver::getGateForFile() and gatedFieldKeys(), GrantInventory::listForField() and revokeJti(), FileGateMetrics::summary(), FileGateRequirements::runtime() and SecretRegistry.

Proposed resolution

Add an optional submodule, file_gate_mcp, with Tool API plugins over those services. The base module keeps its dependencies. The submodule depends on Tool API and MCP Sentinel.

  • file_gate_status (read): runtime requirements, whether any secret is configured, and the gated fields with their method and storage scheme. Secret ids only, never secret material.
  • file_gate_file_gate (read): for a file or media UUID, which gated field and method apply, and that the /system/files URL will not serve it. No paths, no trusted-issuer detail.
  • file_gate_grants_list (read): active grants for one gated field, bounded.
  • file_gate_metrics (read): mint, deny and authentication-failure counts for 1 to 90 days.
  • file_gate_grant_revoke (write): revoke one grant by field and id, with the same field and scope check the controllers apply, written to the audit log.

The gated-field overview is a private method of the settings form today. Move it to a service so the form and the status tool share it.

Not tools, by design: minting a download URL, serving bytes, issuing an OTP, bulk revoke, editing secrets or scopes, and switching gating on or off.

Remaining tasks

  • Kernel tests: discovery and direct execution, anonymous and wrong-permission refusal, governance not ready, invalid input does not leak, no secret material or file path in any output, revoke refuses a field outside scope.
  • CI step for the optional submodule.
  • README section and CHANGELOG entry.
  • The submodule can declare only the core versions that both this module and MCP Sentinel support.

API changes

One new service for the gated-field overview. No change to routes or to gate behaviour.

Comments

jmcerda created an issue. See original summary.

  • jmcerda committed 0045e23a on 1.x
    fix: tighten file_gate_mcp after a findings review (#3624444)
    
    - Grants...

  • jmcerda committed 87b98fc9 on 1.x
    feat: add optional file_gate_mcp tools submodule (#3624444)
    
    Five Tool...
jmcerda’s picture

Status: Active » Fixed

Committed to 1.x. The optional file_gate_mcp submodule adds file_gate_status, file_gate_file_gate, file_gate_grants_list, file_gate_metrics and file_gate_grant_revoke, plus the file_gate.gated_field_overview service the settings form now shares. A findings review changed three things before commit: the grants list reports whether a grant is bound to a subject instead of returning the stored subject hash, revoke keeps the kill mark at least as long as the grant would have lived, and Tool API and MCP Sentinel are suggest only so the Drupal 12 pipeline leg still resolves. The kill mark default on the HTTP route is tracked in #3624450, and the save-time scheme check in #3624449.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.