Problem/Motivation
An API client cannot tell which fields this module guards. A write to a guarded field fails with a clear 403, but only after the client has built and sent the request. A read is worse: JSON:API leaves a view-denied field out of the resource with no marker, and GraphQL returns null, so a guarded field looks exactly like an empty one. Tools that sample entities to describe a bundle never see the field at all.
The module knows the answer. ProtectedFieldMap holds the map, and the access hook already decides whether an account holds the permission a guard names.
Proposed resolution
Add an optional submodule, field_guard_mcp, with two read-only Tool API plugins. It depends on Tool API and MCP Sentinel. The base module gains no dependency.
field_guard_list_guarded: for an entity type and optional bundle, the guarded fields, the operations guarded (view, edit) and the permission each one requires. Names only, never values.field_guard_check_access: for the acting account only, whether it may view or edit each of up to 50 named fields on a bundle, so a client can check before it writes.
Move the explicit-permission check out of the underscore-prefixed function in the module file into a service method, so the hook, the tools and other modules share one implementation.
Not tools, by design: any write to the protected map or to role permissions (a reviewed config change is what the module's separation of duties rests on), reading guarded values (that would be the guard's bypass), checking access for an arbitrary user (a grant oracle), and own-subject resolution for an arbitrary entity (an ownership oracle).
Remaining tasks
- Kernel tests: discovery and direct execution, anonymous and wrong-permission refusal, governance not ready, the check tool answers for the acting account only, no field value in any output.
- CI step for the optional submodule.
- README section and CHANGELOG entry.
- The submodule declares only the core versions that MCP Sentinel also supports. The base module keeps its own range.
API changes
One new public service method for the explicit-permission check. The function stays as a wrapper.
Comments
Comment #2
jmcerdaCommitted to 1.x. The optional
field_guard_mcpsubmodule ships in 1.3.0 with two read-only tools:field_guard_list_guardedandfield_guard_check_access, which answers for the acting account only. The explicit-permission rule moved into thefield_guard.explicit_permission_checkerservice; the function stays as a wrapper. Run database updates after deploying, so the container is rebuilt before the access hook asks for the new service.