Skip to content

Update from code changes: A2A UNVERIFIABLE semantics + doc corrections - #248

Open
mintlify[bot] wants to merge 2 commits into
mainfrom
mintlify/2f129d13
Open

Update from code changes: A2A UNVERIFIABLE semantics + doc corrections#248
mintlify[bot] wants to merge 2 commits into
mainfrom
mintlify/2f129d13

Conversation

@mintlify

@mintlify mintlify Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Align the A2A docs with the interceptor's UNVERIFIABLE fail-closed behavior and correct five materially false claims that previously described the pipeline differently from the code.

Changes

  • a2a/interceptor.mdx — removed the "Trusted Agent Bypass" step (trusted agents are only pre-added to the allowlist), added a verdict-status table, rewrote Code Guard as AST-first + regex-heuristic (with BLOCKED / HEURISTIC_PASS), reframed passthrough as UNVERIFIABLE with no JWT, noted that empty/malformed finance and logic payloads now return UNVERIFIABLE, and updated the trusted_agents config row.
  • a2a/quickstart.mdx — updated the GENERAL gateway response example to show status: "unverifiable", attestation_jwt: null, and the reason string.
  • a2a/architecture.mdx — pipeline table and payload-type routing table now reflect unverifiable + heuristic_pass and the AST-first Code Guard.
  • a2a/overview.mdx — small wording tweaks (Code Guard blurb and diagram label).
  • a2a/crypto-attestations.mdx — JWT exp default corrected to 300 seconds (5 minutes); signing example updated from validity_seconds=86400 to validity_seconds=300.
  • changelog.mdx — new top-of-file entry summarizing the behavior change, the JWT-attestation contract, and the caller-side impact.

Context

  • qwed-ai/qwed-a2a#40 — empty finance/logic payloads return UNVERIFIABLE instead of a signed FORWARDED.
  • qwed-ai/qwed-a2a#57 — README corrections for the five materially false claims (no Bypass stage, GENERAL/DATA_QUERY are UNVERIFIABLE, CodeGuard is AST + heuristics, JWT expiry is 300 s, no JWT on UNVERIFIABLE).

@codeant-ai

codeant-ai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Skipping PR review because a bot author is detected.

If you want to trigger CodeAnt AI, comment @codeant-ai review to trigger a manual review.

@qwed-security

qwed-security Bot commented Jul 28, 2026

Copy link
Copy Markdown

QWED Security Verification Report

6 files scanned | 0 blocked | 0 warnings | 15 info | 0 suppressed | 1 verified

Informational Findings

File Line Context Issue
a2a/crypto-attestations.mdx L100 DOCUMENTATION Hardcoded credential-like material detected.
a2a/interceptor.mdx L134 DOCUMENTATION eval() executes untrusted code. In agentic pipelines, LLM- or caller-controlled expressions reach this sink.
a2a/interceptor.mdx L134 DOCUMENTATION Dynamic import() call should be reviewed.
a2a/interceptor.mdx L134 DOCUMENTATION compile() can be part of dynamic code generation.
a2a/interceptor.mdx L135 DOCUMENTATION os.system() shell execution primitive detected.
a2a/interceptor.mdx L135 DOCUMENTATION subprocess invocation detected.
a2a/interceptor.mdx L145 DOCUMENTATION Dynamic import() call should be reviewed.
a2a/interceptor.mdx L146 DOCUMENTATION os.system() shell execution primitive detected.
a2a/interceptor.mdx L147 DOCUMENTATION os.popen() shell execution primitive detected.
a2a/overview.mdx L100 DOCUMENTATION os.system() shell execution primitive detected.
a2a/quickstart.mdx L39 DOCUMENTATION Hardcoded credential-like material detected.
a2a/quickstart.mdx L151 DOCUMENTATION os.system() shell execution primitive detected.
a2a/quickstart.mdx L194 DOCUMENTATION Binding to 0.0.0.0 exposes the service broadly.
changelog.mdx L21 DOCUMENTATION eval() executes untrusted code. In agentic pipelines, LLM- or caller-controlled expressions reach this sink.
changelog.mdx L21 DOCUMENTATION subprocess invocation detected.

Engines

  • entropy_scan: ✅
  • pattern_scan: ⚠️ 18 finding(s)

Verified Files

  • a2a/architecture.mdx

Verified by QWED — deterministic security verification. No LLM used.

Comment thread a2a/interceptor.mdx
| `compile` | `\bcompile\s*\(` | Code compilation |
| `importlib` | `\bimportlib\s*\.` | Runtime module loading |
If either layer finds a threat, the verdict is `BLOCKED` (the reason notes which layer triggered). If both layers are clean, the verdict is `HEURISTIC_PASS` — a signed attestation that no known dangerous constructs were found, **not** a deterministic guarantee that the code is safe to execute.

Comment thread a2a/interceptor.mdx
| `compile` | `\bcompile\s*\(` | Code compilation |
| `importlib` | `\bimportlib\s*\.` | Runtime module loading |
If either layer finds a threat, the verdict is `BLOCKED` (the reason notes which layer triggered). If both layers are clean, the verdict is `HEURISTIC_PASS` — a signed attestation that no known dangerous constructs were found, **not** a deterministic guarantee that the code is safe to execute.

Comment thread a2a/interceptor.mdx
| `compile` | `\bcompile\s*\(` | Code compilation |
| `importlib` | `\bimportlib\s*\.` | Runtime module loading |
If either layer finds a threat, the verdict is `BLOCKED` (the reason notes which layer triggered). If both layers are clean, the verdict is `HEURISTIC_PASS` — a signed attestation that no known dangerous constructs were found, **not** a deterministic guarantee that the code is safe to execute.

Comment thread a2a/interceptor.mdx
| `importlib` | `\bimportlib\s*\.` | Runtime module loading |
If either layer finds a threat, the verdict is `BLOCKED` (the reason notes which layer triggered). If both layers are clean, the verdict is `HEURISTIC_PASS` — a signed attestation that no known dangerous constructs were found, **not** a deterministic guarantee that the code is safe to execute.

```python
Comment thread a2a/interceptor.mdx
| `importlib` | `\bimportlib\s*\.` | Runtime module loading |
If either layer finds a threat, the verdict is `BLOCKED` (the reason notes which layer triggered). If both layers are clean, the verdict is `HEURISTIC_PASS` — a signed attestation that no known dangerous constructs were found, **not** a deterministic guarantee that the code is safe to execute.

```python
Comment thread a2a/interceptor.mdx
# verdict.reason = "Dangerous code patterns detected (AST): subprocess import"
```

### Passthrough
Comment thread a2a/interceptor.mdx
```

### Passthrough
### Passthrough (unverifiable)
Comment thread a2a/interceptor.mdx

### Passthrough
### Passthrough (unverifiable)

Comment thread changelog.mdx
- **Empty/malformed finance and logic payloads → `UNVERIFIABLE`, no JWT.** A `FINANCIAL_TRANSACTION` missing `data`, `line_items`, or `claimed_total`, or with non-numeric amounts, now returns `status=unverifiable` from `finance_guard`. A `LOGIC_ASSERTION` with a missing, non-list, or empty `assertions` array, or malformed entries, returns `status=unverifiable` from `logic_guard`. Earlier releases collapsed these cases to `verified=True` + a signed `FORWARDED` verdict.
- **`GENERAL` and `DATA_QUERY` are no longer silently forwarded.** The passthrough branch now returns an `unverifiable` verdict with `engine_used="passthrough"`, `attestation_jwt=None`, and reason `"No verification engine available for this payload type"`. Callers must decide their own downstream policy for unverified traffic.
- **No `Bypass` verification stage.** The pipeline has four stages, not five. `config.trusted_agents` is pre-added to the `TrustBoundary` allowlist at interceptor construction time — trusted agents still flow through engine routing and receive a normal verdict. The [Verification interceptor](/a2a/interceptor#verification-pipeline) and [Architecture](/a2a/architecture) pages have been corrected.
- **`CodeGuard` is AST-first, regex-second.** Code payloads are first parsed into an AST and inspected for direct dangerous constructs (`eval(`, `exec(`, `subprocess.run(`, `import subprocess`, etc.). Only if the AST layer is clean does a regex heuristic scan run to catch obfuscation patterns (`getattr(__builtins__, ...)`, base64-encoded exec, dynamic `__import__`). The verdict is `BLOCKED` if either layer triggers, or `HEURISTIC_PASS` if both are clean — not a proof of safety.
Comment thread changelog.mdx
- **Empty/malformed finance and logic payloads → `UNVERIFIABLE`, no JWT.** A `FINANCIAL_TRANSACTION` missing `data`, `line_items`, or `claimed_total`, or with non-numeric amounts, now returns `status=unverifiable` from `finance_guard`. A `LOGIC_ASSERTION` with a missing, non-list, or empty `assertions` array, or malformed entries, returns `status=unverifiable` from `logic_guard`. Earlier releases collapsed these cases to `verified=True` + a signed `FORWARDED` verdict.
- **`GENERAL` and `DATA_QUERY` are no longer silently forwarded.** The passthrough branch now returns an `unverifiable` verdict with `engine_used="passthrough"`, `attestation_jwt=None`, and reason `"No verification engine available for this payload type"`. Callers must decide their own downstream policy for unverified traffic.
- **No `Bypass` verification stage.** The pipeline has four stages, not five. `config.trusted_agents` is pre-added to the `TrustBoundary` allowlist at interceptor construction time — trusted agents still flow through engine routing and receive a normal verdict. The [Verification interceptor](/a2a/interceptor#verification-pipeline) and [Architecture](/a2a/architecture) pages have been corrected.
- **`CodeGuard` is AST-first, regex-second.** Code payloads are first parsed into an AST and inspected for direct dangerous constructs (`eval(`, `exec(`, `subprocess.run(`, `import subprocess`, etc.). Only if the AST layer is clean does a regex heuristic scan run to catch obfuscation patterns (`getattr(__builtins__, ...)`, base64-encoded exec, dynamic `__import__`). The verdict is `BLOCKED` if either layer triggers, or `HEURISTIC_PASS` if both are clean — not a proof of safety.
@mintlify

mintlify Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor Author

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
qwed-ai 🟢 Ready View Preview Jul 28, 2026, 4:17 AM

@greptile-apps

greptile-apps Bot commented Jul 28, 2026

Copy link
Copy Markdown

Greptile Summary

The PR realigns the A2A documentation with fail-closed UNVERIFIABLE behavior.

  • Documents unsigned UNVERIFIABLE results for unsupported and malformed payloads.
  • Describes Code Guard as AST-first with regex heuristics and HEURISTIC_PASS.
  • Corrects the default JWT lifetime to five minutes.
  • Updates examples, architecture tables, trusted-agent semantics, and the changelog.

Confidence Score: 4/5

The documentation update appears safe to merge after resolving three non-blocking contract and terminology inconsistencies.

The principal behavior corrections are coherent, but the Overview still promises JWTs for every verdict, the new error row conflicts with the documented exception mapping, and one passthrough field is named inconsistently.

Files Needing Attention: a2a/overview.mdx, a2a/interceptor.mdx, changelog.mdx

Important Files Changed

Filename Overview
a2a/interceptor.mdx Substantially updates pipeline and verdict semantics, but leaves ambiguity around the error status and the passthrough field name.
a2a/architecture.mdx Updates routing, attestation, and Code Guard architecture to include UNVERIFIABLE and HEURISTIC_PASS.
a2a/quickstart.mdx Correctly changes the unsupported-payload response example to an unsigned unverifiable verdict.
a2a/crypto-attestations.mdx Corrects the documented default JWT lifetime and signing example to 300 seconds.
a2a/overview.mdx Updates Code Guard terminology but retains a universal attestation claim that conflicts with the new verdict contract.
changelog.mdx Adds a detailed release entry, including the same unresolved error-status contract presented by the interceptor page.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  M[Agent message] --> T[Trust boundary]
  T --> R{Payload type}
  R -->|Finance| F[Finance guard]
  R -->|Logic| L[Logic guard]
  R -->|Code| C[AST and regex guard]
  R -->|General or data query| U[UNVERIFIABLE]
  F --> V[Signed verdict]
  L --> V
  C --> V
  U --> N[No JWT]
Loading

Reviews (1): Last reviewed commit: "docs: improve SEO titles for a2a overvie..." | Re-trigger Greptile

Comment thread a2a/overview.mdx
</Card>
<Card title="Deterministic Engines" icon="microchip" href="/a2a/interceptor#verification-engines">
Financial verification uses `Decimal` arithmetic. Logic uses set-based contradiction detection. Code uses regex-hardened pattern scanning.
Financial verification uses `Decimal` arithmetic. Logic uses set-based contradiction detection. Code uses AST structural analysis backed by regex heuristics.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Universal JWT claim remains

The Overview still says every verdict is signed, contradicting the new contract that UNVERIFIABLE results have attestation_jwt=None. Integrators relying on this entry-point guidance can unconditionally verify an absent token or reject legitimate unverifiable results.

Comment thread a2a/interceptor.mdx
| `blocked` | Engine detected a violation (bad math, contradiction, dangerous code). Do not forward. | Signed |
| `heuristic_pass` | Code guard ran, no known dangerous constructs found. Not a proof of safety. | Signed |
| `unverifiable` | No engine could evaluate the payload (`GENERAL`/`DATA_QUERY`, empty/malformed finance or logic payload). No attestation is issued. | **None** |
| `error` | Internal exception during verification. Behavior depends on `block_on_error`. | Signed |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Error status contract conflicts

The new table presents error as the status for internal exceptions, while the error-handling section says those exceptions return blocked or forwarded according to block_on_error. Callers therefore cannot determine which status represents an internal failure and can implement an unreachable or incomplete branch.

Comment thread a2a/interceptor.mdx
### Passthrough (unverifiable)

Messages with `payload_type` of `GENERAL` or `DATA_QUERY` are forwarded without verification.
Messages with `payload_type` of `GENERAL` or `DATA_QUERY` have no verification engine. The interceptor returns an **`UNVERIFIABLE`** verdict with `engine="passthrough"`, **no JWT attestation**, and reason `"No verification engine available for this payload type"`. The message is not silently forwarded — callers must decide whether to route unverified content downstream based on their own policy.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Passthrough field name differs

This prose names the returned field engine, but the adjacent example and documented VerificationVerdict model expose engine_used. Copying this contract leads integrations to access a nonexistent verdict.engine attribute and mishandle the passthrough result.

Suggested change
Messages with `payload_type` of `GENERAL` or `DATA_QUERY` have no verification engine. The interceptor returns an **`UNVERIFIABLE`** verdict with `engine="passthrough"`, **no JWT attestation**, and reason `"No verification engine available for this payload type"`. The message is not silently forwarded — callers must decide whether to route unverified content downstream based on their own policy.
Messages with `payload_type` of `GENERAL` or `DATA_QUERY` have no verification engine. The interceptor returns an **`UNVERIFIABLE`** verdict with `engine_used="passthrough"`, **no JWT attestation**, and reason `"No verification engine available for this payload type"`. The message is not silently forwarded — callers must decide whether to route unverified content downstream based on their own policy.

@mintlify

mintlify Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor Author

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
qwed-ai 🟡 Building Jul 28, 2026, 4:16 AM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant