diff --git a/src/agentrust_trace/models.py b/src/agentrust_trace/models.py index fe324ed..ae75a8c 100644 --- a/src/agentrust_trace/models.py +++ b/src/agentrust_trace/models.py @@ -1,10 +1,12 @@ from __future__ import annotations + from typing import Annotated, Literal from pydantic import BaseModel, ConfigDict, Field, model_validator _DIGEST_RE = r"^sha(256:[0-9a-f]{64}|384:[0-9a-f]{96})$" +_JWK_PRIVATE_PARAMS = frozenset({"d", "p", "q", "dp", "dq", "qi", "k"}) DigestStr = Annotated[str, Field(pattern=_DIGEST_RE)] @@ -97,6 +99,12 @@ def _require_key_material(self) -> JWK: raise ValueError( f"jwk with kty={self.kty!r} must carry key material: missing {', '.join(missing)}" ) + extra = dict(self.model_extra) if self.model_extra else {} + private = _JWK_PRIVATE_PARAMS & extra.keys() + if private: + raise ValueError( + f"cnf.jwk must not contain private key parameters: {sorted(private)}" + ) return self diff --git a/tests/test_models.py b/tests/test_models.py index f1799f0..4798752 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -150,3 +150,10 @@ def test_okp_jwk_with_key_material_accepted() -> None: } record = TrustRecord.model_validate(data) assert record.cnf.jwk.x is not None + +def test_jwk_private_key_d_rejected() -> None: + """cnf.jwk must not contain private key parameter d (RFC 8747 ยง3).""" + data = _load("intel-tdx.json") + data["cnf"]["jwk"]["d"] = "PRIVATE_KEY_MATERIAL" + with pytest.raises(ValidationError): + TrustRecord.model_validate(data)