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`.
75 lines
3.3 KiB
Markdown
75 lines
3.3 KiB
Markdown
---
|
|
name: grant-scope-evaluation
|
|
description: 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 than
|
|
`outputs_prefix`).
|
|
* `grant_ttl_seconds` — how long the grant lives.
|
|
* `allow_scope_expansion` — whether `ctx.request_scope` may be called.
|
|
|
|
## What the skill body actually does
|
|
|
|
Read the skill body and tabulate:
|
|
|
|
1. **Reads** — every `ctx.workspace.read(...)` / `read_bytes`, and every
|
|
built-in DeepAgents `read_file` / `grep` / `glob`. Each read implies a
|
|
path or glob that must be matched by `grant_allow_patterns`.
|
|
2. **Writes** — every `ctx.workspace.write(...)`, `write_artifact`,
|
|
`ctx.workspace_shell` / `workspace_python` invocation that produces
|
|
files. Each write implies a path that must be under
|
|
`grant_outputs_prefix` or one of `grant_write_prefixes`.
|
|
3. **Scope expansion** — any call to `ctx.request_scope(...)`. If present
|
|
without `allow_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 reads `agents/{name}/**`. Tighten the declaration.
|
|
* **Under-declared writes** (`critical`): body writes to a path not under
|
|
any declared write prefix → FUSE returns `EACCES` and 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=True`** combined with `allow_scope_expansion=True`
|
|
(`critical`): scope expansion requires the SSE stream.
|
|
* **Long TTL on a fast skill** (`info`): `grant_ttl_seconds=3600` on 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's `name` arg 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 hit `EACCES`, scope expansion
|
|
without `stream`, template references missing arg).
|
|
* `warning` — works but mismatched (over-broad scope, divergent siblings).
|
|
* `info` — tighten-the-declaration suggestions.
|