Datalog Policy Reference
MCPVault tokens encode authorization policy as Datalog facts and checks. This reference covers the full fact and check namespace used by the SDK.
Facts (Authority Block)
Facts are asserted in block 0 (the authority block) at mint time. They define what the token grants.
| Fact | Signature | Description |
|---|---|---|
tool |
tool($name: string) |
Grants access to a specific MCP tool by name |
tool_wildcard |
tool_wildcard("*") |
Grants access to all tools (use with caution) |
operation |
operation($tool: string, $op: string) |
Scopes an operation on a tool. $op is one of "read", "write", "execute" |
resource_limit |
resource_limit($tool: string, $key: string, $max: integer) |
Numeric constraint, e.g. max_rows, max_bytes |
delegation_depth |
delegation_depth($current: integer) |
Current depth in the delegation chain (0 = root) |
issuer |
issuer($id: string) |
Identity of the token issuer |
subject |
subject($id: string) |
Identity of the token holder |
Fact Builder Examples
// Grant two specific tools
tool("db_query");
tool("file_read");
// Grant all tools (wildcard)
tool_wildcard("*");
// Scope operations
operation("db_query", "read");
operation("file_read", "read");
// Numeric resource limit
resource_limit("db_query", "max_rows", 100);
// Identity facts
issuer("server-01");
subject("agent-alpha");
// Delegation tracking (always starts at 0 in root token)
delegation_depth(0);
Checks
Checks are constraints evaluated at authorization time. They appear in the authority block or in attenuation blocks. A token is denied if any check fails.
| Check | Datalog | Description |
|---|---|---|
| TTL | check if time($t), $t < {expiry} |
Token expires at {expiry} (RFC 3339 timestamp) |
| Delegation cap | check if delegation_depth($d), $d < {max} |
Reject if chain exceeds {max} levels |
| Resource limit cap | check if resource_limit($tool, $key, $max), $max <= {cap} |
Enforce upper bound on a resource limit |
| Operation scope | check if operation($tool, "read") |
Restrict to a specific operation type |
Authorizer Policies (Server-Side)
The MCP server injects runtime facts and runs standard allow/deny policies.
Required Runtime Facts
// Current time (injected by the server at verification)
time(2026-04-13T12:00:00Z);
// The tool being requested
requested_tool("db_query");
Standard Policy
// Allow if the token grants the specific requested tool
allow if tool($name), requested_tool($name);
// Allow if the token grants wildcard access
allow if tool_wildcard("*");
// Default deny (must be last)
deny if true;
Common Policy Patterns
| Pattern | Datalog Check | Where to Add |
|---|---|---|
| Read-only access | check if operation("db_query", "read") |
Attenuation block |
| Row cap | check if resource_limit("db_query", "max_rows", $m), $m <= 50 |
Attenuation block |
| Short TTL | check if time($t), $t < 2026-04-13T12:30:00Z |
Attenuation block |
| Depth limit | check if delegation_depth($d), $d < 3 |
Authority block |
| Tool restriction | check if tool("db_query") (implicit via allow policy) |
Authority block |
Full Token Example
1. Root token — two tools, 1-hour TTL
// Authority block
tool("db_query");
tool("file_read");
operation("db_query", "read");
operation("file_read", "read");
resource_limit("db_query", "max_rows", 100);
delegation_depth(0);
issuer("server-01");
subject("agent-alpha");
check if time($t), $t < 2026-04-13T13:00:00Z;
check if delegation_depth($d), $d < 5;
2. Attenuation block — restrict to db_query, tighter row limit
// Appended by delegating agent (offline, no server call)
check if operation("db_query", "read");
check if resource_limit("db_query", "max_rows", $max), $max <= 50;
check if time($t), $t < 2026-04-13T12:30:00Z;
3. Wildcard token for a trusted orchestrator
// Authority block
tool_wildcard("*");
delegation_depth(0);
issuer("root-server");
subject("orchestrator-1");
check if delegation_depth($d), $d < 3;
Design Constraints
- No third-party blocks: tokens are sealed to the issuer's key hierarchy; external parties cannot append blocks
- Monotonic restriction: attenuation blocks can only reduce grants — never expand them
- Delegation depth:
delegation_depthis incremented automatically on eachattenuate()call - Default depth cap: 5 levels (configurable at mint time via
max_delegation_depth) - Key algorithm: Ed25519 (biscuit-auth default)
Transport
| Transport | Token Location |
|---|---|
| HTTP (SSE/Streamable) | X-MCPVault-Token request header |
| stdio (JSON-RPC) | params._meta.token field in request body |