OIDC Reference

Endpoints, parameters, ID token and logout token claims, and OIDC client configuration fields for Hawcx SSO.

Reference for the Hawcx OpenID Connect provider. All endpoints are served from api.hawcx.com; the issuer is https://api.hawcx.com.

Discovery

EndpointPath
Discovery documentGET /.well-known/openid-configuration
JWKSGET /.well-known/jwks.json
UserInfoGET /userinfo

Key discovery values:

FieldValue
issuerhttps://api.hawcx.com
authorization_endpointhttps://api.hawcx.com/authorize
token_endpointhttps://api.hawcx.com/oauth2/token
userinfo_endpointhttps://api.hawcx.com/userinfo
end_session_endpointhttps://api.hawcx.com/oauth2/end_session
jwks_urihttps://api.hawcx.com/.well-known/jwks.json
response_types_supported["code"]
response_modes_supported["query"]
grant_types_supported["authorization_code"]
code_challenge_methods_supported["S256"]
id_token_signing_alg_values_supported["ES512"] (ECDSA — the ID-token signing algorithm)
subject_types_supported["public"]
scopes_supported["openid", "profile", "email", "phone", "address"]
claims_supported["sub", "name", "given_name", "family_name", "email", "email_verified", "phone_number", "birthdate", "address", "locale", "zoneinfo", "updated_at"]
token_endpoint_auth_methods_supported["none", "private_key_jwt"]
token_endpoint_auth_signing_alg_values_supported["EdDSA"] (client private_key_jwt auth only — not ID-token signing)
backchannel_logout_supportedtrue
backchannel_logout_session_supportedtrue

scopes_supported and claims_supported above list the OIDC values relevant to interactive sign-in. The live document also advertises the machine-to-machine scopes used by the client-credentials and token-exchange grants (users:*, consent:*, audit:read, profile:self), and claims_supported additionally enumerates the ID-token claims (iss, aud, iat, sid, amr, and so on).

Authorization request

GET /authorize

ParameterRequiredNotes
response_typeYesMust be code.
client_idYesYour OIDC client.
redirect_uriYesExact match against the client's registered redirect URIs.
scopeYesMust include openid.
code_challengeYesPKCE challenge (43-char base64url).
code_challenge_methodYesMust be S256.
stateRecommendedReturned unchanged on the redirect.
nonceRecommendedBound into the ID token; verify on return.
promptNonone (never show UI; error=login_required if no session) or login (force re-auth).
max_ageNoForce re-auth if the existing session is older than this many seconds.
id_token_hintNoHints which user; a mismatch forces re-auth.

On success the browser is redirected to redirect_uri with code and state. Errors on an unvetted client_id/redirect_uri render an error page (no redirect); other errors redirect with error and error_description.

Token request

POST /oauth2/token (application/x-www-form-urlencoded)

ParameterRequiredNotes
grant_typeYesauthorization_code.
codeYesSingle-use authorization code.
code_verifierYesPKCE verifier, required for both client types.
client_idFor public clientsPublic client identification.
client_assertionFor private_key_jwtEdDSA-signed JWT; iss/sub = client_id, aud = token endpoint URL.
client_assertion_typeFor private_key_jwturn:ietf:params:oauth:client-assertion-type:jwt-bearer.
redirect_uriYesMust match the value used at /authorize.

Response 200:

{
  "access_token": "<JWS>",
  "id_token": "<JWS>",
  "token_type": "Bearer",
  "expires_in": 300,
  "scope": "email openid"
}
  • id_token — the OIDC ID token you verify to authenticate the user (claims below). Signed ES512.
  • access_token — an RFC 9068 at+jwt whose aud is the issuer. Its only use is calling UserInfo; it is not a credential for your own APIs and cannot be replayed against any other Hawcx service.
  • expires_in — the access token's lifetime in seconds (default 300, configurable per client, clamped 1..3600). The ID token has its own separate lifetime (see Client configuration).
  • scope — the scopes actually granted (the intersection of what you requested with scopes_supported).

Errors use the standard OAuth envelope: invalid_request, invalid_client, invalid_grant (unknown / expired / already-used code, or PKCE mismatch), temporarily_unavailable.

For verifying the returned token in your backend, see ID Token Verification; for the full client_assertion construction, see private_key_jwt authentication.

UserInfo request

GET /userinfo

Returns the OIDC standard claims for the signed-in user. Present the access_token from the token response as a bearer token; a stock OIDC client library calls this automatically after the token exchange.

curl https://api.hawcx.com/userinfo \
  -H "Authorization: Bearer <access_token>"
  • Requires the access_token (not the ID token): the endpoint pins typ=at+jwt, requires aud to equal the issuer, and requires the openid scope.
  • The route is keyless and CORS-enabled, so a browser-based SPA may call it cross-origin directly (see CORS). No client key or X-Config-Id header is needed.
  • Response is application/json. Which claims appear depends on the granted scopes (profile, email, phone, address) and on what data exists for the user; absent claims are omitted rather than returned as null.

Response 200:

{
  "sub": "<stable user id>",
  "name": "Ada Lovelace",
  "given_name": "Ada",
  "family_name": "Lovelace",
  "email": "[email protected]",
  "email_verified": true,
  "phone_number": "+15551234567",
  "birthdate": "1815-12-10",
  "address": { "locality": "London", "country": "GB" },
  "locale": "en-US",
  "zoneinfo": "Europe/London",
  "updated_at": 1723200000
}

Errors: a missing bearer token returns a bare 401 challenge (WWW-Authenticate: Bearer, no error body); a present-but-rejected token — expired, wrong aud, or an ID token supplied instead of an access token — returns 401 invalid_token; a token passed as a query parameter returns 400 invalid_request; and a token that lacks the openid scope returns 403 insufficient_scope.

CORS

The four browser-reachable endpoints — /.well-known/openid-configuration, /.well-known/jwks.json, /oauth2/token, and /userinfo — send CORS headers and answer OPTIONS preflight, so a browser SPA can run the whole flow client-side.

EndpointAccess-Control-Allow-Origin
/.well-known/openid-configuration, /.well-known/jwks.json* (public documents)
/oauth2/token, /userinfoThe requesting Origin, if it matches one of the client's registered redirect_uris; otherwise not reflected.

Because the token and UserInfo allowlists are derived from your registered redirect_uris, there is no separate CORS origin list to maintain — add the SPA's origin as a redirect URI and it is allowed.

ID token claims

ClaimAlwaysDescription
issYeshttps://api.hawcx.com.
subYesStable user identifier for this client.
audYesYour client_id.
iat, nbf, expYesIssued-at, not-before, expiry.
jtiYesToken identifier.
auth_timeYesWhen the user authenticated.
amrYesMethods, per RFC 8176, e.g. ["swk"], plus mfa/otp/sms.
acrYesCurrently urn:hawcx:pwdless:v1.
sidWhen under an SSO sessionSession identifier; correlates with Back-Channel Logout.
nonceIf sentThe nonce from the authorization request.
email, email_verifiedWhen an email is on recordUser email. email_verified is true whenever email is present — it reflects presence, not an independent re-verification.
phone_numberWhen a phone is on recordUser phone. A legacy phone claim carries the same value.
cnf.jktFor sender-constrained tokens onlyConfirmation key thumbprint; present only for sender-constrained tokens.

End-session request

GET /oauth2/end_session. See Single Logout.

ParameterRequiredNotes
client_idYesInitiating client.
id_token_hintRecommendedIdentifies the session to end.
post_logout_redirect_uriNoExact-match against the client's post-logout redirect URIs.
stateNoEchoed on the redirect.
logout_scopeNoglobal (default, all sessions) or session (current only).

Logout token claims

Delivered as a form-POST logout_token (a Security Event Token, RFC 8417; typ: secevent+jwt) to a client's backchannel_logout_uri, per OpenID Connect Back-Channel Logout 1.0.

ClaimPresentDescription
issYesIssuer.
audYesThe receiving client_id.
iat, jtiYesIssued-at and unique id (dedupe on jti).
subYesThe user being logged out.
sidSession-scope onlySession to end; absent for global logout.
eventsYesContains http://schemas.openid.net/event/backchannel-logout.
nonceNeverMust not be present; reject the token if it is.

Client configuration

Configured per client under Settings → OAuth (Admin Console).

FieldDescription
client_idGlobally-unique OIDC client identifier; becomes the ID token aud.
token_endpoint_auth_methodnone (public + PKCE) or private_key_jwt.
jwksInline public JWK (single Ed25519 key) for private_key_jwt.
redirect_urisAllowlisted /authorize callbacks. Exact-match; https only (loopback http allowed).
post_logout_redirect_urisAllowlisted RP-Initiated Logout return URLs.
backchannel_logout_uriHTTPS endpoint that receives logout_token POSTs.
backchannel_logout_session_requiredWhether the logout_token must carry sid (default true).

Project-level, under Session policy:

FieldDefaultDescription
Idle timeout30 minSliding SSO session timeout.
Maximum session length8 hAbsolute SSO session cap.
ID token lifetime60 sValidity of issued ID tokens.
Access token lifetime300 sValidity of the access_token used at UserInfo (access_token_ttl_seconds, clamped 1..3600).

Last updated on