Authentication & Authorization

Secure your application and authorize Sinch client (user) registrations.

When you initiate SinchClient, or register user via UserController you have to provide user identity. The first time the application instance and the Sinch client are running on behalf of a particular user, it's required to register against the Sinch service. The step of registering a user identity against the Sinch service requires the application instance to provide a token that authenticates the Application and grants permission (authorizes) the user to register. Once the application instance has successfully registered the user identity, the client will have obtained the necessary credentials to perform further authorized requests on behalf of the Application and for that specific user to make and receive calls.

Token-based User Registration - Overview

To authorize the registration of a user, the application must provide a registration token to the SinchClient or UserController. This token should be in the form of a JSON Web Token (JWT) signed with a signing key derived from the Application Secret.

The recommended way to implement this authentication scheme is that the Application Secret should be kept securely on your server-side backend, the signed token should be created and signed on your server, and then passed via a secure channel to the application instance and Sinch client running on a device.

The following sections describes, in detail, how to create and sign the JWT, and how to provide it to the SinchClient or UserController.

Creating a Registration Token

JWT Header

A registration token is a JWT with the following JWT header parameters:

Header Parameter Value Note
alg HS256
kid hkdfv1-{DATE} Where {DATE} is date in UTC on format YYYYMMDD

Example of JWT header:

{ "alg": "HS256", "kid": "hkdfv1-20200102" }

JWT Claims

The JWT must contain the following claims:

Claim Value / Description
iss //rtc.sinch.com/applications/{APPLICATION_KEY}
sub //rtc.sinch.com/applications/{APPLICATION_KEY}/users/{USER_ID}
iat See JWT RFC 7519 section-4.1.1
exp See JWT RFC 7519 section-4.1.4
nonce A unique cryptographic nonce
️Note:

The expiration time for the token itself (exp) should be set so that the Time-to-Live of the token is not less than 1 minute.

Signing the JWT

The JWT should be signed using a signing key derived from the Sinch Application Secret as follows. Given:

  • A function HMAC256(message, key) .
  • A date-formatting function FormatDate(date, format) .
  • The current date as variable now .
  • Sinch Application Secret as variable applicationSecret , holding the secret as a base64 encoded string.

Derive the signing key as follows: signingKey = HMAC256(BASE64-DECODE(applicationSecret), UTF8-ENCODE(FormatDate(now, "YYYYMMDD")))

Note:

Implementations of hash hmac256 to derive the key vary from language to language in terms of the order of the key, data and sometimes the hashing algorithm arguments passed, please pay attention to this.

Some examples are shown below:

JavaJavascriptPHPPython
Copy
Copied
Hmac.hmacSha256(key, formatDate(issuedAt));
Copy
Copied
crypto.subtle.sign(this._algorithm, key, this.convertUTF8ToArrayBuffer(m))
Copy
Copied
hash_hmac(string $algo, string $data, string $key, bool $binary = false): string|false
Copy
Copied
hmac.new(key, data, hashlib.sha256).digest()

Examples

Given the following input:

  • Application Key = a32e5a8d-f7d8-411c-9645-9038e8dd051d
  • Application Secret = ax8hTTQJF0OPXL32r1LHMA== (in base64 encoded format)
  • User ID = foo
  • nonce = 6b438bda-2d5c-4e8c-92b0-39f20a94b34e
  • Current time: 2018-01-02 03:04:05 UTC
  • JWT expiry = 600 seconds ( exp will be set to 600 seconds after iat )

We can construct a JWT as follows:

JWT Header:

Copy
Copied
{
  "alg": "HS256",
  "kid": "hkdfv1-20180102"
}

JWT Payload:

Copy
Copied
{
  "iss": "//rtc.sinch.com/applications/a32e5a8d-f7d8-411c-9645-9038e8dd051d",
  "sub": "//rtc.sinch.com/applications/a32e5a8d-f7d8-411c-9645-9038e8dd051d/users/foo",
  "iat": 1514862245,
  "exp": 1514862845,
  "nonce":"6b438bda-2d5c-4e8c-92b0-39f20a94b34e"
}

Derived Signing Key:

The derived signing key would in this case be AZj5EsS8S7wb06xr5jERqPHsraQt3w/+Ih5EfrhisBQ= (base64 encoded format)

Final Encoded JWT:

Note:

JWT below is only one of many possible JWT encodings of the input above. The example below is with the JSON header and payload as shown above, but with compact/minified JSON serialization and with dictionary key ordering preserved.

eyJhbGciOiJIUzI1NiIsImtpZCI6ImhrZGZ2MS0yMDE4MDEwMiJ9.eyJpc3MiOiIvL3J0Yy5zaW5jaC5jb20vYXBwbGljYXRpb25zL2EzMmU1YThkLWY3ZDgtNDExYy05NjQ1LTkwMzhlOGRkMDUxZCIsInN1YiI6Ii8vcnRjLnNpbmNoLmNvbS9hcHBsaWNhdGlvbnMvYTMyZTVhOGQtZjdkOC00MTFjLTk2NDUtOTAzOGU4ZGQwNTFkL3VzZXJzL2ZvbyIsImlhdCI6MTUxNDg2MjI0NSwiZXhwIjoxNTE0ODYyODQ1LCJub25jZSI6IjZiNDM4YmRhLTJkNWMtNGU4Yy05MmIwLTM5ZjIwYTk0YjM0ZSJ9.EUltTTD4fxhkwCgLgj6qSQXKawpwQ952Ywm3OwQSARo

More detailed examples on how to implement this in various languages, including reference data for unit tests, is available at https://github.com/sinch/sinch-rtc-api-auth-examples.

For additional information about JWT, along with a list of available libraries for generating signed JWTs, see https://jwt.io. For detailed information about the JWT specification, see https://tools.ietf.org/html/rfc7519.

Providing a Registration Token to SinchClient

When starting the client (SinchClient.start()) the client will ask for a token via SinchClientListener.onCredentialsRequired()

Copy
Copied
// Instantiate a SinchClient using the SinchClientBuilder.
const sinchClient = Sinch.getSinchClientBuilder()
    .applicationKey("<application key>")
    .environmentHost("ocra.api.sinch.com")
    .userId("<user id>")
    .build();

sinchClient.addListener(sinchClientListener);
sinchClient.start()

In your SinchClientListener class:

Copy
Copied
onCredentialsRequired: (sinchClient, clientRegistration) => {
  yourAuthServer
    .getRegistrationToken(sinchClient.userId)
    .then((token) => {
      clientRegistration.register(token);
    })
    .catch(() => {
      clientRegistration.registerFailed();
    });
};
info

Note: The client MAY also ask for a registration token on subsequent starts via SinchClientListener.onCredentialsRequired() and only then should provide a new JWT.

If you receive Instance creation rate exceededi messages on user registration, please verify you are using SinchClientListener.onCredentialsRequired()/ correctly and investigate why your application is re-registering the same user with such frequency. If you are not sure, please contact support.

Limiting Client Registration with Expiration Time

Depending on your security requirements, you may want to limit a client registration time-to-live (TTL). Limiting the client registration will effectively limit the Sinch client acting on behalf of the User on the particular device after the TTL has expired. This will prevent the client from making or receiving calls after the registration TTL has expired.

To limit the registration in time, create the JWT as described in the sections above, but with the additional claim sinch:rtc:instance:exp. The value for this claim should be in the same format as claims iat and exp, that's a JSON numeric value representing the number of seconds since Unix Epoch (UTC).

Example JWT Payload:

{ "iss": "//rtc.sinch.com/applications/a32e5a8d-f7d8-411c-9645-9038e8dd051d", "sub": "//rtc.sinch.com/applications/a32e5a8d-f7d8-411c-9645-9038e8dd051d/users/foo", "iat": 1514862245, "exp": 1514862845, "nonce":"6b438bda-2d5c-4e8c-92b0-39f20a94b34e", "sinch:rtc:instance:exp": 1515035045 }

IMPORTANT: TTL of the registration must be >= 48 hours. In other words: sinch:rtc:instance:exp - iat >= 48 * 3600.

Note:

User registration token, the registration is also bound to the particular device. Limiting the TTL of the registration is device-specific and doesn't affect other potential registrations for the same User on other devices.

️Note:

sinch:rtc:instance:exp with the standard JWT claim exp. The former is for limiting the client registration. The latter is only for limiting the TTL of the JWT itself.

Automatic Extension of Client Registration Time-to-Live (TTL)

The Sinch client will automatically request to extend the TTL of its registration by invoking SinchClientListener.onCredentialsRequired()

The request to extend the client registration TTL is triggered when the Sinch client is started and the expiry of TTL is detected to be near in the future. "Near in the future" is subject to internal implementation details, but the Sinch client will try to eagerly extend its registration and will adjust the interval according to the TTL.

️Note:

with a limited TTL has been used before for the given User on the specific device. Once a Sinch client registration has initially been constrained with a TTL, the registration can be extended in time, but not extended indefinitely.

Was this page helpful?