View on GitHub SciTokens

Federated Authorization for Distributed Scientific Computing

SciToken Claims and Scopes Language

Each SciToken has one or more claim associated with it. These claims are typically used to indicate the authorizations the SciToken bearer may have – but other use cases exist (such as adding monitoring or auditing information into the token chain).

In this document, we outline the claims language utilized by SciTokens. Inherent to the SciTokens concept is flexibility: each deployment of SciTokens can add domain-specific claims for their own use cases.

Standard Claims

As a SciToken is a JSON Web Token at its base, we inherit a specific claims language from RFC 7519. In this section, we outline the SciTokens-specific usage of the claims, denoting any changes in claim criticality.

SciToken Claim Semantics

The SciTokens project defines JWT claims behavior specific to our problem domain. From RFC 7519:

A producer and consumer of a JWT MAY agree to use Claim Names that are Private Names: names that are not Registered Claim Names (Section 4.1) or Public Claim Names (Section 4.2). Unlike Public Claim Names, Private Claim Names are subject to collision and should be used with caution.

Currently, the SciTokens domain-specific claims include:

SciTokens Scopes

The claims language defined by JWT is based on JSON, making it extremely flexible. However, when creating an authorization token using the OAuth2 protocol, the client may only provide a space-delimited set of scopes; it is up to the authorization server to generate an appropriate SciToken with a list of claims. SciTokens aims to standardize a set of scopes and the corresponding mapping to claims.

The server-side parsing of scopes should follow Section 3.3 of RFC6749.

A server MUST NOT return tokens with more authorization granted than requested. For example, if the client requests the following scopes:

read:/foo write:/foo/subdir

the server MAY return a token containing the following:

{
   ...
   "scope": "read:/foo/subdir write:/foo/subdir
   ...
}

Example JWT

Suppose we would like to sign the following JWT header and payload:

{
  "alg": "RS256",
  "typ": "JWT"
}
{
  "sub": "bbockelm",
  "exp": 1509991790,
  "iss": "https://scitokens.org/cms",
  "iat": 1509988190,
  "scope": "read:/store write:/store/user/bbockelm",
  "nbf": 1509988190,
  "ver": "scitoken:2.0",
  "aud": "https://transfer-server.example.com"
}

Then, the corresponding base64-encoded and signed payload would be (line breaks are given only for clarity; should not be included in the actual token):

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJiYm9ja2VsbSIsImV4cCI6MTUwOTk5MT
c5MCwiaXNzIjoiaHR0cHM6Ly9zY2l0b2tlbnMub3JnL2NtcyIsImlhdCI6MTUwOTk4ODE5MCwic2Nvc
GUiOiJyZWFkOi9zdG9yZSB3cml0ZTovc3RvcmUvdXNlci9iYm9ja2VsbSIsIm5iZiI6MTUwOTk4ODE5
MCwidmVyIjoic2NpdG9rZW46Mi4wIiwiYXVkIjoiaHR0cHM6Ly9jbXMuZXhhbXBsZS5jb20ifQ.fCty
ZQQNPaowQ5FXFVIlbt2Qpb4ui8Bkl1qXpwLKI3FQ0AKP64Ozf7NLKI8nRHaAqh9XRQAxB9YtAJAeHri
SN422-CraARoYyBdrZMtwlxphOLPkpuxbIusVYB3r4zIRt4BoB7NlqLqwVV2e5rGtkJGvi9tpY2FNr7
eZ6eBrzAg

Examples SciToken scope

In this section, we only show the token payload, not base64-encoded, and remove the standard claims in order to improve readability.

Suppose we have two token-issuing services, https://cms.cern/oauth for the CMS organization and https://ligo.org/oauth for LIGO.

A LIGO user who can read any LIGO file may need the following token:

{
   "scope": "read:/",
   "iss":  "https://ligo.org/oauth"
}

This is equivalent to the following URI-form:

{
   "scope": "https://scitokens.org/v1/authz/read:/",
   "iss": "https://ligo.org/oauth"
}

Note that the resource in the scope claim is implicitly relative to a base authorization for the LIGO organization. Here, / allows access to all LIGO files, not all files in the storage service.

To stageout to /store/user/bbockelm, a part of the CMS namespace at the CMS site T2_US_Nebraska, a user would utilize the following token:

{
   "scope": "write:/store/user/bbockelm",
   "iss":   "https://cms.cern/oauth",
}

The aud claim must be used to restrict a token to a specific endpoint:

{
   "scope": "write:/store/user/bbockelm",
   "iss":   "https://cms.cern/oauth",
   "aud":   "https://transfer.unl.edu"
}