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.
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.

The following sections describe how to create and sign the JWT, and how to provide it to the SinchClient.
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 JWT header:
{
"alg": "HS256",
"kid": "hkdfv1-20200102"
}The {DATE} used in the kid parameter must be the current UTC date at the time the challenge is made (when onCredentialsRequired is called).
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 |
Set the token expiration (exp) so that the token TTL is at least 1 minute.
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")))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 (
expwill be set to 600 seconds afteriat)
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:
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.EUltTTD4fxhkwCgLgj6qSQXKawpwQ952Ywm3OwQSARoMore 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.
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()
}
})
}
The client may also ask for a registration token on subsequent starts via SinchClientListener.onCredentialsRequired(). Only then should a new JWT be provided.
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.
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
}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.
We recommend a 12-month expiry unless you have reasons to keep it shorter.
The instance expiry specified in sinch:rtc:instance:exp will be used:
- as the initial instance expiry when a new instance is created
- as the new instance expiry when an existing instance tries to prolong its lifetime
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.
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.