|
5 | 5 |
|
6 | 6 | from __future__ import annotations |
7 | 7 |
|
8 | | -from dataclasses import dataclass |
| 8 | +from dataclasses import dataclass, replace |
9 | 9 |
|
10 | 10 | import pytest |
11 | 11 | from cryptography.hazmat.primitives.asymmetric import ec |
@@ -404,3 +404,34 @@ def test_action_007_controller_rejection_is_valid_negative_outcome() -> None: |
404 | 404 | LocalPolicy.of(["robot.move"]), |
405 | 405 | ) |
406 | 406 | assert result == _ActionEvidenceResult("valid_negative_outcome", "CONTROLLER_REJECTED") |
| 407 | + |
| 408 | + |
| 409 | +def test_action_008_invalid_delegation_signature_is_provenance_invalid() -> None: |
| 410 | + chain = _action_chain() |
| 411 | + records = _records(chain) |
| 412 | + leaf = chain[-1] |
| 413 | + tampered_signature = f"{int(leaf.signature[:2], 16) ^ 1:02x}{leaf.signature[2:]}" |
| 414 | + bad_chain = [*chain[:-1], replace(leaf, signature=tampered_signature)] |
| 415 | + evidence = _action_evidence( |
| 416 | + records, |
| 417 | + requested_capability="robot.inspect", |
| 418 | + controller_decision="rejected", |
| 419 | + ) |
| 420 | + restrictive_policy = LocalPolicy.of(["robot.move"]) |
| 421 | + permissive_policy = LocalPolicy.of(["robot.move", "robot.inspect"]) |
| 422 | + |
| 423 | + # The controls establish both downstream classifications that invalid provenance must preempt. |
| 424 | + assert _verify_action_evidence(chain, records, evidence, restrictive_policy) == ( |
| 425 | + _ActionEvidenceResult("authorization_invalid", "SCOPE_NOT_PERMITTED") |
| 426 | + ) |
| 427 | + assert _verify_action_evidence(chain, records, evidence, permissive_policy) == ( |
| 428 | + _ActionEvidenceResult("valid_negative_outcome", "CONTROLLER_REJECTED") |
| 429 | + ) |
| 430 | + |
| 431 | + # ACTION-008 verifies provenance validation precedes authorization and controller outcome classification. |
| 432 | + assert _verify_action_evidence(bad_chain, records, evidence, restrictive_policy) == ( |
| 433 | + _ActionEvidenceResult("provenance_invalid", "INVALID_CREDENTIAL") |
| 434 | + ) |
| 435 | + assert _verify_action_evidence(bad_chain, records, evidence, permissive_policy) == ( |
| 436 | + _ActionEvidenceResult("provenance_invalid", "INVALID_CREDENTIAL") |
| 437 | + ) |
0 commit comments