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
| Endpoint | Path |
|---|---|
| Discovery document | GET /.well-known/openid-configuration |
| JWKS | GET /.well-known/jwks.json |
| UserInfo | GET /userinfo |
Key discovery values:
| Field | Value |
|---|---|
issuer | https://api.hawcx.com |
authorization_endpoint | https://api.hawcx.com/authorize |
token_endpoint | https://api.hawcx.com/oauth2/token |
userinfo_endpoint | https://api.hawcx.com/userinfo |
end_session_endpoint | https://api.hawcx.com/oauth2/end_session |
jwks_uri | https://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_supported | true |
backchannel_logout_session_supported | true |
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
| Parameter | Required | Notes |
|---|---|---|
response_type | Yes | Must be code. |
client_id | Yes | Your OIDC client. |
redirect_uri | Yes | Exact match against the client's registered redirect URIs. |
scope | Yes | Must include openid. |
code_challenge | Yes | PKCE challenge (43-char base64url). |
code_challenge_method | Yes | Must be S256. |
state | Recommended | Returned unchanged on the redirect. |
nonce | Recommended | Bound into the ID token; verify on return. |
prompt | No | none (never show UI; error=login_required if no session) or login (force re-auth). |
max_age | No | Force re-auth if the existing session is older than this many seconds. |
id_token_hint | No | Hints 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)
| Parameter | Required | Notes |
|---|---|---|
grant_type | Yes | authorization_code. |
code | Yes | Single-use authorization code. |
code_verifier | Yes | PKCE verifier, required for both client types. |
client_id | For public clients | Public client identification. |
client_assertion | For private_key_jwt | EdDSA-signed JWT; iss/sub = client_id, aud = token endpoint URL. |
client_assertion_type | For private_key_jwt | urn:ietf:params:oauth:client-assertion-type:jwt-bearer. |
redirect_uri | Yes | Must 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). SignedES512.access_token— an RFC 9068at+jwtwhoseaudis 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 (default300, configurable per client, clamped1..3600). The ID token has its own separate lifetime (see Client configuration).scope— the scopes actually granted (the intersection of what you requested withscopes_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 pinstyp=at+jwt, requiresaudto equal the issuer, and requires theopenidscope. - 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-Idheader 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 asnull.
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.
| Endpoint | Access-Control-Allow-Origin |
|---|---|
/.well-known/openid-configuration, /.well-known/jwks.json | * (public documents) |
/oauth2/token, /userinfo | The 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
| Claim | Always | Description |
|---|---|---|
iss | Yes | https://api.hawcx.com. |
sub | Yes | Stable user identifier for this client. |
aud | Yes | Your client_id. |
iat, nbf, exp | Yes | Issued-at, not-before, expiry. |
jti | Yes | Token identifier. |
auth_time | Yes | When the user authenticated. |
amr | Yes | Methods, per RFC 8176, e.g. ["swk"], plus mfa/otp/sms. |
acr | Yes | Currently urn:hawcx:pwdless:v1. |
sid | When under an SSO session | Session identifier; correlates with Back-Channel Logout. |
nonce | If sent | The nonce from the authorization request. |
email, email_verified | When an email is on record | User email. email_verified is true whenever email is present — it reflects presence, not an independent re-verification. |
phone_number | When a phone is on record | User phone. A legacy phone claim carries the same value. |
cnf.jkt | For sender-constrained tokens only | Confirmation key thumbprint; present only for sender-constrained tokens. |
End-session request
GET /oauth2/end_session. See Single Logout.
| Parameter | Required | Notes |
|---|---|---|
client_id | Yes | Initiating client. |
id_token_hint | Recommended | Identifies the session to end. |
post_logout_redirect_uri | No | Exact-match against the client's post-logout redirect URIs. |
state | No | Echoed on the redirect. |
logout_scope | No | global (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.
| Claim | Present | Description |
|---|---|---|
iss | Yes | Issuer. |
aud | Yes | The receiving client_id. |
iat, jti | Yes | Issued-at and unique id (dedupe on jti). |
sub | Yes | The user being logged out. |
sid | Session-scope only | Session to end; absent for global logout. |
events | Yes | Contains http://schemas.openid.net/event/backchannel-logout. |
nonce | Never | Must not be present; reject the token if it is. |
Client configuration
Configured per client under Settings → OAuth (Admin Console).
| Field | Description |
|---|---|
client_id | Globally-unique OIDC client identifier; becomes the ID token aud. |
token_endpoint_auth_method | none (public + PKCE) or private_key_jwt. |
jwks | Inline public JWK (single Ed25519 key) for private_key_jwt. |
redirect_uris | Allowlisted /authorize callbacks. Exact-match; https only (loopback http allowed). |
post_logout_redirect_uris | Allowlisted RP-Initiated Logout return URLs. |
backchannel_logout_uri | HTTPS endpoint that receives logout_token POSTs. |
backchannel_logout_session_required | Whether the logout_token must carry sid (default true). |
Project-level, under Session policy:
| Field | Default | Description |
|---|---|---|
| Idle timeout | 30 min | Sliding SSO session timeout. |
| Maximum session length | 8 h | Absolute SSO session cap. |
| ID token lifetime | 60 s | Validity of issued ID tokens. |
| Access token lifetime | 300 s | Validity of the access_token used at UserInfo (access_token_ttl_seconds, clamped 1..3600). |
Last updated on