API documentation

In this page you can find information to configure the GuardianKey in your web application.

The interaction with GuardianKey is done by an API (Application Programming Interface). We provide a reference implementation in PHP and Python (libraries). The interaction with GuardianKey is easy, you can use our libs or you can implement your own code. Both ways are documented here, in distinct subsections.

We note that we also provide plugins for commonly used software that integrates with GuardianKey in a very simple way: just install and use! Check our plugins’ page to see if you software is already supported via plugins.

We recommend you to make use of our reference implementation to avoid bugs and make your work more simple.

Contents

Overview about the GuardianKey

GuardianKey is focused on providing a modern, intelligent and high-secure way to protect your systems in the authentication phase.

In summary:

  1. You register your system using the API;
  2. Your system use the information received in the registration step to send login attempts to GuardianKey (in cloud);
  3. The GuardianKey process the events with Machine Learning algorithms to provide a risk for each login attempt;
  4. Based on predefined thresholds, your security staff and/or the user can be notified by e-mail;
  5. Also, for high level risks, your system can block or require more steps for the authentication (e.g., a second auth factor); and
  6. Finally, you can see everything (events, graphs, trends, etc.) in our admin interface.

You can configure the thresholds based on your risk acceptance levels, see how in using the admin interface.

Interacting with GuardianKey

Technically, the interaction with GuardianKey is done by the following phases:

  1. registering: create cryptographic keys, get an authgroupID in GuardianKey and register notification options;
  2. sending events: your system send login attempts (events) to be processed in GuardianKey; and
  3. monitoring: you access the GuardianKey admin interface to monitor your systems’ risks and setup your preferences.

In summary:

  1. the registration is done via a webserver, which supports REST and XML-RPC;
  2. alerts are sent via an encrypted JSON using UDP or REST; and
  3. the monitoring can be done via our admin interface.

Below, we describe the interactions described in phases 1 and 2.

For the impatient people, running it fast!

The commands below provide a fast way to create a login page in PHP or Python, using our reference API implementation.

#!/bin/sh
# Install PHP with extensions curl and ...
$ sudo apt-get install php php-json php-curl
 OR
$ sudo yum install php php-json php-curl
# Download the registering code and the class
$ wget https://github.com/pauloangelo/guardiankey-api-php/archive/master.zip

$ unzip master.zip
# run the code for registering
$ php register.php

# copy the output to the top of the file guardiankey-class.php, example:
$GKconfig = array(  
			'email' => 'xxxxx@xxxx.com',
			'agentid' => 'xxxxxxxxxxx',
			'key' => 'xxxxxxxxxxx',
			'iv' => 'xxxxxxxxxxx',
			'orgid' => 'xxxxxxxxxxx',
			'groupid' => 'xxxxxxxxxxx',
			'reverse' => '1',
			);

# Now, you should make a call for this function in the login processing code of your system
# Link to the code above, as in the example below.
<?php 
// This is my system's login page
require_once("guardiankey.class.php");
$GK = new guardiankey();
if ($_POST) {
...
$GK->send_event($username);
echo "<h2>Any data</h2>";
} 
#!/bin/sh
# Install Python dependencies using pip:
$ pip install requests json hashlib time 

# Download the registering code and the class
$ wget https://github.com/pauloangelo/guardiankey-api-python/archive/master.zip

$ unzip master.zip
# run the code for registering
$ python register.py

# copy the output to the top of the file guardiankey.py, example:
GKconfig = {}
GKconfig['email'] = 'xxxx@xxxxxx.com'
GKconfig['agentid'] = 'xxxxxxxxxxx'
GKconfig['key'] = 'xxxxxxxxxxx'
GKconfig['iv'] = 'xxxxxxxxxxx'
GKconfig['service'] = 'Myservice'
GKconfig['orgid'] = ''
GKconfig['groupid'] = ''
GKconfig['reverse'] = '1'




Useful links:

Accessing the API for registering

The registration is performed in the following steps:

  • Step 1: client (you or your system) creates a KEY and IV (Initialization Vector). Additionally, you can register the notification methods;
  • Step 2: client invokes the GuardianKey’s webserver register function with parameters KEY/IV and an admin e-mail; and
  • Step 3: the webserver saves the sent information and returns an authgroupID, which must be used to send events.

Our reference API implementation already provides these steps implemented. In such cases, the interaction process is very simple.

To create an authgroupID, you can also run our code available in GitHub and described in section for the impatient people.

We note that, after registering, you have to send events. The procedures are also described below.

Implementing your own code to register

If you want to use GuardianKey using other programming language or want to create your own code, you can interact directly with the GuardianKey’s API for registering via REST.

The codes below provide examples for registering via REST.

 <?php
/* Dependencies: php-curl */
define('AES_256_CBC', 'aes-256-cbc');
function register($email) {
			$guardianKeyWS='https://api.guardiankey.io/register';
            // Create new Key
            $key = openssl_random_pseudo_bytes(32);
            $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cfb'));
            $keyb64 = base64_encode($key);
            $ivb64 =  base64_encode($iv);
            $agentid = base64_encode(openssl_random_pseudo_bytes(20));
	
            /* Optionally, you can set the notification parameters, such as:
              - notify_method: email or webhook
			  - notify_data: A base64-encoded json containing URL (if method is webhook), server and SMTP port, user, and email password.
		Example for e-mail:
			$notify_method = 'email';
			$notify_data = base64_encode('{"smtp_method":"TLS","smtp_host":"smtp.example.foo","smtp_port":"587","smtp_user":"myuser","smtp_pass":"mypass"}');
		Example for webhook:
		    $notify_method = 'webhook';
			$notify_data = base64_encode('{"webhook_url":"https://myorganization.com/guardiankey.php"}');
			*/
			$data = array(
					'email' => $email,
					'keyb64' => $keyb64,
					'ivb64' => $ivb64,
					/*Uncoment if you defined notify options
					'notify_method' => $notify_method,
					'notify_data' => $notify_data*/
					);
			$ch = curl_init();
			curl_setopt($ch,CURLOPT_URL, $guardianKeyWS);
			curl_setopt($ch,CURLOPT_POST, true);
			curl_setopt($ch,CURLOPT_POSTFIELDS, $data);
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
			$returned = curl_exec($ch);
			curl_close($ch);
			$returns = @json_decode($returned);
			if ($returns === null) {
				echo  'An error ocurred: '.$returned;
			} else {

				if ($_SERVER['SERVER_NAME']) {
						echo "<pre>";
				}
            echo  'Please add in your GuardianKey configuration: 
					$GKconfig = array(
					\'email\' => "'.$email.'",
					\'agentid\' => "'.$agentid.'",
					\'key\' => "'.$keyb64.'",
					\'iv\' => "'.$ivb64.'",
					\'orgid\' => "'.$returns->organizationId.'",
					\'groupid\' => "'.$returns->authGroupId.'",
					\'reverse\' => "1",
					);';
}
if ($_SERVER['SERVER_NAME']) {
	if ($_POST) {
		$email = $_POST['email'];
	} else {
	echo "<form action=# method=post>
		<p>Please enter admin email:</p>
		<input type=email name=email><br>
		<input type=submit value=submit>
	</form>";
	die;
	}
} else {
		echo "Please enter admin email:";
		$handle = fopen ("php://stdin","r");
		$email = trim(fgets($handle));	
	}
register($email);

// to send events, you need to save the $agentid, $key and $iv

import base64
import os
import requests
from Crypto.Cipher import AES

def register(email):
	guardianKeyWS='https://api.guardiankey.io/register'
	data = {}
	data['keyb64'] = base64.b64encode(os.urandom(32))
	data['ivb64']  = base64.b64encode(os.urandom(16))
	data['email'] = email
#Optionally, you can set the notification parameters, such as:
#notify_method: email or webhook
#notify_data: A base64-encoded json containing URL (if method is webhook), server and SMTP port, user, and email password.
#Example for e-mail:
	#data['notify_method'] = 'email'
	#data['notify_data'] = base64.b64encode('{"smtp_method":"TLS","smtp_host":"smtp.example.foo","smtp_port":"587","smtp_user":"myuser","smtp_pass":"mypass"}')
#Example for webhook:
    #data['notify_method'] = 'webhook';
	#data['notify_data'] = base64.b64encode('{"webhook_url":"https://myorganization.com/guardiankey.php"}')
	url = 'https://api.guardiankey.io/register'
	headers = {'Content-type': 'application/x-www-form-urlencoded', 'Accept': 'text/plain'}
	query = requests.post(url, data=data, headers=headers)
	return query.text,data['keyb64'],data['ivb64']


email = raw_input( "Enter the administrator e-mail:")
agentid,key,iv = register(email)

message = 'Put in your configuration this values:\n\
		   email: {}\n\
		   agentid: {}\n\
		   key: {}\n\
		   iv: {}\n'

print message.format(email,agentid,key,iv)



Note: We invite you to share your code for other languages or plugins of systems. Just publish it in GitHub and let us know by sending an e-mail (see the contact page).

Sending events

Sending an event can be done basically following the steps:

  • Step 1: create a JSON containing the information about the event (see the structure below);
  • Step 2: encrypt the JSON using the KEY/IV generated in the register phase;
  • Step 3: send the string “authgroupID|cipher” to GuardianKey via UDP or REST;
  • Step 4: if you use the sync mode (only using REST), you should receive “ALLOW”, “EXTRAREQUIREMENT”, or “BLOCK”, which can be used to block the user or require an extra factor for the user to authenticate.

The GuardianKey’s API supports receiving events via UDP or REST. UDP is more fast, but it is used uniquely to log events for notification, i.e., your system will not receive a feedback in time to block the login attempt, but your CSIRT and users can receive the alerts.

The REST interface is synchronous, the choice between them depends on the support given by the used programming language to these technologies and to the security requirements.

Mode Advantages
UDP (async) fast
REST (sync) enable blocking the access

Sending events using the reference API implementation

Make sure you have downloaded the reference implementation:

You will need to include your KEY/IV, AgentID and other information in the top of the file, like in the example code below. In your implementation, you can save this information in a database and retrieve when required.

 <?php
$GKconfig = array(
	'email' => "",  // Your admin e-mail
	'agentid' => "", // the hash returned in the register phase
	'key' => "",    // the Key generated in the register phase
	'iv' => "",     // the IV generated in the registrer phase
	'orgid' => "",     // use the same value as agentid in first use
	'groupid' => "",   // use the same value as agentid in first use
	'reverse' => "1",  // 1 or 0, to make reverse DNS 
                       // querying for sending
);

# Please run register.py for generate your configuration
GKconfig = {}
GKconfig['email'] = ''
GKconfig['agentid'] = ''
GKconfig['key'] = ''
GKconfig['iv'] = ''
GKconfig['service'] = ''
GKconfig['orgid'] = ''
GKconfig['groupid'] = ''
GKconfig['reverse'] = ''

After saving these parameters in the guardiankey.class.php or guardiankey.py file, you can just make use of it, like in the following codes:

 <?php
echo "<h2>My Login Page</h2>
<p>Please login</p>
<form action=# method=post>
<p>Username:<input type=text name=user></p>
<p>Password:<input type=password name=password></p>
<input type=submit value=submit>
</form>";
if ($_POST) {
   // $systemBlockedAccess is true if your system denied the access,
   // for example, if $username or $password are is valid.
   // Possible values:  0 - username and password is valid, 
   //			1 - username and password NOT is valid
   $systemBlockedAccess= yourLoginFunction($username,$password);

   require_once("guardiankey.class.php");
   $GK = new guardiankey();
   $GK->sendevent($username,$systemBlockedAccess);

}

 <?php
echo "<h2>My Login Page</h2>
<p>Please login</p>
<form action=# method=post>
<p>Username:<input type=text name=user></p>
<p>Password:<input type=password name=password></p>
<input type=submit value=submit>
</form>";
if ($_POST) {
   // $systemBlockedAccess is true if your system denied the access,
   // for example, if $username or $password are is valid.
   // Possible values:  0 - username and password is valid, 
   //			1 - username and password NOT is valid
   $systemBlockedAccess= yourLoginFunction($username,$password);

   require_once("guardiankey.class.php");
   $GK = new guardiankey();


   $GKReturn = json_decode($GK->checkaccess($username,$systemBlockedAccess));

   if($GKReturn['response'] === "ALLOW") {
     echo "<h2>Allowed!</h2>";
   }else if($$GKReturn['action']  === "EXTRAREQUIREMENT") {
     echo "<h2>Require OTP or something else. If not supported, ";
     echo "    you can just allow or deny the access, depending the security policy.</h2>";
   }else{
     echo "<h2>Your access was blocked! Contact the admin!</h2>";
   }
}


println "This is tab 2."

Note: Your system should send even the unauthorized login attempts (login/pass don’t match). GuardianKey will run if you do not send such event, however, this information is useful for our Machine Learning procedures and to provide a better visualization experience.

Creating your own code to send events

GuardianKey basically requires the information about the client’s IP address, the User-Agent submitted by the user’s browser, and if the login failed in the system. This information is available in the user’s request and in the system’s verification routine.

Below we present an example using the PHP language.

 <?php
// The KEY and IV can be saved in Base64 to simplify the manipulation
// But it must be decoded to be used.
$key=base64_decode($keyb64);
$iv=base64_decode($ivb64);

// This is an PHP object, that can be easily converted to JSON 
$json = new stdClass();
$json->generatedTime=$timestamp;
$json->agentId=$agentid;
$json->organizationId=$agentid;
$json->authGroupId=$agentid;
// identification of your system, useful for monitoring
$json->service="MySystem";
// The client's IP
$json->clientIP=$_SERVER['REMOTE_ADDR'];
// reverse lookups are used for some Machine Learning detection algorithms
// however, it can take some time. We recommend to send this information!
$json->clientReverse = ($reverse==1)?  gethostbyaddr($json->clientIP) : "";
// This is the login name
$json->userName=$username;
// Used in some specific cases
$json->authMethod="";
// Put 0 if login was validated in the system and 1 if it failed
$json->loginFailed="0";
// This is the UserAgent provided by the browser
$json->userAgent=substr($_SERVER['HTTP_USER_AGENT'],0,500);
$json->psychometricTyped="";
$json->psychometricImage="";

// Create the JSON
$message = json_encode($json,JSON_UNESCAPED_SLASHES);
// PAD the message
$blocksize=16;
$padsize = $blocksize - (strlen($message) % $blocksize);
$message=str_pad($message,$padsize," ");
// Encrypt using the KEY/IV
$cipher = openssl_encrypt($message, 'aes-256-cfb8', $key, 0, $iv);
// Create the payload and send via UDP
$payload=$agentid."|".$cipher;
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_sendto($socket, $payload, strlen($payload), 0, "collector.guardiankey.net", "8888");

// OR create the payload and send via REST, using curl:
/* $tmpdata->id = $agentid;
   $tmpdata->message = $cipher;
   $data = json_encode($tmpdata)
   $ch = curl_init();
   	curl_setopt($ch,CURLOPT_URL, 'https://api.guardiankey.io/checkaccess');
	curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");                                                                     
	curl_setopt($ch, CURLOPT_HTTPHEADER, array(
		'Content-Type: application/json',                                                                                
                'Content-Length: ' . strlen($data)));  
	curl_setopt($ch,CURLOPT_POSTFIELDS, $data);
	curl_setopt($ch, CURLOPT_REETURNTRANSFER, 1);
   $return = curl_exec($ch);
   curl_close($ch);
   return $return;
*/

Details about the JSON data structure

Table below describes the JSON fields used for sending events to GuardianKey.

Field Description
generatedTime event generation unix timestamp (ex. 1527075751)
agentId agentid to identify uniquely the agent. If you have just one agent, use the authGroupID
organizationId in most cases, use the same authGroupId (ex. 7d97e98f8af…9e0ee507c4)
authGroupId string returned by the register function (ex. 7d97e98f8af…9e0ee507c4)
service text reference for your web system, your choice (ex. NextCloud)
eventType Type of event (Authentication or badaccess(future))
clientIP the IP (v4 or v6) used for user trying to have access (ex. 123.123.123.123)
clientReverse dns reverse of the clientIP (ex. 123.123.123.123.ispdomain.com)
userName the user login name used in the system (ex. john)
userEmail the user e-mail (ex. john@company.com), required only if your users should be notified by suspicious accesses
loginFailed 0 if user/pass matches and 1 otherwise (ex. 0)
userAgent the complete user-agent header sent by the user’s browser (ex. “Mozilla/5.0 (Windows NT 6.1) … Safari/537.”)
sequential sequential number to avoid replay attacks
authMethod used for some services that allows this features, most cases, leave it blank
psychometricTyped under development, leave it blank
psychometricImage under development, leave it blank

Receiving notifications

You have two modes for receive notifications: Via e-mail or Webhook.

Receiving via e-mail

If you want receive notifications via e-mail, just you configure SMTP information in your account on the GuardianKey panel (https://panel.guardiankey.io).

Receiving via webhook

You can receive notifications via webhook. This method enables that you personalize the treatment of notification: Send to a your DB, notificate users via other methods, etc.

For it, you need host the page that receive a json from GuardianKey and indicate in GuardianKey panel (or in the register) the URL of you webhook.

Please view the reference implementation of webhook (in PHP):

https://github.com/pauloangelo/guardiankey-api-php/blob/master/webhook.php

Table below describes the JSON fields sent from GuardianKey to webhook:

Field Description
generatedTime Event generation unix timestamp (ex. 1527075751)
message_contextual Frienldy message about the notification
userName Username used
agentId AgentID of service
eventId ID of event
risk_level Level of Risk
service Service name
clientIP IP used in the access
asn Autonomous System Number of access
clientReverse DNS reverse of IP the access
client_ua Useragent of access
client_device Device of client
client_os Os used
country Country of access
region Region of access
city City of access
country_code Code of country
latitude Latitude position of the access
longitude Longitude position of the access
risk_value Value Risk
authMethod Future implementation
event_response Response of GuardianKey
message_intel Information of threat intelligence
authGroupId AuthgroupID of agent
organizationId Organization ID
message_psychometric Psycometric info (future)

Encryption details

We use a symmetric cryptography algorithm for signature, authentication and protected confidentiality of the events. The systems must send the authgroupID and the JSON encrypted on sending events, as in the example below (in UDP case):

authgroupID|cipher text (JSON) 

If use REST interface, event is sent as JSON:

… id: authgroupID data: cipher text (JSON) …

The table below presents details about the used cryptography.

Parameter Value
crypt algorithm AES
key length 256
block cipher mode CFB
segment size 8

Useful references