Skip to content
Last updated

Authentication & Authorization

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

When you start SinchClient you must provide a user identity. The first time the application instance and the Sinch client run on behalf of a particular user, they must register with the Sinch service. Registration requires a token that authenticates the application and authorizes the user to register. After successful registration, the client obtains credentials to perform authorized requests on behalf of the application and that user, including making and receiving calls.

Token-based user registration

To authorize user registration, the application must provide a registration token to the SinchClient. This token should be a JSON Web Token (JWT) signed with a key derived from the application secret.

We recommend keeping the application secret securely on your backend, generating and signing the token on the server, then sending it over a secure channel to the application and Sinch client running on the device.

Token-based User Registration

The following sections describe how to create and sign the JWT, and how to provide it to the SinchClient.

Creating a Registration Token

JWT header

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

Header ParameterValueNote
algHS256
kidhkdfv1-{DATE}Where {DATE} is current date in UTC on format YYYYMMDD

Example JWT header:

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

The {DATE} used in the kid parameter must be the current UTC date at the time the challenge is made (when onCredentialsRequired is called).

JWT claims

The JWT must contain the following claims:

ClaimValue / Description
iss//rtc.sinch.com/applications/{APPLICATION_KEY}
sub//rtc.sinch.com/applications/{APPLICATION_KEY}/users/{USER_ID}
iatSee JWT RFC 7519 section-4.1.1
expSee JWT RFC 7519 section-4.1.4
nonceA unique cryptographic nonce
Token expiry

Set the token expiration (exp) so that the token TTL is at least 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(key, message).
  • 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")))

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:

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

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"
    }

Derived signing key:

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

Final encoded JWT:

Encoded output

The encoded JWT below contains both the JSON header and payload as shown above, with the claims in the same order as the example and the JSON in minified format.

eyJhbGciOiJIUzI1NiIsImtpZCI6ImhrZGZ2MS0yMDE4MDEwMiJ9.eyJpc3MiOiIvL3J0Yy5zaW5jaC5jb20vYXBwbGljYXRpb25zL2EzMmU1YThkLWY3ZDgtNDExYy05NjQ1LTkwMzhlOGRkMDUxZCIsInN1YiI6Ii8vcnRjLnNpbmNoLmNvbS9hcHBsaWNhdGlvbnMvYTMyZTVhOGQtZjdkOC00MTFjLTk2NDUtOTAzOGU4ZGQwNTFkL3VzZXJzL2ZvbyIsImlhdCI6MTUxNDg2MjI0NSwiZXhwIjoxNTE0ODYyODQ1LCJub25jZSI6IjZiNDM4YmRhLTJkNWMtNGU4Yy05MmIwLTM5ZjIwYTk0YjM0ZSJ9.EUltTTD4fxhkwCgLgj6qSQXKawpwQ952Ywm3OwQSARo

More detailed examples in various languages, including unit-test reference data, are available at https://github.com/sinch/sinch-rtc-api-auth-examples.

For additional information about JWT and 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()) for the first time with a new user, the client asks for a token via SinchClientListener.onCredentialsRequired().

    // Instantiate a SinchClient using the SinchClientBuilder.
    val sinchClient = SinchClient.builder()
            .context(applicationContext)
            .userId("<user id>")
            .applicationKey("<application key>")
            .environmentHost("ocra.api.sinch.com")
            .build()
    sinchClient.addSinchClientListener(SinchClientListener())
    sinchClient.start()

In your SinchClientListener implementation:

    override fun onCredentialsRequired(clientRegistration: ClientRegistration) {

        yourAuthServer.getRegistrationToken(userId, YourAuthCallback() {
            fun onSuccess(token: String) {
                clientRegistration.register(token)
            }
            fun onFailure() {
                clientRegistration.registerFailed()
            }
        })
    }
Subsequent starts

The client may also ask for a registration token on subsequent starts via SinchClientListener.onCredentialsRequired(). Only then should a new JWT be provided.

Instance rate exceeded

If you receive "Instance creation rate exceeded" messages on user registration, verify you are using SinchClientListener.onCredentialsRequired() correctly and investigate why your application is re-registering the same user frequently. 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 registration restricts the Sinch client acting on behalf of the user on that device after TTL expiry. This prevents the client from making or receiving calls after registration TTL has expired.

To limit registration in time, create the JWT as described above, but add the claim sinch:rtc:instance:exp. Its value should use the same format as iat and exp: a JSON numeric value representing 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
}
TTL requirements

Registration TTL must be >= 48 hours: sinch:rtc:instance:exp - iat >= 48 * 3600.

When a Sinch client registers with a user registration token, the registration is bound to the particular device. Limiting TTL is device-specific and doesn't affect registrations for the same user on other devices.

Don't confuse sinch:rtc:instance:exp with the standard JWT claim exp — they are separate claims. The former limits client registration; the latter limits the JWT's own TTL.

Recommendation

We recommend a 12-month expiry unless you have reasons to keep it shorter.

Instance expiry usage

The instance expiry specified in sinch:rtc:instance:exp will be used:

  1. as the initial instance expiry when a new instance is created
  2. as the new instance expiry when an existing instance tries to prolong its lifetime

Automatic extension of client registration TTL

The Sinch client automatically requests to extend its registration TTL by invoking SinchClientListener.onCredentialsRequired().

The request to extend registration TTL is triggered when the Sinch client starts and TTL expiry is detected to be near. "Near" is subject to internal implementation details. The client regularly tries to extend its registration and adjusts the interval according to the TTL.

TTL constraints

You can't provide a JWT without specifying registration TTL if a JWT with limited TTL has been used before for the given user on the specific device. Once a registration has been constrained with TTL, it can be extended in time, but not indefinitely.