Skip to main content

What Is a Tool Manifest?

A tool manifest is a declarative mapping from tool names to permission levels for a specific connector. It tells Grantex exactly which permission is required to call each tool, so enforcement does not have to guess from tool name keywords.
When an agent calls create_lead, Grantex looks up the manifest, sees that create_lead requires write permission, and checks whether the agent’s grant token includes a scope that covers write on the salesforce connector.

The Permission Hierarchy

Grantex defines four permission levels in a strict hierarchy. Higher levels subsume all lower levels:

Coverage Rules

A scope grants access to all tools at or below its permission level: Example: An agent with tool:salesforce:write:* can call query (read) and create_lead (write) but cannot call delete_contact (delete) or run_period_close (admin).

Scope Format

Tool enforcement scopes follow the format:

Examples


How enforce() Uses Manifests

When you call enforce(), Grantex performs these steps:
  1. Decode the JWT — extract scp (scopes), grnt/jti (grant ID), agt (agent DID)
  2. Look up the manifest — find the loaded manifest for the given connector
  3. Resolve the permission — look up the tool name in the manifest to get its required permission level
  4. Check coverage — determine if any scope in the token covers the required permission on this connector
  5. Check caps — if the scope is capped and an amount was provided, verify the amount is within the cap
  6. Return the resultallowed: true or allowed: false with a reason

Defining Manifests

Grantex enforces permissions on any connector you define — not just the ones we ship. You own the manifest, you own the permission mapping.

Custom Manifests

Define a manifest for any tool, API, or internal service. No dependency on Grantex to add support:
  • Inline — define in code with ToolManifest(...):
  • JSON file — load from disk with ToolManifest.from_file("./manifests/my-service.json")
  • Directory — load all manifests from a folder with grantex.load_manifests_from_dir("./manifests/")
  • Extend — add tools to any manifest with manifest.add_tool("new_tool", Permission.WRITE)
  • CLI generate — auto-generate manifests from source code with grantex manifest generate agent_tools.py
The enforce() engine, permission hierarchy, and JWT scope resolution work identically for custom and pre-built manifests. There is no difference at runtime.

Pre-Built Manifests

As a convenience, Grantex ships 53 pre-built manifests covering 339 tools across five categories: Import and load them directly:
These are a starting point, not a boundary. Mix pre-built and custom manifests freely — most production deployments use both.

Fail-Closed Default

If enforce() is called with a connector or tool that has no manifest loaded, the call is denied by default:
This fail-closed behavior ensures that agents cannot bypass enforcement by calling tools that were never declared. Every tool must have an explicit permission entry in a loaded manifest. For development and testing, you can switch to permissive mode:
Never use enforce_mode="permissive" in production. It defeats the purpose of scope enforcement.

JSON Manifest File Format

When storing manifests as files (for git, CI, or team sharing), use this JSON format:

Last modified on April 5, 2026