Authentication & Authorization

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

A user identity must be provided when initiating a Sinch client. 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 SINClient. 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, and the signed token should be created and signed on your server, then passed via a secure channel to the application instance and Sinch client running on a device.

Token-based User Registration

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

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 current date in UTC on format YYYYMMDD

Example of JWT header:

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

The {DATE} passed into the kid parameter has to be valid current date at the time the challenge is made (requiresRegistrationCredentials is called).

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
Important!

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(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:

Copy
Copied
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:

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:

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

Copy
Copied
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 SINClient

When starting the client (-[SINClient start]) the client will ask for a token via -[SINClientDelegate client:requiresRegistrationCredentials:].

Copy
Copied
NSError *error;
id<SINClient> client = [Sinch clientWithApplicationKey:@"<application key>"
                                         environmentHost:@"ocra.api.sinch.com"
                                                  userId:@"<user id>"
                                                  error:&error];

client.delegate = ...;

[client start];

Provide the JWT Token issued by your server-side backend

Copy
Copied
- (void)client:(id<SINClient>)client
        requiresRegistrationCredentials:(id<SINClientRegistration>) registrationCallback {

      [yourAuthServer getRegistrationToken:[client userId]
        onSuccess:(NSString* token)^{
          [registrationCallback registerWithJWT:token];
        }
        onFailure:^(NSError* error) {
          // Notify Sinch client of failure (example if your backend auth server rejects the
          // user, but also if the request to the auth server fails due to temporary
          // network connectivity issues.
          [registrationCallback registerDidFail:error];
        }];
}
Note:

The client MAY also ask for a registration token on subsequent starts via -client:requiresRegistrationCredentials: and only then should provide a new JWT.

If you receive Instance creation rate exceeded messages on user registration, please verify you are using -client:requiresRegistrationCredentials: 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, effectively preventing the client to make or receive 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, a JSON numeric value representing the number of seconds since Unix Epoch (UTC).

Example 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",
      "sinch:rtc:instance:exp": 1515035045
    }
Important!

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

When a Sinch client registers with a 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.

Don't confuse sinch:rtc:instance:exp with the standard JWT claim exp - they're separate claims. The former is for limiting the client registration. The latter is only for limiting the TTL of the JWT itself.

Recommendation

We recommend a 12 months expiry, unless you have reasons to keep it shorter.

Important!

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

  1. Initial instance expiry when a new instance is created
  2. New instance expiry when an existing instance tries to prolong its lifetime

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

The Sinch client will automatically request to extend the TTL of its registration by invoking -[SINClientDelegate client:requiresRegistrationCredentials:] (just as it does on initial start and first registration.)

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 regularly try to extend its registration and will adjust the interval according to the TTL.

Note:

You can't provide a JWT without specifying registration TTL if a JWT 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.

We'd love to hear from you!
Rate this content:
Still have a question?
 
Ask the community.