How tokens have their validity determined.

There are various ways that the lifetime (or expiration time) of a given token can be determined. The tokens types are

Note on tokens and such. The server creates identifiers in its internal format which is designed to make it globally unique, hence it is tied to the service itself. A typical grant for instance may be

You may have the urge to feed that to a browser, but it is not an address, it is simply a unique string with semantics.

Note: such unique strings are indeed checks as strings, so they must not be altered in any way. Sending back the above example as

with some of the arguments permuted (perfectly acceptable if this were an address) will result in an error. Part of this requirement is to prevent forged tokens or replay attacks, so it will be enfroced. Generally just pass along the tokens as they are.

Server settings

On the server, there are maximum values allowed. This means that no matter what any other request tries to do, the server will enforce these limits.

The server will also apply default values if nothing else is specified. Typically these are half what the maximum is, though administrators are free to set their own policies. Therefore, there is no need to specify defaults per se, except in refresh tokens, where a value of zero is taken to mean that no refresh tokens should be created.

Client configurations

Clients may have their access and refresh token lifetimes specified. These are again applied for

The client configuration

The configuration for a client has two properties, at_lifetime in milliseconds, which sets the default access token lifetime for every client and rt_lifetime in milliseconds which is the value for every refresh token. These may be overridden in, for example, the initial request or by scripting. Even though they may be set to values, they are limited to the server maximum.

If you are administering your clients via the client management API, these may be set there.

A note on lifetime and policies. Access tokens allow for access to resources and as such should be limited in their lifetime -- you very probably do not want an access token with a lifetime of a year (the server default is 900 sec or 15 minutes). Refresh tokens are used to get access tokens and can have a much longer lifetime, in the order of weeks or months. Typically you stash the refresh token until you need an access token, then get an access token.

OIDC servers allow for an id token with various bits of user information in it. These are signed JWTs (JSON Web Token) and include both the access token and refresh token. The actual use of one is showing that the user successfully authenticated to the service. A common (and poor use) of them though is as a "poor man's" access token, because, as per the spec., the lifetime of the id token is the same as the lifetime of the access token, and the id token can be verified against the issuing server, so its contents can be trusted. This cannot be condemned enough and you should not do it. There are formats of access tokens that are designed to be self-describing, such as SciTokens or WLCG tokens (both supported in OA4MP) so please use one of these instead.

At the initial request.

The initial request to the service may ask for either and access token lifetime (at_lifetime) or a refresh token lifetime, rt_lifetime. These are typically in milliseconds, though you may specify units for seconds or ms explicitly. E.g., this might be part of your POST to the service

...&at_lifetime=1500 sec.&rt_lifetime=25000000&...

In this case, the client is requesting that access tokens have a lifetime of 1500 seconds and refresh tokens have one of 25000000 milliseconds. The rt_lifetime could have also been specified as 25000000 ms. or 25000 sec.

Again, clients may request just about anything, but server policies will be enforced at all times, so the actual lifetimes determined by the system may well be different. The only place these requests will be honored is in the initial request. Any other time they are ignored (such as in the token exchange).

Token configurations

Clients that need complex token configuration may specify lifetimes as parameters of the token (this is stored in the clients cfg field. Example cfg entry for a client

    {"tokens": {
        "access":  {
            "audience": "",
            "issuer": "",
            "lifetime": 750019,
            "type": "wlcg"

In this case, a WLCG token will be created with the given audience and issuer. Note that in this case, the lifetime must be in milliseconds and units are not allowed (since it is in JSON format as an long integer).


Inside scripts, which are specified in the token configuration if needed, the lifetime may be set to anything. Refer to QDL documentation for scripting and how to do it. Again, server maxima are always enforced no matter what the values are set to.

How do these all relate?

The steps are

  1. The maximum allowed lifetime is taken from the server configuration.
  2. The lifetime is taken from the client configuration. This is the initial value of the computed lifetime.
  3. Token configurations are checked for lifetimes. If present, the minimum of this and computed lifetime is taken.
  4. Requested values are checked. If there was an explicit request for a lifetime, the minimum of that and the computed lifetime is taken.
  5. Scripts may determine lifetimes independent of the computed lifetime and set this. We stress may because this is an exceptional circumstance and does nto occur often.
  6. Finally, the minimum of the computed lifetime and the computed maximum is taken. This is the final value.