google / google/adk-python-community

feat(plugins): add AuthorityRoutingPlugin — pre-execution authority posture (ADVISE/EXECUTE/DEFER/STOP)

Open
#171 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
182
Forks
75
PR merge metrics
No merged PRs in 30d

Description

## Problem

Tool schemas and permissions govern *access* — which tools exist and who may call them. They do not govern *authorization*: whether the agent was allowed to act **at all** for a given request, and within what scope. That gap is where three recurring agent failures live:

- **advice becomes action** — the user asked for a recommendation and the agent executed anyway;
- **scope expansion** — one bounded edit ballooned into a dependent workflow;
- **missing approval** — an approval was clearly required and the agent proceeded.

`AgentGovernancePlugin` (policy-as-code allow/deny) and the HITL approval gateway answer *"is this tool call permitted by policy?"*. Neither answers *"was the agent authorized to act at all, and within what scope?"* — and both require external infrastructure (a policy engine / an approval service).

## Proposal

Add `AuthorityRoutingPlugin`, a self-contained `BasePlugin` that assigns an **authority posture** to every tool call before it runs:

| Posture | Meaning |
| --- | --- |
| ADVISE | Recommendations only; no tool side effects. |
| EXECUTE | Act, within an explicitly bounded scope. |
| DEFER | Pause and request authorization when scope/approval is unclear. |
| STOP | Refuse when the work is not allowed. |

Two stages produce the final posture:

1. **Posture router** (optional, caller-supplied callable — typically a model call) returning a validated verdict with a scope statement.
2. **Deterministic guard** — an irreversibility keyword tripwire + an approval-state check — composed with the router under **most-restrictive-wins**: plain code can only make a posture *stricter*, never looser.

Design properties:

- **Fail-closed** — an unparseable or raised router verdict defaults to DEFER.
- **Guard-only mode** (no router) is fully deterministic and needs no model and no extra dependency.
- Complements, rather than duplicates, the existing governance plugins.

## Scope

- `src/google/adk_community/plugins/authority_routing_plugin.py` + export
- `tests/plugins/test_authority_routing_plugin.py` (deterministic, no credentials)
- `contributing/samples/authority_routing/` (runnable sample with live output)

Happy to adjust the API surface or placement to match maintainer preferences. I have an implementation ready and will open a PR referencing this issue.

Contributor guide

Open the contributing guide

Research direction

Start by reading the existing BasePlugin and governance plugin behavior, then review the proposed paths in src/google/adk_community/plugins/authority_routing_plugin.py and tests/plugins/test_authority_routing_plugin.py. Add deterministic tests for posture routing, fail-closed handling, the irreversibility tripwire, approval checks, and most-restrictive-wins behavior, plus the runnable sample under contributing/samples/authority_routing/. Done means the plugin is exported and the sample produces live output without credentials.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.