JSON web tokens in OCaml
1# JWT and CWT Implementation TODO
2
3RFC 7519 (JWT) and RFC 8392 (CWT) compliance tracking for jsonwt.
4
5## Implementation Status
6
7### JSON Web Token (JWT) - RFC 7519
8- [x] Type definitions for all registered claims
9- [x] Type definitions for JOSE header parameters
10- [x] Type definitions for algorithms
11- [x] Base64url encoding/decoding
12- [x] Basic JWT structure parsing (3-part split)
13- [x] JSON parsing with jsont
14- [x] Signature creation and verification (HMAC, ECDSA, EdDSA)
15- [x] Claims validation
16- [x] JWK parsing and serialization
17- [x] Structured error types
18- [x] Comprehensive tests (30 tests passing)
19
20### CBOR Web Token (CWT) - RFC 8392
21- [x] Type definitions for COSE algorithms (HMAC, ECDSA, EdDSA)
22- [x] Type definitions for COSE keys (Symmetric, Ec2, Okp)
23- [x] Claims with integer keys (1=iss, 2=sub, 3=aud, 4=exp, 5=nbf, 6=iat, 7=cti)
24- [x] CBOR encoding via cbort library
25- [x] COSE_Mac0 structure (MACed CWT)
26- [x] COSE_Sign1 structure (Signed CWT)
27- [x] Signature creation and verification (HMAC, ECDSA, EdDSA)
28- [x] Claims validation (same as JWT)
29- [x] Structured error types
30- [x] Comprehensive tests (28 tests passing)
31
32### CBOR Codec - RFC 8949
33- [x] Low-level CBOR encoding primitives (Cbor_rw)
34- [x] Major type constants and encoding functions
35- [x] Integer encoding (positive and negative)
36- [x] Float encoding (IEEE 754 double precision)
37- [x] Text string and byte string encoding
38- [x] Array and map encoding
39- [x] Tag encoding
40- [x] Simple value encoding (false, true, null, undefined)
41- [x] Comprehensive tests with RFC 8949 Appendix A vectors (46 tests passing)
42
43---
44
45## Completed Phases
46
47### Phase 0: Error Types and Core Infrastructure - DONE
48
49- [x] Structured error type with all RFC-compliant variants
50- [x] `pp_error` and `error_to_string` functions
51- [x] StringOrURI validation (validates URIs per RFC 3986)
52
53### Phase 1: JSON Parsing with jsont - DONE
54
55- [x] Header JSON codec (`Header.of_json`, `Header.to_json`)
56- [x] Claims JSON codec with strict mode for duplicate detection
57- [x] JWK JSON codec for all key types (Oct, RSA, EC, OKP)
58
59### Phase 2: Signature Operations - PARTIALLY DONE
60
61- [x] **HMAC Signatures** (HS256, HS384, HS512) - using digestif
62- [x] **ECDSA Signatures** (ES256, ES384, ES512) - using mirage-crypto-ec
63- [x] **EdDSA Signatures** (Ed25519) - using mirage-crypto-ec
64- [x] **Unsecured JWT** ("none") - with explicit `~allow_none:true` opt-in
65- [x] **Nested JWT Support** - `parse_nested` with max_depth protection
66- [ ] **RSA Signatures** (RS256, RS384, RS512) - STUBBED, needs JWK-to-RSA key parsing
67
68### Phase 3: Claims Validation - DONE
69
70- [x] Time-based claims (exp, nbf) with leeway support
71- [x] Issuer validation (iss)
72- [x] Audience validation (aud)
73- [x] `is_expired` helper function
74- [x] `time_to_expiry` helper function
75
76### Phase 4: Full JWT Creation Flow - DONE
77
78- [x] `create` function for signing JWTs
79- [x] Algorithm/key type validation
80
81### Phase 5: Tests - DONE (104 tests passing)
82
83#### JWT Tests (30 tests)
84
85**RFC Test Vectors:**
86- [x] RFC 7519 Section 3.1 HS256 JWT
87- [x] RFC 7519 Section 6.1 Unsecured JWT
88
89**Algorithm Coverage:**
90- [x] HS256 sign/verify
91- [x] HS384 sign/verify
92- [x] HS512 sign/verify
93- [ ] RS256 sign/verify (stubbed)
94- [ ] RS384 sign/verify (stubbed)
95- [ ] RS512 sign/verify (stubbed)
96- [x] ES256 sign/verify
97- [x] ES384 sign/verify
98- [x] ES512 sign/verify
99- [x] EdDSA sign/verify
100- [x] none (unsecured) with opt-in
101
102**Validation Tests:**
103- [x] Expired token rejection
104- [x] Not-yet-valid token rejection
105- [x] Issuer mismatch rejection
106- [x] Audience mismatch rejection
107- [x] Leeway handling
108
109**Error Cases:**
110- [x] Invalid base64url
111- [x] Invalid JSON
112- [x] Wrong number of parts
113- [x] Signature mismatch
114- [x] Algorithm not in allowed list
115- [x] Unsecured JWT without allow_none
116
117#### CWT Tests (28 tests)
118
119**RFC Test Vectors:**
120- [x] RFC 8392 Appendix A claims timestamps
121- [x] RFC 8392 example values (hex test vectors)
122
123**Algorithm Coverage:**
124- [x] HMAC_256_64 (alg=4)
125- [x] HMAC_256 (alg=5)
126- [x] HMAC_384 (alg=6)
127- [x] HMAC_512 (alg=7)
128- [x] ES256 (alg=-7)
129- [x] ES384 (alg=-35)
130- [x] ES512 (alg=-36)
131- [x] EdDSA (alg=-8)
132
133**COSE Key Tests:**
134- [x] Symmetric key creation
135- [x] Ed25519 key creation
136- [x] P-256 key creation
137- [x] Key ID (kid) support
138
139**Claims Tests:**
140- [x] Claims builder
141- [x] Timestamp claims (exp, nbf, iat)
142- [x] Single and multiple audience
143- [x] CWT ID (cti)
144- [x] CBOR serialization
145
146**Validation Tests:**
147- [x] Expired token rejection
148- [x] Not-yet-valid token rejection
149- [x] Issuer validation
150- [x] Audience validation
151- [x] Leeway handling
152
153#### CBOR Tests (46 tests)
154
155**RFC 8949 Appendix A Test Vectors:**
156- [x] Unsigned integers (0-1000000000000)
157- [x] Negative integers (-1 to -1000)
158- [x] Booleans and null
159- [x] Floats (1.0, 1.1, -4.1, 1.0e+300, Infinity, NaN)
160- [x] Text strings (empty, ASCII, UTF-8 with Unicode)
161- [x] Byte strings
162- [x] Arrays (empty, nested, 25 items)
163- [x] Maps (empty, int keys, string keys, nested)
164- [x] Tags (epoch timestamp)
165- [x] Constants (major types, simple values, additional info)
166
167---
168
169## Remaining Work
170
171### JWT: RSA Signatures (RS256, RS384, RS512)
172
173**Status:** Stubbed - returns `Key_type_mismatch "RSA signing/verification not yet implemented"`
174
175**Required:**
1761. Implement JWK-to-RSA key parsing for `n`, `e` (public) and `d`, `p`, `q`, `dp`, `dq`, `qi` (private) fields
1772. Use `mirage-crypto-pk` for RSASSA-PKCS1-v1_5 signatures
1783. Add tests with RFC test vectors
179
180### CWT: CBOR Decoding
181
182**Status:** Not implemented - current implementation only encodes CWTs
183
184**Required:**
1851. Add CBOR decoding functions to Cbor_rw module
1862. Implement `Cwt.parse` to decode CWT from CBOR bytes
1873. Add tests with RFC 8392 Appendix A encoded test vectors
188
189### CWT: COSE Key Encoding/Decoding
190
191**Status:** Keys are created in memory but not serialized
192
193**Required:**
1941. Add `Cose_key.to_cbor` and `Cose_key.of_cbor` functions
1952. Follow RFC 9052 Section 7 (COSE Key) format
1963. Add tests with RFC test vectors
197
198### CWT: CWT Tag Support
199
200**Status:** Partial - encodes COSE structures but not outer CWT tag
201
202**Required:**
2031. Add support for CWT tag (61) wrapping per RFC 8392 Section 2
2042. Add support for optional outer COSE tag per RFC 9052
205
206### Future Work (Not in Current Scope)
207
2081. **JWK Set (JWKS)**: RFC 7517 Section 5 support for multiple keys
209 - Useful for key rotation and fetching keys from JWKS endpoints
210 - Example: `/.well-known/jwks.json`
211 - Consider adding `Jwks.t` type and `Jwks.find_key : kid:string -> Jwks.t -> Jwk.t option`
212
2132. **JWE Support**: RFC 7516 JSON Web Encryption
214 - Required for encrypted JWTs (as opposed to signed JWTs)
215 - Lower priority unless needed for specific use cases
216
217---
218
219## Design Decisions (Implemented)
220
2211. **StringOrURI validation**: YES - Validates that `iss`/`sub` values containing ":" are valid URIs per RFC 3986.
222
2232. **Duplicate claims**: STRICT MODE - Rejects JWTs with duplicate claim names by default. `~strict:false` allows lenient parsing.
224
2253. **"none" algorithm**: REQUIRE OPT-IN - `~allow_none:bool` parameter to `verify` (default false). Unsecured JWTs rejected unless explicitly allowed.
226
2274. **Error types**: STRUCTURED - Proper error variant type for pattern matching and error handling.
228
2295. **Algorithm allowlist**: YES - `~allowed_algs` parameter to `verify`, defaulting to all algorithms (except none).
230
2316. **Clock source**: EXPLICIT - Always requires `~now:Ptime.t` parameter. No implicit system clock usage.
232
2337. **Nested JWTs**: YES - Support via `parse_nested` with `~max_depth` protection (default 2).
234
235---
236
237## File Summary
238
239| File | Lines | Description |
240|------|-------|-------------|
241| `lib/jsonwt.ml` | ~1010 | JWT implementation |
242| `lib/jsonwt.mli` | ~480 | JWT interface with RFC documentation |
243| `lib/cwt.ml` | ~760 | CWT implementation |
244| `lib/cwt.mli` | ~400 | CWT interface with RFC documentation |
245| `cbort/cbor_rw.ml` | ~200 | Low-level CBOR encoding primitives |
246| `cbort/cbor_rw.mli` | ~200 | CBOR encoding interface |
247| `cbort/cbort.ml` | ~300 | CBOR codec for jsont types |
248| `cbort/cbort.mli` | ~100 | CBOR codec interface |
249| `test/test_jsonwt.ml` | ~440 | 30 JWT tests |
250| `test/test_cwt.ml` | ~500 | 28 CWT tests |
251| `test/test_cbor.ml` | ~320 | 46 CBOR encoding tests |
252
253---
254
255## References
256
257### JWT (JSON Web Token)
258- [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519) - JSON Web Token (JWT)
259- [RFC 7515](https://datatracker.ietf.org/doc/html/rfc7515) - JSON Web Signature (JWS)
260- [RFC 7517](https://datatracker.ietf.org/doc/html/rfc7517) - JSON Web Key (JWK)
261- [RFC 7518](https://datatracker.ietf.org/doc/html/rfc7518) - JSON Web Algorithms (JWA)
262- [RFC 8037](https://datatracker.ietf.org/doc/html/rfc8037) - CFRG Elliptic Curve (EdDSA)
263
264### CWT (CBOR Web Token)
265- [RFC 8392](https://datatracker.ietf.org/doc/html/rfc8392) - CBOR Web Token (CWT)
266- [RFC 9052](https://datatracker.ietf.org/doc/html/rfc9052) - CBOR Object Signing and Encryption (COSE) Structures
267- [RFC 9053](https://datatracker.ietf.org/doc/html/rfc9053) - CBOR Object Signing and Encryption (COSE) Algorithms
268- [RFC 8949](https://datatracker.ietf.org/doc/html/rfc8949) - Concise Binary Object Representation (CBOR)