NAV
cURL Python

Welcome to the Authentication Cloud API

This API documentation explains in detail how to create the right HTTP requests for calling the Authentication Cloud API endpoints, listing all available parameters, HTTP requests and responses.

Add passwordless authentication and transaction signing to your own applications and services with just a few REST API calls to our Authentication Cloud API. Moreover, the Authentication Cloud also offers various additional authentication factors, like SMS or Recovery Codes. For more details about the Nevis Authentication Cloud, see our documentation.

In this pane we provide examples for both cURL and Python 3.

# Make sure you have curl installed:
curl --version

# Set your instance id and securely paste your access key:
instance=your-instance-id-abc123
read -s access_key
export instance access_key
# Requires Python 3 and the requests library: pip install requests
# Make sure this works:
import requests

# Set your instance id and securely read your access key:
instance = 'your-instance-id-abc123'
access_key = ...

When you sign up for the service, you can use the Management Console to obtain the API endpoint URL and generate an authorization token for the machine-to-machine communication with your Nevis Auth Cloud.

Endpoint

The Authentication Cloud API is organized around REST and has predictable resource-oriented URLs. The base URL for your instance is as follows:

https://{instance}.mauth.nevis.cloud/

curl "https://$instance.mauth.nevis.cloud/ping" \
  -H "Authorization: Bearer $access_key"
resp = requests.get(f'https://{instance}.mauth.nevis.cloud/ping',
                    headers = {'authorization': f'Bearer {access_key}'})
print(resp.text) # => PONG

Authentication

The Authentication Cloud API uses access keys to authenticate requests. You can view and manage your access keys in the Management Console under Custom Integrations. Authentication Cloud expects the access key to be included in all API requests to the server in a header as the following:

Authorization: Bearer {access_key}

Media Type

Throughout the API we use the following media types:

Accept: application/json
Content-Type: application/json;charset=utf-8

Our API accepts JSON-encoded request bodies, returns JSON-encoded responses. It also uses standard HTTP response codes, authentication, and verbs. If an endpoint expects a different content type, it's highlighted within the documentation.

Versioning

We release new versions of the API in a backwards-compatible way. You can expect the same version, noted in the URL, to return the same information even over time. New features are added either as new fields, options, or exposed as different resources. The API endpoint is at https://{instance}.mauth.nevis.cloud/api/v1/, the versioning scheme currently used is v1.

Current API Scheme: v1

Errors

403 Forbidden: Invalid access token provided

{
    "error": "Forbidden",
    "path": "/api/v1/users/enroll",
    "status": 403,
    "timestamp": 1600863157593
}

400 Bad Request: Request body wasn't JSON-encoded

{
    "error": "Bad Request",
    "message": "Required request body ...",
    "path": "/api/v1/users/enroll",
    "status": 400,
    "timestamp": "2020-09-23T12:13:45Z",
}

400 Bad Request: Validation error

{
    "error": "Bad Request",
    "message": "The username '%%%%%' contains invalid characters ...",
    "path": "/api/v1/users/enroll",
    "status": 400,
    "timestamp": "2020-09-23T12:15:23Z",
}

The REST API provides consistent, predictable error reporting, with HTTP status codes and detailed error messages.

The following error codes may be returned:

Error Code Meaning
400 Bad Request Indicates that the sent request is malformed, for example the request has wrong headers or invalid JSON formatting.
401 Unauthorized Indicates that the Authorization header is missing in the request.
403 Forbidden Indicates that the provided access token for the call is not valid or no longer valid.
404 Not Found Indicates that the specified resource is not found, for example the user with the supplied user ID does not exist.
405 Method Not Allowed Indicates that the API endpoint does not exist.
409 Conflict Duplicate content detected, usally in creation API calls.
412 Precondition Failed Used by the status polling endpoint to indicate a failed operation.
415 Unsupported Media Type Indicates invalid media type provided, for example sending a form encoded POST request body, instead of JSON.
5xx Any 5xx error code indicates a server-side problem and should be followed up with Nevis support.

Enroll users

The first step is to enroll an authentication factor for a user. The following is a typical enrollment flow:

  1. Your users open the login page of your application.
  2. They enter existing credentials, usually username and password. This is checked against your existing identity management system.
  3. If this login step is successful, your system calls the Nevis Authentication Cloud API to enroll the user. A QR code is returned in the response that can be displayed as part of your new login process. Users will need to use the Access App to scan the code.
  4. In the meantime, the system starts to poll the status endpoint to see whether the user completes the registration.
  5. The user downloads the Access App and scans the QR code to complete the registration of their authenticator.
  6. The Access App sends the confirmed registration directly back to the Nevis Authentication Cloud.
  7. The polling continues until it returns either "status": "succeeded" in the JSON response, indicating that the user successfully registered, or it returns an error.

From now on, the user can use the Access App to perform any authentication operation without using a password.

Enroll Your Access App

Enroll a new user for the Access App without a username. This always creates a new user.

curl "https://$instance.mauth.nevis.cloud/api/v1/users/enroll" \
  -XPOST \
  -H "Authorization: Bearer $access_key" \
  -H 'Content-Type: application/json' \
  -d '{}'
resp = requests.post(f'https://{instance}.mauth.nevis.cloud/api/v1/users/enroll',
                     headers = {'authorization': f'Bearer {access_key}'},
                     json = {})
print(resp.json())

The simplest case is enrolling a new user without any additional arguments. The code sample on the side initiates the registration flow that must be confirmed. Note that it does not contain a username, but the response returns a unique userId that identifies the user for the entire life cycle.

This endpoint starts enrollment for the Access App.

Enroll with a username for two-way linking

curl "https://$instance.mauth.nevis.cloud/api/v1/users/enroll" \
  -XPOST \
  -H "Authorization: Bearer $access_key" \
  -H 'Content-Type: application/json' \
  -d '{ "username": "u12345" }'
data = {'username': 'u12345'}
resp = requests.post(f'https://{instance}.mauth.nevis.cloud/api/v1/users/enroll',
                     headers = {'authorization': f'Bearer {access_key}'},
                     json = data)
print(resp.json())

We recommend using unique static information as the username for enrollment. To link a user to your internal systems, you may use, for example, an internal customer ID or employee ID, and provide that as a username in the user enrollment request. It is important to use information which is static and does not change over the life cycle of a user.

We also recommend using a username without any personally identifiable information (PII). A bad example would be to use the e-mail address, as this is not only PII data, but may also change over the lifecycle of a user.

HTTP Request

POST https://{instance}.mauth.nevis.cloud/api/v1/users/enroll

Parameters

Parameter In Description
username
string
body External static identifier to link a user to your systems. Can only contain a-z, A-Z, 0-9, [email protected] and is limited to max. 300 characters.
Only allowed when userId is not present.
userId
UUID
body UUID of an existing user, to start enrollment for this existing user.
Only allowed when username is not present.

HTTP Response

201 Created: Enroll Access App

{
  "userId": "7e16ba00-92e2-4fcb-b30e-1af8fdc843aa",
  "username": "u12345",
  "status": "new",
  "createdAt": "2020-10-09T12:13:11.845958Z",
  "updatedAt": "2020-10-09T12:13:11.845958Z",
  "authenticators": [],
  "enrollment": {
    "transactionId": "67cae36e-e3d5-4d67-9aa6-ab7ae3050576",
    "statusToken": "eyJhbGciO...PxOZZYow",
    "qrCode": {
      "type": "image/png",
      "size": 300,
      "dataUri": "data:image/png;base64,iVBO...YII"
    },
    "appLinkUri": "https://{instance}.mauth.nevis.cloud/open?dispatchTokenResponse=eyJub...IxIn0"
  }
}

See User for the documentation of all user attributes, like username or authenticators.

The enrollment response always contains an enrollment object with the following fields:

Field Description
transactionId
UUID
Unique identifier of this enrollment operation.
statusToken
string
Publishable token that can be used to get the status of this enrollment operation, see the Status endpoint for details.
qrCode.dataUri
URI
The PNG image of the QR code to display for the Access App to scan, can be directly displayed with an <img src="data:image/png..."/> tag.
appLinkUri
URI
The URI for mobile-only registration using deep links.

Prerequisites

Enroll Your Phone Number

Request Your SMS Code for Enrollment

Set your username and phone variables. The username can be any alphanumeric string of no more than 300 characters, while the phone should be your phone number in the international format.

curl -X POST https://$instance.mauth.nevis.cloud/api/v1/users/enroll \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $access_key" \
  -d "{ \"username\":\"$username\", \"channel\":\"sms\", \"message\":\"SMS Registration Test, code: {{CODE}}\", \"phone\":\"$phone\" }"

Enrolling a phone number enables your users to register for second factor authentication using only a phone number and any low-end mobile device. It means that mTAN via SMS is used as the second factor in addition to their existing authentication process, such as a username and password.

HTTP Request

POST https://{instance}.mauth.nevis.cloud/api/v1/users/enroll

Parameters

Parameter In Description
username
string
body External static identifier to link a user to your systems. Can only contain a-z, A-Z, 0-9, [email protected] and is limited to max. 300 characters.
Only allowed when userId is not present.
userId
UUID
body UUID of an existing user, to start enrollment for this existing user.
Only allowed when username is not present.
channel
string
body channel must be set to sms.
message
string
body A message of your choice. Only GSM-7 charset is supported, and the string must contain {{CODE}} as a placeholder for the authentication code.
phone
string
body This is the phone number that the message is sent to. The number must conform to the international format: [+][country code][area code][local phone number].

HTTP Response

{
    "authenticators": [],
    "createdAt": "2021-06-28T11:53:33.312492Z",
    "enrollment": {
        "statusToken": "eyJhbGciiJ9.ey..._ZQ6D8tw",
        "transactionId": "4bb078e1-...-20ee97eaca2d"},
    "phones": [],
    "recoveryCodes": null,
    "status": "new",
    "updatedAt": "2021-06-28T11:53:33.312493Z",
    "userId": "02c14dba-bdb2-...-9474c59a40d1",
    "username": "TestUser"
}

The enrollment response contains an enrollment object with the following fields:

Field Description
statusToken
string
Publishable token that can be used to get the status of this enrollment operation, see the Status endpoint for details.
transactionId
UUID
Unique identifier of this enrollment operation.

Verifying the Registration

Set your statusToken, userId and the registration code variables. The userId and the statusToken are returned as JSON object members by the previous API call. The code is the mTAN delivered to your phone as an SMS.

curl -v -X POST https://$instance.mauth.nevis.cloud/api/v1/users/$userId/verification \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $access_key" \
  -d "{ \"code\":\"$code\", \"statusToken\":\"$statusToken\" }"

HTTP Request

POST https://{instance}.mauth.nevis.cloud/api/v1/users/{userId}/verification

Parameters

Parameter In Description
userId
UUID
body UUID of an existing user, to start enrollment for this existing user.
Only allowed when username is not present. This string is part of the API endpoint as each user has a verification endpoint.
code
string
body This is the multi-digit code that the user received on their phone as a text message.
statusToken
string
body This is the status code returned by the registration response.

HTTP Response

HTTP/1.1 200 OK

The response is either an HTTP/1.1 200 if the verification is successful, or an HTTP/1.1 4xx otherwise.

Enroll for Recovery Codes

Enroll to Request Your Recovery Codes

Set your username variable. The username must be that of the user who requires emergency authentication.

curl -v -X POST https://$instance.mauth.nevis.cloud/api/v1/users/enroll \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $access_key" \
  -d "{ \"username\":\"$recovery_username\", \"channel\":\"recovery\" }"

Enrolling for recovery codes provides your existing users with a fallback authentication method in case they lose or damage their mobile phone. Recovery codes are a set of static 16-digit, alphanumeric, case-sensitive codes. Each can be used once for emergency authentication.

HTTP Request

POST https://{instance}.mauth.nevis.cloud/api/v1/users/enroll

Parameters

Parameter In Description
username
string
body External static identifier to link a user to your systems. Can only contain a-z, A-Z, 0-9, [email protected] and is limited to max. 300 characters.
Only allowed when userId is not present.
userId
UUID
body UUID of an existing user, to start enrollment for this existing user.
Only allowed when username is not present.
channel
string
body It must be set to recovery in order for recovery codes to be returned in the response.

HTTP Response

A set of sixteen recovery codes is returned as part of the enrollment data. Each code may be used only once. If a new batch is requested, all previous codes become invalid.

{
    "authenticators": [],
    "createdAt": "2021-07-05T07:57:12.184902Z",
    "enrollment": {
        "recoveryCodes": [
            "3YL2-...-PnZh",
            "4B90-...-fgF2",
            ...
            "YTbB-...-lCI0"
        ],
        "transactionId": "bec412cc-...-d2cb24bac64b"
    },
    "phones": [],
    "recoveryCodes": null,
    "status": "new",
    "updatedAt": "2021-07-05T07:57:12.184904Z",
    "userId": "2eda9f3c-...-a897e3bf0b7c",
    "username": "testUser20210702C"
}

The enrollment response contains an enrollment object with the following fields:

Field Description
recoveryCodes
array
Array of sixteen recovery codes that can be used for one-time authentication by this particular user.
transactionId
UUID
Unique identifier of this enrollment operation.

Enroll with FIDO2

The endpoint starts enrollment for a FIDO2-capable device that natively supports biometric authentication.

Enrolling the device

Enroll with a username that uniquely identifies your user.

curl "https://$instance.mauth.nevis.cloud/api/v1/users/enroll" \
  -XPOST \
  -H "Authorization: Bearer $access_key"  \
  -H 'Content-Type: application/json;charset=utf-8'   \
  -d '{ "username": "u_12654",
        "channel": "fido2",
        "displayName": "John Doe"
      }'

Use a unique static information as the username for enrollment. This can be used to link the user to your internal systems. An internal customer ID or employee ID, as a username can be added to the user enrollment request. It is important to use information which is static and does not change over the life cycle of a user.

We also recommend using a username without any personally identifiable information (PII). A bad example would be to use the e-mail address, as this is not only PII data, but may also change over the lifecycle of a user.

Enrolling the device with custom FIDO2 options

For more advanced enrollment, you can extend the usual username, displayName, and channel by optional fido2Options.

curl "https://$instance.mauth.nevis.cloud/api/v1/users/enroll" \
  -XPOST \
  -H "Authorization: Bearer $access_key"  \
  -H 'Content-Type: application/json;charset=utf-8'   \
  -d '{ "username": "u_12654",
        "channel": "fido2",
        "displayName": "John Doe",
        "fido2Options": {
            "authenticatorSelection": {
                "userVerification": "required",
                "authenticatorAttachment": "platform",
                "requireResidentKey": false,
                "residentKey": "discouraged"
            },
            "attestation": "none"
        }
      }'

HTTP Request

POST https://{instance}.mauth.nevis.cloud/api/v1/users/enroll

Parameters

Parameter In Description
username
string
body External static identifier to link a user to your systems. Can only contain a-z, A-Z, 0-9, [email protected], and is limited to max. 50 characters.
Mandatory for FIDO2 enrollment.
userId
UUID
body UUID of an existing user.
Cannot be set for FIDO2, as username is mandatory for FIDO2 enrollment.
channel
string
body Set channel to fido2.
displayName
string
body The human-readable name of the user. For the fido2 channel, this is an obligatory member. The length is limited to 64 bytes.
userVerification
enum
body Optional The fido2Options object contains the authenticatorSelection parameters. userVerification option values are preferred, which is the default option, required or discouraged. See User Verification Requirement Enumeration.
authenticatorAttachment
enum
body Optional The available values are platform or cross-platform. See Authenticator Attachment
requireResidentKey
bool
body Optional The value can be true or false. See Authenticator Selection Criteria.
residentKey
enum
body Optional The available values are required, preferred, or the default discouraged. See Resident Key Requirement Enumeration.
attestation
enum
body Optional The fido2Options object also contains an attestation preference, which may be none, direct, or indirect. See Attestation Conveyance Preference Enumeration.

HTTP Response

201 Created: Enroll FIDO2 device

{
    "authenticators": [],
    "createdAt": "2022-03-04T11:04:51.523566769Z",
    "enrollment": {
        "credentialCreationOptions": {
            "attestation": "none",
            "authenticatorSelection": {
                "authenticatorAttachment": "platform",
                "requireResidentKey": false,
                "residentKey": "discouraged",
                "userVerification": "required"
            },
            "challenge": "h6U-j...PUrw",
            "excludeCredentials": [],
            "pubKeyCredParams": [
                {
                    "alg": -65535,
                    "type": "public-key"
                },
                ...
                {
                    "alg": -36,
                    "type": "public-key"
                }
            ],
            "rp": {
                "id": "your-nevis-dev.mauth.nevis.cloud",
                "name": "NEVIS Authentication Cloud: your-nevis-dev"
            },
            "timeout": 60000,
            "user": {
                "displayName": "John Doe",
                "id": "ZmY0Mj...1YTky",
                "name": "u_12654"
            }
        },
        "statusToken": "eyJh...9.eyJh...ZQI-MuCQ",
        "transactionId": "e7bf20-...-56b6683"
    },
    "phones": [],
    "recoveryCodes": null,
    "status": "new",
    "updatedAt": "2022-03-04T11:04:51.523567669Z",
    "userId": "ff4-a...d5a92",
    "username": "u_12654"
}

See User for the documentation of all user attributes, like username or authenticators.

The registration response always contains an enrollment object with the following fields:

Field Description
transactionId
UUID
Unique identifier of the registration.
statusToken
string
Publishable token used to get the status of this enrollment operation, see Status endpoint.
credentialCreationOptions
DICT
The PublicKeyCredentialCreationOptions object, which contains options required to create a WebAuthn credential.
credentialCreationOptions.user
DICT
The member stores data about the user account for which the relying party requests attestation.
credentialCreationOptions.challenge
DICT
The member contains the challenge for generating the attestation credentials.
credentialCreationOptions.timeout
long
The member defines in milliseconds how much time the call has to complete.
credentialCreationOptions.authenticatorSelection
DICT
The member is used by the relying party to select an appropriate authenticator.
credentialCreationOptions.attestation
string
The member is used by the relying party to express preference for attestation conveyance.
credentialCreationOptions.rp
DICT
The member describes the relying party responsible for the request.

Next steps

Continue with Register the device

Authenticate and Approve

After a user's status becomes active and thus has at least one registered authenticator, it is possible to start an authentication or transaction approval for that user. The exact same process can be used for both login and any other transaction approval.

Similar to enrollments, an approval process is always split into two REST API calls:

  1. Start the approval process with a message and other details about the approval.
  2. Keep polling the authenticator for a change in the approval status.

The approval request, as part of a second-factor login using the Access App and QR-code login, is explained below. Polling is explained subsequently in Polling for the Status.

  1. Your user opens the login page of your application.
  2. The user enters their existing credentials, usually a username and a password. This is checked against the existing systems of the provider.
  3. After a successful login, the system triggers an approval REST API call. This call may contain a custom message, such as: "New login request to your business application".
  4. You start polling for approval by the user.
  5. The Nevis Authentication Cloud creates a QR code to be scanned by the user's mobile device.
  6. The user scans the QR code with the Access App.
  7. The user confirms the approval to "New login request to your business application" using their fingerprint scan or face recognition. The user may also deny a request if they did not initiate the login.
  8. The cryptographically signed confirmation is directly sent back to the cloud service.
  9. In the meantime, the regular polling continues, and it now returns "status": "succeeded", indicating that the user did indeed approve the request. The system then logs the user in and forwards the user to the application.

Authenticate using the Access App

Approval using QR code or deep link:

curl "https://$instance.mauth.nevis.cloud/api/v1/approval" \
  -XPOST \
  -H "Authorization: Bearer $access_key" \
  -H 'Content-Type: application/json' \
  -d '{ "channel": "app", "username": "u12345" }'
data = { 'channel': 'app', 'username': 'u12345' }
resp = requests.post(f'https://{instance}.mauth.nevis.cloud/api/v1/approval',
                     headers = {'authorization': f'Bearer {access_key}'},
                     json = data)
print(resp.json())

By default, the approval endpoint uses push notifications for approvals and confirmations. To use QR code or deep link, you can provide the channel parameter in the JSON body:

Approve using push

Approval using push:

curl "https://$instance.mauth.nevis.cloud/api/v1/approval" \
  -XPOST \
  -H "Authorization: Bearer $access_key" \
  -H 'Content-Type: application/json' \
  -d '{ "channel": "push", "username": "u12345",
        "message": "Login request for example.com" }'
data = { 'channel': 'push', 'username': 'u12345',
         'message': 'Login request for example.com' }
resp = requests.post(f'https://{instance}.mauth.nevis.cloud/api/v1/approval',
                     headers = {'authorization': f'Bearer {access_key}'},
                     json = data)
print(resp.json())

If your users cannot receive push notifications on their mobile phones, QR codes are an alternative means for authentication.

Request in-app user confirmation

Request in-app user confirmation:

curl "https://$instance.mauth.nevis.cloud/api/v1/approval" \
  -XPOST \
  -H "Authorization: Bearer $access_key" \
  -H 'Content-Type: application/json' \
  -d '{ "channel": "app", "prompt": "true", "username": "u12345",
        "message": "Login request for example.com" }'
data = { 'channel': 'app', 'prompt': True, 'username': 'u12345',
         'message': 'Login request for example.com' }
resp = requests.post(f'https://{instance}.mauth.nevis.cloud/api/v1/approval',
                     headers = {'authorization': f'Bearer {access_key}'},
                     json = data)
print(resp.json())

Rather than only asking for biometric confirmation, with the flag "prompt": true the user is shown the full message within the app, and they either approve or deny that request.

Approval with any authenticator

Approval with allowing any authenticator:

curl "https://$instance.mauth.nevis.cloud/api/v1/approval" \
  -XPOST \
  -H "Authorization: Bearer $access_key" \
  -H 'Content-Type: application/json' \
  -d '{ "channel": "app", "username": "u12345", "authenticatorId": "*" }'

Rather than starting an approval with a specific authenticator or the default (last registered) device, the user can authenticate with any registered authenticator of the user. For an approval with any authenticator, set the channel parameter to app.

Usernameless authentication

Usernameless approval request:

curl "https://$instance.mauth.nevis.cloud/api/v1/approval" \
  -XPOST \
  -H "Authorization: Bearer $access_key" \
  -H 'Content-Type: application/json' \
  -d '{ "channel": "app" }'

Usernameless authentication allows the convenience to your users authenticate without providing their username or userId. For usernameless authentication, set the channel parameter to app.

HTTP Request

POST https://{instance}.mauth.nevis.cloud/api/v1/approval

Parameters

Parameter In Description
username or userId body The user for which to create and start the approval operation.
Required if channel is not set to app.
authenticatorId
string
body Optional ID of the authenticator to which an approval is to be sent.
(Default: last registered device)
Can be set to * to allow any authenticator of the user if channel is app.
channel
enum
body By default, it is using push authentication. Use app if push is not available or in mobile-only cases.
(Default: push)
prompt
boolean
body Flag to request the user to actively accept or deny the approval.
(Default: false)
message
string
body Optional message displayed as a notification on the user device.
Required if prompt is set to true.
-method-
enum
body method is deprecated. Use channel instead. Available enum values are app, sms, recovery, and push.

HTTP response

201 Created: Approval with QR Code or deep link

{
  "transactionId": "9ede8ca8-bb5f-47f1-9d3e-f14500a3cab6",
  "userId": "7e16ba00-92e2-4fcb-b30e-1af8fdc843aa",
  "statusToken": "eyJhb...lc3g",
  "qrCode": {
    "type": "image/png",
    "size": 300,
    "dataUri": "data:image/png;base64,iVBORw0...U5ErkJggg"
  },
  "appLinkUri": "https://{instance}-app.mauth.nevis.cloud/open?dispatchTokenResponse=eyJub...AQIn3"
}

201 Created: Approval using push

{
  "transactionId": "e7c4328a-5497-4768-ac49-471db85defd4",
  "userId": "7e16ba00-92e2-4fcb-b30e-1af8fdc843aa",
  "statusToken": "eyJhb...CGJNfkA"
}

The response is slightly different, depending on the channel used for the approval.

Field Description
transactionId
UUID
Unique identifier of the approval operation.
userId
UUID
The user for which this transaction is being asked.
statusToken
string
Publishable token used to get the status of this approval operation, see the Status endpoint for details.
qrCode.dataUri
URI
The PNG image of the QR code to be displayed for the Access App to scan, can be directly displayed with an <img src="data:image/png..."/> tag.
Only for qr-code
appLinkUri
URI
The URI for mobile-only approval operations using deep links.
Only for qr-code

Authenticate with SMS

Once your phone number has been registered, you can use an mTAN as a second factor to authenticate a transaction. For example, in case of a login, after processing the usual username and password, you send a text message with a one-time code to the user's mobile to provide a second factor for authentication.

Prerequisites

Request an SMS Code for Authentication

NOTE: Set your username and access_key variables.

Authenticate a transaction

curl -v -X POST https://$instance.mauth.nevis.cloud/api/v1/approval \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $access_key" \
  -d "{ \"username\":\"$username\", \"channel\":\"sms\", \"message\":\"SMS Transaction Approval Test, code: {{CODE}}\" }"

HTTP Request

POST https://{instance}.mauth.nevis.cloud/api/v1/approval

Parameters

Parameter In Description
username or userId body Required The user for which to create and start the approval operation.
channel
string
body channel must be set to sms.
message
string
body A message of your choice. Only GSM-7 charset is supported, and the string must contain {{CODE}} as a placeholder for the authentication code.

HTTP Response

{
    "statusToken": "eyJhbGciOiJIUzUxMiJ9.eyJhd...hInHRfSw",
    "transactionId": "d9db4760-...-5cbe533389e3",
    "userId": "7a342fb4-...-bb837ed32d9d"
}

The response for the sms channel returns a status token that can be used for the verification of the transaction.

Field Description
statusToken
string
Publishable token that can be used to get the status of this approval operation, see the Status endpoint for details.
transactionId
UUID
Unique identifier of this approval operation.
userId
UUID
The user for which this transaction is being asked for.

Verify the Code

Set your userId, code and the statusToken variables.

curl -v -X POST https://$instance.mauth.nevis.cloud/api/v1/users/$userId/verification \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $access_key" \
  -d "{ \"code\":\"$code\", \"statusToken\":\"$statusToken\" }"

HTTP Request

POST https://{instance}.mauth.nevis.cloud/api/v1/users/{userId}/verification

Parameters

Parameter In Description
userId
UUID
body UUID of an existing user, to start enrollment for this existing user.
Only allowed when username is not present. This string is part of the API endpoint as each user has a verification endpoint.
code
string
body This is the multi-digit code that the user received on their phone as a text message.
statusToken
string
body This is the status code returned by the approval response.

HTTP Response

HTTP/1.1 200 OK

The response is either an HTTP/1.1 200 if the verification is successful, or an HTTP/1.1 4xx otherwise.

Authenticate with Recovery Codes

Set your code and userId variables. The userId must be the ID of the recovery_username you set previously when you enrolled for recovery codes.

curl -v https://$instance.mauth.nevis.cloud/api/v1/users/$userId/verification \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $access_key" \
    -d "{ \"code\":\"$code\", \"channel\":\"recovery\" }"

As a fall-back recovery mechanism, users can use any of their previously generated recovery codes to authenticate a transaction. To generate a set of recovery codes, see the section on enrolling for recovery codes.

You need the userId for this specific authentication channel.

HTTP Request

POST https://{instance}.mauth.nevis.cloud/api/v1/users/{userId}/verification

Parameters

Parameter In Description
userId
UUID
body Required The ID of the user for which to start the approval operation.
channel
string
body channel must be set to recovery.
code
string
body This is an alpha-numeric code containing dashes, received from the recovery codes enrollment endpoint.

HTTP Response

HTTP/1.1 200 OK

The response is either an HTTP/1.1 200 if the verification is successful, or an HTTP/1.1 4xx otherwise.

Authenticate with a FIDO2 authenticator

Approval with default FIDO2 options

curl "https://$instance.mauth.nevis.cloud/api/v1/approval"  \
  -XPOST \
  -H "Authorization: Bearer $access_key"    \
  -H 'Content-Type: application/json;charset=utf-8'     \
  -d '{ "username": "u_12654",
        "channel": "fido2"
      }'

Approval with custom FIDO2 options

curl "https://$instance.mauth.nevis.cloud/api/v1/approval"  \
  -XPOST \
  -H "Authorization: Bearer $access_key"    \
  -H 'Content-Type: application/json;charset=utf-8'     \
  -d '{ "username": "u_12654",
        "channel": "fido2",
        "fido2Options": {
            "userVerification": "required"
        }
      }'

The approval endpoint triggers device notifications for approvals and confirmations when the channel parameter in the JSON body is set to fido2.

HTTP Request

POST https://{instance}.mauth.nevis.cloud/api/v1/approval

Parameters

Parameter In Description
username or userId
UUID
body Required The user for which to create and start the approval operation.
channel
enum
body Required Set the channel property to fido2.
userVerification
enum
body Optional fido2Options is an optional object to house userVerification options. Possible values are preferred, which is the default option, required, or discouraged. For more information, see the W3 recommendations on user verification.

HTTP Response

201 Created: Approval using a FIDO2 device

{
  "statusToken": "eyJ...iJ9.ey...fVag0LMfTMX5kQ",
  "transactionId": "8b2373-...-9698e35e",
  "userId": "d517-...-7cb4521b3",
  "credentialRequestOptions": {
    "allowCredentials": [
      {
        "id": "hZAe...aNBS7rX8jBY",
        "type": "public-key"
      }
    ],
    "challenge": "2LpI-1C...drA",
    "rpId": "nevis-latest-dev-cbbc98.mauth.nevis.cloud",
    "timeout": 60000,
    "userVerification": "required"
  }
}
Field Description
transactionId
UUID
Unique identifier of the approval operation.
userId
UUID
The user for which this transaction is being asked.
statusToken
string
Publishable token used to get the status of this approval operation, see the Status endpoint for details.
credentialRequestOptions
string
The PublicKeyCredentialRequestOptions object, which contains options required to authenticate with the WebAuthn credential.

Next steps

Proceed with Authenticate using FIDO2

Verify an operation

Using the statusToken received in enrollment or approval call responses, you can poll for the status of the operation.

Status polling

Poll for the status as long as status is pending:

# Set $statusToken
curl "https://$instance.mauth.nevis.cloud/api/v1/status" \
  -XPOST \
  -H 'Content-Type: application/json' \
  -d "{ \"statusToken\": \"$statusToken\" }"
data = {'statusToken': 'eyJhb...lc3g'}
resp = requests.post(f'https://{instance}.mauth.nevis.cloud/api/v1/status', json = data)
print(resp.json())

When the polling is completed on the client side (user), then there are two ways to verify a transaction:

Get the userId with usernameless authentication

In case of Usernameless authentication, you can use the status endpoint to get the identifier of the authenticated user. Since in this case the user is not known until the authentication is successfully finished, the intermediate status responses do not contain a userId. After the user is successfully authenticated, the userId is included in the status response.

HTTP request

POST https://{instance}.mauth.nevis.cloud/api/v1/status

Parameters

Parameter In Description
statusToken
string
body Required The status token as retrieved during enrollment or approval.

HTTP response

200 OK: Pending - The transaction is still waiting for confirmation by the user

{
  "transactionId": "b7d44592-91f3-4f4b-9e37-202a3061edc3",
  "status": "pending",
  "userId": "7e16ba00-92e2-4fcb-b30e-1af8fdc843aa",
  "token": "eyJhb...Fl9bpEXGGw",
  "createdAt": "2020-10-09T12:52:48Z",
  "lastUpdatedAt": "2020-10-09T12:52:48Z"
}

200 OK: Succeeded - The transaction was successfully confirmed by the user

{
  "transactionId": "b7d44592-91f3-4f4b-9e37-202a3061edc3",
  "status": "succeeded",
  "userId": "7e16ba00-92e2-4fcb-b30e-1af8fdc843aa",
  "token": "eyJhb...Fl9bpEXGGw",
  "createdAt": "2020-10-09T12:52:48Z",
  "lastUpdatedAt": "2020-10-09T12:52:48Z"
}

412 Precondition Failed: The transaction was aborted or timed out

{
  "transactionId": "b7d44592-91f3-4f4b-9e37-202a3061edc3",
  "status": "failed",
  "userId": "7e16ba00-92e2-4fcb-b30e-1af8fdc843aa",
  "token": "eyJhb...Fl9bpEXGGw",
  "createdAt": "2020-10-09T12:52:48Z",
  "lastUpdatedAt": "2020-10-09T12:52:48Z"
}

404 Not Found: The provided status token is not known

{
  "status": "unknown",
}

You can then check for the status and react accordingly:

Field Description
transactionId
UUID
Unique identifier of the operation.
status
enum
The status of the transaction, one of pending, succeeded, failed or unknown.
userId
UUID
The user for which this transaction is being asked.
In case of usernameless authentication, the userId is only present when the status is succeeded.
token
string
Consumable token that contains the verifable result of the current status, see the Token introspection endpoint for details.

Check token validity

Check the validity and authenticity of a token:

# Set $token
curl "https://$instance.mauth.nevis.cloud/api/v1/introspect" \
  -XPOST \
  -H "Authorization: Bearer $access_key" \
  --data-urlencode "token=$token"
data = {'token': 'eyJhb...lc3g'}
resp = requests.post(f'https://{instance}.mauth.nevis.cloud/api/v1/introspect',
                     headers = {'authorization': f'Bearer {access_key}'},
                     data = data)
print(resp.json())

Use the introspect API endpoint to check whether a token is valid, and whether a transaction token was actually issued by your Authentication Cloud instance. You can use the endpoint to verify the authenticity of transaction tokens after successful authentications, especially in cases like in-band operations.

HTTP request

POST https://{instance}.mauth.nevis.cloud/api/v1/introspect

Parameters

Parameter In Description
token
string
body Required The token to verify, can be any kind of token issued or provided by the Authentication Cloud, including transaction token.

HTTP response

200 OK: Active and valid API token

{
    "active": true,
    "exp": 1613572626000,
    "iat": 1610980626000,
    "sub": "100",
    "aud": "api",
    "iss": "https://{instance}.mauth.nevis.cloud/"
}

200 OK: Invalid token

{
    "active": false,
}
Field Description
active
boolean
Indicator of whether the presented token is currently active and is issued by this instance. If false is returned, then the token is never OK and not to be trusted.
iat
timestamp
Expiration time, measured in the number of seconds since January 1 1970 UTC and indicating when this token expires, as defined in JSON Web Token (JWT) specification.
nbf
timestamp
Not before timestamp, measured in the number of seconds since January 1 1970 UTC, indicating when this token becomes valid, as defined in JSON Web Token (JWT) specification.
sub
string
The subject of the token, in case of transaction tokens, the userId of the user in the operation.
aud
enum
Audience. Service-specific string identifier or list of string identifiers representing the intended audience for this token, as defined in JSON Web Token (JWT) specification.
iss
URI
The issuer of this token, as defined in the JSON Web Token (JWT) specification. Expect here your instance in the following format: https://{instance}.mauth.nevis.cloud/.

Users and Authenticators

The primary resources within the Nevis Authentication Cloud are users, and authenticators, such as our brandable Access App.

User

Example user resource

{
  "userId": "7e16ba00-92e2-4fcb-b30e-1af8fdc843aa",
  "username": "u12345",
  "status": "active",
  "createdAt": "2020-06-16T16:42:44Z",
  "updatedAt": "2020-06-16T16:42:44Z",
  "authenticators": [
    ...
  ]
}

The user is the primary resource in the Authentication Cloud, and has a 1:1 mapping to user objects within your existing identity management system.

Field Description
userId
UUID
Unique identifier of this user.
username
string
Nullable The internal customer ID or unique identifier to link a user to your internal systems. Use information that is static, unique and ideally does not contain PII information.
status
enum
The current status of the user, either new: The user has no confirmed authenticator yet; or active: The user has registered at least one authenticator and is able to log in.
authenticators
array
List of successfully registered authenticators.

Authenticator

The authenticator resource can represent:

Access App authenticator

Example Access App authenticator object

{
  "authenticatorId": "f3ef70fc-9231-48f8-8e81-8eef7826d594",
  "name": "Anna's iPhone X",
  "type": "ios",
  "authenticatorType": "app",
  "state": "active",
  "enrolledAt": "2020-10-09T08:44:36Z",
  "updatedAt": "2020-10-09T08:44:36Z",
}

The Access App authenticator is based on the FIDO UAF protocol. This is both available as a native, brandable iOS or Android application - or for integration into existing business apps, as a native SDK for both platforms.

authenticator refers to the mobile device enrolled for the user, whereas authentication method refers to the actual means, such as biometric or PIN-based authentication.

Field Description
authenticatorId
UUID
Unique identifier of this authenticator.
name
string
The user-provided name of the authenticator, to make it easier to identify during authentication.
type
enum
For Access App authenticators defines the mobile platform: iOS (ios) or Android (android).
authenticatorType
enum
Determines the type of the authenticator. For an Access App authenticator, the value is app.

During the lifetime of a user, it may be necessary to replace their existing authenticator, that is, their mobile phone, so that they can continue accessing your systems using passwordless authentication. Use the enrollment requests and provide an existing userId or username in the process.

FIDO2 authenticator

The FIDO2 authenticator represents a FIDO2 / WebAuthn capable device. The FIDO2 authenticator can be a roaming authenticator (for example, YubiKey), or a platform authenticator (for example, a Windows 10 device with Windows Hello, or a MacBook with Touch ID).

Example FIDO2 authenticator object

{
  "authenticatorId": "ee46aeca-0419-43a4-be12-a652c0ac48a8",
  "name": "My MacBook",
  "authenticatorType": "fido2",
  "state": "active",
  "enrolledAt": "2022-02-14T15:56:37Z",
  "updatedAt": "2022-02-14T15:56:57Z",
  "fido2": {
    "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36",
    "rpId": "yourinstance.mauth.nevis.cloud",
    "aaguid": "08987058-cadc-4b81-b6e1-30de50dcbe96",
    "userVerificationRequirement": "preferred",
    "attestationConveyancePreference": "direct",
    "residentKeyRequirement": "discouraged"
  }
}
Field Description
authenticatorId
UUID
Unique identifier of this authenticator.
name
string
The user-provided name of the authenticator, to make it easier to identify during authentication.
authenticatorType
enum
Determines the type of the authenticator. For a FIDO2 authenticator, the value is fido2.
fido2.userAgent
string
Optional User-Agent sent by the browser used for registering and authenticating with the authenticator.
fido2.rpId
string
The identifier in FIDO2 integration prerequisites, for which the authenticator is registered.
fido2.aaguid
string
The Authenticator Attestation Globally Unique Identifier, a unique number that indicates the type (for example, make and model) of the authenticator.

Retrieve a user

Get user by userId

# Set $userId
curl "https://$instance.mauth.nevis.cloud/api/v1/users/$userId" \
  -H "Authorization: Bearer $access_key"
userId = '7e16ba00-92e2-4fcb-b30e-1af8fdc843aa'
resp = requests.get(f'https://{instance}.mauth.nevis.cloud/api/v1/users/{userId}',
                    headers = {'authorization': f'Bearer {access_key}'})
print(resp.json())

You can search for users by userId, or alternatively also by username.

Use the enrollment endpoint to create a new user.

HTTP Request

GET https://{instance}.mauth.nevis.cloud/api/v1/users/{userId}

Parameters

Parameter In Description
userId
UUID
path Required Unique identifier of the user to retrieve.

HTTP Response

200 OK: User is found.

404 Not found: No user with provided userId exists.

For the details of the response, see User.

Retrieve user by username

Get user by username

# Set $username
curl "https://$instance.mauth.nevis.cloud/api/v1/users?username=$username" \
  -H "Authorization: Bearer $access_key"
data = {'username':'u12345'}
resp = requests.get(f'https://{instance}.mauth.nevis.cloud/api/v1/users',
                    headers = {'authorization': f'Bearer {access_key}'},
                    params = data)
print(resp.json())

You can directly look up a user by your own unique identifier defined during the enrollment of the user.

HTTP Request

GET https://{instance}.mauth.nevis.cloud/api/v1/users?username={username}

Parameters

Parameter In Description
username
string
query Required The custom unique identifier set during the enrollment of the user.

HTTP Response

200 OK: User is found.

404 Not found: No user with provided userId exists.

For the details of the response, see User.

Delete a user

Delete a user

# Set $userId
curl "https://$instance.mauth.nevis.cloud/api/v1/users/$userId" \
  -X DELETE \
  -H "Authorization: Bearer $access_key"
userId = '7e16ba00-92e2-4fcb-b30e-1af8fdc843aa'
resp = requests.delete(f'https://{instance}.mauth.nevis.cloud/api/v1/users/{userId}',
                       headers = {'authorization': f'Bearer {access_key}'})
print(resp.status_code) # => 204

A user is deleted by their unique, permanent userId. The action also deletes all registered authenticators for this user.

HTTP Request

DELETE https://{instance}.mauth.nevis.cloud/api/v1/users/{userId}

Parameters

Parameter In Description
userId
UUID
path Required Unique identifier of the user to delete.

HTTP Response

204 No Content: User and associated authenticators are successfully deleted.

404 Not found: No user with provided userId exists.

No response body is returned in case of successful deletion.

Rename an authenticator

Change authenticator name

# Set $authenticator_id
curl "https://$instance.mauth.nevis.cloud/api/v1/authenticators/$authenticator_id" \
  -X PATCH \
  -H "Authorization: Bearer $access_key" \
  -H 'Content-Type: application/json' \
  -d '{ "name": "Personal Phone" }'
authenticator_id = 'f3ef70fc-9231-48f8-8e81-8eef7826d594'
data = {'name':'Personal Phone'}
resp = requests.patch(f'https://{instance}.mauth.nevis.cloud/api/v1/authenticators/{authenticator_id}',
                      headers = {'authorization': f'Bearer {access_key}'},
                      json = data)
print(resp.json())

As device names can be rather non-descriptive, users may want to change the name of the mobile phone they use as an authenticator. They can do this using the authenticators API endpoint.

HTTP Request

PATCH https://{instance}.mauth.nevis.cloud/api/v1/authenticators/{authenticatorId}

Parameters

Parameter In Description
authenticatorId
UUID
path Required The unique identifier of the authenticator to change the name for.
name
string
body Required The new name of the authenticator device, so it can be distinguished if multiple devices are used.

HTTP Response

200 OK: Authenticator is updated.

{
  "authenticatorId": "f3ef70fc-9231-48f8-8e81-8eef7826d594",
  "name": "Personal Phone",
  "type": "ios",
  "enrolledAt": "2020-10-09T08:44:36Z",
  "updatedAt": "2020-10-09T08:44:36Z",
}

404 Not found: No authenticator with provided authenticatorId exists.

For the details of the response, see Authenticator.

Delete an authenticator

Delete an authenticator

# Set $authenticator_id
curl "https://$instance.mauth.nevis.cloud/api/v1/authenticators/$authenticator_id" \
  -X DELETE \
  -H "Authorization: Bearer $access_key"
authenticator_id = 'f3ef70fc-9231-48f8-8e81-8eef7826d594'
resp = requests.delete(f'https://{instance}.mauth.nevis.cloud/api/v1/authenticators/{authenticator_id}',
                       headers = {'authorization': f'Bearer {access_key}'})
print(resp.status_code) # => 204

An authenticator is deleted by its unique, permanent authenticatorId. After deleting an authenticator, the user can no longer use this authenticator for authentication.

HTTP Request

DELETE https://{instance}.mauth.nevis.cloud/api/v1/authenticators/{authenticatorId}

Parameters

Parameter In Description
authenticatorId
UUID
path Required Unique identifier of the authenticator to delete.

HTTP Response

204 No Content: Authenticator is successfully deleted.

404 Not found: No authenticator with provided authenticatorId exists.

No response body is returned in case of successful deletion.

Integrating the Widget

The Authentication Widget enables Auth Cloud customers to integrate authentication capabilities into their existing infrastructure. The Widget can be embedded into a webapp in a matter of hours.

In order to prevent exposing your access key, the Authentication Widget uses temporary, one-time tokens that are tied to specific users and specific intent. Your backend needs to request these intent tokens from the Auth Cloud, using the access key, username or userId and the intent (enroll or approve). The widget, using the intent token returned by the Auth Cloud API, can then complete the transaction.

A generic flow may be as follows:

  1. Your web app asks the user for a username and whether they want to register or log in.
  2. The app sends this information bundle to your backend application.
  3. Your backend, using the securely stored access key, calls the intent API endpoint to request a token for this user for this purpose.
  4. The Auth Cloud API returns an Intent Token to your backend.
  5. Your web app creates a widget config that contains:
    • Intent token
    • Result callback function
    • brand color
    • brand logo URI
  6. Your web app instantiates the widget with the config and intent token.
  7. The widget takes over control and instructs the user to install the app, authenticate with the phone and complete the action.
  8. The widget relinquishes control and calls the result callback function with the result of the operation, for example success, and a data member with the userId, or error and a brief description.
  9. For security purposes, the widget also returns a token with the result. Your frontend should send this to you backend.
  10. Your backend doublechecks against the Auth cloud API if the token is valid. (See Checking Token Validity)
  11. If it is valid, your backend completes the transaction for your user.

Request an intent token

When requesting an intent token, you need to specify the user for whom the token is issued and the purpose of the transaction, the intent, that will be carried out. Registration for new users is enroll, transaction signing for existing users is approve.

Requesting an intent token:

curl "https://$instance.mauth.nevis.cloud/api/v1/intent" \
  -XPOST \
  -H "Authorization: Bearer $access_key" \
  -H 'Content-Type: application/json' \
  -d "{ \"username\":\"u12345\",\"operation\":\"enroll\" }"

HTTP Request

POST https://{instance}.mauth.nevis.cloud/api/v1/intent

Parameters

Parameter In Description
username or userId body Required The user for which to start the enrollment or the approval operation.
operation
enum
body Use enroll to register a new user, and approve for authenticating transactions such as a login or payment approval.

HTTP Response

200 OK

{
  "token":"eyJhb...ZgP_8NBw"
}
Field Description
token
string
An intent token that has the user and the purpose encoded. It is a one-time token to be used by the widget to complete the transaction with the Auth cloud API.