Authentication

Plain Auth

The most simple authentication system of the RIPS API expects a username and a password in the following custom HTTP headers for every request:

X-API-Email: yourusername
X-API-Password: yourpassword

Your credentials are the same than the ones used in the web interface of RIPS. When no credentials are given or when the given credentials are not correct a 401 error is thrown.

It is also possible to specify the headers with Base64 encoding to avoid problems with special characters:

X-API-Email-Enc: eW91cnVzZXJuYW1l
X-API-Password-Enc: eW91cnBhc3N3b3Jk

OAuth2

Besides the plain header authentication the RIPS API also supports OAuth 2.0. It is faster than the plain authentication because it reduces expensive hash calculations.

Access Token

In order to make requests to the API an access token is required. Such an access token can be obtained by sending a request to the API end-point /oauth/v2/auth/tokens. The body of the request needs to contain the following fields encoded as JSON object.

{
	"client_id": "xxx",
	"username": "yyy",
	"password": "zzz",
	"grant_type": "password"
}

A list of global available client ids can be found on the publicly available API end-point /oauth/v2/global/clients. Private clients that are tied to your user account can be managed using the /oauth/v2/clients API end-points. The username and password are the same than the ones used in the web interface of RIPS.


An example result of the access token request looks like the following.

{
	"token_type": "Bearer",
	"expires_in": 2419200,
	"access_token": "eyJ0....5XRk",
	"refresh_token": "def50200ff..02b01ec576"
}

API Requests

In order to make authorized requests the access token needs to be passed with every request in the header. The header field should look like this:

Authorization: Bearer eyJ0....5XRk

The eyJ0....5XRk part is the returned access token from the access token request. If it is no longer valid a 401 error is thrown.

Refresh Token

Passed alongside the access token is a refresh token. This can be used to generate a new access token if the old access token has expired. The expire date can be calculated by adding the seconds of the expires_in filed to the current time. Since the access token is a JWT token the expiration date can also be found in the access token itself.

To request a new access token using a refresh token a request to /oauth/v2/auth/tokens with the following JSON body needs to be made:

{
	"grant_type": "refresh_token",
	"refresh_token": "def50200...d5c943f5",
	"client_id": "xxx"
}

Additional Headers

If a request with an invalid access token is made additional headers are returned in the response besides the body to signal different error types.

  • X-API-Expired: The access token has expired. A new token needs to be created.

  • X-API-Revoked: The access token has been revoked. A new token needs to be created.

MFA (TOTP)

All users can enable Multi-Factor Authentication for their own accounts. To initialize MFA send a request (POST) to the API end-point /mfas/secret. The API returns a secret, issuer, and a label that can be used to generate a QR code for Google Authenticator or similar tools. The response looks like this:

{
    "secret": "MBMY67M6K42A5YIUCT7464WK7JUKAWOPOLYJQQZVU7IE3CPZMFJA",
    "label": "user@ripstech.com",
    "issuer": "RIPS"
}

The additional protection is not enabled yet. To enable it a second request (POST) has to be send to the API end-point /mfas/token that contains a valid, generated code. The request looks like this:

{
	"challenge": {
		"code": "123456"
	}
}

If the code is valid the API will return a token that has to be included in every API request through the header X-API-MFA. The response looks like this:

{
    "token": "6a4bfd3d469fa97499917ddb7925d320f3a0c423"
}

Be aware that a valid code can only be submitted once. There is also a brute force protection in place that limits the attempts to 3 in 30 seconds.

To disable the Multi-Factor Authentication send a request (POST) to /mfas/delete. The request has to contain a valid code as well, for example:

{
	"challenge": {
		"code": "123456"
	}
}