Tool permission checks
Configuration administrators can open Tool permissions in the administration UI. Select a backend or HTTP tool group to see published and unpublished tools, effective read/write classification, required scopes, argument resource limits and approval requirements. Search and filters highlight unclassified or unpublished tools. Catalog inspection does not execute tools; HTTP group status indicates whether it is enabled, not upstream connectivity.
Edit tool policy edits an exact-name rule and, for MCP backends, publication in the same revision. Other matching rules continue to apply: an exact read rule cannot override a wildcard write or approval rule. The form supports scopes, JSON Pointer resource allowlists, reviewer subjects, quorum and step-up authentication; advanced approval fields are preserved. HTTP publication remains in the existing tool/group or OpenAPI import editor. All saves use the existing revision checks and configuration-approval workflow when enabled.
Access check explains publication, readiness, scope, resource, client Grant and approval gates without calling a tool, running previews, creating approvals or acquiring execution quotas. Select a test user to load their current effective scopes, then select an active client grant for this service. Disabled users and expired enterprise verification are highlighted. Scopes remain editable for hypothetical checks; advanced fields accept exact subject and grant IDs. Effective scopes are intersected with the grant. A successful check is not execution authorization: argument schema, live quotas, resource versions, previews and upstream ACLs are still enforced during execution. The admin-only APIs are GET /api/v1/tool-policies?endpoint=<id> and POST /api/v1/access-check:
{"endpoint":"projects","tool":"get_project","scopes":["projects:read"],"arguments":{"project":"work"}}
Explicit publication and resource limits
Tools start unpublished. Select every approved original tool name in the backend editor/API; scope rules do not publish tools. An empty or omitted publication list hides tools and denies direct calls. Catalog refresh does not publish new tools. Manual HTTP tools start disabled; enable reviewed tools explicitly and select approved OpenAPI operations during import.
published_tools: [search]
required_scopes: [mcp:read]
tool_rules:
- match: search
effect: read
required_scopes: [projects:read]
resource_rules:
- argument: /project
allowed_values: [work, sandbox]
- argument: /body/database
allowed_values: [reports]
Every matching resource rule must pass, alongside all required scopes and the current publication/enable state. argument is an object-key JSON Pointer into the original tools/call.arguments, including the HTTP tool's body object where applicable (~1 escapes /, ~0 escapes ~). The value must be an allowed string or a non-empty array containing only allowed strings. Missing/null/non-string values fail closed. Rules for the same argument intersect; allowed values within one rule are alternatives. With no resource rules, arguments have no additional resource restriction.
Allowed values compare exactly and case-sensitively: no glob, prefix, directory traversal, URL decoding, filesystem or SQL interpretation. Configure the actual resource selector used by the tool. This is a shared per-tool allowlist, not an ownership check against user claims. Backends must enforce authorization for embedded queries, aliases, symlinks and secondary resource selectors. Resource rejection returns an MCP tool error (isError: true) without forwarding the call or closing the client connection. Constrained arguments are normalized before forwarding to remove duplicate-key ambiguity while preserving JSON number precision.
Publishing, unpublishing and rules use the existing revisioned admin API and SQLite/PostgreSQL storage; YAML mode supports SIGHUP. A cached tool listing is not authorization: forwarding rechecks the current definition, scopes and resource arguments. Old HTTP handlers are rejected after a manager replacement. Already admitted requests may finish; revocation does not roll back an upstream operation. Probe results include the discovered original tool names without approving them.
Backend-local tool rules
tool_rules is evaluated per backend before the configured ID is added to a public tool name. A rule's match uses Go path.Match on the original backend tool name: matching is full-string and case-sensitive, so a pattern such as admin.* does not match Admin.Read or a substring. Every matching rule contributes its required_scopes; MCPHub unions and deduplicates those scopes, then requires all of them together with the backend-level required_scopes.
Validation expands existing ${ENV} placeholders in match and rule scope strings; every match must be non-empty and a valid Go path.Match pattern, every rule must declare at least one of effect, approval, required_scopes, or resource_rules, scope entries must be non-empty with no whitespace or duplicates, and duplicate match entries within one backend are rejected.
Tools that fail this policy are omitted from tools/list. If a client directly calls a known tool without the required scopes, MCPHub returns 403 and a precise WWW-Authenticate challenge with error="insufficient_scope", the path-aware resource_metadata URL, and a space-delimited scope value containing the missing scopes. A rule that matches no tool in the current catalog generation emits one warning, remains valid, and can match after a later catalog refresh. Editing tool_rules is supported by SIGHUP and takes effect with the reloaded backend policy.
Backend IDs are compared case-insensitively for uniqueness. Tool and prompt names retain the configured ID, while every exposed resource or resource-template URI uses a lowercase authority and resolves back to the configured ID.