From b223ee41ac9e3b635651f9636a08061801b5c826 Mon Sep 17 00:00:00 2001 From: BIN Zhang Date: Sun, 2 Aug 2026 00:47:28 +0800 Subject: [PATCH 1/2] test: cover invalid delegation signature in action evidence Signed-off-by: BIN Zhang --- tests/conformance/README.md | 1 + tests/conformance/test_profile_conformance.py | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/conformance/README.md b/tests/conformance/README.md index 08ad059..cf03ec8 100644 --- a/tests/conformance/README.md +++ b/tests/conformance/README.md @@ -101,3 +101,4 @@ Spec: [trace-a2a-profile.md](../../docs/spec/trace-a2a-profile.md), [provenance- | ACTION-005 | MUST | A requested action outside the effective delegated scope is classified as authorization-invalid, not malformed provenance. | `SCOPE_NOT_PERMITTED`. | | ACTION-006 | MUST | A valid delegated action denied by local policy is classified as authorization-invalid, not malformed provenance. | `SCOPE_NOT_PERMITTED`. | | ACTION-007 | MUST | A valid delegated action whose controller outcome is negative remains valid evidence of a negative outcome. | `valid_negative_outcome`. | +| ACTION-008 | MUST | An action whose delegation chain contains a credential with an invalid signature is rejected as provenance-invalid before authorization or outcome handling. | `INVALID_CREDENTIAL`. | diff --git a/tests/conformance/test_profile_conformance.py b/tests/conformance/test_profile_conformance.py index b923bec..dbbd2db 100644 --- a/tests/conformance/test_profile_conformance.py +++ b/tests/conformance/test_profile_conformance.py @@ -5,7 +5,7 @@ from __future__ import annotations -from dataclasses import dataclass +from dataclasses import dataclass, replace import pytest from cryptography.hazmat.primitives.asymmetric import ec @@ -404,3 +404,18 @@ def test_action_007_controller_rejection_is_valid_negative_outcome() -> None: LocalPolicy.of(["robot.move"]), ) assert result == _ActionEvidenceResult("valid_negative_outcome", "CONTROLLER_REJECTED") + + +def test_action_008_invalid_delegation_signature_is_provenance_invalid() -> None: + chain = _action_chain() + records = _records(chain) + leaf = chain[-1] + tampered_signature = f"{int(leaf.signature[:2], 16) ^ 1:02x}{leaf.signature[2:]}" + bad_chain = [*chain[:-1], replace(leaf, signature=tampered_signature)] + result = _verify_action_evidence( + bad_chain, + records, + _action_evidence(records), + LocalPolicy.of(["robot.move"]), + ) + assert result == _ActionEvidenceResult("provenance_invalid", "INVALID_CREDENTIAL") From 9fb5c3b112c1f2d083bc97a12d55f7a583190b9f Mon Sep 17 00:00:00 2001 From: BIN Zhang Date: Sun, 2 Aug 2026 02:39:55 +0800 Subject: [PATCH 2/2] test: strengthen action invalid signature ordering coverage Signed-off-by: BIN Zhang --- tests/conformance/test_profile_conformance.py | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/tests/conformance/test_profile_conformance.py b/tests/conformance/test_profile_conformance.py index dbbd2db..09fd14a 100644 --- a/tests/conformance/test_profile_conformance.py +++ b/tests/conformance/test_profile_conformance.py @@ -412,10 +412,26 @@ def test_action_008_invalid_delegation_signature_is_provenance_invalid() -> None leaf = chain[-1] tampered_signature = f"{int(leaf.signature[:2], 16) ^ 1:02x}{leaf.signature[2:]}" bad_chain = [*chain[:-1], replace(leaf, signature=tampered_signature)] - result = _verify_action_evidence( - bad_chain, + evidence = _action_evidence( records, - _action_evidence(records), - LocalPolicy.of(["robot.move"]), + requested_capability="robot.inspect", + controller_decision="rejected", + ) + restrictive_policy = LocalPolicy.of(["robot.move"]) + permissive_policy = LocalPolicy.of(["robot.move", "robot.inspect"]) + + # The controls establish both downstream classifications that invalid provenance must preempt. + assert _verify_action_evidence(chain, records, evidence, restrictive_policy) == ( + _ActionEvidenceResult("authorization_invalid", "SCOPE_NOT_PERMITTED") + ) + assert _verify_action_evidence(chain, records, evidence, permissive_policy) == ( + _ActionEvidenceResult("valid_negative_outcome", "CONTROLLER_REJECTED") + ) + + # ACTION-008 verifies provenance validation precedes authorization and controller outcome classification. + assert _verify_action_evidence(bad_chain, records, evidence, restrictive_policy) == ( + _ActionEvidenceResult("provenance_invalid", "INVALID_CREDENTIAL") + ) + assert _verify_action_evidence(bad_chain, records, evidence, permissive_policy) == ( + _ActionEvidenceResult("provenance_invalid", "INVALID_CREDENTIAL") ) - assert result == _ActionEvidenceResult("provenance_invalid", "INVALID_CREDENTIAL")