-
Notifications
You must be signed in to change notification settings - Fork 16
Protocol documentation
This document describes the Tiqr protocol between Tiqr clients and servers. Each step in the process is documented from the view of the server and from the client. If you're implementing a Tiqr server, you will want to adhere to the server side of the protocol. If you're developing a client, you will want to know what to send to the server.
There have been 2 major versions of the Tiqr protocol. The first, from the initial prototype, was a simple, ASCII based protocol that exchanged simple responses such as 'OK'. As the Tiqr system got more features, we needed the ability to add more data to various responses, so we eventually switched to JSON based messages.
This was done in a backward compatible way: servers include a version indicator in their authentication QR code and version headers in their responses, so that clients know what the max version is the server supports. Clients include a version header in their request, to indicate the maximum version a client understands.
The protocol to be used is the minimum of the two; e.g. if both client and server advertise version 2, then version 2 will be used for response formatting. If one of the 2 advertises version 1, then version 1 (ascii) will be used.
Example of the version header:
X-TIQR-Protocol-Version: 2
When implementing a server or a client, always include this header in any request or response.
Enrollment is the process of adding an identity to a tiqr client, by scanning a QR code. Note that creating user accounts is not discussed here, as each server implementation might have its own way of dealing with users. Most implementations will want users to create an account, and then enroll that account on their phone.
Servers should generate a QR code that the client will use to perform the enrollment. The QR code is a string of data in the form of an pseudo URI following this format:
urlhandler://metadataurl
An example:
tiqrenroll://https://tiqrserver.com/metadata?key=a9b13aaf34ff
The url consist of the following main parts:
- urlhandler: The url handler can be used to distinguish between tiqr clients. Typically a tiqr client supports any tiqr server, but if a user uses a generic QR code scanner to scan the QR, then this urlhandler can tell the user's phone which app to start up to process the QR code. 'tiqrenroll' will trigger the Tiqr app on Android and iOS.
- metadataurl: This is the URL of the endpoint that the server implements to provide the enrollment details. This url typically contains a key or session identifier or token so that the server knows which enrollment session this is about.
Once the QR code is scanned, the client must make a request to the metadata url retrieved from the QR code.
The input parameters are abritrary and depend on your server implementation. No additional parameters will be added by the client, the metadata url should already contain any variable that the server expects. The tiqr demo server for example includes a key in its metadata to match the user's browser session with the enrollment session, in order to enroll the correct user.
This methodology makes the Tiqr protocol very versatile; by having the server specify the urls and parameters, the client does not need to know any additional logic to be able to fetch the metadata.
The server will return a response that looks like the following:
{
"service": {
"displayName": "Tiqr Demo", // display name of the service
"identifier": "tiqr", // unique identifier. Using a 'com.example.tiqrserver' scheme is recommended
"logoUrl": "http://example.com/logo.png", // A url of a logo that a client may display to visualize this server.
"infoUrl": "http://example.com/about", // An info url with more information about this server
"authenticationUrl": "http://example.com/login", // The endpoint for authentication
"ocraSuite": "OCRA-1:HOTP-SHA1-6:QH10-S", // the OCRA suite the server will use for challenge/response
"enrollmentUrl": "http://example.com/enroll?key=1413ab134eff" // The endpoint for the enrollment process
},
"identity": {
"identifier": 1, // user identifier
"displayName": "John Doe" // user display name
}
}
As you can see, the response contains 2 pieces of information: info about the server itself, and info about the identity to be enrolled. The server metadata should be stored by the client for later use, alongside the identity. The identity specifies the user to be enrolled.
The enrollmentUrl should already contain any variable that the server needs to identify the enrollment and link it to the user. However it must not contain any user id or other easily identifiable information.
After retrieving the enrollment metadata, the client should generate a shared secret for this identity and pass it on to the enrollment endpoint. The endpoint to use is defined in the metadata retrieved in the previous step.
The client should perform a POST request to the URL specified by enrollmentUrl in the metadata. It should post the generated secret as part of the request, so that the server and client now have a shared secret.
POST parameters:
- secret: The generated secret
The parameters should be passed as a regular HTTP POST request.
The enrollment server endpoint should respond to the client request with the following JSON body:
{
"responseCode": 1
}
A list of all responseCodes for enrollment and their meaning:
responseCode | Description |
---|---|
1 | Enrollment OK |
101 | Enrollment error |
sessionKey The phone will post a session key, this should be passed to this method in order for the server to unlock the user's browser session.
userId The userid of the user that should be authenticated
response The response to the challenge that the phone has posted.
{
"responseCode": 1,
"attemptsLeft": 3, // optional, this is only present when responseCode is 201 and the config is set to have a maximum number of attempts, this will tell you how many attempts are still left
"duration": 5 // in minutes, optional, only present when responseCode is 204 (account blocked) and temporary blocks are enabled in the config
}
responseCode | Description |
---|---|
1 | Login OK |
200 | Login error, unknown |
201 | Invalid response, username/password combination is invalid |
202 | Invalid request |
203 | Invalid challenge |
204 | Account blocked, this could be temporary and therefore duration could be part of the response as well |
205 | Invalid user |