New User Authentication API
These API calls are only supported for organizations that are integrated with Active Directory. It will perform just-in-time user provisioning for users that don't have an existing Arculix account.
Note
For an overview of the Authentication API, including a glossary of terms and prerequisites, see Authentication API.
Authenticating to the API
This REST API uses the OAuth client_credentials
authentication flow.
Get Access Token from the authorization endpoint (/oauth/token
)
Note
This API requires a public scope
.
The client_id
and client_secret
must match the ID and secret of the application the user is attempting to access. Additionally, the same token should be used for all requests to the API endpoint for the same user authentication event.
Parameter | Type | Description |
---|---|---|
grant_type | String |
|
client_id | String | The |
client_secret | String | The client secret for the application in Arculix |
scope | String | A space-delimited list of scopes to be issued to the access token This API requires a public |
Sample request
{ "grant_type": "client_credentials", "client_id": "YOUR_ARCULIX_APPLICATION_UID", "client_secret": "YOUR_ARCULIX_APPLICATION_SECRET", "scope": "public" }
This will return the access token if that application is authorized with the requested scopes.
Note
The generated access tokens are more than 255 bytes in length, so when storing them make sure to have at least 500 bytes of storage available or else they will be truncated.
Sample response
{ "access_token": "YOUR_OAUTH_ACCESS_TOKEN", "token_type": "Bearer", "expires_in": 7200, "scope": "public", "created_at": 1630710187 }
Call API endpoint, sending the access token in the Authorization
HTTP header with Bearer
:
Authorization: Bearer YOUR_OAUTH_ACCESS_TOKEN
Authenticate a User
Initiate a user authentication flow.
Header
Field | Type | Description |
---|---|---|
Accept-Language | String | Preferred language for user-facing messages. Default value: |
HTTP-X-ACCEPTTO-RISK-ENGINE | json | JSON string that will be passed to the risk engine and will be available as Note that the name of the parameter might vary based on your deployment configuration. ( |
Request
Method | URL |
---|---|
POST |
|
Parameters
Field | Type | Description |
---|---|---|
credential_type | String | Type of authentication/authorization. Users will see this value as the event type in the mobile app and elsewhere unless a Allowed values: |
auth_credentials | Object | The credential that will be used for authentication. Internal schema of For more information, see sample requests. |
session_uid | String | A unique identifier for the session. This is the unique value that the relying party should generate for the lifetime of a session and should be unique across the relying party organization between different applications. |
message | String | Message that user receives using push notification on Arculix Mobile app or via text/voice message. |
type | String | Type of authentication/authorization. User will see this value as the type of transaction on mobile app. For example: |
auth_factor | String | Array of strings identifying preferred out of band method to be automatically sent to the user (currently only supports first item). The possible values are: |
timeout | Integer | The timeout value for the authentication request in seconds; if the user does not respond within the specified time, the request expires. The default value is 300 seconds (5 minutes). |
ip_address | String | The end user's IP address, to be used for policy-based risk assessment and logging. |
remote_ip_address | String | End user's remote ip address (IP behind proxy) for enabling IP based policies and logging. |
totp | String | Users can be authenticated via TOTP by allowing them to enter their time based one-time passcodes while signing in. When TOTP is specified and is correct, the status of the response is If the TOTP is incorrect, the authentication request will be rejected and no other MFA method will be offered. |
bfpToken | String | The value of the Arculix DBFP cookie, if in use. |
response_format | String | Requested response format. Default value: Allowed values: |
Sample request
{ "credential_type": "password_less_login", "auth_credentials": { "username": "abe.lincoln" }, "type": "BillPayment", "auth_factor": [ "push" ], "bfpToken": "a6a5effa4d8c6xxxx123efed89033ab70ae" }
Response
Successful response
Field | Type | Description |
---|---|---|
success | Boolean | Shows whether operation was successful or not. |
response_code | String | Returns response code of |
status | String | Shows status of MFA. The possible values are: |
session_uid | String | A unique identifier for the session. This is the unique value that the relying party should generate for the lifetime of a session and should be unique across the relying party organization between different applications. |
user_email | String | Email address of the user that is authenticating. |
auth_options | Array | Allowed authentication methods for the MFA step. The possible values are: |
expires_at | String | Shows expiry time of MFA in ISO 8601 format. |
notification_type | String | The type of notification that has been sent to the user, if any. |
Successful response example
HTTP/1.1 200 OK { "success": true, "response_code": "success", "channel": "1556910423f49963ade2d1951359b1fe15fcd72c41", "status": "approved/pending/rejected", "session_uid": 10037, "user_email": "abe.lincoln@mailinator.com", "auth_options": ["push", "totp"], "expires_at": "2020-02-11T10:23:57-08:00", "notification_type": null }
Unsuccessful response
Error
Field | Type | Description |
---|---|---|
response_code | String | Normalized response code describing the error type. |
success | String | Generally false. |
message | String | Informative message describing the error. |
Response codes
Field | Type | Description | Response example |
---|---|---|---|
no_authenticator_found | String | No authenticator with the specified type found for the organization. | HTTP/1.1 422 Unprocessable Entity { "content": { "response_code": "no_authenticator_found", "success": false, "message": "Something went wrong, Please contact support@secureauth.com for further assistance." } } |
generic_error | String | If anything else goes wrong, such as a missing parameter or invalid JWT, then a general error message is returned | HTTP/1.1 4XX OK { "response_code": "generic_error", "success": false, "message": "error message" } |
Send Out of Band
Send out of band MFA request to user.
Header
Field | Type | Description |
---|---|---|
Accept-Language | String | Preferred language for user-facing messages. Default value: |
Request
Method | URL |
---|---|
POST |
|
Parameters
Field | Type | Description |
---|---|---|
type | String | Out of band method to be sent to user. Allowed values: |
response_format | String | Requested response format. Default value: Allowed values: |
channel | String | The channel returned from a successful authentication request, uniquely identifying the MFA transaction. |
Response
Successful response
Field | Type | Description |
---|---|---|
response_code | String | Returns response code. The possible values are: |
success | Boolean | Shows whether operation was successful or not. |
status | String | Shows status of MFA. The possible values are: |
expires_at | String | Shows expiry time of MFA in ISO 8601 format. |
notification_type | String | Notification type sent to user. The possible values are: |
message | String | Message that can be shown to end-user. |
Successful response example
HTTP/1.1 200 OK { "response_code": "[otp_type]_sent", "success": true, "status": "pending", "expires_at": "2020-02-11T10:23:57-08:00", "notification_type": "sms/email/call/push", "message": "We just sent you a 6-digit passcode, please check your SMS inbox." }
Unsuccessful response
Error
Field | Type | Description |
---|---|---|
response_code | String | Normalized response code describing the error type. |
success | String | Generally false. |
message | String | Informative message describing the error. |
Response codes
Field | Type | Description | Response example |
---|---|---|---|
mfa_invalid_state | String | Authentication request is no longer valid, no OOB sent. | HTTP/1.1 200 OK { "content": { "response_code": "mfa_invalid_state", "success": false, "message": "Your authentication request is no longer valid, please try to login again.", "expires_at": "2020-02-11T10:23:57-08:00", "notification_type": "sms/email/voice", "status": "expired/rejected/approved" } } |
not_allowed | String | Authentication method not allowed for this application and user. | HTTP/1.1 200 OK { "content": { "response_code": "not_allowed", "success": false, "message": "Authentication method is not allowed for this application and user!", "expires_at": "2020-02-11T10:23:57-08:00", "notification_type": null, "status": "pending" } } |
wait_for_resend | String | Must wait to re-send OOB notification. | HTTP/1.1 200 OK { "content": { "response_code": "wait_for_resend", "success": false, "message": "MFA request rate exceeded. Please wait 22 seconds before requesting a new sms.", "expires_at": "2020-02-11T10:23:57-08:00", "notification_type": "sms", "status": "pending" } } |
tfa_not_found | String | No TFA with the given channel found for this application. | HTTP/1.1 404 Not Found { "content": { "response_code": "tfa_not_found", "success": false, "message": "No authentication request found for this user with the specified channel.", } } |
Verify Factor
Verifies the credential of the chosen authentication factor type.
Header
Field | Type | Description |
---|---|---|
Accept-Language | String | Preferred language for user-facing messages. Default value: |
Request
Method | URL |
---|---|
POST |
|
Parameters
Field | Type | Description |
---|---|---|
type | String | Factor type being verified. Allowed values: |
response_format | String | Requested response format. Default value: Allowed values: |
channel | String | The channel returned from a successful authentication request, uniquely identifying the MFA transaction. |
Request body
Field | Type | Description |
---|---|---|
factor_response | Object | Object with factor verifier details. |
factor_response.code | String | Authentication factor code. This is the passcode entered by the user to verify the MFA. |
Sample request
{ "factor_response": { "code": "123456" } }
Response
Successful response
Field | Type | Description |
---|---|---|
success | Boolean | Shows whether the API call was successful or not. |
response_code | String | Returns response code of |
status | String | Shows status of MFA. The possible values are: |
message | String | Message that explains success. |
retry_attempts_remaining | Integer | The number of attempts remaining to verify factor. |
Successful response example
HTTP/1.1 200 OK { "response_code": "success", "success": true, "status": "approved", "message": "Your Authorization Request Was Successful!", "retry_attempts_remaining": 3 }
Unsuccessful response
Error
Field | Type | Description |
---|---|---|
response_code | String | Normalized response code describing the error type. |
success | String | Generally false. |
message | String | Informative message describing the error. |
Response codes
Field | Type | Description | Response example |
---|---|---|---|
mfa_invalid_state | String | Authentication request is no longer valid, or OTP not checked. | HTTP/1.1 200 OK { "response_code": "mfa_invalid_state", "success": false, "message": "Your authentication request is no longer valid, please try to login again.", "status": "expired/rejected/approved" } |
invalid_otp | String | Invalid passcode specified. | HTTP/1.1 200 OK { "response_code":"invalid_otp", "success": false, "message":"Invalid passcode was specified, please try again!", "status": "pending", "retry_attempts_remaining": 2 } |
max_retry | String | OTP is invalid and the number of max attempts has been exceeded. TFA is automatically rejected. | HTTP/1.1 200 OK { "response_code": "max_retry", "success": false, "message":"Maximum PIN attempts exceeded. Authorization request denied.", "status": "rejected", "retry_attempts_remaining": 0 } |
tfa_not_found | String | No TFA with the given channel found for this application. | HTTP/1.1 404 Not Found { "response_code": "tfa_not_found", "success": false, "message": "No authentication request found for this user with the specified channel.", } |
Status
Checks and returns authentication result status based on channel.
Header
Field | Type | Description |
---|---|---|
Accept-Language | String | Preferred language for user-facing messages. Default value: |
Request
Method | URL |
---|---|
GET |
|
Parameters
Field | Type | Description |
---|---|---|
channel | String | The channel returned from a successful authentication request, uniquely identifying the MFA transaction. |
response_format | String | Requested response format. Default value: Allowed values: |
Response
Successful response
Field | Type | Description |
---|---|---|
success | Boolean | Whether the API call was successful or not. |
response_code | String | Normalized response code describing the error type or "success". |
status | String | Shows status of MFA, possible values pending/expired/approved/rejected. |
channel | String | The channel uniquely identifying the TFA. |
user_id | String | Internal user ID. |
expires_at | String | The TFA expiry in ISO 8601 format. |
session_uid | String | Unique user session identifier. |
Successful response example
HTTP/1.1 200 OK { "success": true, "response_code": "success", "status": "approved/pending/rejected", "channel": "1556910423f49963ade2d1951359b1fe15fcd72c41", "user_id": 3891, "expires_at": "2020-02-11T10:23:57-08:00", "session_uid": "aea7f1d0dd368e448e92ac30a5d8e34d" }
Unsuccessful response
Error
Field | Type | Description |
---|---|---|
response_code | String | Normalized response code describing the error type. |
success | String | Generally false. |
message | String | Informative message describing the error. |
Response codes
Field | Type | Description | Response example |
---|---|---|---|
tfa_not_found | String | No TFA with the given channel found for this application. | HTTP/1.1 404 Not Found { "content": { "response_code": "tfa_not_found", "success": false, "message": "No authentication request found for this user with the specified channel.", } } |
OAuth calculate LOA score (Risk Engine)
If your organization and relying party application both have access to a standalone risk engine license, the relying party application can submit raw request information to the Arculix API to calculate the LOA score for the current session.
To calculate the LOA score, it takes user data from the history and normality of user behavior, and from other sources like AI/ML engine, user browser fingerprint, geolocation, and so on. You can use this API for continuous authentication, enabling the Arculix risk engine to calculate the LOA score based on changes to the current session and context to the existing request.
For example, during a user session, a change in the IP address, browser fingerprint, or GPS location can impact the LOA score in a current session. You can also use the API to send data to the risk engine from native or web applications that do not have a direct integration with the Arculix Mobile SDK or a single sign-on solution.
Note
For the OAuth calculate LOA score API to work, the application must have permission to send data to the risk_engine
.
Request
Method | URL |
---|---|
POST |
|
Parameters
Field | Type | Description |
---|---|---|
String | User's email address. Email domain should belong to the organization. | |
session_uid | String | A unique identifier for the session. This is the unique value that the relying party should generate for the lifetime of a session and should be unique across the relying party organization between different applications. |
event | String | The authentication event; possible values are |
context | JSON | The context of the authentication request should contain all the key/values the relying party has from the user’s request. Depending on the keys present in this parameter, the Arculix risk engine decides which risk analyzers it must engage in calculating the final LOA score. For the list of possible key-value pairs, see the Context section. |
Note
If you want the risk engine to mark the provided data, like IP, location, and DBFP as trusted for future MFAs, use post-auth
for the value of the event
key. Otherwise, it will discard data from all other events.
Context
The Arculix risk engine captures and stores any key/value sent to this API. But, certain keys have special meanings used by existing risk analyzers to calculate the LOA score for the request. The following is a list of keys and corresponding risk analyzers that are looking for the key in context.
Key | Description | Risk Analyzer |
---|---|---|
ip_address | The public IP address of the end user. | IP Risk Analyzer |
latitude | The | Location Risk Analyzer |
longitude | The | Location Risk Analyzer |
accuracy | The Arculix will discard the geolocation information if accuracy is above a certain threshold. By default this number is 100 and it will discard any data with accuracy above 100. | Location Risk Analyzer |
bfpToken | When integrating with the Arculix DBFP JavaScript plugin, the device and browser fingerprints (DBFP) engine will create a cookie named The value of this cookie should be passed as | DBFP Risk Analyzer |
user_agent | A characteristic string that enables servers and network peers to identify the application, operating system, vendor, or version of the requesting user agent. | DBFP Risk Analyzer |
oob_name | Out-of-band method used during authentication. Supported values are:
| Auth Method Risk Analyzer |
mobile_device.device_uuid | A universally unique mobile device identifier if the data is coming from a native mobile application. | Device Trust |
mobile_device.device_type | Model information of the mobile device. For example, iPhone 11. | Device Trust |
mobile_device.app_version | Native mobile application version number that is sending the information. | Device Trust |
mobile_device.os_type | Mobile device operating system. For example, iOS or Android. | Device Trust |
mobile_device.os_version | Operating system version of the mobile device. For example, 14.5.1. | Device Trust |
mobile_device.device_brand | Maker of the mobile device. For example Apple, Samsung, or Google. | Device Trust |
mobile_device.ip_address | X-Forwarded-For or the source IP address of a client connecting to a web server through an HTTP proxy or a load balancer. | Device Trust |
mobile_device.locations | List of geolocation coordinates information captured by the mobile device. (Requires user consent and permission.) For details, see Sample Mobile Request. | Device Trust |
mobile_device.locations.latitude | The latitude property is a double-precision floating point value which represents the latitude of a geographical position, specified in decimal degrees. | Location Risk Analyzer |
mobile_device.locations.longitude | The longitude property is a double-precision floating point value which represents the longitude of a geographical position, specified in decimal degrees. | Location Risk Analyzer |
mobile_device.locations.log_date | The timestamp at which coordinates data was collected from the user's mobile device. The timestamp should be in ISO-8601 format. | Location Risk Analyzer |
Note
If the context contains the mobile_device
key, the type of application in Arculix should be set as mobile_application
; otherwise, Arculix will discard the mobile_device
key data.
Sample web request
{ "session_uid":"xxxxx1f1f5a634355702ced92951xxxx", "email":"jian-yang@piedpiper.com", "event": "post-auth", "context": { "ip_address":"74.50.231.26", "latitude": 50.09951255599202, "longitude": -120.98416469567863, "accuracy": 50, "bfpToken": "xxxxbGciOiJIUzI1NiJ9.xxxxxW5nZXJwcmludCI6IjA3NmIzNWIwNjQ3NzkyNzAyYTk2NmMzMWUwMTY5ZjNiIiwiaGFzaDEiOiJkOWUwNWFhZDM3MmQwODM4YzIyZWNiYjI3MjZmYzY0YSIsImhhc2gyIjoiYmNiNmYyMzVkZTM2YmU5NWY5Yjk4YTE5ZGI5NmQwZjIiLCJoYXNoMyI6IjhkYjljYWY2YWM1MzYzYzAwZmFmZGEzZjdlYzFkN2FiIiwiaGFzaDQiOiJhMzU4ZDUyNjkyNjAyNDRjYTA0MDdmZDIxYzRhNjYwOCIsInJpc2siOjAuNSwiYnJvd3Nlcl9vdXRkYXRlZCI6ZmFsc2V9.l5U-KSI5A1fEz2R9HD6CiViCF9VFfaWLG3BlweYZkoo", "auth_method": "totp", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.3 Safari/605.1.15" } }
Sample mobile application request
{ "email":"jian-yang@piedpiper.com", "session_uid": "session-5faaa6cf22b9d6351c5794de399e33a1", "event": "post-auth", "context": { "mobile_device": { "device_uid": "D0C3EABF-40D0-4EDE-8DC6-0AB758C82AF0", "device_type": "iPhone 11", "app_version": "6.2.0", "os_type": "iOS", "os_version": "13.3", "device_brand": "Apple", "ip_address": "70.69.146.204", "remote_ip_address": "192.168.1.210", "locations": [ { "log_date": "2021-05-12T21:56:00+00:00", "latitude": 50.09951255599202, "longitude": -120.98416469567863 }, { "log_date": "2021-05-12T10:29:00-07:00", "latitude": 51.09951255599202, "longitude": -123.98416469567863 } ] } } }
Response
Successful response
Field | Type | Description |
---|---|---|
response_code | String |
|
success | Boolean |
|
content.loa_score | Float | LOA score calculated by the risk engine based on the parameters provided in the request context. |
content.message | String | Blank for successful requests. |
content.id | Integer | Internal risk session ID. |
content.risk_analyzers | Array | Risk analyzer result objects describing the reason behind the LOA score |
Successful response example
{ "response_code": "success", "content": { "id": 100, "message": "", "success": true, "loa_score": 2.9, "risk_analyzers": [ { "id": 1, "data": { "hash1": "6a5057d0727ba9e96c9c64ad174518f5", "hash2": "75d9149d8bb2316b34dc1bf642c7ce84", "hash3": "95a4eba02f8986ba7e74cca5450219c1", "hash4": "48bcd22cd441408ba438a64929185b75", "fingerprint": "f834686715c5aefd0109e337e2f9fe14" }, "name": "DBFP", "reasons": { "hash2": 1, "hash4": 0.25, "matched_via": "hash4,hash2", "matched_dbfp_id": 3082 }, "loa_delta": 1.25, "class_name": "RiskDbfpAnalyzer", "updated_at": "2021-02-12T17:52:12.607-08:00", "description": "Provides LOA Score Analysis based on Browser fingerprints" }, { "id": 4, "data": { "mobile_vs_auth_request_distance_in_meters": 6.16 }, "name": "GPS", "reasons": { "mobile_browser_proximity": "6.16 meters" }, "loa_delta": 4, "class_name": "RiskLocationAnalyzer", "updated_at": "2021-02-12T17:52:12.616-08:00", "description": "Provides LOA Score Analysis based on the GPS coordinates of requests" }, { "id": 2, "data": { "ip_address": "76.115.75.122" }, "name": "IP", "reasons": { "known_exclusive_user_ip_address": 4 }, "loa_delta": 4, "class_name": "RiskIpAnalyzer", "updated_at": "2021-02-12T17:52:12.631-08:00", "description": "Provides LOA Score Analysis based on the IP address of requests" } } } }
Unsuccessful response
Field | Type | Description |
---|---|---|
response_code | String | Always |
message | String | Informative message describing the error. |
content.loa_score | Integer | 0 for unsuccessful requests. |
Unsuccessful response examples
HTTP/1.1 401 { "response_code": "invalid", "message": "Risk Engine APIs are not enabled for this application. please contact SecureAuth Support for more information.", "content": { "loa_score": 0.0 } }
HTTP/1.1 422 { "response_code": "invalid", "message": "Email domain is not owned by your organization.", "content": { "loa_score": 0.0 } }
HTTP/1.1 422 { "response_code": "invalid", "message": "Unable to create the user with 1234-xyz: Invalid email address format.", "content": { "loa_score": 0.0 } }
Notification
After initiating an authentication request, the relying party has the option of getting notified as soon as the MFA phase is complete. This can be a result of the user taking action to approve or reject the request or the request having expired.
To listen for the notification, the relying party should use the channel
returned by the initial user authentication request to subscribe to the Arculix Faye server. Use the following JavaScript snippet (written using jQuery but vanilla JavaScript works as well).
<script src="https://faye.acceptto.com/faye/faye.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script type="text/JavaScript"> $(function() { var faye = new Faye.Client("https://faye.acceptto.com/faye"); faye.subscribe("/messages/<%= @channel %>", function (data) { window.location.reload(); // refresh the page and call check api on refresh }); }); </script>
As soon as the MFA phase is complete, a notification is sent to Faye which relays it to any relying party subscribed to the channel and the code block inside faye.subscribe
executes. Make sure that you are replacing the <%= @channel %>
with the channel
returned by the user authentication call and customize the code block inside faye.subscribe
; the method above simply refreshes the page but generally a redirection to a results page is used.
MFA integration with device browser fingerprint
Use the following steps to integrate MFA with DBFP.
In the body element of your HTML page, add the following DBFP JavaScript file script:
<!-- Arculix DBFP --> <script type="text/JavaScript" src="https://dbfp.acceptto.com/bfp6.js"></script> <!-- End Arculix DBFP -->
This script sets a cookie named jwt that can be passed as a parameter to the initial user authentication APIs using the key
bfpToken
orjwt
. Arculix uses this data to assess the risk of the authentication request including browser fingerprint, IP address of user and GPS location of the user’s browser. The server compares this data with the history of user behavior data to detect anomalies.Save your changes.