- Rename `par` to `pred` (predecessor) in types, serialization, tests - Remove `pol`, `pol_decision` from core payload; move to `ect_ext` - Remove `sub` from payload (not part of ECT spec) - Update `typ` from `wimse-exec+jwt` to `exec+jwt` (accept both) - Rename MaxParLength to MaxPredLength everywhere - Update testdata, demos, READMEs with migration table - All Go tests pass, all 56 Python tests pass (90% coverage)
4.0 KiB
Possible Improvements (Go & Python Refimpls)
Suggestions that could make the implementations more robust, spec-strict, or production-friendly. All items below have been implemented in both refimpls unless noted.
1. Spec alignment ✅
-
ext size/depth (Section 4.2.7)
Done. Both refimpls reject when serializedect_extexceeds 4096 bytes or JSON depth exceeds 5 (ValidateExt/validate_ext). Used in create and verify. -
jti / wid format
Done. Optional UUID (RFC 9562) validation:CreateOptions.ValidateUUIDs/VerifyOptions.ValidateUUIDs(Go),validate_uuids(Python). Helpers:ValidUUID/valid_uuid.
2. API and safety ✅
-
Payload mutation in Create
Done. Documented in both: Create may set Iat, Exp, Sub, Par when zero/nil. Go: comment onCreate(); Python: create works on a deep copy so the caller’s payload is not modified. -
Structured errors (Go)
Done. Sentinel errors inect/errors.go:ErrExpired,ErrReplay,ErrInvalidSignature(wrapped),ErrInvalidTyp,ErrPolPolDecisionPair, etc. Verify and create return these where applicable.
3. Production / operations ✅
-
Replay cache
Done. Documented: JTICache is in-memory; for multi-instance deployments a shared store (Redis, DB) is required. See refimpl README and go-lang/README “Replay cache (multi-instance)”. -
Observability
Done. Go:VerifyOptions.LogVerify func(jti string, err error)called after each verify. Python:VerifyOptions.on_verify_attempt(jti, err)callback.
4. Small cleanups ✅
-
Python Ledger docstring
Done. “Lookup by task id (jti)”. -
Python
verify
Done. Documented thatparmay be set to[]when missing;from_claimsalready supplies[], so mutation is defensive only. -
par length
Done. Go:CreateOptions.MaxParLength,VerifyOptions.MaxParLength,DAGConfig.MaxParLength(0 = no limit; default 100 in DAG). Python:CreateOptions.max_par_length,VerifyOptions.max_par_length,DAGConfig.max_par_length.
5. Nice-to-have ✅
-
inp_hash / out_hash format
Done. Optional check in create and verify:algorithm:base64urlwith algorithm in allowlist (sha-256, sha-384, sha-512). Helpers:ValidateHashFormat/validate_hash_format. -
Constant-time comparison
Done. Go:crypto/subtle.ConstantTimeComparefortypin verify. Python:hmac.compare_digestfortyp.
Summary: All listed improvements are implemented. For production, also consider: key rotation, WIT integration, and metrics around verify/create latency and error kinds.
6. draft-01 migration (PARTIALLY IMPLEMENTED)
The refimpl was built against draft-nennemann-wimse-ect-00. The -01 draft introduced breaking changes:
- Rename
partopred: ✅ Done. Struct fields, JSON tags, serialization/deserialization, tests, testdata, READMEs updated in both Go and Python. - Remove
polandpol_decision: ✅ Done. Policy claims removed from core Payload. DAG policy checks now read fromect_ext. Tests and demos updated to use ext. - Remove
sub: ✅ Done. Removed from Payload struct (Go) and dataclass (Python). Create no longer defaults sub=iss. - Update
typdefault: ✅ Done.exec+jwtis now preferred;wimse-exec+jwtaccepted for backward compat. Verify checks both (constant-time). - Update
MaxParLengthnaming: ✅ Done. Renamed toMaxPredLength/max_pred_lengtheverywhere. - Add L1 support: The -01 draft introduces unsigned JSON ECTs (Level 1). The refimpl currently only supports L2 (signed JWS).
- Add L3 support: The -01 draft introduces audit ledger requirements for Level 3. The existing in-memory ledger needs hash chain and receipt support.
- Update hash format: The -01 draft specifies SHA-256 base64url without algorithm prefix (no
sha-256:prefix), consistent with RFC 9449.