caf_security/tokens

Tokens are the primary mechanism to implement single sign on for all the user apps.

A token is used by the client to create a secure channel with its corresponding CA running in the cloud.

We use the JSON Web Tokens (draft-ietf-oauth-json-web-token-32) format for our tokens.

Not all apps are equally trusted, and we want to ensure that a rogue app cannot reuse tokens in a different context.

We achieve that by weakening tokens with the following optional constraints:

  • appPublisher: publisher of the app hosting CAs.

  • appLocalName: name of the app in the appPublisher context.

  • caOwner: owner name of the CA.

  • caLocalName: name of the CA in the owner's context.

  • expiresAfter: Expire time of token in milliseconds since midnight January 1,1970 UTC

Tokens form a meet semi-lattice, where a meet (^) operator defines a partial ordering of tokens, i.e.,:

             A^B = A iff A <= B

and this makes it much simpler to weaken tokens.

In fact, in CAF if you have a valid token you can always request a weaker one regardless of who you are. Providing a service to manage user tokens becomes trivial.

The meet (^) operator is just simply set intersection for each of the constraints:

        a^a = a
        a^* = a
        *^b = b
        a^b = 'empty' when (a !== b and a !== * and b !== *)

and in the case of expiresAfter, pick the shortest deadline.

ACLs (Access Control Lists) are also expressed with the same semi-lattice, using the meet operator for access checks:

    ALLOW if  ACL[i] ^ Token != empty    for some ACL[i] in ACL

where the result of ^ is 'empty' if any of the constraints has an 'empty' set.

Source:

Methods

decode(tokenStr) → {tokenType}

Source:

Decode a token without doing any checks. This is sometimes useful to choose a public key for validation.

Parameters:
Name Type Description
tokenStr string

A string encoding a token.

Returns:

An untrusted token that has NOT been validated.

Type
tokenType

lessOrEqual(t1, t2) → {boolean}

Source:

Whether for tokens t1 and t2, t1 <= t2.

Note that null represents the empty token, and null <= t2 for all t2.

Parameters:
Name Type Description
t1 tokenType

A token to compare.

t2 tokenType

A token to compare.

Throws:

Malformed token.

Type
Error
Returns:

t1 <= t2

Type
boolean

meet(t1, t2) → {tokenType|null}

Source:

'Meet' (^) operation of two tokens. Performs set intersection for each constraint, and if any resulting constraint is empty it returns null, the empty token.

A missing constraint is assumed to be *, i.e., all the elements in the set.

Intersection of expiresAfter uses time intervals.

There is no validation of the tokens or signing of the result.

Parameters:
Name Type Description
t1 tokenType

A token to combine with the 'meet' operator.

t2 tokenType

A token to combine with the 'meet' operator.

Returns:

Null if the resulting set is empty or an unsigned token payload with 't1^t2'.

Type
tokenType | null

newPayload(appPublisheropt, appLocalNameopt, caOwneropt, caLocalNameopt, durationInSecopt) → {tokenType}

Source:

Constructor for a new token or acl element payload.

The type of tokenType is

 {appPublisher: string=, appLocalName:string=,
  caOwner: string=, caLocalName: string=, expiresAfter: number=}
Parameters:
Name Type Attributes Description
appPublisher string <optional>

Publisher of the app hosting CAs.

appLocalName string <optional>

Name of the app in the 'appPublisher' context.

caOwner string <optional>

Owner of the CA.

caLocalName string <optional>

Name of the CA in the owner's context.

durationInSec number <optional>

Time in seconds from 'now' till token expires.

Throws:

when input is malformed.

Type
Error
Returns:

A token or acl element payload.

Type
tokenType

satisfyACL(acl, token) → {boolean}

Source:

Checks whether a valid token satisfies an ACL (Access control List).

Inefficient with many ACLs. See module:caf_security/rules for a recommended alternative.

Parameters:
Name Type Description
acl Array.<tokenType> | tokenType

An ACL formed with one or an array of constraints using a token format.

token tokenType

A previously validated token to check 'acl'.

Returns:

True if satisfies at least one element of the ACL.

Type
boolean

sign(token, privKey) → {string}

Source:

Signs a token.

Parameters:
Name Type Description
token tokenType

Token to sign.

privKey Object

Private key for signing.

Throws:

Cannot sign.

Type
Error
Returns:

A serialized signed token.

Type
string

similar(t1, t2, ignoreExpires) → {boolean}

Source:

Deep equality of two tokens ignoring fields that are not constraints.

Note that null represents the empty token.

Parameters:
Name Type Description
t1 tokenType

A token to compare.

t2 tokenType

A token to compare.

ignoreExpires boolean

True if we ignore the token expire date.

Returns:

t1 similarTo t2

Type
boolean

validate(tokenStr, pubKey)

Source:

Validates a token.

Checks signature, expire time, and string format (ASCII alphanumeric).

Parameters:
Name Type Description
tokenStr string

A string with the encoded token.

pubKey Object

A public key to validate the token

Throws:

Token does not validate

Type
Error

validExtendedNobody(from) → {boolean}

Source:

Checks whether a username is an extended NOBODY user.

This user can have many CAs as long as their names have only two characters.

Parameters:
Name Type Description
from string

A full name, e.g., foo-bar, to check.

Returns:

True if ok, false otherwise.

Type
boolean

validUsername(username) → {boolean}

Source:

Checks whether a username contains only valid characters (lower case letters and numbers, ASCII only), and it has at least three characters.

Parameters:
Name Type Description
username string

A username to check.

Returns:

True if ok, false otherwise.

Type
boolean