{
	"id": "2e3b2693-c1cf-423a-aa81-7401a7a62b85",
	"created_at": "2026-04-06T00:18:44.395988Z",
	"updated_at": "2026-04-10T13:12:21.697128Z",
	"deleted_at": null,
	"sha1_hash": "7bbfbb460e6b1125e6a0169664eff587957139fb",
	"title": "Access tokens in the Microsoft identity platform - Microsoft identity platform",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 118144,
	"plain_text": "Access tokens in the Microsoft identity platform - Microsoft\r\nidentity platform\r\nBy cilwerner\r\nArchived: 2026-04-05 13:35:01 UTC\r\nAccess tokens are a type of security token designed for authorization, granting access to specific resources on\r\nbehalf on an authenticated user. Information in access tokens determines whether a user has the right to access a\r\nparticular resource, similar to keys unlocking specific doors in a building. These individual pieces of information\r\nthat make up tokens are called claims. Therefore, they are sensitive credentials and pose a security risk if not\r\nhandled correctly. Access tokens differ from ID tokens which serve as proof of authentication.\r\nAccess tokens enable clients to securely call protected web APIs. Although client applications can receive and use\r\naccess tokens, they should be treated as opaque strings. The client application shouldn't attempt to validate access\r\ntokens. The resource server should validate the access token before accepting it as proof of authorization. The\r\ncontents of the token are intended only for the API, which means that access tokens must be treated as opaque\r\nstrings. For validation and debugging purposes only, developers can decode JWTs using a site like jwt.ms. Tokens\r\nthat a Microsoft API receives might not always be a JWT that can be decoded.\r\nClients should use the token response data that's returned with the access token for details on what's inside it.\r\nWhen the client requests an access token, the Microsoft identity platform also returns some metadata about the\r\naccess token for the consumption of the application. This information includes the expiry time of the access token\r\nand the scopes for which it's valid. This data allows the application to do intelligent caching of access tokens\r\nwithout having to parse the access token itself. This article explains essential information about access tokens,\r\nincluding formats, ownership, lifetimes and how APIs can validate and use the claims inside an access token.\r\nNote\r\nAll documentation on this page, except where noted, applies only to tokens issued for registered APIs. It doesn't\r\napply to tokens issued for Microsoft-owned APIs, nor can those tokens be used to validate how the Microsoft\r\nidentity platform issues tokens for a registered API.\r\nToken formats\r\nThere are two versions of access tokens available in the Microsoft identity platform: v1.0 and v2.0. These versions\r\ndetermine the claims that are in the token and make sure that a web API can control the contents of the token.\r\nWeb APIs have one of the following versions selected as a default during registration:\r\nv1.0 for Microsoft Entra-only applications. The following example shows a v1.0 token (the keys are\r\nchanged and personal information is removed, which prevents token validation):\r\nhttps://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens\r\nPage 1 of 9\n\neyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Imk2bEdrM0ZaenhSY1ViMkMzbkVRN3N5SEpsWSIsImtpZCI6Imk2bEdrM0Za\r\nv2.0 for applications that support consumer accounts. The following example shows a v2.0 token (the keys\r\nare changed and personal information is removed, which prevents token validation):\r\neyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Imk2bEdrM0ZaenhSY1ViMkMzbkVRN3N5SEpsWSJ9.eyJhdWQiOiI2ZTc0MTc\r\nSet the version for applications by providing the appropriate value to the requestedAccessTokenVersion setting\r\nin the app manifest. The values of null and 1 result in v1.0 tokens, and the value of 2 results in v2.0 tokens.\r\nToken ownership\r\nAn access token request involves two parties: the client, who requests the token, and the resource (Web API) that\r\naccepts the token. The resource that the token is intended for (its audience) is defined in the aud claim in a\r\ntoken. Clients use the token but shouldn't understand or attempt to parse it. Resources accept the token.\r\nThe Microsoft identity platform supports issuing any token version from any version endpoint. For example, when\r\nthe value of requestedAccessTokenVersion is 2 , a client calling the v1.0 endpoint to get a token for that\r\nresource receives a v2.0 access token.\r\nResources always own their tokens using the aud claim and are the only applications that can change their token\r\ndetails.\r\nToken lifetime\r\nThe default lifetime of an access token is variable. When issued, the Microsoft identity platform assigns a random\r\nvalue ranging between 60-90 minutes (75 minutes on average) as the default lifetime of an access token. The\r\nvariation improves service resilience by spreading access token demand over a time, which prevents hourly spikes\r\nin traffic to Microsoft Entra ID.\r\nTenants that don't use Conditional Access have a default access token lifetime of two hours for clients such as\r\nMicrosoft Teams and Microsoft 365.\r\nAdjust the lifetime of an access token to control how often the client application expires the application session,\r\nand how often it requires the user to reauthenticate (either silently or interactively). To override the default access\r\ntoken lifetime variation, use Configurable token lifetime (CTL).\r\nApply default token lifetime variation to organizations that have Continuous Access Evaluation (CAE) enabled.\r\nApply default token lifetime variation even if the organizations use CTL policies. The default token lifetime for\r\nlong lived token lifetime ranges from 20 to 28 hours. When the access token expires, the client must use the\r\nrefresh token to silently acquire a new refresh token and access token.\r\nOrganizations that use Conditional Access sign-in frequency (SIF) to enforce how frequently sign-ins occur can't\r\noverride default access token lifetime variation. When organizations use SIF, the time between credential prompts\r\nhttps://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens\r\nPage 2 of 9\n\nfor a client can range from the sign-in frequency interval to the token lifetime that ranges from 60 - 90 minutes\r\nplus the sign-in frequency interval.\r\nHere's an example of how default token lifetime variation works with sign-in frequency. Let's say an organization\r\nsets sign-in frequency to occur every hour. When the token has lifetime ranging from 60-90 minutes due to token\r\nlifetime variation, the actual sign-in interval occurs anywhere between 1 hour to 2.5 hours.\r\nIf a user with a token with a one hour lifetime performs an interactive sign-in at 59 minutes, there's no credential\r\nprompt because the sign-in is below the SIF threshold. If a new token has a lifetime of 90 minutes, the user\r\nwouldn't see a credential prompt for another hour and a half. During a silent renewal attempt, Microsoft Entra ID\r\nrequires a credential prompt because the total session length has exceeded the sign-in frequency setting of 1 hour.\r\nIn this example, the time difference between credential prompts due to the SIF interval and token lifetime\r\nvariation would be 2.5 hours.\r\nValidate tokens\r\nNot all applications should validate tokens. Only in specific scenarios should applications validate a token:\r\nWeb APIs must validate access tokens sent to them by a client. They must only accept tokens containing\r\none of their AppId URIs as the aud claim.\r\nWeb apps must validate ID tokens sent to them by using the user's browser in the hybrid flow, before\r\nallowing access to a user's data or establishing a session.\r\nIf none of the previously described scenarios apply, there's no need to validate the token. Public clients like native,\r\ndesktop, or single-page applications don't benefit from validating ID tokens because the application communicates\r\ndirectly with the IDP where SSL protection ensures the ID tokens are valid. They shouldn't validate the access\r\ntokens, as they are for the web API to validate, not the client.\r\nAPIs and web applications must only validate tokens that have an aud claim that matches the application. Other\r\nresources may have custom token validation rules. For example, you can't validate tokens for Microsoft Graph\r\naccording to these rules due to their proprietary format. Validating and accepting tokens meant for another\r\nresource is an example of the confused deputy problem.\r\nIf the application needs to validate an ID token or an access token, it should first validate the signature of the\r\ntoken and the issuer against the values in the OpenID discovery document.\r\nThe Microsoft Entra middleware has built-in capabilities for validating access tokens. See samples to find one in\r\nthe appropriate language. There are also several third-party open-source libraries available for JWT validation. For\r\nmore information about authentication libraries and code samples, see the authentication libraries. If your web app\r\nor web API is on ASP.NET or ASP.NET Core, use Microsoft.Identity.Web, which handles the validation for you.\r\nv1.0 and v2.0 tokens\r\nWhen your web app/API is validating a v1.0 token ( ver claim =\"1.0\"), it needs to read the OpenID\r\nConnect metadata document from the v1.0 endpoint ( https://login.microsoftonline.com/{example-https://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens\r\nPage 3 of 9\n\ntenant-id}/.well-known/openid-configuration ), even if the authority configured for your web API is a\r\nv2.0 authority.\r\nWhen your web app/API is validating a v2.0 token ( ver claim =\"2.0\"), it needs to read the OpenID\r\nConnect metadata document from the v2.0 endpoint ( https://login.microsoftonline.com/{example-tenant-id}/v2.0/.well-known/openid-configuration ), even if the authority configured for your web API\r\nis a v1.0 authority.\r\nThe following examples suppose that your application is validating a v2.0 access token (and therefore reference\r\nthe v2.0 versions of the OIDC metadata documents and keys). Just remove the \"/v2.0\" in the URL if you validate\r\nv1.0 tokens.\r\nValidate the issuer\r\nOpenID Connect Core says \"The Issuer Identifier [...] MUST exactly match the value of the iss (issuer) Claim.\"\r\nFor applications which use a tenant-specific metadata endpoint (like\r\nhttps://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-dddd2222eeee/v2.0/.well-known/openid-configuration or https://login.microsoftonline.com/contoso.onmicrosoft.com/v2.0/.well-known/openid-configuration ), this is all that is needed.\r\nMicrosoft Entra ID has a tenant-independent version of the document available at\r\nhttps://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration. This endpoint returns an\r\nissuer value https://login.microsoftonline.com/{tenantid}/v2.0 . Applications may use this tenant-independent endpoint to validate tokens from every tenant with the following modifications:\r\n1. Instead of expecting the issuer claim in the token to exactly match the issuer value from metadata, the\r\napplication should replace the {tenantid} value in the issuer metadata with the tenant id that is the target\r\nof the current request, and then check the exact match.\r\n2. The application should use the issuer property returned from the keys endpoint to restrict the scope of\r\nkeys.\r\nKeys that have an issuer value like https://login.microsoftonline.com/{tenantid}/v2.0 may be\r\nused with any matching token issuer.\r\nKeys that have an issuer value like https://login.microsoftonline.com/9188040d-6c67-4c5b-b112-36a304b66dad/v2.0 should only be used with exact match.\r\nMicrosoft Entra tenant-independent key endpoint\r\n(https://login.microsoftonline.com/common/discovery/v2.0/keys) returns a document like:\r\n{\r\n \"keys\":[\r\n {\"kty\":\"RSA\",\"use\":\"sig\",\"kid\":\"A1bC2dE3fH4iJ5kL6mN7oP8qR9sT0u\",\"x5t\":\"A1bC2dE3fH4iJ5kL6mN7oP8qR9sT0u\r\n {\"kty\":\"RSA\",\"use\":\"sig\",\"kid\":\"C2dE3fH4iJ5kL6mN7oP8qR9sT0uV1w\",\"x5t\":\"C2dE3fH4iJ5kL6mN7oP8qR9sT0uV1w\r\n {\"kty\":\"RSA\",\"use\":\"sig\",\"kid\":\"E3fH4iJ5kL6mN7oP8qR9sT0uV1wX2y\",\"x5t\":\"E3fH4iJ5kL6mN7oP8qR9sT0uV1wX2y\r\nhttps://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens\r\nPage 4 of 9\n\n]\r\n}\r\n3. Applications that use a Microsoft Entra tenant id ( tid ) claim as a trust boundary instead of the standard\r\nissuer claim should ensure that the tenant-id claim is a guid and that the issuer and tenant id match.\r\nUsing tenant-independent metadata is more efficient for applications which accept tokens from many tenants.\r\nNote\r\nWith Microsoft Entra tenant-independent metadata, claims should be interpreted within the tenant, as under\r\nstandard OpenID Connect, claims are interpreted within the issuer. That is,\r\n{\"sub\":\"ABC123\",\"iss\":\"https://login.microsoftonline.com/aaaabbbb-0000-cccc-1111-\r\ndddd2222eeee/v2.0\",\"tid\":\"aaaabbbb-0000-cccc-1111-dddd2222eeee\"} and\r\n{\"sub\":\"ABC123\",\"iss\":\"https://login.microsoftonline.com/bbbbcccc-1111-dddd-2222-\r\neeee3333ffff/v2.0\",\"tid\":\"bbbbcccc-1111-dddd-2222-eeee3333ffff\"} describe different users, even though the\r\nsub is the same, because claims like sub are interpreted within the context of the issuer/tenant.\r\nValidate the signature\r\nA JWT contains three segments separated by the . character. The first segment is the header, the second is the\r\nbody, and the third is the signature. Use the signature segment to evaluate the authenticity of the token.\r\nMicrosoft Entra ID issues tokens signed using the industry standard asymmetric encryption algorithms, such as\r\nRS256. The header of the JWT contains information about the key and encryption method used to sign the token:\r\n{\r\n \"typ\": \"JWT\",\r\n \"alg\": \"RS256\",\r\n \"x5t\": \"H4iJ5kL6mN7oP8qR9sT0uV1wX2yZ3a\",\r\n \"kid\": \"H4iJ5kL6mN7oP8qR9sT0uV1wX2yZ3a\"\r\n}\r\nThe alg claim indicates the algorithm used to sign the token, while the kid claim indicates the particular\r\npublic key that was used to validate the token.\r\nAt any given point in time, Microsoft Entra ID may sign an ID token using any one of a certain set of public-private key pairs. Microsoft Entra ID rotates the possible set of keys on a periodic basis, so write the application to\r\nhandle those key changes automatically. A reasonable frequency to check for updates to the public keys used by\r\nMicrosoft Entra ID is every 24 hours.\r\nAcquire the signing key data necessary to validate the signature by using the OpenID Connect metadata document\r\nlocated at:\r\nhttps://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration\r\nhttps://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens\r\nPage 5 of 9\n\nTip\r\nTry this in a browser: URL\r\nThe following information describes the metadata document:\r\nIs a JSON object that contains several useful pieces of information, such as the location of the various\r\nendpoints required for doing OpenID Connect authentication.\r\nIncludes a jwks_uri , which gives the location of the set of public keys that correspond to the private keys\r\nused to sign tokens. The JSON Web Key (JWK) located at the jwks_uri contains all of the public key\r\ninformation in use at that particular moment in time. RFC 7517 describes the JWK format. The application\r\ncan use the kid claim in the JWT header to select the public key, from this document, which corresponds\r\nto the private key that has been used to sign a particular token. It can then do signature validation using the\r\ncorrect public key and the indicated algorithm.\r\nNote\r\nUse the kid claim to validate the token. Though v1.0 tokens contain both the x5t and kid claims, v2.0\r\ntokens contain only the kid claim.\r\nDoing signature validation is outside the scope of this document. There are many open-source libraries available\r\nfor helping with signature validation if necessary. However, the Microsoft identity platform has one token signing\r\nextension to the standards, which are custom signing keys.\r\nIf the application has custom signing keys as a result of using the claims-mapping feature, append an appid\r\nquery parameter that contains the application ID. For validation, use jwks_uri that points to the signing key\r\ninformation of the application. For example: https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration?appid=00001111-aaaa-2222-bbbb-3333cccc4444 contains a jwks_uri of\r\nhttps://login.microsoftonline.com/{tenant}/discovery/keys?appid=00001111-aaaa-2222-bbbb-3333cccc4444 .\r\nValidate the issuer\r\nWeb apps validating ID tokens, and web APIs validating access tokens need to validate the issuer of the token\r\n( iss claim) against:\r\n1. the issuer available in the OpenID connect metadata document associated with the application\r\nconfiguration (authority). The metadata document to verify against depends on:\r\nthe version of the token\r\nthe accounts supported by your application.\r\n2. the tenant ID ( tid claim) of the token,\r\n3. the issuer of the signing key.\r\nSingle tenant applications\r\nhttps://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens\r\nPage 6 of 9\n\nOpenID Connect Core says \"The Issuer Identifier [...] MUST exactly match the value of the iss (issuer) Claim.\"\r\nFor applications that use a tenant-specific metadata endpoint, such as\r\nhttps://login.microsoftonline.com/{example-tenant-id}/v2.0/.well-known/openid-configuration or\r\nhttps://login.microsoftonline.com/contoso.onmicrosoft.com/v2.0/.well-known/openid-configuration .\r\nSingle tenant applications are applications that support:\r\nAccounts in one organizational directory (example-tenant-id only):\r\nhttps://login.microsoftonline.com/{example-tenant-id}\r\nPersonal Microsoft accounts only: https://login.microsoftonline.com/consumers (consumers being a\r\nnickname for the tenant 9188040d-6c67-4c5b-b112-36a304b66dad)\r\nMultitenant applications\r\nMicrosoft Entra ID also supports multitenant applications. These applications support:\r\nAccounts in any organizational directory (any Microsoft Entra directory):\r\nhttps://login.microsoftonline.com/organizations\r\nAccounts in any organizational directory (any Microsoft Entra directory) and personal Microsoft accounts\r\n(for example, Skype, XBox): https://login.microsoftonline.com/common\r\nFor these applications, Microsoft Entra ID exposes tenant-independent versions of the OIDC document at\r\nhttps://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration and\r\nhttps://login.microsoftonline.com/organizations/v2.0/.well-known/openid-configuration respectively.\r\nThese endpoints return an issuer value, which is a template parametrized by the tenantid :\r\nhttps://login.microsoftonline.com/{tenantid}/v2.0 . Applications may use these tenant-independent\r\nendpoints to validate tokens from every tenant with the following stipulations:\r\nValidate the signing key issuer\r\nInstead of expecting the issuer claim in the token to exactly match the issuer value from metadata, the\r\napplication should replace the {tenantid} value in the issuer metadata with the tenant ID that is the\r\ntarget of the current request, and then check the exact match ( tid claim of the token).\r\nValidate that the tid claim is a GUID and the iss claim is of the form\r\nhttps://login.microsoftonline.com/{tid}/v2.0 where {tid} is the exact tid claim. This validation\r\nties the tenant back to the issuer and back to the scope of the signing key creating a chain of trust.\r\nUse tid claim when they locate data associated with the subject of the claim. In other words, the tid\r\nclaim must be part of the key used to access the user's data.\r\nValidate the signing key issuer\r\nApplications using the v2.0 tenant-independent metadata need to validate the signing key issuer.\r\nKeys document and signing key issuer\r\nhttps://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens\r\nPage 7 of 9\n\nAs discussed, from the OpenID Connect document, your application accesses the keys used to sign the tokens. It\r\ngets the corresponding keys document by accessing the URL exposed in the jwks_uri property of the\r\nOpenIdConnect document.\r\n \"jwks_uri\": \"https://login.microsoftonline.com/{example-tenant-id}/discovery/v2.0/keys\",\r\nThe {example-tenant-id} value can be replaced by a GUID, a domain name, or common, **organizations, and\r\nconsumers.\r\nThe keys documents exposed by Azure AD v2.0 contains, for each key, the issuer that uses this signing key. For\r\ninstance, the tenant-independent \"common\" key endpoint\r\nhttps://login.microsoftonline.com/common/discovery/v2.0/keys returns a document like:\r\n{\r\n \"keys\":[\r\n {\"kty\":\"RSA\",\"use\":\"sig\",\"kid\":\"A1bC2dE3fH4iJ5kL6mN7oP8qR9sT0u\",\"x5t\":\"A1bC2dE3fH4iJ5kL6mN7oP8qR9sT0u\",\"n\":\"\r\n {\"kty\":\"RSA\",\"use\":\"sig\",\"kid\":\"C2dE3fH4iJ5kL6mN7oP8qR9sT0uV1w\",\"x5t\":\"C2dE3fH4iJ5kL6mN7oP8qR9sT0uV1w\",\"n\":\"\r\n {\"kty\":\"RSA\",\"use\":\"sig\",\"kid\":\"E3fH4iJ5kL6mN7oP8qR9sT0uV1wX2y\",\"x5t\":\"E3fH4iJ5kL6mN7oP8qR9sT0uV1wX2y\",\"n\":\"\r\n ]\r\n}\r\nValidation of the signing key issuer\r\nThe application should use the issuer property of the keys document, associated with the key used to sign the\r\ntoken, in order to restrict the scope of keys:\r\nKeys that have an issuer value with a GUID like https://login.microsoftonline.com/9188040d-6c67-\r\n4c5b-b112-36a304b66dad/v2.0 should only be used when the iss claim in the token matches the value\r\nexactly.\r\nKeys that have a templated issuer value like https://login.microsoftonline.com/{tenantid}/v2.0\r\nshould only be used when the iss claim in the token matches this value after substituting the tid claim\r\nin the token for the {tenantid} placeholder.\r\nUsing tenant-independent metadata is more efficient for applications that accept tokens from many tenants.\r\nNote\r\nWith Microsoft Entra tenant-independent metadata, claims should be interpreted within the tenant, as under\r\nstandard OpenID Connect, claims are interpreted within the issuer. That is,\r\n{\"sub\":\"ABC123\",\"iss\":\"https://login.microsoftonline.com/{example-tenant-id}/v2.0\",\"tid\":\"{example-tenant-id}\"} and {\"sub\":\"ABC123\",\"iss\":\"https://login.microsoftonline.com/{another-tenand-id}/v2.0\",\"tid\":\"{another-tenant-id}\"} describe different users, even though the sub is the same, because\r\nclaims like sub are interpreted within the context of the issuer/tenant.\r\nhttps://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens\r\nPage 8 of 9\n\nRecap\r\nHere's some pseudo code that recapitulates how to validate issuer and signing key issuer:\r\n1. Fetch keys from configured metadata URL\r\n2. Check token if signed with one of the published keys, fail if not\r\n3. Identify key in the metadata based on the kid header. Check the \"issuer\" property attached to the key in the\r\nmetadata document:\r\nvar issuer = metadata[\"kid\"].issuer;\r\nif (issuer.contains(\"{tenantId}\", CaseInvariant)) issuer = issuer.Replace(\"{tenantid}\", token[\"tid\"], Cas\r\nif (issuer != token[\"iss\"]) throw validationException;\r\nif (configuration.allowedIssuer != \"*\" \u0026\u0026 configuration.allowedIssuer != issuer) throw validationExceptio\r\nvar issUri = new Uri(token[\"iss\"]);\r\nif (issUri.Segments.Count \u003c 1) throw validationException;\r\nif (issUri.Segments[1] != token[\"tid\"]) throw validationException;\r\nRelated content\r\nAccess token claims reference\r\nSecure applications and APIs by validating claims\r\nSource: https://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens\r\nhttps://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens\r\nPage 9 of 9",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens"
	],
	"report_names": [
		"access-tokens"
	],
	"threat_actors": [],
	"ts_created_at": 1775434724,
	"ts_updated_at": 1775826741,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/7bbfbb460e6b1125e6a0169664eff587957139fb.pdf",
		"text": "https://archive.orkl.eu/7bbfbb460e6b1125e6a0169664eff587957139fb.txt",
		"img": "https://archive.orkl.eu/7bbfbb460e6b1125e6a0169664eff587957139fb.jpg"
	}
}