> For the complete documentation index, see [llms.txt](https://docs.msquared.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.msquared.io/creation/unreal-development/features-and-tutorials/web-services/validating-identity.md).

# Identity Validation

If you have called 'Fetch M2 Web Platform Delegated Auth Token' and passed into HTTP blueprint nodes, your request to web servers will contain a token that can be used to prove the sender is either a logged-in client, or the game server.

<figure><img src="/files/jOhKQ9vQ3d4EPTTMW5AD" alt=""><figcaption></figcaption></figure>

This JWT is very short-lived (expiry \~5 minutes) and is designed to prove the identity of the caller as having come from the MSquared platform.

The token has the following payload for clients:

```
{
  "scopes": [],
  "user_id": "<userid>",
  "iat": 1717077960,
  "iss": "<issuer>:auth",
  "exp": 1717078260,
  "aud": [
    "<aud>"
  ]
}
```

And the following payload for the game server:

{% hint style="warning" %}
Unreal Servers only support 'World' scope of tokens, other types will not be generated
{% endhint %}

```
{
  "scopes": [],
  "client_type": "ue_server",
  "iat": 1717077960,
  "iss": "<issuer>:auth",
  "exp": 1717078260,
  "aud": [
    "<aud>"
  ]
}
```

{% hint style="danger" %}
The `client_type` claim being set to `ue_server` **does not mean that the requester is trustworthy.**

This claim will have the same value in delegated auth tokens for local and user-generated worlds.

Some additional gating is **strongly recommended** when relying on this claim, e.g. checking the project ID claim as well.
{% endhint %}

The JWT token header will contain a key id claim `(kid)` which can be used to validate the token using the JWKS published at <https://admin.m2worlds.io/.well-known/jwks.json>

The token can be validated using any JWT validation library, for example [jose](https://github.com/panva/jose) for JavaScript/Typescript users.

The current issuer in use is `scarcely-calm-lark:auth` and the audience is `scarcely-calm-lark`

```typescript
import * as jose from 'jose'

const JWKS = jose.createRemoteJWKSet(new URL('https://admin.m2worlds.io/.well-known/jwks.json'))
const { payload, protectedHeader } = await jose.jwtVerify(jwt, JWKS, {
  issuer: 'scarcely-calm-lark:auth',
  audience: 'scarcely-calm-lark',
})
```

If the token validates successfully, you can use the `user_id` or `ue_server` claim to identify the caller.

If you specified a scope in the request, then your token will contain additional claims depending on the scope. For example, if you requested world scope for a user:

```
{
  "scopes": [],
  "user_id": "<userid>",
  "organization_id": "<orgid>",
  "project_id": "<projectid>",
  "world_id": "<worldid>",
  "iat": 1717077960,
  "iss": "<issuer>:auth",
  "exp": 1717078260,
  "aud": [
    "<aud>"
  ]
}
```

It is recommended that you verify the tokens contain the organization, project and world claims you expect.
