Policies decide which upstream tools a user or group can see and call. Generated projects include a limited guest policy and a broader admin policy.
Allow Rules
Policies are expressed as allow rules against upstream server names and tool names.
const limitedPolicy = policy("limited-demo")
.mcp("demo-files")
.allow("list_directory")
.mcp("specification")
.allow("*");
Wildcards
allow("*") grants access to all matching tools in the selected scope.
Use broad wildcards intentionally. Health checks warn when policy grants broad access across every server and target.
Rate Limits
Attach rate limiters to the policy permission that should be limited. Fentaris enforces policy-attached limiters automatically before forwarding the tool call.
import { SlidingWindowRateLimiter, policy } from "@fentaris/core";
const supportLimiter = new SlidingWindowRateLimiter({
maxPerWindow: 60,
windowMs: 60_000,
});
const supportPolicy = policy("support")
.mcp("github")
.allow("create_issue", { limiter: supportLimiter });
The effective key includes the subject, upstream server, and tool, so the example allows each support user up to 60 github.create_issue calls per minute. For shared team quotas, provide a custom limiter or store that normalizes keys by group or tenant.
App-Level Composition
When a proxy is assembled across modules, declare policies and groups from the app handle before start():
import { fentaris, user } from "@fentaris/core";
const app = fentaris();
app.policy("readonly").mcp("github").allow("search_issues");
app.group("guests").users(user("guest")).policy("readonly");
Repeated app.policy("readonly") calls return the same policy instance. Fentaris validates the final configuration and reports diagnostics for missing named policies, empty groups, duplicate declarations, and policies that reference servers not yet registered.
Use app.usePolicy(...) when one policy should apply globally and you are not configuring groups:
app.policy("demo").mcp("github").allow("search_issues");
app.usePolicy("demo");
You can also apply a concrete policy directly:
app.usePolicy(policy("demo").mcp("github").allow("search_issues"));
See Governance auth and Proxy setup for full examples.