The OpenID Connect Protocol is a layer on top of OAuth 2.0. It is an authentication protocol; as such, it shares the identity of a subject with an application (a client, in OAuth terms). It does so by encapsulating claims in a JSON Web Token (JWT).

OpenID Connect defines several tokens, including the ID Token.
It captures the essence of the OpenID Connect protocol.
It conveys the identity of the subject.

The ID Token is specified in the OpenID Connect Core 1.0 - section 2:

The primary extension that OpenID Connect makes to OAuth 2.0 to enable End-Users to be authenticated is the ID Token data structure.
The ID Token is a security token that contains claims about the authentication of an End-User by an Authorization Server when using a Client, and potentially other requested claims. The ID Token is represented as a JSON Web Token (JWT).

Claims

The id_token contains several important claims.
Some of these claims are used to convey user identity, while others provide information about the validity of the token.
For a detailed description of the claims, refer to this page here.

ID Tokens differ from Access Tokens because they serve different purposes.
Both are JWTs, and since they are both security tokens, they contain similar claims that allow for the assessment of their validity.
Unlike ID Tokens, Access Tokens contain claims that allow the receiver of the token to determine whether access is granted.

Obtaining Tokens And Claims

Claims that are not required are not included in the id_token by default.
Only the claims that have been requested by the client are included.
The client requests the claims by specifying scope in the /authorize request.

OpenID Connect has five standard scopes: openid profile address email phone.
Each of these scopes discloses claims via the id_token and the access_token.
Notice how a /authorize request includes scopes:

GET /authorize?
response_type=...&
client_id=...&
redirect_uri=...&
scope=openid profile email&
state=...&
code_challenge=...&
code_challenge_method=...

This list shows which scopes are required to obtain claims and in which token they belong:

Claim TypeScope RequiredID TokenAccess Token
issopenidrequiredrequired
audopenidrequiredrequired
expopenidrequiredrequired
iatopenidrequiredrequired
subopenidrequiredoptional
scopeopenid
auth_timeopenid
nonceopenid
nameopenid, profilenot recommended
given_nameopenid, profilenot recommended
family_nameopenid, profilenot recommended
middle_nameopenid, profilenot recommended
nicknameopenid, profilenot recommended
preferred_usernameopenid, profilenot recommended
profileopenid, profilenot recommended
addressopenid, addressnot recommended
pictureopenid, profilenot recommended
websiteopenid, profilenot recommended
genderopenid, profilenot recommended
zoneinfoopenidnot recommended
updated_atopenidnot recommended
emailopenid, emailnot recommended
email_verifiedopenid, emailnot recommended
phone_numberopenid, phonenot recommended
phone_number_verifiedopenid, phonenot recommended

Using the ID Token

ID tokens convey identity, while access tokens convey authorization.
As such, ID tokens are well-suited for displaying user details like a username, preferred name, or avatar in a front-end application.

However, an ID token is still a JWT, which means it is readable by anyone who can access it.
While the ID token can be securely stored when implemented correctly, it still makes for a potentially poor choice for storing sensitive information, such as data protected under regulations like GDPR, for example.

Therefore, it is important to carefully consider what information is included in an ID token, and to retrieve more sensitive or extensive data from the /userinfo endpoint instead.

Read more about obtaining claims from the /userinfo endpoint.

Verifying The JWT

Since a JWT is typically base64-encoded, you must verify its authenticity before trusting it.
A JWT includes several mechanisms that enable this verification process.

Read how to verify the authenticity of a JSON Web Token.