Files
ietf-wimse-ect/refimpl/IMPROVEMENTS.md
Christian Nennemann 884d2dc836 feat: migrate refimpls from draft-00 to draft-01 claim names
- 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)
2026-04-03 10:55:58 +02:00

4.0 KiB
Raw Blame History

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 serialized ect_ext exceeds 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 on Create(); Python: create works on a deep copy so the callers payload is not modified.

  • Structured errors (Go)
    Done. Sentinel errors in ect/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 that par may be set to [] when missing; from_claims already 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:base64url with algorithm in allowlist (sha-256, sha-384, sha-512). Helpers: ValidateHashFormat / validate_hash_format.

  • Constant-time comparison
    Done. Go: crypto/subtle.ConstantTimeCompare for typ in verify. Python: hmac.compare_digest for typ.


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 par to pred: Done. Struct fields, JSON tags, serialization/deserialization, tests, testdata, READMEs updated in both Go and Python.
  • Remove pol and pol_decision: Done. Policy claims removed from core Payload. DAG policy checks now read from ect_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 typ default: Done. exec+jwt is now preferred; wimse-exec+jwt accepted for backward compat. Verify checks both (constant-time).
  • Update MaxParLength naming: Done. Renamed to MaxPredLength / max_pred_length everywhere.
  • 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.