A lease (spec §9) is the authority an agent operates under. It is immutable for the life of the job and is granted at submit time by the client.
var lease = new Lease(new Dictionary<string, IReadOnlyList<string>>
{
[LeaseNamespaces.FsRead] = new[] { "/workspace/**" },
[LeaseNamespaces.FsWrite] = new[] { "/workspace/src/**" },
[LeaseNamespaces.NetFetch] = new[] { "https://api.example.com/*" },
[LeaseNamespaces.ToolCall] = new[] { "search.*", "fetch.*" },
[LeaseNamespaces.CostBudget]= new[] { "USD:5.00" },
[LeaseNamespaces.ModelUse] = new[] { "tier-fast/*" },
});
var handle = await client.SubmitAsync("research", leaseRequest: lease);| Namespace | Pattern grammar | Semantics |
|---|---|---|
fs.read |
path glob | Filesystem read. |
fs.write |
path glob | Filesystem write. |
net.fetch |
URL glob | Outbound HTTP/HTTPS. |
tool.call |
tool-name glob | Calling registered tools. |
agent.delegate |
agent-name glob | Delegation. |
cost.budget |
currency:decimal |
Cumulative cost ceiling (§9.6). |
model.use |
model-id glob | Allowed upstream model set (§9.7). |
Use the LeaseNamespaces static class for the namespace string constants.
Glob matching is case-sensitive; ** matches zero or more path segments.
server.RegisterAgent("file-writer", async (ctx, ct) =>
{
var lm = new LeaseManager(timeProvider);
try
{
lm.AuthorizeOperation(
ctx.Lease,
ctx.LeaseConstraints,
LeaseNamespaces.FsWrite,
pattern: "/workspace/src/output.cs");
}
catch (PermissionDeniedException ex)
{
await ctx.ToolResultAsync(callId, null,
new ToolError { Code = ex.Code, Message = ex.Message }, ct);
return null;
}
// perform the write ...
return new { wrote = "/workspace/src/output.cs" };
});lm.AuthorizeModelUse(ctx.Lease, ctx.LeaseConstraints, modelId: "tier-fast/gpt-4o-mini");
// throws PermissionDeniedException(PERMISSION_DENIED) on mismatchChild leases MUST be a subset of the parent's in every namespace and in every
budget ceiling. LeaseManager.AssertSubset validates this in one pass:
var parentLease = new Lease(new Dictionary<string, IReadOnlyList<string>>
{
[LeaseNamespaces.ModelUse] = new[] { "tier-fast/*" },
[LeaseNamespaces.CostBudget]= new[] { "USD:2.00" },
});
var childLease = new Lease(new Dictionary<string, IReadOnlyList<string>>
{
[LeaseNamespaces.ModelUse] = new[] { "tier-fast/gpt-4o-mini" },
[LeaseNamespaces.CostBudget]= new[] { "USD:0.50" },
});
leaseManager.AssertSubset(parentLease, childLease);
// throws LeaseSubsetViolationException if any namespace is not coveredSet ExpiresAt in LeaseConstraints to bound the job's authority to a
deadline:
var handle = await client.SubmitAsync(
"research",
leaseRequest: lease,
leaseConstraints: new LeaseConstraints
{
ExpiresAt = DateTimeOffset.UtcNow.AddMinutes(30),
});The runtime starts a watchdog that cancels the agent's CancellationToken
at ExpiresAt and emits job.error { code: "LEASE_EXPIRED" }. Requires the
lease_expires_at feature to be negotiated.
See Jobs — cost budget for reporting spend via
ctx.MetricAsync and handling BUDGET_EXHAUSTED.
- Jobs — submit, cancel, idempotency.
- Delegation — child-job lease subset.
- Errors —
PERMISSION_DENIED,LEASE_EXPIRED,BUDGET_EXHAUSTED.