You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 09ca357
Browse filesBrowse the repository at this point in the historyBrowse files
datasets: define the agent-trace schema, validator and format docs
agentdataflow_toolexchange_traces/ has been open for contributions with a
TODO where its data format should be. This defines the format and ships the
tooling that enforces it. Entries follow in a separate PR, so the format can
be reviewed without the data riding along.
provenance.tier records how a trace was obtained - sanitized production, lab
or CTF, derived from a documented public fact, or hypothetical - because the
people who hold real agent traces mostly cannot publish them. Every tier
above hypothetical requires evidence a reader can check without the
contributor, enforced by validate.py, so the kinds of contribution never
pretend to be one another. A contributor-controlled source does not
establish a precondition at any tier; that rule cannot be checked
mechanically and is stated as a review-time obligation in the README and
schema, not implied to be automated.
The category enum matches the values already used by the repo's central
data_validation/schemas/agentdataflow_trace.schema.json. Where this schema
diverges from that one, the divergence is deliberate and set out in the pull
request description.
validate.py checks schema conformance, the span graph (including that a
span cannot name itself or a later span as its parent), citation form per
evidence type, and ISO dates on date_added/date_observed and every span
timestamp in every environment, and scans every string in an entry - not
only span payloads - for credential-, secret-, and internal-hostname-shaped
values and for clusters of addresses that look like real routable public
IPv4 addresses, independently of the contributor's sanitization attestation.
It passes with entries/ empty, validating example.json on its own.
A GitHub Actions workflow runs validate.py and checks index.csv is current,
path-filtered to this dataset, so the checks above run on every PR rather
than depending on a contributor having run them locally.
Copy file name to clipboardExpand all lines: datasets/agentdataflow_toolexchange_traces/README.md
+92-18Lines changed: 92 additions & 18 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,39 +10,113 @@ Structured traces capturing how data flows through agentic AI systems — betwee
10
10
11
11
Categories include:
12
12
13
-
-**Tool call traces** — Sequences of tool invocations showing what data is sent to and received from external tools (APIs, databases, file systems, code execution environments)
14
-
-**Multi-agent delegation chains** — Traces showing how tasks and data are passed between agents, including what context is forwarded, filtered, or accumulated
15
-
-**Plugin data exchange logs** — Records of data shared with third-party plugins, including request/response payloads and metadata
16
-
-**Credential and permission flows** — How credentials, tokens, and permissions are scoped, delegated, and consumed across agent workflows
17
-
-**Context accumulation patterns** — Traces showing how agent context windows grow over multi-step tasks, what data persists across steps, and where over-sharing occurs
18
-
-**Memory read/write traces** — How agents interact with short-term and long-term memory stores, including what data is persisted and retrieved
13
+
-**Tool call traces** (`tool_call`) — Sequences of tool invocations showing what data is sent to and received from external tools (APIs, databases, file systems, code execution environments)
14
+
-**Multi-agent delegation chains** (`multi_agent_delegation`) — Traces showing how tasks and data are passed between agents, including what context is forwarded, filtered, or accumulated
15
+
-**Plugin data exchange logs** (`plugin_data_exchange`) — Records of data shared with third-party plugins, including request/response payloads and metadata
16
+
-**Credential and permission flows** (`credential_flow`) — How credentials, tokens, and permissions are scoped, delegated, and consumed across agent workflows
17
+
-**Context accumulation patterns** (`context_accumulation`) — Traces showing how agent context windows grow over multi-step tasks, what data persists across steps, and where over-sharing occurs
18
+
-**Memory read/write traces** (`memory_read_write`) — How agents interact with short-term and long-term memory stores, including what data is persisted and retrieved
19
+
20
+
## Files
21
+
22
+
| File | Purpose |
23
+
|---|---|
24
+
|`schema.json`| JSON Schema (draft 2020-12) every entry validates against |
25
+
|`example.json`| Worked example. Read it with the schema before writing an entry |
26
+
|`entries/`| One trace per file, named `<trace_id>.json`. Empty until the first entry merges; `validate.py` passes against `example.json` alone in the meantime. |
|`index.csv`| Flat index of all entries, for filtering and citation. Generated once `entries/` is non-empty. |
19
30
20
31
## Data Format
21
32
22
-
<!-- TODO: Define schema once initial data is contributed -->
33
+
One trace per file in `entries/`, named after its `trace_id` (`DSGAI-TRACE-<slug>.json`). The authoritative definition is `schema.json`; the summary below is orientation.
23
34
24
-
Contributions should include:
35
+
Every entry carries:
25
36
26
-
-**Trace ID**
27
-
-**Category** — From the list above
28
-
-**DSGAI mapping** — Primary DSGAI entries relevant to this trace
29
-
-**Agent framework** — LangGraph, AutoGPT, CrewAI, custom, etc. (if disclosable)
30
-
-**Trace data** — The sequence of events, tool calls, and data exchanges in structured format (JSON, JSONL, or OpenTelemetry-compatible spans)
31
-
-**Data sensitivity annotations** — Flag any steps where sensitive data is present, over-shared, or inadequately scoped
32
-
-**Security observations** — What data security risks this trace illustrates
33
-
-**Benign / adversarial** — Whether this is a normal workflow trace or one demonstrating a security failure
37
+
-**`trace_id`, `title`, `description`** - what flows, and what makes it security-relevant
38
+
-**`category`** - one of the six above
39
+
-**`disposition`** - `benign`, `adversarial`, or `unintentional_failure`
40
+
-**`dsgai_mapping`** - DSGAI entries this trace illustrates, primary risk first
41
+
-**`provenance`** - where the trace came from, and what backs it (see below)
42
+
-**`sanitization`** - a hard attestation plus the techniques applied
43
+
-**`spans`** - the trace itself: an ordered sequence of events
44
+
-**`security_observations`** - what the trace demonstrates, one falsifiable claim per item
A span is one event. The shape is OpenTelemetry-compatible without requiring an OTel pipeline to produce it, so a trace can be exported from a real system or written by hand and still validate the same way.
51
+
52
+
```json
53
+
{
54
+
"span_id": "s7",
55
+
"parent_span_id": "s6",
56
+
"t_offset_ms": 176400910,
57
+
"actor": "tool",
58
+
"actor_id": "tool://server-b/lookup_record",
59
+
"operation": "tool.result",
60
+
"summary": "Tool returns the full record, three fields wider than the schema the agent bound to.",
"note": "Entitlement was enforced once, against a schema that has since changed.",
67
+
"severity": "High"
68
+
}
69
+
}
70
+
```
71
+
72
+
Two conventions carry most of the weight:
73
+
74
+
**Payloads are shapes, not content.** String values in `payload` should be typed placeholders - `<synthetic:email>`, `<redacted:bearer-token>`, `<shape:string,len=1840>`. Literal content belongs in a trace only where the literal *is* the published artifact, such as a prompt-injection string from a paper. This is not only a privacy rule: it is what makes traces from real systems shareable at all, because the finding almost always lives in the shape.
75
+
76
+
**Findings hang off spans.** Attaching a risk to the span where it materializes lets a reader see exactly where a flow stops being safe, instead of inferring it from prose. `validate.py` requires every span-level `finding.dsgai_id` to appear in the trace's top-level `dsgai_mapping`.
77
+
78
+
Prefer `t_offset_ms` over wall-clock timestamps. Relative offsets carry the ordering that matters without inventing precision or disclosing when a system was running. Use `timestamp` only where the absolute date is part of the finding.
79
+
80
+
### Provenance tiers
81
+
82
+
Most people who hold real agent traces cannot publish them, because production telemetry contains everything that must not be published. A dataset that accepts only production telemetry stays empty; a dataset that accepts anything fills with plausible fiction. The `provenance.tier` field is how this dataset takes both contributions without confusing them:
83
+
84
+
| Tier | Meaning |
85
+
|---|---|
86
+
|`observed_production`| Sanitized telemetry from a real deployed system |
87
+
|`observed_lab`| Sandbox, test environment, CTF, or red-team exercise |
88
+
|`derived_from_public_documentation`| The mechanism is rendered as a trace, and its precondition is a documented public fact carried in `evidence` - a specification, an advisory, a CVE, third-party research. The source may be normative (what a protocol permits) or empirical (what was observed); either is fine, as long as it is checkable without the contributor. |
89
+
|`hypothetical`| Illustrative only, no empirical backing |
90
+
91
+
Every tier except `hypothetical` requires at least one `provenance.evidence` item, enforced by `validate.py`, and every item has to say what it supports, narrowly. Acceptable backing is anything a reader can check without the contributor: a normative statement in a protocol specification, a published advisory or CVE, a vendor changelog, third-party research, a DOI. A source the contributor owns or controls - their own site, their own dataset, their own publication - does not establish a precondition here, whatever it says. This rule is not machine-checkable and is not enforced by `validate.py`; it is a review-time obligation, the same as the sanitization judgment call a reviewer makes on every entry. Where a contributor-controlled source is the only backing available, the honest tier is `hypothetical`. Statistics computed over this dataset should be reported per tier, never pooled across them.
92
+
93
+
Choose the tier honestly. `derived_from_public_documentation` is not a lesser contribution; it is the tier that lets a documented phenomenon be studied as a data flow without anyone publishing their logs. A specification saying what a protocol permits and telemetry saying what happened are different claims with different weight, which is exactly why the field is named "documentation" and not "observation."
94
+
95
+
### MITRE ATLAS mappings
96
+
97
+
`mitre_atlas_mapping` is release-pinned by construction: an entry records the ATLAS release it was verified against and the name each identifier carried in that release. ATLAS identifiers and their names have both moved between releases, so an unpinned pair silently rots. Omit the property rather than guess.
34
98
35
99
## Sanitization Requirements
36
100
37
101
All traces **must** be sanitized before submission:
38
102
39
-
- No real API keys, tokens, credentials, or secrets — replace with placeholder values (e.g., `sk-REDACTED`, `Bearer EXAMPLE_TOKEN`)
103
+
- No real API keys, tokens, credentials, or secrets — replace with placeholder values (e.g.`<redacted:bearer-token>`)
40
104
- No real PII, PHI, or proprietary data — use synthetic equivalents
41
105
- No internal hostnames, IP addresses, or infrastructure details
42
106
- Generalize organization-specific tool names if they could identify the source
43
107
44
108
Traces from test environments, sandboxes, or CTF exercises are ideal. Production traces must be thoroughly sanitized.
45
109
110
+
Two things back this up rather than leaving it to good intentions. `sanitization.attestation` must be a literal `true`, so an entry cannot merge with the box quietly unticked. And `validate.py` scans every string in the entry, independently of that attestation: payloads, summaries, notes, evidence locators. Placeholders are exempt; values matching one of its patterns fail the run - common credential shapes, RFC1918 addresses, `.internal`/`.corp`/`.lan`/`.intra` hostnames, home directory paths, credential-shaped `key=value` assignments, and two or more addresses in one string that look like real routable public IPv4 addresses. The scan is deliberately wider than the payloads, because prose written while looking at a real trace is where a real hostname actually gets typed. It is pattern matching, not a guarantee: a contributor is still the one certifying `sanitization.attestation`, and a reviewer is still the backstop for anything the patterns miss.
111
+
112
+
Naming a third party as the subject of a security failure is a disclosure act, not a dataset contribution. Generalize the counterparty unless you have gone through disclosure and are prepared to say so in `notes`.
113
+
46
114
## Contributing
47
115
48
-
Add traces as individual JSON, JSONL, or YAML files and submit a pull request. See the [main datasets README](../README.md) for general contribution guidelines.
116
+
1. Copy `example.json` and edit it, or export spans from your own system into the same shape
117
+
2. Save as `entries/<trace_id>.json`
118
+
3. Run `python validate.py` - it must print OK
119
+
4. Run `python build_index.py` to refresh `index.csv`
120
+
5. Open a pull request describing what the trace demonstrates and which DSGAI entries it maps to
121
+
122
+
See the [main datasets README](../README.md) for general contribution guidelines, and `#team-genai-data-security-initiative` on the [OWASP Slack workspace](https://owasp.slack.com) for anything that needs a conversation first.
0 commit comments