Java SDK API Reference
Complete API reference for the Hawcx Java SDK
Java SDK API Reference
All public types live under com.hawcx. Add the dependency:
<dependency>
<groupId>com.hawcx</groupId>
<artifactId>hawcx-java-sdk</artifactId>
<version>0.2.0</version>
</dependency>HawcxOauthClient
The OAuth client. Thread-safe; construct once and reuse.
import com.hawcx.oauth.HawcxOauthClient;
import com.hawcx.oauth.HawcxOauthConfig;
HawcxOauthConfig config = new HawcxOauthConfig(System.getenv("HAWCX_BASE_URL"));
HawcxOauthClient client = new HawcxOauthClient(config);HawcxOauthConfig exposes two endpoint helpers:
config.tokenEndpoint()→<baseUrl>/oauth2/tokenconfig.keysEndpoint()→<baseUrl>/keys(use this as thejwksUrlforJwtVerifier.VerifyOptions)
exchangeCode(TokenRequest)
Exchange an authorization code for an id_token without verifying it. Useful when you only need the raw token. Most apps should use exchangeCodeForClaims instead.
TokenRequest req = new TokenRequest(configId, authCode, codeVerifier);
TokenResponse resp = client.exchangeCode(req);
String idToken = resp.getIdToken();
String tokenType = resp.getTokenType();
long expiresIn = resp.getExpiresIn();exchangeCodeForClaims(TokenRequest, VerifyOptions)
Exchange the code, verify the returned id_token, and return the claims. The recommended end-to-end entry point.
JsonObject claims = client.exchangeCodeForClaims(req, opts);
String userId = claims.get("sub").getAsString();exchangeCodeForTokenAndClaims(TokenRequest, VerifyOptions)
Same as above but also returns the raw TokenResponse, useful when you need the id_token itself (e.g. to set as a cookie):
HawcxOauthClient.TokenAndClaims result = client.exchangeCodeForTokenAndClaims(req, opts);
String idToken = result.tokenResponse().getIdToken();
JsonObject claims = result.claims();verifyJwt(String token, VerifyOptions)
Standalone JWT verification, useful when you already have a token (e.g. from a session cookie) and just want to validate it.
JsonObject claims = client.verifyJwt(idToken, opts);getKeys(TokenRequest)
Fetch the raw JWKS document for inspection. Most callers don't need this; JwtVerifier fetches and caches JWKS internally via jwksUrl.
KeysResponse keys = client.getKeys(req);
JsonObject jwks = keys.getJwks();TokenRequest
Value object describing a single token exchange.
// Without redirect URI:
new TokenRequest(configId, authCode, codeVerifier);
// With OAuth 2.0 redirect URI (required by some providers):
new TokenRequest(configId, authCode, codeVerifier,
"https://app.example.com/auth/callback");JwtVerifier.VerifyOptions
Builder-style options controlling JWT verification. Build one per audience/issuer pair and reuse.
import com.hawcx.oauth.JwtVerifier;
JwtVerifier.VerifyOptions opts = JwtVerifier.VerifyOptions.builder()
.jwksUrl(config.keysEndpoint()) // OR .publicKeyPem("-----BEGIN PUBLIC KEY-----...")
.audience(System.getenv("HAWCX_CONFIG_ID"))
.issuer(System.getenv("HAWCX_BASE_URL"))
.verifyExp(true) // default true
.leewaySeconds(10) // default 0; tolerate small clock skew
.algorithms(java.util.Set.of(JWSAlgorithm.RS256)) // default: RS256, ES256/384/512, EdDSA
.build();| Method | Default | Notes |
|---|---|---|
jwksUrl(String) | (none) | Either this or publicKeyPem must be set. JWKS is fetched once per TTL window (default 1h) and cached. |
publicKeyPem(String) | (none) | Static PEM key. Use for fixed-key setups or tests. |
audience(String) | not validated | Expected aud claim. Set this in production. |
issuer(String) | not validated | Expected iss claim. Set this in production. |
verifyExp(boolean) | true | Disable only for unit tests. |
leewaySeconds(long) | 0 | Tolerated clock skew, in seconds. |
algorithms(Set<JWSAlgorithm>) | RS256, ES256, ES384, ES512, EdDSA | Only tokens signed with one of these algorithms are accepted. |
JwksCache
In-memory TTL cache for JWKS documents. Defaulted automatically by HawcxOauthClient. Override only if you need a custom TTL or want to share a cache across clients:
import com.hawcx.oauth.JwksCache;
import com.hawcx.oauth.JwtVerifier;
JwksCache cache = new JwksCache(/* ttlSeconds */ 600);
JwtVerifier verifier = new JwtVerifier(cache);
HawcxOauthClient client = new HawcxOauthClient(config, verifier);Delegation Client
Optional: advanced flows only
The delegation client is only required for backend-driven MFA setup/verify, suggested-MFA policy, device management, and step-up authentication. Apps that only need OAuth code exchange can skip this section.
Backend-driven MFA setup, user management, and device management. Every request is automatically encrypted (ECIES X25519 + AES-GCM) and signed (Ed25519 / RSA-PSS). Construct once and reuse; thread-safe.
DelegationClient.fromSecretKey(baseUrl, secretKey, configId)
import com.hawcx.delegation.DelegationClient;
DelegationClient client = DelegationClient.fromSecretKey(
System.getenv("HAWCX_BASE_URL"),
System.getenv("HAWCX_SECRET_KEY"), // hwx_sk_v1_...
System.getenv("HAWCX_CONFIG_ID")
);Or with a raw KeyMaterial bundle:
DelegationClient client = DelegationClient.fromKeys(
baseUrl,
KeyMaterial.builder()
.spSigningKey(spEd25519PrivateKeyPem)
.spEncryptionKey(spX25519PrivateKeyPem)
.idpVerifyKey(idpEd25519PublicKeyPem)
.idpEncryptionKey(idpX25519PublicKeyPem)
.build(),
configId
);MFA
import com.google.gson.JsonObject;
import com.hawcx.delegation.MfaMethod;
// Initiate (Email / SMS / TOTP)
JsonObject init = client.mfa.initiate(
"[email protected]",
MfaMethod.SMS,
"+15551234567", // null for EMAIL/TOTP
null // optional target method when changing
);
String sessionId = init.get("session_id").getAsString();
// Verify the OTP and complete the change
client.mfa.verify("[email protected]", sessionId, "123456");Users
JsonObject creds = client.users.getCredentials("[email protected]");
// Suggested-MFA preference: "none", "always", or "risk_only"
client.users.setSuggestedMfa("[email protected]", "always");
JsonObject pref = client.users.getSuggestedMfa("[email protected]");Devices
JsonObject devices = client.devices.list("[email protected]");
client.devices.revoke("[email protected]", "device-h2index");
client.devices.unrevoke("[email protected]", "device-h2index");
client.devices.delete("[email protected]", "device-h2index");Generic request
For endpoints not covered by a typed namespace method:
JsonObject body = new JsonObject();
body.addProperty("userid", "[email protected]");
JsonObject response = client.request("/v1/management/users/phone", body);Exception Hierarchy
Every SDK error extends com.hawcx.HawcxException (which extends RuntimeException). Catch the root if you only want one handler:
HawcxException
├── HawcxOauthException : token exchange failures (network, 4xx/5xx, missing id_token)
├── JwtVerificationException : signature / claims validation failures
├── InvalidPublicKeyException : JWKS unreachable, no usable keys, malformed PEM
└── DelegationException : base for delegation errors
├── DelegationCryptoException : ECIES / signature operation failures
├── DelegationRequestException : HTTP failure; carries statusCode + responseBody
└── DelegationResponseException : response signature, timestamp, or decryption checks failedtry {
JsonObject claims = client.exchangeCodeForClaims(req, opts);
} catch (HawcxException e) {
log.error("Hawcx SDK call failed", e);
}