feat: initial agent-reviewer meta-agent

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`.
This commit is contained in:
robert
2026-05-28 09:59:40 -03:00
commit 64a601a85a
17 changed files with 1065 additions and 0 deletions

View File

@@ -0,0 +1,58 @@
---
name: security-anti-patterns
description: Common security mistakes in A2A agent source. Use when reviewing agent.py, a2a.yaml, or any imported module for credential leakage, unsafe code execution, network egress, or sandbox bypass.
---
# Security Anti-Patterns in A2A Agents
Review the agent's source for these high-confidence red flags. Each finding
must cite a file path and (when available) a line number. Severity guidance
is below — be strict about `critical`, conservative about `info`.
## Credential leakage (critical)
* Hard-coded API keys, tokens, passwords. Even in comments. Patterns to grep:
`sk-`, `gho_`, `AKIA`, `xoxb-`, `Bearer `, `password=`, `api_key="..."`.
* Reading provider keys directly: `os.environ["OPENAI_API_KEY"]`,
`A2A_LITELLM_KEY`, master keys. The agent **must** use `ctx.llm` instead.
* Echoing secrets into logs, `emit_progress`, error messages, or returned dicts.
* Writing secrets to the workspace as files.
## Unsafe execution (critical)
* `eval(...)`, `exec(...)`, `compile(...)` on caller-supplied content.
* `subprocess.run`/`Popen` with `shell=True` and a string built from caller input.
* `os.system(...)` with any caller input.
* `pickle.load`/`pickle.loads` from caller-supplied bytes.
* Running caller-supplied code *outside* `ctx.sandbox`. Any subprocess spawned
in the agent container is unsandboxed.
## Sandbox bypass (critical)
* Calling `asyncio.create_subprocess_exec` for work that should produce
durable files — those run in the agent container, not the sandbox. Use
`ctx.workspace_shell` or `ctx.workspace_python`.
* Writing files outside the agent's declared `grant_write_prefixes`. The
sandbox enforces this at the FUSE layer, but unscoped writes from the
agent container itself are still a smell.
## Network egress (warning, critical if combined with credential exfil)
* `httpx`/`requests`/`urllib` calls to arbitrary caller-supplied URLs without
declaring egress policy. Check `runtime = AgentRuntime(egress=...)`.
* Webhooks or callbacks that send caller data to a third party not declared
in the agent card.
## Resource shape mismatches (warning)
* Long-running shell commands without `timeout` set.
* Unbounded loops over caller-supplied collections.
* Reading large files entirely into memory when streaming would do.
## Severity rubric
* `critical` — exploitable today, or directly violates the platform contract.
* `warning` — would fail a careful review; ship-blocker depending on context.
* `info` — style or hardening suggestion; does not block deploy.
When in doubt, prefer `warning` over `critical`. Reviewers that cry wolf get
ignored. Reviewers that miss credential leakage get fired.