Skip to content

Python: Python sample: give a delegated sub-agent only the authority its task needs (FunctionMiddleware) #9470

Closed

Description

@d8joseph

Category

Samples

Problem

When a coordinator agent hands work to a sub-agent, the sub-agent usually gets its whole tool list, with whatever arguments the model decides to pass. Blocking a tool outright is easy. The harder case, and the one most real agents need, is the middle ground: let the sub-agent act, but only for this task. Refund this invoice, up to this amount, nothing else. And make sure it can't hand anyone more than it was given.

The middleware samples already cover two neighbours of this. atr_validation_middleware.py blocks arguments that match known attack patterns, and ToolApprovalMiddleware asks a human. Neither shows authority that's scoped to a task and gets narrower at each delegation hop.

Evidence

I've built this as a sample and tested it against agent-framework-core 1.22.0:

coordinator    refund <= $500 on any invoice
   |
   | ask_billing_agent(invoice_id="INV-4471", max_refund_cents=4000)
   v
billing_agent  read_invoice(invoice_id == "INV-4471")
               issue_refund(invoice_id == "INV-4471", amount_cents <= 4000)
  • The billing agent reads the invoice and issues the $40 refund. That call goes through.
  • The invoice carries a planted note asking for a refund on INV-5102. The model follows it. A FunctionMiddleware sets context.result to the denial and skips call_next(), so the tool body never runs and the model sees why.
  • The coordinator can't delegate more than its $500, and the billing agent can't re-delegate more than its $40.
  • The same middleware applies to run(stream=True).

What's different from a policy check inside the middleware: the sub-agent's scope is a signed token derived from the parent's, so "child is a subset of parent" is checked mechanically at every hop instead of being re-implemented per agent. And it's per argument, not a tool allowlist: the same issue_refund tool is allowed for one invoice and amount and denied for another.

Working code and tests: https://github.com/tenuo-ai/tenuo-demos/tree/demo/agent-framework-delegated-billing/agent-framework-delegated-billing

Desired Outcome

A single-file sample in python/samples/02-agents/middleware/ plus a row in its README, using FunctionMiddleware and the Foundry client like the other samples there. The Agent Framework part is about 20 lines of middleware. The scope check uses Tenuo (Apache-2.0, pip install tenuo), which runs in-process with no service or account.

Would that fit there, or would you rather it live somewhere else, for example next to the multi-agent samples?

Disclosure: I maintain Tenuo. I'd keep the sample focused on the Agent Framework side: where the check runs, how the denial reaches the model, and how scope narrows when one agent delegates to another.

Language

Python

Acknowledgements

Activity

  1. added
    pythonUsage: [Issues, PRs], Target: Python
    triageUsage: [Issues], Target: All issues that still need to be triaged
    on Oct 17, 2026
  2. changed the title [-]Python sample: give a delegated sub-agent only the authority its task needs (FunctionMiddleware)[/-] [+]Python: Python sample: give a delegated sub-agent only the authority its task needs (FunctionMiddleware)[/+] on Oct 17, 2026
  3. KNIHAL commented on Oct 18, 2026

    @KNIHAL

    Hi, I'd like to contribute the delegated-agent permissions sample for this issue.

    I've reviewed the proposed use case and would like to implement the sample under python/samples/02-agents/middleware/, along with its README entry.

    Would this contribution be welcome? If the proposed scope and Tenuo dependency align with the project's direction, could you please assign this issue to me?

    I'll wait for maintainer confirmation before starting implementation. Thanks!

  4. eavanvalkenburg commented on Oct 27, 2026

    @eavanvalkenburg
    Member

    Thanks for the proposal. For now, this belongs in a sample using the existing FunctionMiddleware primitives; no core MAF change is planned for this issue.

    westey (@westey-m), task-scoped authority that narrows across delegation could be interesting to explore further. Tagging you for that broader follow-up consideration.

  5. aimable100 commented on Nov 9, 2026

    @aimable100
    Contributor

    Thanks Eduard van Valkenburg (@eavanvalkenburg). I've opened the sample PR from the tested version: #10215. It is one file in python/samples/02-agents/middleware/ plus the README row, with no core changes. kumar nihal (@KNIHAL), thanks for offering; a review on the PR would be welcome.

  6. added a commit that references this issue on Nov 11, 2026
    ba6c275
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

pythonUsage: [Issues, PRs], Target: Python

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions