Files
ietf-wimse-ect/refimpl/IMPROVEMENTS.md
Christian Nennemann ba38569319 fix: update hash format validation to -01 spec (plain base64url, no prefix)
Go ValidateHashFormat was still validating the old -00 format
(algorithm:base64url with sha-256/sha-384/sha-512 prefix). Updated to
validate plain base64url without prefix per -01 spec and RFC 9449.
Python was already updated but uncommitted. Both refimpls now match.
2026-04-11 17:51:29 +02:00

76 lines
4.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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: plain base64url without algorithm prefix, per -01 spec and RFC 9449. 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**: ✅ **Done.** Both Go and Python validate plain base64url without algorithm prefix, consistent with -01 spec and RFC 9449.