Changelog

What changed in each published Hawcx SDK release, and what you need to do about it.

Entries are keyed to versions that are actually published, and every API name below was checked against the published package rather than against source. If a release needs action on your side, it says so at the top of the entry.

Current versions

SDKPackageCurrent versionPublished
Web core@hawcx/core (npm)2.6.02026-08-21
Web React@hawcx/react (npm)2.6.02026-08-21
Node.js backend@hawcx/oauth-client (npm)5.2.02026-06-26
Python backendhawcx-oauth-client (PyPI)1.3.02026-06-26
Java backendcom.hawcx:hawcx-java-sdk (Maven Central)0.4.02026-06-26
iOShawcx_ios_sdk (Swift Package Manager)6.0.32026-04-13
Androidapi.hawcx:hawcx (Hawcx Maven repository)6.0.22026-04-07
React Native@hawcx/react-native-sdk (npm)1.1.52026-04-25
Flutterhawcx_flutter_sdk (pub.dev)1.0.52026-01-21

Web SDK

@hawcx/core 2.6.0 and @hawcx/react 2.6.0

Action needed: upgrade @hawcx/core and @hawcx/react to 2.6.0 together. Apart from that, the release is additive: everything the 2.4.x entry points exported is still exported, so existing 2.4.x code keeps working.

Adds the device-revocation surface:

  • getAuthNotice(state) returns the server-driven notice riding along with the current step, or null. It is exported from @hawcx/core.
  • useAuthFlags() gains notice and deviceRevoked. deviceRevoked is true when the notice code is unauthorized_device, meaning this device's access was revoked and completing the flow re-enrolls it.
  • client.logoutEverywhere(bearerToken) ends every active session for the user and resolves to { sessionsEnded }. No device is de-enrolled, so the next sign-in on a trusted device is still silent. useAuthActions() exposes it as logoutAllDevices.
  • AuthResult and the completed state gain an optional sessionToken, the hx_auth session JWT you pass to logoutEverywhere. It is present only when the server minted one.
  • client.resumeSession(session, identifier?) and client.getPkceVerifier() support flows that survive a page navigation.
  • AuthConfig gains an optional scope, the OIDC-standard space-delimited scope string your relying party wants to request (for example "openid profile email"). Leave it unset and the SDK omits scope from the wire request entirely, so the request shape is unchanged from a client that never set it.

Moving from 2.4.x

Three things to get right when you upgrade:

  1. Bump both packages in the same change. @hawcx/react 2.6.0 declares a dependency on @hawcx/core of ^2.4.0, which a lockfile pinned to core 2.4.1 already satisfies; npm will therefore leave core alone if you bump only @hawcx/react. That combination fails at runtime, because useAuthFlags imports getAuthNotice from @hawcx/core and useAuthActions calls client.logoutEverywhere(...), and core 2.4.1 has neither.
  2. If you render a sign-in form, handle the revoked-device notice. Reading it through getAuthNotice(state) narrows the state for you, because notice is declared only on the loading and step variants of AuthState; reading state.notice on an un-narrowed AuthState is a TypeScript error. In React, useAuthFlags().notice gives you the same value with no narrowing needed. Note that @hawcx/react does not re-export getAuthNotice, so import it from @hawcx/core if you want the function itself.
  3. If your flow redirects (OAuth, social sign-in), persist getPkceVerifier() before navigating, and hand the stashed value to your token exchange yourself. There is no API that puts it back: resumeSession() restores the session and identifier only, and getCompletion() reads the verifier off the client instance, so it comes back undefined on the resumed one. A resumed client cannot redeem the authorization code on its own.

If you see @hawcx/core 3.0.0 on npm

A 3.0.0 was published to npm and then deprecated. Its deprecation message reads use @hawcx/core@^2.6.0 instead. 2.6.0 is the latest tag and the version to install. Pin a ^2.6.0 range so an automated dependency bump does not pull 3.0.0 in.

Backend SDKs

@hawcx/oauth-client 5.2.0

Action needed: two things, neither urgent. Rename clearCache() to refreshJwks() if you call it, before 6.0.0 removes the old name. And if you build a StepUpClient from an ECIES secret key, start planning a move to private_key_jwt.

  • StepUpClient.withPrivateKeyJwt(...) authenticates management calls with a per-request EdDSA bearer JWT, reusing the Ed25519 key already registered for OIDC login. The JWT is bound to the exact request body through a body_sha256 claim.
  • StepUpClient.fromSecretKey(...) and StepUpClient.fromKeys(...), the ECIES hwx_sk_v1_ factories, are now deprecated. They emit a one-time deprecation warning, remain fully functional, and will be removed no earlier than the next major version.
  • From 5.1.0: refreshJwks() is the canonical JWKS-cache reset, aligning with the Java refreshJwks() and the Python refresh_jwks().
  • clearCache() is deprecated as of 5.1.0 and will be removed in 6.0.0. Its behaviour is identical to refreshJwks(); only the name changed.

hawcx-oauth-client 1.3.0 (Python)

Action needed: nothing breaks, but if you build a StepUpClient from an ECIES secret key, plan a move to private_key_jwt.

  • StepUpClient.with_private_key_jwt(...) is the recommended constructor, matching the Node.js 5.2.0 change above.
  • StepUpClient.from_secret_key(...) and StepUpClient.from_keys(...) still work but now raise a DeprecationWarning and will be removed in a future major version.

The step-up surface itself is unchanged: start_token, consume_receipt, and management_request.

hawcx-oauth-client 1.2.0 (Python)

Action needed: this one breaks imports. 1.2.0 replaced most of the 1.0.0 public surface rather than extending it, so plan the upgrade instead of running a blind pip install --upgrade. There was no 1.1.x, so 1.0.0 is the version you are coming from.

Gone from 1.0.0:

  • HawcxDelegationClient and MfaMethod, both imported from hawcx_oauth_client.delegation, plus the lower-level IdpDelegationClient. The /hc_auth/v5/* endpoints they called were removed from hx_auth. Use StepUpClient against the current /v1/management/* endpoints instead: start_token, consume_receipt, and management_request cover the same ground.
  • The bootstrap client. HawcxBootstrapClient, BootstrapToken, DPoPSession, and the BootstrapError, BootstrapChallengeError, BootstrapExchangeError and BootstrapSigningError exceptions all went with the hawcx_oauth_client.bootstrap package.
  • The loose OAuth helpers exchange_code_for_claims, exchange_code_for_token_and_claims, verify_jwt, require_oauth_claims, fetch_jwks and get_key_from_jwks. The HawcxOAuth client below replaces the whole group.
  • build_assertion_and_dpop and AssertionResult. The 1.2.0 wheel still contains an assertion.py, but it cannot be imported: it depends on a hawcx_oauth_client._crypto module that the wheel no longer ships, so importing it raises ModuleNotFoundError. Treat both symbols as gone. ClientAssertionSigner, exported from the package root, is the supported replacement from 1.2.0 onward.

What replaces the OAuth half:

  • HawcxOAuth.from_issuer(issuer, config_id, client_id) is the entry point for the OAuth relying-party client. It discovers the OAuth endpoints from <issuer>/.well-known/openid-configuration and wires a verifier that enforces the signature plus iss, aud, exp, and nbf on every verify.
  • Use from_issuer rather than calling HawcxOAuth(...) yourself. The constructor is keyword-only and expects a DiscoveryMetadata object you would have to build first, so from_issuer is the only supported way in.

com.hawcx:hawcx-java-sdk 0.4.0

Action needed: nothing breaks, but if you build a StepUpClient from an ECIES secret key, plan a move to private_key_jwt. This is the same deprecation as Node.js 5.2.0 and Python 1.3.0.

  • StepUpClient.withPrivateKeyJwt(...) authenticates management-API calls with a per-request EdDSA bearer JWT, the Java side of the same change as Node.js 5.2.0 and Python 1.3.0.
  • All four fromSecretKey and fromKeys overloads are now annotated @Deprecated. They still work; only the recommendation changed.
  • JwtBearerTransport is the new transport behind it. It sends the config ID under a single header, because HTTP header names are case-insensitive and setting both X-Config-Id and x-config-id appended a second value to the same header, which made gateways doing key-auth on that header reject the request with "Duplicate API key found".

Mobile SDKs

iOS 6.0.3, Android 6.0.2, React Native 1.1.5

The V6 generation adds an adaptive, server-driven flow: the server chooses the primary and MFA methods, and your app renders each step it is given.

Moving from V4/V5: V6 is additive rather than a forced cutover. The V6 releases ship a new adaptive surface (HawcxV1SDK on iOS, the com.hawcx.protocol.v1 classes reached through buildProtocolV1Sdk on Android) alongside the existing V4/V5 HawcxSDK APIs, so an app already in production can migrate screen by screen. The 5.x releases do not contain that adaptive surface at all, which is why V6 is a version bump rather than a flag. Both generations take a tenant base URL at initialization, so moving to V6 is not what unlocks pointing at a non-production tenant. See the iOS and Android guides.

React Native gained the V6 adaptive flow in 1.1.0; 1.1.5 is the current release.

Flutter 1.0.5

Flutter bridges to the v5-generation native SDK: the published package depends on api.hawcx:hawcx:5.1.4 on Android. The V6 adaptive flow is not yet available for Flutter.


Something here not matching what you see? Get support.

Last updated on