@hawcx/oauth-client 5.1.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +479 -0
  2. package/README.md +75 -10
  3. package/dist/client-assertion.d.ts.map +1 -1
  4. package/dist/client-assertion.js +6 -2
  5. package/dist/client-assertion.js.map +1 -1
  6. package/dist/delegation/exceptions.d.ts +34 -0
  7. package/dist/delegation/exceptions.d.ts.map +1 -1
  8. package/dist/delegation/exceptions.js +39 -1
  9. package/dist/delegation/exceptions.js.map +1 -1
  10. package/dist/delegation/hawcx.d.ts +6 -2
  11. package/dist/delegation/hawcx.d.ts.map +1 -1
  12. package/dist/delegation/hawcx.js.map +1 -1
  13. package/dist/delegation/index.d.ts +2 -1
  14. package/dist/delegation/index.d.ts.map +1 -1
  15. package/dist/delegation/index.js +3 -1
  16. package/dist/delegation/index.js.map +1 -1
  17. package/dist/delegation/transport.d.ts +6 -2
  18. package/dist/delegation/transport.d.ts.map +1 -1
  19. package/dist/delegation/transport.js +9 -2
  20. package/dist/delegation/transport.js.map +1 -1
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.js +1 -1
  23. package/dist/internal/url.d.ts +66 -0
  24. package/dist/internal/url.d.ts.map +1 -0
  25. package/dist/internal/url.js +155 -0
  26. package/dist/internal/url.js.map +1 -0
  27. package/dist/management/jwt_transport.d.ts +150 -0
  28. package/dist/management/jwt_transport.d.ts.map +1 -0
  29. package/dist/management/jwt_transport.js +245 -0
  30. package/dist/management/jwt_transport.js.map +1 -0
  31. package/dist/management/response_signature.d.ts +65 -0
  32. package/dist/management/response_signature.d.ts.map +1 -0
  33. package/dist/management/response_signature.js +170 -0
  34. package/dist/management/response_signature.js.map +1 -0
  35. package/dist/oauth.d.ts +1 -1
  36. package/dist/oauth.d.ts.map +1 -1
  37. package/dist/oauth.js +35 -24
  38. package/dist/oauth.js.map +1 -1
  39. package/dist/stepup/client.d.ts +72 -2
  40. package/dist/stepup/client.d.ts.map +1 -1
  41. package/dist/stepup/client.js +69 -0
  42. package/dist/stepup/client.js.map +1 -1
  43. package/package.json +2 -1
package/CHANGELOG.md ADDED
@@ -0,0 +1,479 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [6.0.0] - 2026-10-10
11
+
12
+ First public release since 5.2.0. **Major version** because of the BREAKING
13
+ entries below, which change behaviour for configurations that 5.2.0 accepted.
14
+ It contains everything from the internal release candidates 6.0.0-rc.1 and
15
+ 6.0.0-rc.2, plus one fix to `ClientAssertionSigner` made after rc.2.
16
+
17
+ ### Breaking — action needed when upgrading from 5.2.0
18
+
19
+ - **Management API response signatures are verified by default
20
+ (TOB-HSDK-11).** `JwtBearerTransport` and `StepUpClient.withPrivateKeyJwt`
21
+ now verify `X-Response-Signature` on every successful response. This
22
+ reverses the 5.2.0 note that callers "may" verify the header themselves.
23
+ The SDK checks the following:
24
+ - the JWS uses ES256, ES384 or ES512 and verifies against
25
+ `${issuer}/.well-known/jwks.json`;
26
+ - `iat` is within `clockSkewSeconds` (default 300);
27
+ - `body_sha256` matches the exact response bytes;
28
+ - the token carries no `aud`, `sub` or `nonce`.
29
+
30
+ Responses with status 400 and above are not verified. hx_auth signs every
31
+ jwt-mode 2xx, so production traffic is unaffected. **Action needed** if any
32
+ of these apply:
33
+ - A gateway, CDN or proxy strips response headers. Every call fails with
34
+ `ResponseSignatureInvalidError`; let `X-Response-Signature` through.
35
+ - Mocks, stubs or contract-test harnesses built against 5.2.0 return
36
+ unsigned 2xx responses. Sign the responses, or disable verification in the
37
+ test harness.
38
+ - `baseUrl` is not the OP host, such as an internal service URL or local dev
39
+ with separate ports. The JWKS is fetched from `baseUrl` by default, so set
40
+ `issuer`.
41
+ - **`baseUrl` (and `issuer`) values that used to be accepted now throw at
42
+ construction (TOB-HSDK-13).** The affected classes are `JwtBearerTransport`
43
+ and `StepUpClient.withPrivateKeyJwt` (`DelegationRequestError`),
44
+ `DelegationTransport` and the `DelegationClient`/`StepUpClient` ECIES
45
+ factories (`DelegationRequestError`), legacy `HawcxOAuth`
46
+ (`HawcxOAuthError`), and `HawcxOAuth.fromIssuer` (`DiscoveryError`):
47
+ - **Plain `http:` on a non-loopback host.** Examples:
48
+ `http://hawcx-api:8080` (docker-compose service name),
49
+ `http://0.0.0.0:8080`, `http://host.docker.internal:8080`, and in-cluster
50
+ service URLs behind a TLS-terminating gateway. Only `localhost`,
51
+ `127.0.0.1` and `[::1]` may use `http:`. **Action needed:** use `https:`,
52
+ or point the SDK at a loopback address.
53
+ - **Userinfo, query or fragment in the base.** For example
54
+ `https://user:pw@api.hawcx.com`, `https://api.hawcx.com?tenant=x` or
55
+ `https://api.hawcx.com#x`. **Action needed:** remove them.
56
+ - **The signed JWT `aud` string changes for non-canonical base spellings
57
+ (TOB-HSDK-13).** Host case and default ports are now normalised, so
58
+ `baseUrl: 'https://API.Hawcx.com:443'` produces
59
+ `aud = https://api.hawcx.com/v1/...`, where 5.2.0 produced
60
+ `https://API.Hawcx.com:443/v1/...`. The new value is the one `fetch`
61
+ actually sends. **Action needed** only if a server compares `aud` by exact
62
+ string against a configured non-canonical value: update that value, or use
63
+ a canonical `baseUrl`. Canonical bases (lower-case host, no default port,
64
+ with or without a trailing slash or a path prefix) produce byte-identical
65
+ URLs and `aud`.
66
+
67
+ ### Added
68
+
69
+ - New options on `JwtBearerTransport` and `StepUpClient.withPrivateKeyJwt`:
70
+ `issuer` (defaults to `baseUrl`), `verifyResponseSignature` (defaults to
71
+ `true`) and `clockSkewSeconds`. `verifyResponseSignature: false` is an
72
+ **emergency escape hatch** that restores the 5.2.0 behaviour and emits a
73
+ one-time process warning. `withPrivateKeyJwt` now also passes
74
+ `clockSkewSeconds` through to the transport.
75
+ - New error classes, both subclasses of `DelegationResponseError`, exported
76
+ with a stable `code`:
77
+ - `ResponseSignatureInvalidError` (`response_signature_invalid`).
78
+ - `ResponseSignatureUnavailableError` (`response_signature_unavailable`).
79
+ It means the signing keys could not be fetched, and **the request may
80
+ already have been applied** server-side.
81
+
82
+ ### Changed
83
+
84
+ - Every security-relevant URL is now parsed and joined with the WHATWG `URL`
85
+ API rather than by string concatenation (TOB-HSDK-13). This covers
86
+ `JwtBearerTransport` and `DelegationTransport` (`baseUrl` + endpoint),
87
+ legacy `new HawcxOAuth({ baseUrl })` (`/oauth2/token` and `/keys`), and the
88
+ `fromIssuer` issuer and discovery URL. Each joined URL must keep the base's
89
+ origin and stay under the base path prefix, or the SDK throws (fail
90
+ closed). An endpoint must be a relative path that starts with a single
91
+ `/`. It may not contain `//`, a backslash, whitespace or control
92
+ characters, a fragment, or a percent-encoded `/`, `.` or `\` (`%2f`,
93
+ `%2e`, `%5c`, any case) in its path.
94
+ - Discovered `token_endpoint` and `jwks_uri` values carrying userinfo are now
95
+ rejected (`DiscoveryError`).
96
+ - The `clearCache()` deprecation warning now says it will be removed in a
97
+ future major version rather than in 6.0.0. It is still deprecated (use
98
+ `refreshJwks()`) and still present in 6.0.0.
99
+
100
+ ### Fixed
101
+
102
+ - **Discovery mode now sends `client_id` on the public-client (PKCE) token
103
+ exchange.** Previously `exchangeCode()` added `client_id` to the token form
104
+ only when a `private_key_jwt` signer was set; a public PKCE exchange sent
105
+ only the `X-Config-Id` header. The OP then fell back to the project's
106
+ default client (`token.legacy_config_id_fallback`) and stamped the id_token
107
+ `aud` with that client's id, so on a project with more than one public OIDC
108
+ client, an app using a non-default client failed verification with
109
+ "Unexpected JWT audience". `exchangeCode()` now always sends the configured
110
+ `clientId` as `client_id` in discovery mode (RFC 6749 §4.1.3), for public
111
+ and `private_key_jwt` clients alike; the OP resolves that specific client
112
+ and stamps `aud` with it. `X-Config-Id` is still sent.
113
+ - Single-client projects are unaffected: their `clientId` is the default
114
+ client, so the resolved client and `aud` are the same as before.
115
+ - Legacy mode (`new HawcxOAuth({ configId, baseUrl })`) has no `clientId`
116
+ and is unchanged: it sends no `client_id`.
117
+ - `ClientAssertionSigner.sign()` now reads the clock once for `iat` and `exp`.
118
+ Two separate reads could straddle a second boundary and make the assertion
119
+ one second longer than its lifetime; at `withLifetimeSeconds(120)` that
120
+ exceeds the OP's 120s cap and the token exchange is rejected.
121
+
122
+ ## [6.0.0-rc.2] - 2026-10-10
123
+
124
+ > **Release candidate, internal only.** Published to AWS CodeArtifact
125
+ > (`npm-internal`), not public npm; the release workflow refuses to publish a
126
+ > prerelease publicly. Contains everything in 6.0.0-rc.1 plus the fix below.
127
+ > To install, point the `@hawcx` scope at CodeArtifact
128
+ > (`aws codeartifact login --tool npm --domain hawcx --repository npm-internal --namespace @hawcx`)
129
+ > and run `npm install @hawcx/oauth-client@6.0.0-rc.2`.
130
+
131
+ ### Fixed
132
+
133
+ - **Discovery mode now sends `client_id` on the public-client (PKCE) token
134
+ exchange.** Previously `exchangeCode()` added `client_id` to the token form
135
+ only when a `private_key_jwt` signer was set; a public PKCE exchange sent
136
+ only the `X-Config-Id` header. The OP then fell back to the project's
137
+ default client (`token.legacy_config_id_fallback`) and stamped the id_token
138
+ `aud` with that client's id, so on a project with more than one public OIDC
139
+ client, an app using a non-default client failed verification with
140
+ "Unexpected JWT audience". `exchangeCode()` now always sends the configured
141
+ `clientId` as `client_id` in discovery mode (RFC 6749 §4.1.3), for public
142
+ and `private_key_jwt` clients alike; the OP resolves that specific client
143
+ and stamps `aud` with it. `X-Config-Id` is still sent.
144
+ - Single-client projects are unaffected: their `clientId` is the default
145
+ client, so the resolved client and `aud` are the same as before.
146
+ - Legacy mode (`new HawcxOAuth({ configId, baseUrl })`) has no `clientId`
147
+ and is unchanged: it sends no `client_id`.
148
+
149
+ ## [6.0.0-rc.1] - 2026-10-07
150
+
151
+ > **Release candidate, internal only.** Published to AWS CodeArtifact
152
+ > (`npm-internal`), not public npm; the release workflow refuses to publish a
153
+ > prerelease publicly. **Major version** because of the BREAKING entries below,
154
+ > which change behaviour for configurations that 5.2.0 accepted. To install,
155
+ > point the `@hawcx` scope at CodeArtifact
156
+ > (`aws codeartifact login --tool npm --domain hawcx --repository npm-internal --namespace @hawcx`)
157
+ > and run `npm install @hawcx/oauth-client@6.0.0-rc.1`.
158
+
159
+ ### Security — management API response signatures are verified by default (TOB-HSDK-11)
160
+
161
+ - **BREAKING — `JwtBearerTransport` and `StepUpClient.withPrivateKeyJwt` now
162
+ verify `X-Response-Signature` on every successful response, and this is on
163
+ by default.** This reverses the 5.2.0 note that callers "may" verify the
164
+ header themselves. The SDK checks the following:
165
+ - the JWS uses ES256, ES384 or ES512 and verifies against
166
+ `${issuer}/.well-known/jwks.json`;
167
+ - `iat` is within `clockSkewSeconds` (default 300);
168
+ - `body_sha256` matches the exact response bytes;
169
+ - the token carries no `aud`, `sub` or `nonce`.
170
+
171
+ Responses with status 400 and above are not verified. hx_auth signs every
172
+ jwt-mode 2xx, so production traffic is unaffected. The following will
173
+ **break**:
174
+ - A gateway, CDN or proxy that strips response headers. Every call fails
175
+ with `ResponseSignatureInvalidError`.
176
+ - Customer mocks, stubs and contract-test harnesses built against 5.2.0 that
177
+ return unsigned 2xx responses. Sign the responses, or disable verification
178
+ in the test harness.
179
+ - A `baseUrl` that is not the OP host, such as an internal service URL or
180
+ local dev with separate ports. The JWKS is fetched from `baseUrl` by
181
+ default, so set `issuer`.
182
+ - New options on both: `issuer` (defaults to `baseUrl`),
183
+ `verifyResponseSignature` (defaults to `true`) and `clockSkewSeconds`.
184
+ `verifyResponseSignature: false` is an **emergency escape hatch** that
185
+ restores the 5.2.0 behaviour and emits a one-time process warning.
186
+ `withPrivateKeyJwt` now also passes `clockSkewSeconds` through to the
187
+ transport.
188
+ - New error classes, both subclasses of `DelegationResponseError`, exported
189
+ with a stable `code`:
190
+ - `ResponseSignatureInvalidError` (`response_signature_invalid`).
191
+ - `ResponseSignatureUnavailableError` (`response_signature_unavailable`).
192
+ It means the signing keys could not be fetched, and **the request may
193
+ already have been applied** server-side.
194
+
195
+ ### Security — structured URL validation and joining (TOB-HSDK-13)
196
+
197
+ - Every security-relevant URL is now parsed and joined with the WHATWG `URL`
198
+ API rather than by string concatenation. This covers `JwtBearerTransport`
199
+ and `DelegationTransport` (`baseUrl` + endpoint), legacy
200
+ `new HawcxOAuth({ baseUrl })` (`/oauth2/token` and `/keys`), and the
201
+ `fromIssuer` issuer and discovery URL. Each joined URL must keep the base's
202
+ origin and stay under the base path prefix, or the SDK throws (fail
203
+ closed). An endpoint must be a relative path that starts with a single
204
+ `/`. It may not contain `//`, a backslash, whitespace or control
205
+ characters, a fragment, or a percent-encoded `/`, `.` or `\` (`%2f`,
206
+ `%2e`, `%5c`, any case) in its path.
207
+ - **BREAKING — `baseUrl` (and `issuer`) values that used to be accepted now
208
+ throw at construction.** The affected classes are `JwtBearerTransport` and
209
+ `StepUpClient.withPrivateKeyJwt` (`DelegationRequestError`),
210
+ `DelegationTransport` and the `DelegationClient`/`StepUpClient`
211
+ ECIES factories (`DelegationRequestError`), legacy `HawcxOAuth`
212
+ (`HawcxOAuthError`), and `HawcxOAuth.fromIssuer` (`DiscoveryError`):
213
+ - **Plain `http:` on a non-loopback host.** Examples:
214
+ `http://hawcx-api:8080` (docker-compose service name),
215
+ `http://0.0.0.0:8080`, `http://host.docker.internal:8080`, and in-cluster
216
+ service URLs behind a TLS-terminating gateway. Only `localhost`,
217
+ `127.0.0.1` and `[::1]` may use `http:`. Use `https:`, or point the SDK
218
+ at a loopback address.
219
+ - **Userinfo, query or fragment in the base.** For example
220
+ `https://user:pw@api.hawcx.com`, `https://api.hawcx.com?tenant=x` or
221
+ `https://api.hawcx.com#x`.
222
+ - **BREAKING — the signed JWT `aud` string changes for non-canonical base
223
+ spellings.** Host case and default ports are now normalised, so
224
+ `baseUrl: 'https://API.Hawcx.com:443'` produces
225
+ `aud = https://api.hawcx.com/v1/...`, where 5.2.0 produced
226
+ `https://API.Hawcx.com:443/v1/...`. The new value is the one `fetch`
227
+ actually sends. A server that compares `aud` by exact string against a
228
+ configured non-canonical value will reject the new form. Canonical bases
229
+ (lower-case host, no default port, with or without a trailing slash or a
230
+ path prefix) produce byte-identical URLs and `aud`.
231
+ - Discovered `token_endpoint` and `jwks_uri` values carrying userinfo are now
232
+ rejected (`DiscoveryError`).
233
+
234
+ ## [5.2.0] - 2026-06-26
235
+
236
+ ### Added — Management API authentication via `private_key_jwt` (Path A)
237
+
238
+ - **`StepUpClient.withPrivateKeyJwt(...)`** — authenticate `/v1/management/*`
239
+ (step-up, MFA enforcement, phone-number changes) with a per-request EdDSA
240
+ Bearer JWT: `iss` = `sub` = `clientId`, `aud` = the full endpoint URL, ~60s
241
+ `exp`, random `jti`, and a `body_sha256` claim binding the JWT to the exact
242
+ request body bytes. Reuses the same Ed25519 OIDC `private_key_jwt` signing key
243
+ already registered in the admin console — one key, standards-based (RFC 7523),
244
+ no ECIES credential blob required. Tenant routing uses the `X-Config-Id`
245
+ header. Options include `timeoutSeconds` (default 15) and `jwtTtlSeconds`
246
+ (default 60).
247
+ - **`JwtBearerTransport`** — the transport backing the Path A client. Responses
248
+ carry an `X-Response-Signature` (ES256) which callers **may** verify against
249
+ the OIDC JWKS they already trust (optional, customer-side per the Path A spec).
250
+
251
+ ### Changed
252
+
253
+ - The ECIES factories **`StepUpClient.fromSecretKey(...)` / `fromKeys(...)`**
254
+ (the proprietary `hwx_sk_v1_…` blob) are now **deprecated** — they emit a
255
+ one-time `DeprecationWarning` but remain fully functional and will only be
256
+ removed in a future major version.
257
+
258
+ ### Migration (ECIES → `private_key_jwt`)
259
+
260
+ Existing ECIES integrations keep working unchanged; adopting `private_key_jwt`
261
+ is opt-in (spec §10.3):
262
+
263
+ 1. Register your Ed25519 `private_key_jwt` public key in the Admin Console
264
+ (OAuth tab → **Client authentication**) — the same key used for OIDC login.
265
+ 2. Switch the project's Management API auth to **Migrating** (accepts both
266
+ `ecies` and `jwt`) so existing and new callers coexist during rollout.
267
+ 3. Replace `StepUpClient.fromSecretKey(...)` / `fromKeys(...)` with
268
+ `StepUpClient.withPrivateKeyJwt({ baseUrl, configId, clientId, oidcSigningKey, kid })`.
269
+ 4. Once every caller uses `private_key_jwt`, move the project to **Signed
270
+ tokens** (`jwt` only). ECIES EOL date: TBA (removed no earlier than the next
271
+ major version).
272
+
273
+ ### Hardening
274
+
275
+ - `JwtBearerTransport` now bounds every request with a timeout (`timeoutSeconds`,
276
+ default 15) via an `AbortController`, so a connected-but-silent server can no
277
+ longer hang the call or exhaust connection pools. Mirrors the ECIES
278
+ `DelegationTransport`.
279
+ - The HTTP status is now checked **before** parsing the response body, so a
280
+ non-JSON error body (e.g. a WAF/proxy HTML 403) surfaces its HTTP status as a
281
+ `DelegationRequestError` instead of being masked as a JSON parse failure.
282
+
283
+ ## [5.1.0] - 2026-06-13
284
+
285
+ > The `private_key_jwt` / `ClientAssertionSigner` surface is **experimental** (`@beta`)
286
+ > and may change before it is marked stable.
287
+
288
+ ### Cross-SDK consistency
289
+
290
+ - Added `HawcxError` as the canonical root exception (aligns with Java/Python);
291
+ `HawcxOAuthError` now extends it (back-compat — catch either).
292
+ - Added a shared **golden test vector** (`tests/fixtures/golden-assertion.json`,
293
+ byte-identical across the three SDKs) pinning the assertion header/claims/signature
294
+ for a fixed key.
295
+ - Added `refreshJwks()` as the canonical JWKS-cache reset (aligns with the Java
296
+ `refreshJwks()` / Python `refresh_jwks()` SDKs). `clearCache()` is now
297
+ **deprecated** (passthrough; one-time `console.warn`) and will be removed in 6.0.0.
298
+
299
+ ### Production-readiness hardening
300
+
301
+ - `ClientAssertionSigner` no longer memoizes a *rejected* key import — a transient/
302
+ structural import failure no longer permanently poisons the signer.
303
+ - `jti` now sourced from `node:crypto` `randomUUID` (explicit import; was the
304
+ `globalThis.crypto` global).
305
+ - `withClientAssertion` refuses to attach a signer when the OP's discovery doc
306
+ advertises `token_endpoint_auth_methods_supported` without `private_key_jwt`
307
+ (prevents a silent downgrade to public-client).
308
+ - `withClientAssertion` is now **immutable** — returns a *new* configured client
309
+ (the backing `clientAssertionSigner` field is `readonly`) rather than mutating
310
+ in place. Chained usage (`(await fromIssuer(...)).withClientAssertion(...)`) is
311
+ unaffected; callers relying on in-place mutation of the original must use the
312
+ return value.
313
+ - `ClientAssertionSigner` gains `ed25519FromPem(pkcs8Pem, kid)` and
314
+ `ed25519(keyObject, kid)` factories (parity with the Java SDK).
315
+ - Replaced the `expectedAudience ?? ''` dead-code fallback with a non-null assertion.
316
+
317
+ ### Added
318
+
319
+ - **`private_key_jwt` client authentication** (RFC 7523 / OIDC Core §9). New
320
+ `ClientAssertionSigner.ed25519FromJwk(...)` + `HawcxOAuth.withClientAssertion(signer)`
321
+ (discovery mode). When set, `exchangeCode` signs and attaches a `client_assertion`
322
+ (EdDSA/Ed25519 only) alongside PKCE; `aud` is the discovered `token_endpoint`.
323
+ Without a signer, the request is unchanged (public-client + PKCE).
324
+ - `exchangeCode` gains an optional 4th `expectedNonce` argument, threaded to verification.
325
+
326
+ ### Changed / hardened
327
+
328
+ - **https required** on the issuer, `token_endpoint`, and `jwks_uri` (loopback http
329
+ still allowed for local dev/tests) — an http issuer let an on-path attacker swap
330
+ the discovery document.
331
+ - **Nonce**: verification now refuses an id_token that carries a `nonce` when none
332
+ was supplied to verify against (OIDC Core §3.1.3.7), instead of silently skipping it.
333
+ - **`exp` and `iat` required** in discovery mode — a token with no `exp` (never-expiring)
334
+ or no `iat` (no issuance anchor) is rejected.
335
+ - **Structured error fields** on the `HawcxOAuthError` hierarchy: new
336
+ `HawcxOAuthErrorFields` carrying optional `error` / `errorDescription`. The
337
+ token-endpoint error path now populates these from the OAuth `error` /
338
+ `error_description` body so callers can dispatch on a stable code without parsing
339
+ the message string (the message string composition is unchanged for back-compat).
340
+ - JWKS fetch timeout pinned explicitly; token-exchange error bodies that aren't JSON
341
+ are preserved in the error message; negative `clockToleranceSeconds` rejected.
342
+
343
+ ## [5.0.0] - 2026-05-23
344
+
345
+ OIDC discovery support. The legacy `new HawcxOAuth({ configId, baseUrl })`
346
+ constructor is unchanged at the signature level — but verification gains a
347
+ default 10-second clock-tolerance window (see `clockToleranceSeconds`
348
+ below). Apps that depend on strict zero-skew validation should pass
349
+ `clockToleranceSeconds: 0`.
350
+
351
+ ### Added
352
+
353
+ #### OIDC discovery construction path
354
+
355
+ - `HawcxOAuth.fromIssuer({ issuer, configId, clientId })` — static async
356
+ factory that fetches `<issuer>/.well-known/openid-configuration` once at
357
+ startup (5s default timeout) and wires a verifier that enforces signature
358
+ + `iss` + `aud` + `exp` + `nbf` on every subsequent `verifyToken` call.
359
+ The legacy path verifies the signature only.
360
+
361
+ **`configId` vs `clientId`.** Hawcx separates the tenant routing key from
362
+ the audience claim, and the SDK forwards each to the right place:
363
+ - `configId` — sent as `X-Config-Id` on the token-exchange POST (opaque
364
+ tenant routing key)
365
+ - `clientId` — the value the tenant has configured (in the Hawcx admin
366
+ console) as the `aud` claim on issued id_tokens. The verifier matches
367
+ the token's `aud` against this exact string.
368
+
369
+ Passing the same value for both fails verification with
370
+ `Unexpected JWT audience` unless the tenant happens to configure them
371
+ identically.
372
+
373
+ - `HawcxOAuth.prototype.exchangeCode(code, codeVerifier, redirectUri?)` —
374
+ new optional third argument. If your authorization request registered a
375
+ `redirect_uri`, RFC 6749 §4.1.3 requires the token request to carry the
376
+ same value. Omit for flows that didn't include it.
377
+
378
+ - `HawcxOAuth.prototype.verifyToken(token, { nonce })` — new options object
379
+ with optional `nonce` field for callers who bind a nonce to the
380
+ authorization request. Has no effect in legacy mode.
381
+
382
+ - `HawcxOAuth.prototype.discoveryMetadata` — the resolved OIDC discovery
383
+ document. `null` on legacy clients; useful for diagnostics ("which
384
+ token endpoint did we resolve to?", "what signing algorithms?").
385
+
386
+ - `clockToleranceSeconds` option on both `HawcxOAuthConfig` (legacy) and
387
+ `HawcxOAuthIssuerConfig` (discovery) — tolerated clock skew in seconds
388
+ when verifying `exp` and `nbf`. Spec.md §3.3 mandates this knob with a
389
+ recommended default of 10 seconds, which the SDK now applies. Without
390
+ it, jose's default of 0 rejected tokens minted under normal NTP drift
391
+ between issuer and verifier — the root cause of the
392
+ `exchangeCodeTolerant` workaround in `hawcx_admin_console` pre-5.0.
393
+ Pass `clockToleranceSeconds: 0` to opt back into strict exact-time
394
+ validation; raise above 10 if drift on your hosts is wider than that.
395
+
396
+ - **Algorithm allowlist (spec.md §3.3) — discovery mode.** `fromIssuer`
397
+ now intersects the issuer's advertised
398
+ `id_token_signing_alg_values_supported` with a closed SDK allowlist
399
+ (`{RS256, ES256, ES384, ES512, EdDSA}`). If no advertised alg is in
400
+ the allowlist, `DiscoveryError` is thrown at construction time. The
401
+ intersection is then passed to `jose.jwtVerify`'s `algorithms` option
402
+ on every `verifyToken` call, so verify-time enforcement matches what
403
+ was resolved at construction — forecloses key-confusion /
404
+ alg-substitution where the JWKS happens to serve a key type matching
405
+ whatever the JWT header claims. Mirrors the Java SDK
406
+ (`JwtVerifier.DEFAULT_ALGORITHMS`). Legacy mode behavior is unchanged
407
+ (no closed allowlist, no `algorithms:` constraint — same as 4.x).
408
+
409
+ - `DiscoveryError` — new error class for discovery-resolution failures
410
+ (DNS / TLS / network failure, non-2xx response, malformed JSON, missing
411
+ required fields). Underlying cause is preserved as `err.cause`.
412
+
413
+ - New exported types: `HawcxOAuthIssuerConfig`, `DiscoveryMetadata`,
414
+ `VerifyTokenOptions`.
415
+
416
+ ### Changed
417
+
418
+ - `TokenVerificationError.message` now distinguishes audience / issuer
419
+ mismatches from generic signature failures by parsing jose's
420
+ `ERR_JWT_CLAIM_VALIDATION_FAILED` code. Code that pattern-matched on
421
+ the legacy "Invalid signature" message still sees it for signature
422
+ failures; new "Unexpected JWT audience" / "Unexpected JWT issuer"
423
+ messages are now used when those specific claims fail.
424
+
425
+ - `exchangeCode` now sets `grant_type=authorization_code` on the form body.
426
+ 4.x callers won't notice — the OAuth server already inferred the grant
427
+ type from the presence of `code`. Listed here for completeness.
428
+
429
+ ### Notes for upgraders
430
+
431
+ If you only construct via `new HawcxOAuth({ configId })`, nothing changes —
432
+ the legacy path is signature-only verification, same as 4.x. If you want
433
+ proper `aud`/`iss` enforcement, switch to `await HawcxOAuth.fromIssuer(...)`
434
+ and pass both `configId` and `clientId` from the admin console.
435
+
436
+ ## [0.2.0] - 2024-11-20
437
+
438
+ ### Breaking Changes
439
+ - **BREAKING**: `apiKey` parameter is now required in `exchangeCodeForClaims()` and `exchangeCodeForTokenAndClaims()`
440
+ - **BREAKING**: At least one of `publicKey` or `jwksUrl` must be provided for JWT verification
441
+
442
+ ### Added
443
+ - Validation to ensure `apiKey` is provided and non-empty
444
+ - Validation to ensure at least one of `publicKey` or `jwksUrl` is provided
445
+ - Clear error messages for missing required parameters
446
+ - Priority logic: `jwksUrl` takes precedence over `publicKey` when both are provided
447
+
448
+ ### Changed
449
+ - Updated all documentation and examples to use `jwksUrl` as the primary recommended method
450
+ - Updated demo application to include `apiKey` parameter
451
+ - Improved error messages for parameter validation
452
+
453
+ ### Fixed
454
+ - Ensures API key is always sent with OAuth token exchange requests
455
+ - Prevents authentication failures due to missing API key
456
+
457
+ ## [0.1.0] - 2024-01-XX
458
+
459
+ ### Added
460
+ - Initial release of Node.js/TypeScript OAuth client SDK
461
+ - OAuth authorization code exchange with PKCE support
462
+ - JWT verification with RS256, ES256/384/512, and EdDSA algorithms
463
+ - Comprehensive error handling with custom exception classes
464
+ - Hawcx delegation client for MFA setup and management
465
+ - ECIES (X25519 + AES-GCM) encryption for secure backend-to-backend communication
466
+ - Ed25519 and RSA-PSS signing support
467
+ - Full TypeScript type definitions
468
+ - Comprehensive documentation and examples
469
+ - Feature parity with Python SDK
470
+
471
+ ### Features
472
+ - 🔐 Secure JWT verification with configurable validation
473
+ - 🆕 Native PKCE (RFC 7636) support
474
+ - 🚀 Simple, async/await API
475
+ - 🎯 High-level Hawcx client with automatic encryption/signing
476
+ - 🛡️ Comprehensive error handling
477
+ - 📝 Full TypeScript support
478
+ - 🔧 Framework-agnostic (works with Express, Fastify, etc.)
479
+
package/README.md CHANGED
@@ -450,22 +450,65 @@ try {
450
450
 
451
451
  For step-up authentication flows (e.g., changing MFA method requires re-authentication).
452
452
 
453
- ### `StepUpClient`
453
+ ### `StepUpClient` (recommended: `withPrivateKeyJwt`)
454
+
455
+ `StepUpClient.withPrivateKeyJwt` is the recommended construction path. It reuses
456
+ the same Ed25519 `private_key_jwt` signing key already registered in the Hawcx admin
457
+ console for OIDC — one standards-based key, no separate credential blob required.
454
458
 
455
459
  ```typescript
456
460
  import { StepUpClient } from '@hawcx/oauth-client';
457
461
 
458
- const stepUp = StepUpClient.fromSecretKey({
462
+ const privateJwk = JSON.parse(process.env.HAWCX_PRIVATE_JWK!); // OKP/Ed25519, with kid
463
+
464
+ const stepUp = StepUpClient.withPrivateKeyJwt({
459
465
  baseUrl: 'https://api.hawcx.com',
460
- secretKey: process.env.HAWCX_SECRET_KEY!,
461
- relyingParty: 'your-app.com', // Required
462
- apiKey: 'optional-api-key', // Optional
463
- apiPrefix: '/v1', // Optional (default: '/v1')
464
- timeoutSeconds: 15, // Optional
465
- clockSkewSeconds: 300, // Optional
466
+ configId: process.env.HAWCX_CONFIG_ID!, // X-Config-Id tenant routing
467
+ clientId: process.env.HAWCX_CLIENT_ID!, // iss/sub in per-request JWT
468
+ oidcSigningKey: privateJwk, // same key as ClientAssertionSigner
469
+ kid: privateJwk.kid,
470
+ relyingParty: 'your-app.com', // Optional
471
+ apiKey: 'optional-api-key', // Optional
472
+ apiPrefix: '/v1', // Optional (default: '/v1')
466
473
  });
467
474
  ```
468
475
 
476
+ The signing key must be Ed25519 (`kty: 'OKP', crv: 'Ed25519'`). It accepts a JWK
477
+ object, a PKCS#8 PEM string, or a pre-imported jose `KeyLike`.
478
+
479
+ Each request is signed with a short-lived per-request EdDSA JWT whose `aud` is the
480
+ full request URL and whose `body_sha256` claim covers the exact bytes sent.
481
+
482
+ Every successful response is authenticated too. The SDK verifies the
483
+ `X-Response-Signature` JWS (ES256/ES384/ES512) against
484
+ `${issuer}/.well-known/jwks.json`. It also checks that the JWS `iat` is within
485
+ `clockSkewSeconds` (default 300) and that its `body_sha256` matches the exact
486
+ response bytes. `issuer` defaults to `baseUrl`, because the management API and
487
+ the OP share a host in every Hawcx environment. Set `issuer` explicitly if they
488
+ differ, for example in local development.
489
+
490
+ > **Scope:** by default the JWKS comes from the **same origin as the API**.
491
+ > Verification therefore protects against tampering *between* that origin and
492
+ > you: caches, proxies and gateways, or a compromised downstream service. It
493
+ > does **not** protect against a compromised origin. If you need that, pin
494
+ > `issuer` to a separately trusted host.
495
+
496
+ Failures throw one of two subclasses of `DelegationResponseError`, each with a
497
+ stable `code`:
498
+
499
+ - `ResponseSignatureInvalidError` (`code: 'response_signature_invalid'`): the
500
+ header is missing or empty, or the signature does not verify. Treat the
501
+ response as untrusted.
502
+ - `ResponseSignatureUnavailableError` (`code: 'response_signature_unavailable'`):
503
+ the signing keys could not be obtained. The JWKS fetch failed, timed out or
504
+ returned something unusable, or a newly rotated `kid` arrived while refetching
505
+ was cooling down. **The server has already processed the request**, so a
506
+ non-idempotent write such as `consumeReceipt` may have been applied. Reconcile
507
+ state rather than retrying blindly.
508
+
509
+ `verifyResponseSignature: false` turns verification off. It is an emergency
510
+ escape hatch only, and it logs a one-time process warning.
511
+
469
512
  ### Methods
470
513
 
471
514
  #### `stepUp.startToken(options): Promise<StepUpStartTokenResponse>`
@@ -512,6 +555,23 @@ interface StepUpConsumeResponse {
512
555
  }
513
556
  ```
514
557
 
558
+ ### Legacy (deprecated): `fromSecretKey`
559
+
560
+ `StepUpClient.fromSecretKey` and `StepUpClient.fromKeys` are deprecated since 5.2.0
561
+ and will be removed in a future major version. They use a proprietary ECIES credential
562
+ format. Migrate to `withPrivateKeyJwt`.
563
+
564
+ ```typescript
565
+ // DEPRECATED — migrate to withPrivateKeyJwt above
566
+ import { StepUpClient } from '@hawcx/oauth-client';
567
+
568
+ const stepUp = StepUpClient.fromSecretKey({
569
+ baseUrl: 'https://api.hawcx.com',
570
+ secretKey: process.env.HAWCX_SECRET_KEY!, // hwx_sk_v1_… blob
571
+ relyingParty: 'your-app.com',
572
+ });
573
+ ```
574
+
515
575
  ---
516
576
 
517
577
  ## Examples
@@ -595,9 +655,14 @@ async function revokeAllDevices(userId: string) {
595
655
  ```typescript
596
656
  import { StepUpClient, DelegationClient, MfaMethod } from '@hawcx/oauth-client';
597
657
 
598
- const stepUp = StepUpClient.fromSecretKey({
658
+ const privateJwk = JSON.parse(process.env.HAWCX_PRIVATE_JWK!);
659
+
660
+ const stepUp = StepUpClient.withPrivateKeyJwt({
599
661
  baseUrl: process.env.HAWCX_API_URL!,
600
- secretKey: process.env.HAWCX_SECRET_KEY!,
662
+ configId: process.env.HAWCX_CONFIG_ID!,
663
+ clientId: process.env.HAWCX_CLIENT_ID!,
664
+ oidcSigningKey: privateJwk,
665
+ kid: privateJwk.kid,
601
666
  relyingParty: 'myapp.com',
602
667
  });
603
668
 
@@ -1 +1 @@
1
- {"version":3,"file":"client-assertion.d.ts","sourceRoot":"","sources":["../src/client-assertion.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAmC,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AAKjE,qEAAqE;AACrE,eAAO,MAAM,qBAAqB,2DACwB,CAAC;AAK3D,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6B;IACzD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,iEAAiE;IACjE,OAAO,CAAC,UAAU,CAAC,CAAuB;IAE1C,OAAO;IAUP;;;;;OAKG;IACH,MAAM,CAAC,cAAc,CAAC,UAAU,EAAE,GAAG,GAAG,MAAM,GAAG,qBAAqB;IA0BtE;;;OAGG;IACH,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,qBAAqB;IAkB3E;;;OAGG;IACH,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,qBAAqB;IAazE;;;;OAIG;IACH,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB;IAK3D,OAAO,CAAC,SAAS;IAYjB;;;;;;OAMG;IACG,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAYhE"}
1
+ {"version":3,"file":"client-assertion.d.ts","sourceRoot":"","sources":["../src/client-assertion.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAmC,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AAKjE,qEAAqE;AACrE,eAAO,MAAM,qBAAqB,2DACwB,CAAC;AAK3D,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6B;IACzD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,iEAAiE;IACjE,OAAO,CAAC,UAAU,CAAC,CAAuB;IAE1C,OAAO;IAUP;;;;;OAKG;IACH,MAAM,CAAC,cAAc,CAAC,UAAU,EAAE,GAAG,GAAG,MAAM,GAAG,qBAAqB;IA0BtE;;;OAGG;IACH,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,qBAAqB;IAkB3E;;;OAGG;IACH,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,qBAAqB;IAazE;;;;OAIG;IACH,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB;IAK3D,OAAO,CAAC,SAAS;IAYjB;;;;;;OAMG;IACG,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAgBhE"}
@@ -119,13 +119,17 @@ class ClientAssertionSigner {
119
119
  */
120
120
  async sign(clientId, audience) {
121
121
  const key = await this.importKey();
122
+ // One clock read for both claims: separate reads can straddle a second
123
+ // boundary and make exp - iat one second longer than the lifetime, which at
124
+ // the 120s maximum exceeds the OP's cap.
125
+ const now = Math.floor(Date.now() / 1000);
122
126
  return new jose_1.SignJWT({})
123
127
  .setProtectedHeader({ alg: 'EdDSA', typ: 'JWT', kid: this.kid })
124
128
  .setIssuer(clientId)
125
129
  .setSubject(clientId)
126
130
  .setAudience(audience)
127
- .setIssuedAt()
128
- .setExpirationTime(`${this.lifetimeSeconds}s`)
131
+ .setIssuedAt(now)
132
+ .setExpirationTime(now + this.lifetimeSeconds)
129
133
  .setJti((0, node_crypto_1.randomUUID)())
130
134
  .sign(key);
131
135
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client-assertion.js","sourceRoot":"","sources":["../src/client-assertion.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client-assertion.js","sourceRoot":"","sources":["../src/client-assertion.ts"],"names":[],"mappings":"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"}