a2aproject / a2aproject/A2A

[Feat]: Data-taint extension to carry data-flow sensitivity across A2A hops

Open
#2,041 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Shell
Stars
25.7k
Forks
2.6k
Avg merge
3d 6h
Merged PRs (30d)
16

Description

### Is your feature request related to a problem? Please describe.

When one agent classifies data as untrusted and passes it to another, that classification does not travel with it. A2A carries no field for it, so the receiving agent sees a clean-looking value with no indication it derives from an untrusted source. Each hand-off strips the fact again, and an agent about to call a privileged tool cannot tell its input traces back to attacker-controlled content, the distributed form of the confused-deputy problem.

A2A metadata already records who acted #2028, how work moved #2026 , and when an output existed #2011. It does not record whether a value is derived from untrusted or sensitive data.

Scope: cooperative fleets and agents run by one operator, increasingly across frameworks via A2A handling untrusted data. This is not a defense against malicious agents, which can simply decline to propagate; it is data-flow hygiene within a trusted fleet, the same threat model as CaMeL and dual-LLM.

### Describe the solution you'd like

An optional, data-only extension reserving one metadata member, dataTaint, on Message, Task, and Artifact metadata:

```json
{ "dataTaint": { "labels": ["untrusted-external"] } }
```

- **labels**: sensitivity tags carried with the value. The extension defines a small standard set (untrusted-external, pii, secret); implementers extend under a vendor: prefix.
- An agent that emits a value derived from a labeled input carries the labels onto its output and MUST NOT drop existing labels. Agents originating data from a known-untrusted source apply the initial label.
- Labels are advisory history, not an access decision. Enforcement lives at the consuming agent, which gates its own privileged tools:

```python
if "untrusted-external" in input.dataTaint.labels and tool.is_privileged:
require_human_approval()
```
This is the CaMeL check; today it cannot fire in a distributed system because the label never survives to the sink. The extension is the plumbing that gets it there.

Agents that don't support the extension ignore the member (metadata is tolerate-by-default), so it is backward-compatible.

**Conformance is minimal.** A supporting agent reads dataTaint.labels, unions them onto derived outputs, and applies its own policy at privileged sinks. Read-and-propagate can be handled by executor middleware, so adoption is a library import, not an agent rework. The spec does not mandate when a value counts as derived or untrusted; that policy stays with the agent. It standardizes only the label shape and the propagation guarantee.

### Describe alternatives you've considered

- Let the model track it in context: unreliable. The model may drop the fact across a long context or a hand-off, and there's no deterministic way to enforce or audit it. An explicit field is checkable without trusting the model to remember.
- Private metadata (status quo): interoperates with nothing; every fleet reinvents the shape.
- Reusing actor-chain scopes #2028: conflates authority with data sensitivity; scopes narrow along a chain where taint accumulates.
- Enforcement in the spec: out of scope. The wire format defines the label; whether it survives a transformation and when to declassify are left to the implementing agent.

### Additional context

Limitation: propagation is coarse. Labels only accumulate, so after enough hops most values carry untrusted-external and the gate stops discriminating. Deciding when a transformation preserves taint and when to declassify is left to the implementing agent, not the wire format.

Happy to draft a fuller experimental-ext-data-taint spec and a reference middleware implementation if a maintainer wants to sponsor it under the extension governance framework.

### Code of Conduct

- [x] I agree to follow this project's Code of Conduct

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.