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:
- You register your system using the API;
- Your system use the information received in the registration step to send login attempts to GuardianKey (in cloud);
- The GuardianKey process the events with Artificial Intelligence algorithms to provide a risk for each login attempt;
- Based on predefined thresholds, your security staff and/or the user can be notified by e-mail;
- Also, for high level risks, your system can block or require more steps for the authentication (e.g., a second auth factor); and
- 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:
- registering: create cryptographic keys, get an authgroupID in GuardianKey and register notification options;
- sending events: your system send login attempts (events) to be processed in GuardianKey; and
- monitoring: you access the GuardianKey admin interface to monitor your systems’ risks and setup your preferences.
In summary:
- the registration is done via a webserver, which supports REST and XML-RPC;
- alerts are sent via an encrypted JSON using UDP or REST; and
- 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/guardiankey/guardiankey-api-php/archive/master.zip
$ unzip master.zip
# run the code for registering
$ cd guardiankey-api-php-master
$ php register.php
# copy the output to the top of the file guardiankey-class.php, example:
$GKconfig = array(
'email' => '[email protected]',
'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/guardiankey/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'] = '[email protected]'
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”, “NOTIFY”,“HARD NOTIFY” 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:
- PHP – https://github.com/guardiankey/guardiankey-api-php/
- Python – https://github.com/guardiankey/guardiankey-api-python/
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;
*/
Avoiding Event Flooding
When a system receives a brute force attack, it often sends GuardianKey many events. GuardianKey has an advanced brute force detection system. When such an attack is detected, GuardianKey returns “1” in the “response_cache” field of the event response json. With this, you can for example put the attacker’s IP in a “blacklist”, discarding and / or blocking access from that IP.
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. [email protected]), 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/guardiankey/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) |
Creating Your Own Confirmation Screen
By default, GuardianKey sends a link to the confirmation screen (for the user to see if they recognize access or not) using the “guardiankey.io” domain. You may want to host this screen on your domain (which gives the user more credibility). For this you have to follow the following steps:
- You will need a web server (running PHP, for example) and on that web server you will configure webhook and the confirmation screen. At the address below you will find the reference files (webhook.php and viewresolveevent.php). https://github.com/guardiankey/guardiankey-api-php
- In the “guardiankey.class.php” file options, you set the “resolveEventURL” option to your screen URL for resolving events.
- You configure your webhook action to send the user the link from your confirmation screen and the link to be sent to the user you add as parameters: eventId and event_token. Ex: https: //xxxxxxxxxx.com/viewresolveevent.php?e=<eventId>&t=<event_token>
- Finally, on the confirmation screen, you will retrieve event information and send the user response via API to GuardianKey, as in the viewresolveevent.php file.
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
- PHP API reference implementation – https://github.com/guardiankey/guardiankey-api-php/
- Python API reference implementation – https://github.com/guardiankey/guardiankey-api-python/
- Getting help in the discussion group – https://groups.google.com/forum/#!forum/guardiankey
- Already implemented plugins
- Contact the developers