"""RFC-9421-shaped HTTP signature round-trip and tamper-detection.""" from __future__ import annotations import pytest from act.errors import ACTSignatureError from poc.http_sig import sign_request, verify_request def _sign_verify_ok(identities, body: bytes): agent = identities["agent"] target = "http://127.0.0.1:8765/mcp" signed = sign_request( method="POST", target_uri=target, body=body, wimse_ect="ect.placeholder.compact", wimse_aud=identities["mcp-server"].name, keyid=agent.kid, private_key=agent.private_key, ) parsed = verify_request( method="POST", target_uri=target, body=body, wimse_ect_header="ect.placeholder.compact", content_digest_header=signed.content_digest, signature_input_header=signed.signature_input, signature_header=signed.signature, expected_audience=identities["mcp-server"].name, public_key=agent.public_key, ) return signed, parsed def test_signature_round_trips(identities): signed, parsed = _sign_verify_ok(identities, body=b'{"method":"tools/call"}') assert parsed.keyid == identities["agent"].kid assert parsed.wimse_aud == "mcp-server" assert parsed.alg == "ecdsa-p256-sha256" def test_signature_fails_on_tampered_body(identities): agent = identities["agent"] signed, _ = _sign_verify_ok(identities, body=b"original") with pytest.raises(ACTSignatureError): verify_request( method="POST", target_uri="http://127.0.0.1:8765/mcp", body=b"tampered", # different body → different digest → no match wimse_ect_header="ect.placeholder.compact", content_digest_header=signed.content_digest, signature_input_header=signed.signature_input, signature_header=signed.signature, expected_audience="mcp-server", public_key=agent.public_key, ) def test_signature_fails_on_wrong_audience(identities): agent = identities["agent"] signed = sign_request( method="POST", target_uri="http://example/mcp", body=b"{}", wimse_ect="ect.placeholder", wimse_aud="the-wrong-workload", # signed for the wrong audience keyid=agent.kid, private_key=agent.private_key, ) with pytest.raises(ACTSignatureError): verify_request( method="POST", target_uri="http://example/mcp", body=b"{}", wimse_ect_header="ect.placeholder", content_digest_header=signed.content_digest, signature_input_header=signed.signature_input, signature_header=signed.signature, expected_audience="mcp-server", public_key=agent.public_key, )