Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Introduction

This page introduces how we will implement passwordless login for set top boxes.

It describes the standard flow to implement passwordless login with Amino supplied STB interacting with Amino API

Solution summary

In three lines, the solution hinges on this:

  1. When logging in the STB makes a claim about its identity to Amino
  2. Amino is able to verify that claim
  3. We know which user has which STB and so can log the user in

Drawio
bordertrue
viewerToolbartrue
fitWindowfalse
diagramNamebig picture
simpleViewerfalse
width400
diagramWidth842
revision1

Table of Contents


User Stories

High level diagrams

Manufacturing process

Drawio
bordertrue
viewerToolbartrue
fitWindowfalse
diagramNamemanufacture
simpleViewerfalse
width600
diagramWidth771
revision1

Entone has a certificate authority (CA).

At the time of manufacture an RSA keypair signed by this CA will be added to the box.

User provisioning


Drawio
bordertrue
viewerToolbartrue
fitWindowfalse
diagramNameuser provisioning
simpleViewerfalse
width600
diagramWidth811
revision12

The user purchases a STB.

The retail partner provisions a user account by calling the user management API (documentation)

The retail partner links the STB to the user (documentation)

The retail partner only needs to inform Amino of the STB mac addressserial number

Info

You can see details of how to manage the user account here on this page.

User login


Drawio
bordertrue
viewerToolbartrue
fitWindowfalse
diagramNameuser login
simpleViewerfalse
width600
diagramWidth1061
revision23

Note:

The Entone API will include the STB public key as one of the claims of the signed JWT token.

Detailed flow

Details of logging in with JWT

Sequence overview

  1. Client calls the Entone API to get a JWT used for logging in
  2. Client sends login JWT token to Middleware
  3. Middleware responds with two tokens that can be used to authenticate future requests

This is diagrammed in the section "user login" above.

Entone API

The View team will add a new function to the API with the following signature:

String ENTONE.stb.createJWT(algorithm, claim) 

Where claim is a object containing the payload of the JWT, algorithm is the mechanism to sign the signature.

The returned string is a JWT which is based64 encoded string. 

Parameters to pass to Entone API

The algorithm must be one of the values supported as the "alg" parameter in the JWT spec (here).  The only algorithm supported is RSA with sha-256 and so the algorithm parameter value should always be "RS256".

The client MUST use this format for the claim object:

Code Block
languagephp
$claim = [
    "iss"                => "EntoneAPI",
    "iat"                => time(),
    "exp"                => time() + TEN_MINUTES,
    "aud"                => "www.aminocom.com",
    "subsn"                 => "Serial number 12325-1234567",
    'certificate'  "cdsn"        => getPublicKey(),     'batchCACertificate' => getBatchCACertificate(),
];

It will receive a JWT from EntoneAPI and must then call the MoveAPI endpoint as below.

MoveAPI

Endpoint

Method typeURLAuthorizationPOSThttps://domain.tld/api/stb/authService-Token

The code behind this endpoint must be modified to accept the JWT token. 

We cannot make a breaking change to the endpoint that will affect other customers.

Options to consider:

  • Make signature optional and if it is missing assume that the token is a JWT (bad, makes magic assumption, could be made better through strategy pattern though, I guess)
  • Add a new optional parameter for JWT (slightly better, but then we're having two parameters for token)
  • Use a new version of the endpoint

Note:

  • It would be better to have a new endpoint for this, but we need to use the most efficient way of doing this

Service authorization

Is this 100% needed?

Validation rules

The MoveAPI must validate the JWT as follows:

  1. Decode the JWT
  2. Retrieve the supplied public key from the "certificate" claim
  3. Retrieve the suppled CA certificate from the "batchCACertificate" claim
  4. Verify that:
    1. The issuer is EntoneAPI
    2. The audience is www.aminocom.com
    3. The token has not expired
    4. The token was issued in the past, or otherwise within a tolerable window to allow for server time drift
    5. JWT was signed with the key you obtained in step 2
  5. Verify that the CA certificate is signed by the Entone CA certificate
  6. Obtain the "sub" claim
  7. Find the user associated with the STB serial code indicated in the "sub"

(warning) It is important that the JWT is signed with the supplied key AND that the key was generated from the Entone root CA

(warning) Note: Please expect different "iss" types that have different logic.  Try to encapsulate steps of 3 to 6 and link it to this specific "iss" type.... in other words deploy this as a changeable strategy in case we ever want to support other issuers of JWT (which seems plausible right now).   I don't want to have loads of jwt login endpoints, like one for Entone, one for Bob, another for Alice.  I'd rather we're able to use one JWT login url and swap logic depending on the "iss"

Response

The Move Middleware will respond with two JWT tokens that can be used for authentication in future requests.  This is identical to DNA.

200
{
"jwt": "jp0cnVlLCJjb21wYW55IjoiVG9wdGFsIiw...",
"jwt_expiry": "Fri, 04 Dec 2015 16:01:07 +0000",
"refresh_token": "WkiUzKELZ49eM7oWxAQK_ZX...",
"refresh_token_expiry": "Fri, 04 Jan 2016 16:01:07 +0000",
"client_keystore": "MIIKwIBAzCCoYCSqGSIb3...",
"serial_no": "615500266162",
"chipset_id": "8c10d4de5760",
"mac": "8C10D4DE5761",
"user_id": "email@example.com"
}

JWT token both jwt and refresh_token are encrypted using a pass phrase and HS256 encryption.

Pass phrase is configurable by config file and will be shared separately.

JWT Sample Data

{
"iss": "dna.booxmedia.com",
"aud": "dna.booxmedia.com",
"type": "access",
"jti": "lAjYiDbptZ",
"iat": 1459161322,
"nbf": 1459161323,
"exp": 1459161922,
"data": {
         "stb": "370",
          "serial_no": "615500266162",
         "chipset_id": "8c10d4de5760",
         "mac": "8C10D4DE5761",
         "userId": "email@example.com"
}
}

401none -

Logout STB

API to handle logout request of STB

Request

MethodURLAuthorization
POST
https://boox.fi/api/stb/logout
STB (Using JWT), Service (Using service_token)

POST Body

Please note that M is for Mandatory and O is for Optional. 

Body FieldsM/ODescriptionValues
service_token
M

Token generated for a service. For example DNA has own service_token.

This token is generated from Backend and provided to application developers.

Warning

This token should be kept in a secured location on application, i.e STB

This param will be skipped if Service-Token HTTP Header  exists.
String of Alpha numeric values. Mostly MD5 or SHA1 string.
 e.g. 8f9cf3f5789e16124f38936954a98668

Headers

Please note that M is for Mandatory and O is for Optional.

HeaderM/ODescription
Authorization: Bearer
MJWT json web token provided by backend after STB authenticated successfully

Response

HTTP CodeResponse200

none

401none

Link STB to a User

After user bought a STB this API need to be called. This API link or grant ownership of a STB to a user.

Request

MethodURLAuthorization
POST
https://boox.fi/api/management/stb/link_user
IP, Service (Digest Authentication)

POST Data Parameters

Please note that M is for Mandatory and O is for Optional.

ParametersM/ODescriptionValuesserviceMService to which the user belongs.String of service username. Shared separately.
serial_no
MSerial Number of STB. If device does not exists with provided serial no then it will be added.

Alpha numeric string.
e.g.  615507895162

email
MEmail address of user who is provisioned for using the STBValid email address.
e.g. john.doe@example.com 
public_keys
M

8 Public keys which will be used to authenticate the STB.

Note

Public keys are stored based on the POST body order.

So first public key is considered having key index 0.

Last public key is considered having key index 7.

key0_base64;key1_base64;...........;key7_base64 (no limit on max length).

where each public key is base-64 encoded,semicolon(;) is used between keys as separator.

chipset_idOSTB device chipset number/ID.chipset_id is a random list of characters (max 32 characters).macOEthernet interface MAC address.mac is a random list of characters (max 18 characters).

Response

HTTP CodeResponse200

{

	"id": "123",
	"serial_no": "DNA-STB0001",
	"user": {
		"id": "10001",
		"email": "stb_user@dnastb.com"
	}
}
400
{
  "error" {
    "code": 9,
    "text": "Access to this resource is locked to IP addresses"
  }
}
401none

Error Codes

Error CodeDescription1414Email does not exist1426Parameter is required1427Invalid length of chipset_id1428Invalid length of mac1433STB exists and linked1434Record already exists for value1435STB is already assigned1436Invalid email address format

Unlink STB from User

This API remove ownership of a STB from an user. Use cases: when user sells his/her device, when a device got stolen. 

Request

MethodURLAuthorization
POST
https://boox.fi/api/management/stb/unlink_user
IP, Service (Digest Authentication)

POST Data Parameters

Please note that M is for Mandatory and O is for Optional.

ParametersM/ODescriptionValuesserviceMService to which the user belongs.String of service username. Shared separately.
serial_no
MSerial Number of STBAlpha numeric string.
e.g.  615507895162
email
MEmail address of user who is provisioned for using the STBValid email address.
e.g. john.doe@example.com 

Response

HTTP CodeResponse200

none

400
{
  "error" {
    "code": 9,
    "text": "Access to this resource is locked to IP addresses"
  }
}
401none

Error Codes

Error CodeDescription1414Email does not exist1426Parameter is required1432serial_no does not exists1418Invalid STB link1436Invalid email address format

Add New User Account

Info
Existing API linkhttps://dna.booxmedia.com:10086/docs/d5/d8b/user_management.html#add_account

This API is used to add a new user account. Following rules apply:

  • Email address or customer-id should not belong to any customer that is not in DELETED state; otherwise API will return an error.
  • If the user with that email exists in DELETED state and his grace period is not expired, his previous registration state is restored.
  • A new user is created in UNREGISTERED state.

Design Points (to be considered for future):

  1. The main problem with making the two pin params as mandatory is that this feature is very specific to a customer requirements, while other frontends don't expect them. Therefore, we need a way so that both parties remain happy by giving a better design.
  2. For that we should make it configurable whether the two params are mandatory. So for those who require those PINs, we will configure them as mandatory, so that if they are not provided by 3rd provisioning system when creating a new user API will return an error to provide the mandatory input param. While for others, we will configure them as optional so that if they don't provide the params, API will successfully create a user and set the pins in DB as NULL (empty).
  3. It is easy to implement from effort point of view and much flexible and reliable

Request

Method Type
"Client Device-allocated Serial Number 48318382081",
    'certificate'        => "String containing the STB public key"
    'batchCACertificate' => "String containing the STB batch CA certificate",
];

It will receive a JWT from EntoneAPI and must then call the MoveAPI endpoint as below.

Example of generating a JWT

Code Block
languagejs
themeEclipse
titleJavascript example of creating JWT
collapsetrue
let passwordlessLoginHandle = null;
export const passwordlessLogin = async () => {
  if (!ENTONE) {
    return Promise.reject();
  }

  // Combine concurrent login requests
  if (passwordlessLoginHandle) {
    return passwordlessLoginHandle;
  }

  const now = sdk.time.get();
  const claim = {
    iss: "EntoneAPI",
    iat: now,
    exp: now + 60 * 10,
    aud: "www.aminocom.com",
    sn: ENTONE.stb.getFullSerialNumber(),
    cdsn: ENTONE.system.getIrdetoCDSN() || "",
    certificate: ENTONE.stb.getPublicKey(),
    batchCACertificate: ENTONE.stb.getBatchCACertificate()
  };
  const token = ENTONE.stb.createJWT(ENTONE.stb.ALG_RS256, claim);

  passwordlessLoginHandle = sdk.user.stbLogin(token);

  try {
    const user = await passwordlessLoginHandle;
    setUserCallback && setUserCallback(user);
    passwordlessLoginHandle = null;
  } catch (error) {
    passwordlessLoginHandle = null;
    throw error;
  }
};

window.passwordlessLogin = passwordlessLogin;


What is the STB serial number?

Amino STBs with Irdeto Chipset contain several identifiers, two of them are:

  1. SN - basic serial number (printed on the STB) (73-2345532)
  2. CDSN - secure SN, which is stored on the device. STB UI gets it via Entone JS API, sends it to Amino backend. Entitlements with Irdeto are based on this identifier (6454386863). This is device id.

The basic STB serial number is composed of two parts: the hw model prefix and the ESN. e.g. 87(hw model)-6593553 (ESN). and the mac address is derived from the ESN of the STB.

MoveAPI

Endpoint

Method typeURLAuthorizationParameters
POST
https://domain.tld/api/stb/auth
Service-TokenThe JWT must be passed as POST body parameter named "Token"

Validation rules

The MoveAPI must validate the JWT as follows:

  1. Decode the JWT
  2. Retrieve the supplied public key from the "certificate" claim
  3. Retrieve the suppled CA certificate from the "batchCACertificate" claim
    1. If it is omitted then read the CA certificate for batch 0133 from disk
  4. Verify that:
    1. The issuer is EntoneAPI
    2. The audience is www.aminocom.com
    3. The token has not expired
    4. The token was issued in the past, or otherwise within a tolerable window to allow for server time drift
    5. JWT was signed with the key you obtained in step 2
  5. Verify that the CA certificate is signed by the Entone CA certificate
  6. Obtain the "sn" claim
  7. Find the user associated with the STB serial code indicated in the "sn" claim

(warning) It is important that the JWT is signed with the supplied key AND that the key was generated from the Entone root CA

Info

If the CDSN is stored in the STBDevice table then the API needs to compare the "cdsn" claim


Response

The Move Middleware will respond with two JWT tokens that can be used for authentication in future requests.

200
{
"jwt": "jp0cnVlLCJjb21wYW55IjoiVG9wdGFsIiw...",
"jwt_expiry": "Fri, 04 Dec 2015 16:01:07 +0000",
"refresh_token": "WkiUzKELZ49eM7oWxAQK_ZX...",
"refresh_token_expiry": "Fri, 04 Jan 2016 16:01:07 +0000",
"client_keystore": "MIIKwIBAzCCoYCSqGSIb3...",
"serial_no": "615500266162",
"chipset_id": "8c10d4de5760",
"mac": "8C10D4DE5761",
"user_id": "email@example.com"
}

JWT token both jwt and refresh_token are encrypted using a pass phrase and HS256 encryption.

Pass phrase is configurable by config file and will be shared separately.

JWT Sample Data

{
"iss": "example.com",
"aud": "example.com",
"type": "access",
"jti": "lAjYiDbptZ",
"iat": 1459161322,
"nbf": 1459161323,
"exp": 1459161922,
"data": {
         "stb": "370",
          "serial_no": "615500266162",
         "chipset_id": "8c10d4de5760",
         "mac": "8C10D4DE5761",
         "userId": "email@example.com"
}
}

401none -

Refreshing the access token

The JWT is valid for an hour, configurable at deployment time. The client should use the refresh token to obtain a new access token when access token is expired or about to expire.

This can be done by calling

POST https://domain.tld/api/stb/auth/refresh_token?refresh_token=123abc...

The refresh token should be supplied as a query string parameter.

The API will respond with a new access token and refresh token


Logout STB

API to handle logout request of STB

Request

MethodURLAuthorization
POST
https://customer.domain/api/stb/logout
STB (Using JWT), Service (Using service_token)

POST Body

Please note that M is for Mandatory and O is for Optional. 

Body FieldsM/ODescriptionValues
service_token
M

Token generated for a service.

This token is generated from Backend and provided to application developers.

Warning

This token should be kept in a secured location on application, i.e STB

This param will be skipped if Service-Token HTTP Header  exists.
String of Alpha numeric values. Mostly MD5 or SHA1 string.
 e.g. 8f9cf3f5789e16124f38936954a98668

Headers

Please note that M is for Mandatory and O is for Optional.

HeaderM/ODescription
Authorization: Bearer
MJWT json web token provided by backend after STB authenticated successfully

Response

HTTP CodeResponse
200

none

401none

Link STB to a User

After user bought a STB this API need to be called. This API link or grant ownership of a STB to a user.

Request

MethodURLAuthorization
POST
https://boox.fi/api/management/stb/link_user
IP, Service (Digest Authentication)
Query Strings

POST Data Parameters

Please note that M is for Mandatory and O is for Optional.

Querystrings
String of service username. Shared separately. the user.
ParameterParametersM/ODescriptionValues
serviceMService to which the user belongs.belongs.String of service username. Shared separately.
serial_no
MSerial Number of STB. If device does not exists with provided serial no then it will be added.

Alpha numeric string.
e.g.  615507895162

email
MEmail address (being used as an user identifier in AminoTV) of Email address of the user
cidMCustomer Identifier.Numeric ID generated from Visio
auth_pinM

Authentication PIN code.

Info
titleChange

This is new field.

At the DNA TV Rel 2.9 publish time, the provisioning party (Visio)
is not capable of supporting this. Change to optional temporarily. See Design Points above

Number with the length of 4.
e.g. 8798 
purchase_pinM

Purchase PIN code.

Info
titleChange

This is new field.

At the DNA TV Rel 2.9 publish time, the provisioning party (Visio)
is not capable of supporting this. Change to optional temporarily. See Design Points above

Number with the length of 4.
e.g. 8798 
dobOUser Date of birth in YYYY-MM-DD format.SUSPEND or ACTIVATE keywords are allowed only.

Error Codes

Error CodeDescription1403email is missing1405cid is missing1406auth_pin is missing1407purchase_pin is missing1412Email already exists1413CID already Exists

Edit Existing User Account

Info
Existing API linkhttps://dna.booxmedia.com:10086/docs/d5/d8b/user_management.html#edit_account

This API is used to suspend or activate a user account. It can also be used to change the email or customer-id of an existing account. Following rules apply:

  • A user in DELETED state is not updated.
  • "email" and "cid" parameters should not belong to any existing user, even if the user in in DELETED state
  • If a user is suspended, his state is changed to DISABLED
  • If a DISABLED user is activated and grace period has not expired, then previous registration state is restored, otherwise his state is changed to UNREGISTERED
  • In other cases, if a user is activated, his state changed to REGISTERED.

Request

Method TypeURLAuthorizationPUThttps://boox.fi/api/management/user/<email>Service (Digest Authentication)
user who is provisioned for using the STBValid email address.
e.g. john.doe@example.com 
public_keys
O

Public keys which will be used to authenticate the STB. Maximum 8 keys.



key0_base64;key1_base64;...........;key7_base64 (no limit on max length).

where each public key is base-64 encoded,semicolon(;) is used between keys as separator.


chipset_idOSTB device chipset number/ID.chipset_id is a random list of characters (max 32 characters).
macOEthernet interface MAC address.mac is a random list of characters (max 18 characters).

Response

HTTP CodeResponse
200

{

	"id": "123",
	"serial_no": "STB0001",
	"user": {
		"id": "10001",
		"email": "stb_user@example.com"
	}
}
400
{
  "error" {
    "code": 9,
    "text": "Access to this resource is locked to IP addresses"
  }
}
401none

Error Codes

Error CodeDescription
1414Email does not exist
1426Parameter is required
1427Invalid length of chipset_id
1428Invalid length of mac
1433STB exists and linked
1434Record already exists for value
1435STB is already assigned
1436Invalid email address format

Unlink STB from User

This API remove ownership of a STB from an user. Use cases: when user sells his/her device, when a device got stolen. 

Request

MethodURLAuthorization
POST
https://customer.domain/api/management/stb/unlink_user
IP, Service (Digest Authentication)

POST Data Parameters

Please note that M is for Mandatory and O is for Optional.

username. Shared separately.Number with the length of 4
ParameterParametersM/ODescriptionValues
serviceMService to which the user belongs.String of service
emailONew email address of the user. Defaults to no value.Email address of the user
cidONew customer Identifier. Defaults to no value.Numeric ID generated from Visio
auth_pinO

Authentication PIN code.

Info
titleChange

This is new field.

username. Shared separately.
serial_no
MSerial Number of STBAlpha numeric string.
e.g.  615507895162
email
MEmail address of user who is provisioned for using the STBValid email address.
e.g. 8798 
purchase_pinO

Purchase PIN code.

Info
titleChange

This is new field.

Number with the length of 4.
e.g. 8798 
actionOSUSPEND or ACTIVATE keywords. Defaults to no value.SUSPEND or ACTIVATE keywords are allowed only.. john.doe@example.com 

Response

HTTP CodeResponse
200

none

400
{
  "error" {
    "code": 9,
    "text": "Access to this resource is locked to IP addresses"
  }
}
401none

Error Codes

cid is invlid
Error CodeDescription
1407action value is invalid
100User not found in the system
1404email is invalid
1406
1414Email does not exist
1426Parameter is required
1432serial_no does not exists
1418Invalid STB link
1436Invalid email address format