[RECIPE PROPOSAL] oncall-task-scoped-authority: task-scoped authority for an on-call agent team, verified per tool call

Author: aimable100Created Sep 18, 2026Updated Sep 18, 2026
Labelspythoncontributestatus/ai-triaged

1. What is the intent/purpose of your new recipe? In what way will it help the ADK community?

A multi-agent recipe for contrib/python/ that shows how to give a sub-agent less authority than its parent at the argument level, and check it at the ADK plugin callback on every tool call.

Scenario: an on-call coordinator receives a production alert for web-checkout and transfers it to a remediation_agent. The coordinator holds the on-call role as a signed warrant (read any logs; scale or restart web-* up to ten replicas; page; hand off). Before the transfer it narrows that role into a ticket bound to the remediation agent's own key: web-checkout only, at most four replicas, ten minutes. The logs the remediation agent reads contain an injected line telling it to scale web-checkout to 50, scale db-primary, and restart web-payments. All three are refused before the tool body runs; the one legitimate change goes through. ADK's transfer_to_agent is checked the same way, so the sub-agent cannot pass the alert on.

What it teaches that the current recipes do not:

  • Why a system prompt, a tool allowlist, a shared API key or a static role cannot express "this service, at most four replicas, for ten minutes, verified where the tool runs", and what can.
  • Narrowing as a checked operation: a child warrant that widens any bound is refused at grant time, not at call time.
  • Per-agent keys: each agent signs its own tool calls, so a ticket copied out of one agent is useless in another.
  • A refusal returned from before_tool_callback replaces the tool result and ADK skips the body; the tools record their own entry so the tests can prove "refused before it ran", not "ran, then reported".

Shape follows the merged attenu-guard-customer-service recipe: offline demo.py through the real Runner with a scripted BaseLlm, demo.py --live for a real model, tests that need no key.

2. What language is your recipe implemented in (e.g. Python, Go, etc)?

Python (3.11+), google-adk 2.9.x.

3. Will this be a deployable recipe, either by having a Dockerfile, or by utilizing Vertex AI?

No. It is a standalone recipe that runs offline by default and against Gemini via AI Studio or Vertex AI with demo.py --live / adk run app. No Dockerfile.

4. What GCP services or third-party APIs (Salesforce, Jira, etc.) are required?

None for the default run. A live run needs a Gemini model via GOOGLE_API_KEY or a Vertex AI project, exactly as the other Python recipes. The only non-Google dependency is the PyPI package tenuo (Apache-2.0, https://github.com/tenuo-ai/tenuo), which provides the signed warrants and the verifier. No hosted service is involved.

5. Who (individual/team) will own and maintain this?

tenuo-ai (team), point of contact @aimable100. I maintain the tenuo library the recipe uses.

6. Please include any additional information you'd like to share.

  • Proposed folder: contrib/python/warrant-scoped-oncall-team (30 chars), 15 files, ~58 KB plus uv.lock, hardcoded data only.
  • The recipe wires the library's verifier into a small ADK plugin of its own (app/authz.py) so that each agent can hold its own signing key; the library's stock TenuoPlugin covers the single-key case. The README says so plainly.
  • Already passes every local check the checklist lists: uv run validate, check_env_vars.py, check_recipe_pyproject.py, uv lock --check, check_lockfile_hashes.py, ruff format/check with the root config, check_house_rules.py, and pytest (18 tests, offline).
  • Disclosure: I maintain the library used. No product, cloud link or badge is referenced; the README links the library once, as the attenu-guard recipe does.