OpenID Connect
OpenID Connect (OIDC) is a thin identity layer on top of OAuth 2.0. It’s the recommended protocol for new integrations — lighter than SAML, native to modern web and mobile stacks, and easier to debug.
Hygrade acts as the OpenID Provider (OP) for first-party integrations. For federation into Hygrade — where your IdP authenticates your employees — use SAML 2.0. OIDC federation for IdP-into-Hygrade is on the roadmap.
Discovery
Hygrade publishes a standard OpenID discovery document at a well-known URL. Most client libraries can configure themselves from this one endpoint.
https://order.hygradebusiness.comhttps://test.hygradebusiness.comhttps://order.hygradebusiness.com/.well-known/openid-configurationhttps://test.hygradebusiness.com/.well-known/openid-configurationhttps://order.hygradebusiness.com/oauth/jwks.jsonhttps://test.hygradebusiness.com/oauth/jwks.json{
"issuer": "https://order.hygradebusiness.com",
"authorization_endpoint": "https://order.hygradebusiness.com/oauth/authorize",
"token_endpoint": "https://order.hygradebusiness.com/oauth/token",
"userinfo_endpoint": "https://order.hygradebusiness.com/oauth/userinfo",
"jwks_uri": "https://order.hygradebusiness.com/oauth/jwks.json",
"revocation_endpoint": "https://order.hygradebusiness.com/oauth/revoke",
"introspection_endpoint": "https://order.hygradebusiness.com/oauth/introspect",
"end_session_endpoint": "https://order.hygradebusiness.com/oauth/logout",
"response_types_supported": ["code", "id_token", "code id_token"],
"grant_types_supported": ["authorization_code", "refresh_token", "client_credentials"],
"subject_types_supported": ["public"],
"id_token_signing_alg_values_supported": ["RS256"],
"scopes_supported": [
"openid", "profile", "email",
"orders:read", "orders:write", "catalog:read",
"users:read", "users:write"
],
"claims_supported": [
"sub", "iss", "aud", "exp", "iat", "auth_time",
"email", "email_verified",
"given_name", "family_name", "name",
"cust_id", "login", "groups", "cost_center"
],
"code_challenge_methods_supported": ["S256"],
"token_endpoint_auth_methods_supported": ["client_secret_basic", "client_secret_post", "private_key_jwt"]
}
Sign-in flow
Hygrade supports the Authorization Code flow with PKCE. The request is identical to the OAuth flow, with the addition of the openid scope and (optionally) nonce.
GET https://order.hygradebusiness.com/oauth/authorize
?response_type=code
&client_id=hg_live_8f3c92e4a1b04e79
&redirect_uri=https%3A%2F%2Fapp.acmecorp.com%2Fcallback
&scope=openid%20profile%20email
&state=9a1dcf4b
&nonce=f7d23c0b9e
&code_challenge=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
&code_challenge_method=S256
The token response includes an id_token alongside the access token:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVC...",
"id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVC...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "hgr_a4f2e8c1d9b34...",
"scope": "openid profile email"
}
ID token
The ID token is a JWT signed with RS256. Always verify the signature against the JWKS and enforce the following:
issmatcheshttps://order.hygradebusiness.comaudcontains your client IDexpis in the futurenoncematches the value you sent in the authorization request
{
"iss": "https://order.hygradebusiness.com",
"sub": "shopper:acme001:jdoe",
"aud": "hg_live_8f3c92e4a1b04e79",
"exp": 1760731200,
"iat": 1760727600,
"auth_time": 1760727598,
"nonce": "f7d23c0b9e",
"email": "jane.doe@acmecorp.com",
"email_verified": true,
"given_name": "Jane",
"family_name": "Doe",
"name": "Jane Doe",
"cust_id": "ACME001",
"login": "jdoe",
"groups": ["buyer", "approver"],
"cost_center": "CC-4420"
}
Claims
| Claim | Scope | Description |
|---|---|---|
sub | openid | Stable, opaque identifier for the shopper. Format: shopper:<custId>:<login>. |
email | email | Primary email address. |
email_verified | email | Boolean; always true for SSO-authenticated users. |
given_name | profile | First name. |
family_name | profile | Last name. |
name | profile | Full display name. |
cust_id | profile | Hygrade customer account code. |
login | profile | Hygrade login identifier. |
groups | profile | Role memberships. Array of strings. |
cost_center | profile | Default cost center code, if assigned. |
UserInfo endpoint
Clients that need user attributes without decoding the ID token can call the UserInfo endpoint with the access token. Requires the openid scope.
curl https://order.hygradebusiness.com/oauth/userinfo \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsI..."
{
"sub": "shopper:acme001:jdoe",
"email": "jane.doe@acmecorp.com",
"email_verified": true,
"given_name": "Jane",
"family_name": "Doe",
"name": "Jane Doe",
"cust_id": "ACME001",
"login": "jdoe",
"groups": ["buyer", "approver"],
"cost_center": "CC-4420"
}
Logout (end session)
The end_session_endpoint terminates the Hygrade session. Clients should also clear their own session.
GET https://order.hygradebusiness.com/oauth/logout
?id_token_hint=eyJhbGciOiJSUzI1NiIs...
&post_logout_redirect_uri=https%3A%2F%2Fapp.acmecorp.com%2Fsigned-out
&state=9a1dcf4b
Tested client libraries
Any OIDC-conformant library works. These are the ones we regularly see in integrations and exercise in our test suite:
- Node.js —
openid-client - PHP —
jumbojett/openid-connect-php, Laravel Socialite - Python —
authlib,python-jose - .NET —
Microsoft.AspNetCore.Authentication.OpenIdConnect - Go —
github.com/coreos/go-oidc - Browser / SPA —
oidc-client-ts
Related: for the OAuth primitives themselves (token formats, scopes, error handling) see the OAuth 2.0 reference.