Overview
The enforce API verifies that an agent’s grant token includes sufficient scope to call a specific tool on a specific connector. It combines JWT verification with manifest-based permission resolution in a single call.
import { Grantex } from '@grantex/sdk';
import { salesforceManifest } from '@grantex/sdk/manifests/salesforce';
const grantex = new Grantex({ apiKey: 'gx_...' });
grantex.loadManifest(salesforceManifest);
const result = await grantex.enforce({
grantToken: token,
connector: 'salesforce',
tool: 'delete_contact',
});
if (!result.allowed) {
console.log(result.reason); // "write scope does not cover delete operations on salesforce"
}
enforce()
Check whether a grant token permits a tool call.
enforce(options: EnforceOptions): Promise<EnforceResult>
Parameters: EnforceOptions
The JWT grant token issued by Grantex. Decoded and verified inline.
The connector name to check against (e.g., "salesforce", "s3", "jira"). Must match a loaded manifest.
The tool name to check (e.g., "delete_contact", "create_lead"). Must be declared in the connector’s manifest.
Optional amount for capped scopes. When the token includes a capped scope like tool:stripe:write:*:capped:500, pass the transaction amount to check against the cap.
Response: EnforceResult
true if the tool call is permitted by the token’s scopes.
Human-readable reason when allowed is false. Empty string when allowed.
The grant ID extracted from the JWT grnt (or jti) claim.
The agent DID extracted from the JWT agt claim.
All scopes from the JWT scp claim.
The resolved permission level for this tool from the manifest ("read", "write", "delete", or "admin").
The connector name that was checked.
The tool name that was checked.
Example
const result = await grantex.enforce({
grantToken: 'eyJhbGciOiJSUzI1NiIs...',
connector: 'salesforce',
tool: 'create_lead',
});
if (result.allowed) {
console.log(`Allowed: ${result.tool} on ${result.connector}`);
console.log(`Grant: ${result.grantId}, Agent: ${result.agentDid}`);
} else {
console.log(`Denied: ${result.reason}`);
}
Capped Scopes
When a token includes a capped scope, pass the amount to enforce against the cap:
const result = await grantex.enforce({
grantToken: token,
connector: 'stripe',
tool: 'create_payment_intent',
amount: 750,
});
// If token scope is tool:stripe:write:*:capped:500
// result.allowed = false
// result.reason = "amount 750 exceeds cap of 500 on tool:stripe:write:*:capped:500"
loadManifest()
Load a single tool manifest into the client. Must be called before enforce() for the corresponding connector.
loadManifest(manifest: ToolManifest): void
Example
import { salesforceManifest } from '@grantex/sdk/manifests/salesforce';
grantex.loadManifest(salesforceManifest);
loadManifests()
Load multiple tool manifests at once.
loadManifests(manifests: ToolManifest[]): void
Example
import { salesforceManifest } from '@grantex/sdk/manifests/salesforce';
import { hubspotManifest } from '@grantex/sdk/manifests/hubspot';
import { jiraManifest } from '@grantex/sdk/manifests/jira';
grantex.loadManifests([salesforceManifest, hubspotManifest, jiraManifest]);
A manifest declares the permission level required for each tool on a connector.
class ToolManifest {
constructor(options: {
connector: string;
description?: string;
version?: string;
tools: Record<string, Permission>;
});
readonly connector: string;
readonly description: string;
readonly version: string;
readonly toolCount: number;
getPermission(toolName: string): Permission | undefined;
addTool(toolName: string, permission: Permission): void;
static fromJSON(json: {
connector: string;
description?: string;
version?: string;
tools: Record<string, string>;
}): ToolManifest;
}
Constructor
import { ToolManifest, Permission } from '@grantex/sdk';
const manifest = new ToolManifest({
connector: 'inventory-service',
description: 'Internal warehouse inventory API',
version: '1.0.0',
tools: {
'get_stock_level': Permission.READ,
'reserve_inventory': Permission.WRITE,
'force_stock_reset': Permission.ADMIN,
},
});
getPermission()
Look up the required permission for a tool. Returns undefined if the tool is not in the manifest.
const perm = manifest.getPermission('reserve_inventory');
// Permission.WRITE
const unknown = manifest.getPermission('nonexistent_tool');
// undefined
Add a tool to an existing manifest. Useful for extending pre-built manifests with custom tools.
import { salesforceManifest } from '@grantex/sdk/manifests/salesforce';
salesforceManifest.addTool('bulk_delete_all', Permission.ADMIN);
salesforceManifest.addTool('export_all_contacts', Permission.READ);
console.log(salesforceManifest.toolCount); // 8 (6 built-in + 2 custom)
fromJSON()
Create a manifest from a plain JSON object (e.g., loaded from a file):
import { ToolManifest } from '@grantex/sdk';
import manifest from './manifests/inventory-service.json';
const inventoryManifest = ToolManifest.fromJSON(manifest);
grantex.loadManifest(inventoryManifest);
Permission
An enum representing the four permission levels in the hierarchy.
enum Permission {
READ = 'read', // Level 0
WRITE = 'write', // Level 1
DELETE = 'delete', // Level 2
ADMIN = 'admin', // Level 3
}
Higher levels subsume all lower levels: admin > delete > write > read.
permissionCovers()
Check whether a granted permission level covers a required permission level.
function permissionCovers(granted: Permission, required: Permission): boolean;
Example
import { permissionCovers, Permission } from '@grantex/sdk';
permissionCovers(Permission.WRITE, Permission.READ); // true — write covers read
permissionCovers(Permission.WRITE, Permission.DELETE); // false — write does not cover delete
permissionCovers(Permission.ADMIN, Permission.DELETE); // true — admin covers everything
permissionCovers(Permission.READ, Permission.READ); // true — exact match
Wrap a LangChain StructuredTool so that enforcement runs automatically before every invocation.
wrapTool(
tool: StructuredTool,
options: {
connector: string;
tool: string;
grantToken: string | (() => string);
},
): StructuredTool
Example
const protectedTool = grantex.wrapTool(myLangChainTool, {
connector: 'salesforce',
tool: 'create_lead',
grantToken: () => currentState.grant_token,
});
// Use protectedTool in your LangChain agent chain.
// If the token lacks sufficient scope, the tool throws an error
// instead of executing the underlying function.
enforceMiddleware()
Express middleware that enforces scope on every request to a route.
grantex.enforceMiddleware(options: {
extractToken: (req: Request) => string | undefined;
extractConnector: (req: Request) => string;
extractTool: (req: Request) => string;
}): RequestHandler
Example
app.use('/api/tools/:connector/:tool', grantex.enforceMiddleware({
extractToken: (req) => req.headers.authorization?.replace('Bearer ', ''),
extractConnector: (req) => req.params.connector,
extractTool: (req) => req.params.tool,
}));
// Requests with insufficient scope receive a 403 response automatically.