Skip to content
TDACorpIDENTITYSign in

Userinfo

Read the signed-in person's profile claims with an access token, and what the endpoint refuses.

On this page

The userinfo endpoint returns profile claims for the person an access token was issued for. Use it when you need profile data that is not in the ID token, or fresher than the ID token. It returns nothing about authorization: roles and permissions are never here.

Request#

GET or POST the userinfo_endpoint from discovery, which is /userinfo. Send the access token in the Authorization header.

TokenHeader
A DPoP-bound token (the usual case)Authorization: DPoP <token> and DPoP: <proof>. The proof must carry ath, the hash of the token, and a current server nonce.
An unbound tokenAuthorization: Bearer <token>

There are no other parameters. A token in the query string is refused with invalid_request, because addresses end up in logs.

What the token must be#

  • Issued to a person. A token from client_credentials or a token exchange is refused as invalid_token.
  • Carrying the openid scope. Without it the answer is 403 insufficient_scope.
  • Addressed to your client or to the issuer. A token you requested for a resource (its aud is the resource address) is not accepted here; ask for the profile with the ID token, or request a second token without resource.
  • Still live. If the session behind the token has ended, or the person or the client is no longer active, the token is refused. A token revoked at the revocation endpoint is refused too.
  • Bound to the key you prove, when it is a DPoP token.

Response#

200 with Content-Type: application/json and Cache-Control: no-store. A DPoP request also gets a fresh DPoP-Nonce header.

MemberReleased when
subAlways. For a client registered pairwise it is that client's per-sector sub, not the person's real one.
name, locale, zoneinfo, preferred_username, picture, updated_atThe token carries profile. A claim the person has not set is left out.
email, email_verifiedThe token carries email, and the person has a verified primary email. Otherwise both are left out.

picture is an address on the issuer. A client registered pairwise gets no picture, because that address contains the real sub. updated_at is seconds since the epoch. A claim is left out rather than sent as null, so a missing claim means either it was not released to you or the person has none.

tid, tslug, acr, amr, auth_time and sid are not returned here, although the discovery document lists them under claims_supported: they are claims of the ID token and the access token. Read them from those. See the claims reference.

Errors#

StatusBody and headerWhen
400{"error": "invalid_request"} with WWW-Authenticate: Bearer error="invalid_request"The token is in the query string, or the Authorization header is malformed or too large.
401{"error": "unauthorized"} with a WWW-Authenticate offering Bearer and DPoPNo credentials, or a scheme other than Bearer or DPoP.
401invalid_tokenThe token is unreadable, expired, revoked, from an ended session, for a suspended client, not for a person, not addressed to this endpoint, or fails its key binding.
401use_dpop_nonce with a DPoP-Nonce headerThe proof lacks a current nonce. Retry once with the header value.
403insufficient_scope with the required scope in WWW-AuthenticateThe token does not carry openid.
429Retry-After headerThe request was refused for sending too many requests. Wait that long.

The error codes follow RFC 6750 and RFC 9449. Identity does not say which check failed for an invalid_token.

Worked example#

curl -s https://identity.tdacorp.in/userinfo \  -H "Authorization: DPoP $ACCESS_TOKEN" \  -H "DPoP: $DPOP_PROOF"
{  "sub": "0194f2b6-7c1e-7a30-9d4e-2f6f0f3b8c11",  "name": "Asha Rao",  "locale": "en",  "zoneinfo": "Asia/Kolkata",  "preferred_username": "asha",  "updated_at": 1790000000,  "email": "asha@example.com",  "email_verified": true}

The values are illustrative.

Security notes#

  • Key accounts on sub. It is stable and never reused. preferred_username, name and email can change and, for a username, can later belong to someone else.
  • Do not cache for long. A profile can change at any time. Do not use userinfo to decide what a person may do.
  • Browser applications. A browser application served from a registered client origin may call this endpoint cross-origin. Keep the token out of storage that other scripts can read.
  • Bind to the right token. Never send an access token meant for your API to someone else's server. Send the token only to identity's endpoint from discovery.

Verified against commit 7ff8932