Skip to content

Commit a466fba

Browse files
security: pre-launch hardening fixes
- update schema subject pattern to accept did: URIs (aligns with v0.2 spec) - add private key material check in TR-SIG: fail if cnf.jwk contains 'd' field - sync __version__ to 0.2.0 (matches pyproject.toml) - tighten subject URI validation regex in tr_env (require method+id for DID) - pin CI workflow action references to commit SHAs Signed-off-by: Imran Siddique <imran.siddique@opaque.co> Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 863446f commit a466fba

5 files changed

Lines changed: 16 additions & 5 deletions

File tree

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ jobs:
1616
matrix:
1717
python-version: ["3.11", "3.12", "3.13"]
1818
steps:
19-
- uses: actions/checkout@v4
20-
- uses: actions/setup-python@v4
19+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
20+
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v5.3.0
2121
with:
2222
python-version: ${{ matrix.python-version }}
2323
- name: Install package and test deps

schemas/trace-claim.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"properties": {
1212
"eat_profile": {"type": "string", "const": "tag:agentrust.io,2026:trace-v0.1"},
1313
"iat": {"type": "integer", "minimum": 1700000000},
14-
"subject": {"type": "string", "pattern": "^spiffe://"},
14+
"subject": {"type": "string", "pattern": "^(spiffe://|did:)"},
1515
"model": {
1616
"type": "object",
1717
"required": ["provider", "model_id"],

src/trace_tests/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""TRACE conformance test suite."""
22

3-
__version__ = "0.1.0"
3+
__version__ = "0.2.0"

src/trace_tests/modules/tr_env.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22

33
from __future__ import annotations
44

5+
import re
56
import time
67
from typing import Any
78

89
from trace_tests.result import Finding, Status
910

1011
_PROFILE = "tag:agentrust.io,2026:trace-v0.1"
12+
_SUBJECT_RE = re.compile(r'^(spiffe://[^/]+/.+|did:[a-z0-9]+:.+)$')
1113
_IAT_MIN = 1_700_000_000
1214

1315
#: Default maximum record age (seconds). Records older than this fail freshness.
@@ -45,7 +47,7 @@ def check(trace: dict[str, Any], max_age_seconds: int = DEFAULT_MAX_AGE_SECONDS)
4547
findings.append(Finding("TR-ENV-002", Status.FAIL, f"iat must be a Unix timestamp >= {_IAT_MIN}, got {iat!r}"))
4648

4749
subject = trace.get("subject", "")
48-
if isinstance(subject, str) and subject.startswith(("spiffe://", "did:")):
50+
if isinstance(subject, str) and _SUBJECT_RE.match(subject):
4951
findings.append(Finding("TR-ENV-003", Status.PASS, f"subject is a valid workload identity URI ({subject!r})"))
5052
else:
5153
findings.append(Finding("TR-ENV-003", Status.FAIL, f"subject must be a SPIFFE URI (spiffe://) or DID URI (did:), got {subject!r}"))

src/trace_tests/modules/tr_sig.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,15 @@ def check(trace: dict[str, Any], record: dict[str, Any], fmt: str, level: int =
102102
jwk = trace.get("cnf", {}).get("jwk", {})
103103
kty = jwk.get("kty")
104104
crv = jwk.get("crv")
105+
x = jwk.get("x")
106+
107+
if "d" in jwk:
108+
findings.append(Finding(
109+
rule="TR-SIG-002",
110+
status=Status.FAIL,
111+
message="cnf.jwk must not contain private key material ('d' field present in JWK)",
112+
))
113+
return findings
105114

106115
if kty in _SUPPORTED_KTY:
107116
label = f"kty={kty!r}" + (f", crv={crv!r}" if crv else "")

0 commit comments

Comments
 (0)