Authorization and Access

Last updated 3 months ago

Accessing mitter APIs

This section details the various ways the Mitter.io APIs can be accessed. There are three primary ways that these APIs can be accessed:

  1. By making an anonymous call to a public API. Do note that some public APIs, even though they are public, return a different (or rather a more informative) response when called in an authenticated context.

  2. Calling the API as an application. This is generally used for wide-user operations, creation and management of chats.

  3. Calling the API as a user. This is generally used for managing user profile and messaging.

One of the main differences between methods 2 and 3 is that calling an API as a user can be done purely from a remote-client. A mobile app or a web app can directly make calls to the API as an authenticated user via federated authentication. In contrast, calling an API as an application must only be done from a secure server because this requires non-distributable credentials.

There is also another way, where APIs are called as a subscriber - but these APIs are currently marked internal; and while they can be called using the issued tokens, such usage is highly discouraged. There is a possibility of Mitter.io providing Subscriber-level authentication credentials for making API calls. These APIs generally give access to the provisioning and management of a subscriber's applications.

Application Access Keys

You can request an access key for your application to make calls to the API authenticated as an application. Do note that there is a hard limit on the number of access keys that can be generated for an application (currently 3) and these credentials are expected to be kept securely with extremely limited distribution. As opposed to user-level tokens, a revocation is expected only to occur in the case of the credentials being compromised.

To get a new Access Key, go to your application panel, and click on the 'Access Keys' tab, followed by the 'New access key' button.

Once you do, you will be provided with the following dialog:

Do note that the Secret is presented to the user exactly this one time. Once the user closes the dialog, this information can never be retrieved. It is extremely critical for application security that this secret be never transmitted on the wire.

If you are using one of our SDKs, you can use the AccessKeyTestClient / accessKeyTestClient to run test methods to verify that the keys you have copied are valid.

Signing Algorithm

The secret is never transmitted over the wire for proving authenticity (as you would a password), but rather is used to prove the possession of such a password. For every request, a signing algorithm is followed, which imposes the following requirements on the request:

  1. A method with a non-prescribed body is treated as if its content is an empty string (with reference Md5 hash (base64): 1B2M2Y8AsgTpgAmY7PhCfg==)

  2. It must contain a Date header, with the value reflecting the time the request was made. A maximum clock skew of 25 seconds is tolerated. Time values differing from the server time more than that duration are aborted immediately.

  3. It must contain a randomly generated string against the header Nonce. This value cannot be repeated in any request executed in the last 35 seconds (calculated against server time). A value generated with sufficient entropy need not worry about this constraint - it is statistically guaranteed to have not repeated.

The following headers are mandatory:

  1. Date (see above for value restrictions)

  2. Nonce (see above for value restrictions)

  3. X-Mitter-Application-Access-Key The Access Key that was generated

  4. Content-Type The content type of the request

  5. Content-Md5 Base64 value of the MD5 hash of the payload of this data. For methods like GET, it is the hash of the empty string (1B2M2Y8AsgTpgAmY7PhCfg==)

  6. Authorization A string Auth <access-key>:<digest> where <access-key> is the generated access key and <digest>

    is the computed digest as per the algorithm below.

Algorithm for computing the digest:

  1. Construct a string which is the concatenation of the following fields with alternating newline characters (0xB):

    1. The HTTP method of the call in uppercase

    2. The Content-Type

    3. The Base64 of the Md5 hash of the payload.

    4. Value of the date header that will be supplied along with the request.

    5. The path of the request

    6. Value of the nonce that will be supplied along with the request.

  2. Compute the HmacSha1 digest of the string.

  3. Get the Base64 representation of the digest.

An example of the algorithm in node.js is available here: https://git.mitter.io/mitter-io/mitter-ts-node/blob/master/src/auth/AccessKeySigner.ts

User Tokens

User Tokens are simple JWTs issued to the user. These JWTs contain a session identifier that the server uses to identify the user. Mitter.io only allows signed JWTs to be used and hence, JWTs are to be used as-is from the server, and the server does not allow any choice of signing algorithm or construction of the JWT. For more details on fetching user tokens, refer to our docs on Federated Authentication.

Currently, user tokens can be created by the application (using an access key) from a server backend, or by using Federated Authentication (such as OAuth) if developing a serverless apps. Refer to the section Federated Authentication for more details.

Any user-level operation MUST declare the application within which the operation is being performed. This is done by setting the HTTP header X-Mitter-Application-Id in the request with the application id as the value.

Sudo User Access

Sometimes it is useful to act on behalf of a user while still using Application credentials, rather than fetching user tokens and managing the whole token lifecycle. Usually, backend services that power your applications will often require to simulate actions as if they were performed by a user (especially if it is a bot or a machine-type user). To do so, follow the same process as the above to sign the request and add all the required headers. In addition to those, another header X-Mitter-Sudo-User-Id can also be provided to make the request behave as if it was performed by the user. For instance, given a user with user ID 7479a76c-a9db-47ff-871e-af6c1f7155e1, the following request is the same as performing the request while using one of the user tokens generated by the user:

GET /v1/channels/my-channel/messages
X-Mitter-Application-Access-Key: <access-key>
.. other digest headers ..
X-Mitter-Sudo-User-Id: 7479a76c-a9db-47ff-871e-af6c1f7155e1

Subscriber Access Keys

Similar to Application access keys, Mitter.io also provides a way to authenticate as a subscriber when making all API calls, giving you API access across all your applications and resources while maintaining a single access credential.

Unless you have a very specific use-case that might involve using a dynamic number of applications (the most common use case is when your product itself is tenanted and every client maps to a unique application on Mitter.io), avoid using these type of credentials as they give complete, unrestricted access to all of your subscriber resources.

NOTE To prevent systematic abuse, subscriber access keys are only provided on a case-by-case basis. If you have identified a use for the same, please reach out to contact@mitter.io with your use case to request subscriber access keys.

When using subscriber access keys, all API calls must identify an application. A subscriber access key allows you to sudo to any application within your account. To do so, specify the X-Mitter-Sudo-Application-Id header. For example, a request to GET /v1/channels/my-channel/messages would now look like:

GET /v1/channels/my-channel/messages
X-Mitter-Subscriber-Access-Key: <subscriber-access-key>
X-Mitter-Sudo-Application-Id: <application-id>

If such a header is not provided, for any of the application-specific APIs, you will get an error with 403 status and error code missing_context.

The other headers, i.e., the computed digest in the Authorization header, Date, Nonce, Content-MD5, etc. must also be provided as specified in the Signing Algorithm section.

If required, you can further sudo to a particular user within this particular application:

GET /v1/channels/my-channel/messages
X-Mitter-Subscriber-Access-Key: <subscriber-access-key>
X-Mitter-Sudo-Application-Id: <application-id>
X-Mitter-Sudo-User-Id: 7479a76c-a9db-47ff-871e-af6c1f7155e1

You can also use subscriber access keys to create new applications via an API, but it is not publically supported for all accounts. When you apply for subscriber access keys, and if one is provisioned to you, a separate reference document will also be provided for dynamically creating applications (if your use case requires it).