A2A agent that audits another deployed agent's source pre-deploy. Reads the target Gitea repo via a short-lived read-only token minted through ctx.mint_gitea_token(), runs an inner DeepAgents graph backed by GiteaBackend, and emits a typed ReviewReport. Skill bundles: - security-anti-patterns (credentials, eval, sandbox bypass, egress) - a2apack-best-practices (class shape, decorators, types, timeouts) - grant-scope-evaluation (declared vs actual workspace scope) Tools: - sandbox_a2a_card : round-trips the project through microsandbox - sandbox_ruff_check: objective static checks - submit_review_report: typed final report 7 smoke tests pass; agent card loads cleanly via `a2a card`.
3.3 KiB
3.3 KiB
name, description
| name | description |
|---|---|
| grant-scope-evaluation | Evaluate whether a skill's declared workspace grants match what its code actually does. Use when reviewing @skill grant_* parameters against ctx.workspace, ctx.sandbox, and file-writing patterns in the skill body. |
Grant Scope Evaluation
A2A grants are the platform's principle-of-least-authority lever. Every public skill declares the scope it intends to use; the platform mints a matching grant; the runtime enforces it at the FUSE layer.
Your job is to flag mismatches between declared and actual scope.
What the decorator declares
Look at the @skill(...) call. The relevant fields:
grant_mode—read_only,read_write_overlay, or absent.grant_allow_patterns— fnmatch globs the skill may read.grant_deny_patterns— fnmatch globs explicitly denied (overrides allow).grant_outputs_prefix— single prefix the skill writes outputs under.grant_write_prefixes— multiple write prefixes (more flexible thanoutputs_prefix).grant_ttl_seconds— how long the grant lives.allow_scope_expansion— whetherctx.request_scopemay be called.
What the skill body actually does
Read the skill body and tabulate:
- Reads — every
ctx.workspace.read(...)/read_bytes, and every built-in DeepAgentsread_file/grep/glob. Each read implies a path or glob that must be matched bygrant_allow_patterns. - Writes — every
ctx.workspace.write(...),write_artifact,ctx.workspace_shell/workspace_pythoninvocation that produces files. Each write implies a path that must be undergrant_outputs_prefixor one ofgrant_write_prefixes. - Scope expansion — any call to
ctx.request_scope(...). If present withoutallow_scope_expansion=True→critical(will raise at runtime).
Common findings
- Over-broad declared scope (
info/warning): grants the agent more than it uses, e.g.grant_allow_patterns=("**",)when the body only readsagents/{name}/**. Tighten the declaration. - Under-declared writes (
critical): body writes to a path not under any declared write prefix → FUSE returnsEACCESand the skill fails. - Under-declared reads (
warning): body reads paths not in allow patterns → reads return "not found" even when the file exists. - Missing
stream=Truecombined withallow_scope_expansion=True(critical): scope expansion requires the SSE stream. - Long TTL on a fast skill (
info):grant_ttl_seconds=3600on a 10-second skill is sloppy. Match TTL to expected runtime + buffer.
Path template variables
Decorators support {name} and similar template variables that the
runtime substitutes from skill args. When evaluating coverage:
- Treat
agents/{name}/**as "any path matching that template after the caller'snamearg is substituted". - Flag templates referencing args that don't exist on the skill (
critical).
Cross-skill consistency
If the agent has multiple skills writing to overlapping prefixes, they
should declare consistent patterns. Divergence is warning.
Severity rubric
critical— would fail at runtime (writes hitEACCES, scope expansion withoutstream, template references missing arg).warning— works but mismatched (over-broad scope, divergent siblings).info— tighten-the-declaration suggestions.