Tokens#

Types#

ID token#

The Skalio ID service issues a long-lived ID token after successful authentication of a person. The token is in the format of a JSON Web Token. There is no limit on the number of ID tokens that can be issued for one person.

The ID token has scope idtoken.

Example:

{
  "iss": "http://skalio.com",
  "sub": "ftv_lknlywsmmmfn",
  "aud": "http://skalio.com/id",
  "iat": 1700745292,
  "jti": "z-qigy1kl9xygu8l",
  "ver": "3.0",
  "scope": "idtoken",
  "locale": "de-DE",
  "zoneinfo": "Europe/Berlin",
  "email_verified": true,
  "roles": [
    "Organization.Admin"
  ],
  "http://skalio.com/org_id": ".mzlig7-009iduhl",
  "http://skalio.com/auth_level": 1,
  "exp": 1703337292,
  "email": "b9307fef-709e-4d6b-94bf-a5d7ae44d119@example.org"
}

Note: older versions of the API may issue ID tokens with slightly different format. Example, older API version 2:

{
  "iss": "http://skalio.com",
  "sub": "9zpwrohd45ljlqy0",
  "aud": "http://skalio.com/id",
  "iat": 1693564174,
  "jti": "ds6kdg7xa316pgvc",
  "ver": "2.0",
  "scope": [
    "idtoken"
  ],
  "http://skalio.com/org_units": "[ {\n  \"uid\" : \"desc754-xc863v6y\",\n  \"privilege\" : \"admin\"\n} ]",
  "locale": "de-DE",
  "zoneinfo": "Europe/Berlin",
  "email_verified": true,
  "roles": [
    "desc754-xc863v6y:Organization.Admin",
    "desc754-xc863v6y:Service.Transfer.Use"
  ],
  "http://skalio.com/auth_level": 1,
  "exp": 1696156174,
  "email": "hank+novospace@pray4snow.de"
}

Access token#

In order to use a service, the client must provide the ID token and request an access token. The ID token contains sufficient information about the person and its privileges in order for the remote service to make its grant-decision.

Each service issues their own access tokens, and access tokens can only be used with the service that issued them.

Access tokens typically have a much shorter live time, and clients should automatically refresh tokens on demand.

Web-applications can benefit from having access tokens delivered as a cookie.

The token has scope access.

UID token#

Skalio ID also issues a shorter uid token, which contains only the unique identifier (UID) of the person. This token has a long lifetime, but very limited authority. To obtain it, a valid ID token must be used. The uid token can be used as an identifier of a person when making otherwise unauthenticated requests. It can be used to track a person across multiple requests, even when the ID token has expired. It can be used as a key for throttling requests per person. It does not authorize requests that modify data, or grant access secure resources.

The token has scope uidtoken.

Example:

{
  "aud": "http://skalio.com/uid",
  "sub": "4wly0wmk1.y9e0sy",
  "scope": "uidtoken",
  "iss": "https://skalio.com",
  "exp": 1672921050
}

Pickup tokens#

In the context of the OpenID Connect Form-post flow, Skalio ID issues a short-lived pickup-token. It can be used once to complete the flow and obtain the ID token for the authenticated person.

The token has scope preflight.

Example:

{
  "aud": "http://skalio.com/id",
  "sub": "b867_9c_lhdahdx-",
  "scope": "preflight",
  "iss": "https://skalio.com",
  "exp": 1652953134
}

It is also possible to park an ID token temporarily. To retrieve the parked token again, Skalio ID issues a very short-lived, single-use pickup-token with scope park.

Example:

{
  "aud": "http://skalio.com/id",
  "sub": "rcc5zshe6o3zwl2_",
  "scope": "park",
  "iss": "https://skalio.com",
  "exp": 1652953134
}

Delay token#

This type of token is deprecated and no longer in use.

The token has scope delay.

Multi-Factor Authentication token#

When a person requires multi-factor authentication, a mfa token is issued after successful first-factor authentication. The short-lived token contains scope mfa and a list of available factors the person can use to complete authentication. The subject contains the person's unique id.

The mfa token is used to authenticate the second-factor authentication request.

The token has scope mfa.

Example:

{
  "aud": "http://skalio.com/id",
  "sub": "k7apfcpb.sgz2sb6",
  "scope": "mfa",
  "iss": "https://skalio.com",
  "exp": 1666259895,
  "locale": "en-US",
  "http://skalio.com/authenticators": [
    "totp"
  ]
}

Principal#

An ID token authenticates a specific person. This is called the principal. The token references a principal by his unique identifier.

Token verification#

The tokens are cryptographically signed. The recipient of a token can verify the signature and thus chose to trust the encoded information. Tokens that are used across multiple services employ asymmetric cryptography:

  • An ECDSA private key is used to create the signature. The private key is protected, and only accessible to the service issuing tokens.
  • The matching public key is widely available. The remote service, consuming the token, can use it to verify the signature.

Token expiration#

Every token contains an expiration timestamp. When an ID token expires, the person must go through the authentication process again to receive a new token. When access or uid tokens expire, they must be obtained again, using the ID token for authentication.

An expired pickup-token cannot be refreshed. Instead, the client has to initiate the authentication flow again from the beginning.

Scope#

Tokens describe their purpose using a scope claim. Over time, the use of this claim will be extended.

Available scopes:

  • idtoken: The token describes the verified identity of a person and can be used to authenticate against Skalio ID.
  • uidtoken: The token describes the unique ID of a person. Used for identification only, not used for authentication.
  • preflight: The token covers the OpenID Connect authentication and can be used to fetch a Skalio ID token.
  • mfa: The token can be used to authenticate the submission of a second factor during multi-factor authentication.
  • access: The token grants access to resources. It is derived from an ID token.
  • park: The token can be used to retrieve a previously parked ID token.

Deprecated scopes:

  • delay: The token is used in an attempt to rate-limit requests.

Roles & organization membership#

An ID token contains the roles claim, describing the privileges the person has in an organization. A person can have none, one or multiple (distinct) roles in an organization. The claim contains an array of strings.

The following role types are defined:

  • Organization.Admin: can manage details of the organization and its subscriptions
  • Contract.Admin: can manage the subscriptions
  • Contract.Read: can view details of the subscriptions, such as invoices
  • Service.Transfer.Use: can use TeamBeam Transfer
  • Service.Transfer.Archive.CreateRoot: can create root-folders in TeamBeam Archive
  • Service.Drive.CreateSpace: can create new Spaces in TeamBeam Drive
  • Service.All.Use: deprecated, implies all Service.* roles
  • Service.Spaces.Use: deprecated, use Service.Drive.CreateSpace instead

Services may choose to transfer the roles claim into their access token or encode the associated permissions in any other way that the service itself understands.

Version 3.0#

A person can be member of none or one organization. The claim http://skalio.com/org_id contains the UID of the organization the person is a member of, or null if the person is not a member anywhere.

The roles claim contains a list of role types that have been assigned to the person. If the person is not a member anywhere, or if simply no roles got assigned, the claim contains an empty list.

Example:

{
  "http://skalio.com/org_id": "desc754-xc863v6y",
  "roles": [
    "Organization.Admin",
    "Service.Transfer.Use"
  ]
}

Version 2.0#

Each entry consists of the organization UID and the role identifier, separated by a colon.

Example:

{
  "roles": [
    "desc754-xc863v6y:Organization.Admin",
    "desc754-xc863v6y:Service.Transfer.Use"
  ]
}

Token blacklisting#

A person can choose to terminate the validity of an unexpired ID token. This action is commonly called "user logout". As a result of this action, the unique transaction ID of the ID token is blacklisted until the natural expiration time of the token. This information is replicated to all known remote services. See deauthentication for details.

ID tokens may get blacklisted for other reasons as well:

  • Since ID tokens encode privileges of organization members, these tokens need to be blacklisted, whenever the organization membership or assigned privileges change. Examples:
  • A person can selectively refresh or park individual ID tokens, which blacklists them. However, in this process, new ID tokens are issued.
  • For persons authenticating via Microsoft Entra, logging out of a Microsoft session is propagated to Skalio ID. This will blacklist all ID tokens issued from within that Microsoft session.
  • Other federated identity providers, such as Apple or Google, may consider a user's session as compromised, triggering the blacklisting of all sessions of the person.

A blacklisted token must be rejected by all services. Once blacklisted, an ID token can no longer be used to request a service access token.

However, this does not affect the validity of a previously issued access or uid token. It remains valid until its expiration time has passed. Therefore, it is important to balance comfort versus security when choosing the live-time of access tokens.

After an ID token has been blacklisted, the person can obtain a new token through authentication. In some cases, the Skalio ID backend returns an updated ID token directly within the response, using the HTTP header AUTHORIZATION (example: joining an organization).

Authentication levels#

An ID token contains an auth_level claim, indicating the levels of trust a token provides. The auth level is expressed as a numeric integer. The following values exist:

Level Description Purpose
0 Unverified The principal has signed up to Skalio ID, but has not yet verified his initial email address. The token is short lived. The principal is not allowed to interact with other persons.
1 Verified The principal has one or more verified email address. The principal was authenticated using a single factor (typically password).
2 multi-factor authenticated The person has used multi-factor authentication to establish the session.

Note: raising the authentication level does not blacklist the ID token. The weaker ID token remains valid, although a client has an interest to upgrade it as soon as possible.

JSON Web Token#

ID and access tokens are following the JSON Web Token format, as defined in RFC 7519. See jwt.io for more information.

The following information is encoded in the token (called claims in the JWT domain). Every token contains the following information:

  • iss (issuer): A string identifying the operator of the service.
  • sub (subject): A string containing the unique ID of the principal. This is not a human-readable id.
  • exp (expiration): The point in time until the token is valid.
  • iat (issued at): The point in time when the token was issued. Fights replay attacks.
  • aud (audience): The intended use of the token. One of:
    • http://skalio.com/id: declares it to be an ID token
    • http://skalio.com/uid: declares it to be a uid token
    • http://skalio.com/spaces: declares it to be an access token for the Novospace service
    • http://skalio.com/skp: declares it to be an access token for the TeamBeam Transfer service
    • http://skalio.com/drive: declares it to be an access token for the TeamBeam Drive service
    • ... other services as required ..

ID tokens might contain additional information, see all standard claims here. The following are claims supported by Skalio ID tokens:

  • jti (transaction ID): A unique string used to ward off replay attacks and support blacklisting (aka server-side-session-end).
  • ver (String): The version of the ID token. Valid values are: "3.0" (current), "2.0".
  • locale (String): The chosen locale of the person, separated by a dash, e.g. "en-US".
  • zoneinfo (String): The chosen timezone of the person.
  • name (String): The persons name. Optional; not present if the person did not specify their name.
  • email (String): The primary email address of the person.
  • email_verified (boolean): True if the person's e-mail address has been verified; otherwise false.
  • scope (String): The scope associated with the token. See scopes.
  • http://skalio.com/auth_level (number, >=0): Indicates the level of authentication reached. Higher numbers indicate higher degree of account security.
  • http://skalio.com/set_password (boolean, default false): If present and set to true, the token authorizes the client to set a new user password without providing the current valid password (bypassing the safety check).
  • http://skalio.com/org_units Deprecated (JSON): A list of organizational units, and the privileges that the person has in them.
  • http://skalio.com/oidc_provider (String): Only present, when the account is externally managed. The claim contains the name of the external identity provider.
  • http://skalio.com/org_id (String): Contains the UID of the organization the person is a member of; null if the person is not a member anywhere.
  • roles (Array of string): List of roles the person has been granted. See roles. May be empty, but not null.

Access tokens for Spaces contain additional information:

  • http://skalio.com/space_id (String): The public ID of the project space that the token refers to.
  • http://skalio.com/privilege (read, write, admin): The privilege with which the principal can access data in the space. Higher privileges include lower privileges.

Multi-factor authentication tokens use the following claims:

  • http://skalio.com/authenticators (Array of String): List of authenticator types that are available for the person as a second factor.

Access tokens for TeamBeam contain additional information:

  • http://skalio.com/hostname (String): The token is tied to a specific hostname.