Kainos Developer Guide
Enterprise biometric authentication integration
How It Works
Our facial authentication system works like payment gateways. Your application redirects users to our secure authentication pages, and we handle the entire biometric verification process before returning them to your application.
Send user to our enrollment/authentication page with signed parameters
We handle face capture, liveness detection, and verification
Banking-grade encryption and audit logging throughout
User is redirected back with authentication result and token
User Enrollment
Redirect users to enroll their biometric data:
JavaScript Example:
function enrollUser(userId, userName, userEmail) {
const clientId = 'YOUR_CLIENT_ID';
const apiSecret = 'YOUR_API_SECRET';
const callbackUrl = 'https://yourapp.com/auth-callback';
const timestamp = Math.floor(Date.now() / 1000);
// Create signature
const message = `${clientId}${timestamp}${callbackUrl}${userId}`;
const signature = hmacSHA256(message, apiSecret);
const enrollUrl = new URL('https://auth.kainosit.co.in/integrate/enroll');
enrollUrl.searchParams.set('client_id', clientId);
enrollUrl.searchParams.set('callback_url', callbackUrl);
enrollUrl.searchParams.set('user_id', userId);
enrollUrl.searchParams.set('name', userName);
enrollUrl.searchParams.set('email', userEmail);
enrollUrl.searchParams.set('timestamp', timestamp);
enrollUrl.searchParams.set('signature', signature);
// Redirect user
window.location.href = enrollUrl.toString();
}
User Authentication
Redirect users to authenticate with their biometric data:
JavaScript Example:
function authenticateUser(userId) {
const clientId = 'YOUR_CLIENT_ID';
const apiSecret = 'YOUR_API_SECRET';
const callbackUrl = 'https://yourapp.com/auth-callback';
const timestamp = Math.floor(Date.now() / 1000);
// Create signature
const message = `${clientId}${timestamp}${callbackUrl}${userId}`;
const signature = hmacSHA256(message, apiSecret);
const authUrl = new URL('https://auth.kainosit.co.in/integrate/authenticate');
authUrl.searchParams.set('client_id', clientId);
authUrl.searchParams.set('callback_url', callbackUrl);
authUrl.searchParams.set('user_id', userId);
authUrl.searchParams.set('timestamp', timestamp);
authUrl.searchParams.set('signature', signature);
// Redirect user
window.location.href = authUrl.toString();
}
Backend Integration Examples
import hmac
import hashlib
import time
from flask import redirect, url_for
from urllib.parse import urlencode
def create_auth_url(user_id, action='enroll', name='', email=''):
client_id = 'YOUR_CLIENT_ID'
api_secret = 'YOUR_API_SECRET'
callback_url = url_for('auth_callback', _external=True)
timestamp = str(int(time.time()))
# Create signature message
message = f"{client_id}{timestamp}{callback_url}{user_id}"
signature = hmac.new(
api_secret.encode(),
message.encode(),
hashlib.sha256
).hexdigest()
# Build parameters
params = {
'client_id': client_id,
'callback_url': callback_url,
'user_id': user_id,
'timestamp': timestamp,
'signature': signature
}
# Add optional parameters for enrollment
if action == 'enroll':
if name:
params['name'] = name
if email:
params['email'] = email
base_url = f"https://your-kainos-instance.com/integrate/{action}"
return f"{base_url}?{urlencode(params)}"
@app.route('/auth-callback')
def auth_callback():
status = request.args.get('status')
user_id = request.args.get('user_id')
token = request.args.get('token')
if status == 'success':
# Handle successful authentication
confidence = request.args.get('confidence')
return f"Authentication successful for {user_id}"
else:
# Handle failed authentication
error = request.args.get('error')
return f"Authentication failed: {error}"
const crypto = require('crypto');
const express = require('express');
function createAuthUrl(userId, action = 'enroll', name = '', email = '') {
const clientId = 'YOUR_CLIENT_ID';
const apiSecret = 'YOUR_API_SECRET';
const callbackUrl = 'https://yourapp.com/auth-callback';
const timestamp = Math.floor(Date.now() / 1000);
// Create signature
const message = `${clientId}${timestamp}${callbackUrl}${userId}`;
const signature = crypto
.createHmac('sha256', apiSecret)
.update(message)
.digest('hex');
// Build parameters
const params = new URLSearchParams({
client_id: clientId,
callback_url: callbackUrl,
user_id: userId,
timestamp: timestamp,
signature: signature
});
// Add optional parameters for enrollment
if (action === 'enroll') {
if (name) params.append('name', name);
if (email) params.append('email', email);
}
return `https://your-kainos-instance.com/integrate/${action}?${params}`;
}
// Express callback handler
app.get('/auth-callback', (req, res) => {
const { status, user_id, token, confidence, error } = req.query;
if (status === 'success') {
// Handle successful authentication
res.json({
success: true,
message: `Authentication successful for ${user_id}`,
confidence: parseFloat(confidence)
});
} else {
// Handle failed authentication
res.status(400).json({
success: false,
message: `Authentication failed: ${error}`
});
}
});
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/auth")
public class KainosAuthController {
private static final String CLIENT_ID = "YOUR_CLIENT_ID";
private static final String API_SECRET = "YOUR_API_SECRET";
private static final String KAINOS_BASE_URL = "https://your-kainos-instance.com/integrate";
public String createAuthUrl(String userId, String action, String name, String email)
throws Exception {
String callbackUrl = "https://yourapp.com/auth-callback";
long timestamp = Instant.now().getEpochSecond();
// Create signature
String message = CLIENT_ID + timestamp + callbackUrl + userId;
String signature = createHmacSha256(message, API_SECRET);
// Build parameters
Map params = new HashMap<>();
params.put("client_id", CLIENT_ID);
params.put("callback_url", callbackUrl);
params.put("user_id", userId);
params.put("timestamp", String.valueOf(timestamp));
params.put("signature", signature);
// Add optional parameters for enrollment
if ("enroll".equals(action)) {
if (name != null && !name.isEmpty()) {
params.put("name", name);
}
if (email != null && !email.isEmpty()) {
params.put("email", email);
}
}
// Build URL with parameters
String queryString = params.entrySet().stream()
.map(entry -> URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8) +
"=" + URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8))
.collect(Collectors.joining("&"));
return KAINOS_BASE_URL + "/" + action + "?" + queryString;
}
private String createHmacSha256(String message, String secret) throws Exception {
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKeySpec = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
mac.init(secretKeySpec);
byte[] hash = mac.doFinal(message.getBytes());
StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
}
@GetMapping("/callback")
public ResponseEntity> authCallback(@RequestParam Map params) {
String status = params.get("status");
String userId = params.get("user_id");
String token = params.get("token");
if ("success".equals(status)) {
// Handle successful authentication
String confidence = params.get("confidence");
return ResponseEntity.ok()
.body(Map.of(
"success", true,
"message", "Authentication successful for " + userId,
"confidence", Double.parseDouble(confidence)
));
} else {
// Handle failed authentication
String error = params.get("error");
return ResponseEntity.badRequest()
.body(Map.of(
"success", false,
"message", "Authentication failed: " + error
));
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class KainosAuthController : ControllerBase
{
private const string CLIENT_ID = "YOUR_CLIENT_ID";
private const string API_SECRET = "YOUR_API_SECRET";
private const string KAINOS_BASE_URL = "https://your-kainos-instance.com/integrate";
public string CreateAuthUrl(string userId, string action, string name = "", string email = "")
{
var callbackUrl = "https://yourapp.com/api/auth/callback";
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
// Create signature
var message = $"{CLIENT_ID}{timestamp}{callbackUrl}{userId}";
var signature = CreateHmacSha256(message, API_SECRET);
// Build parameters
var parameters = new Dictionary
{
{"client_id", CLIENT_ID},
{"callback_url", callbackUrl},
{"user_id", userId},
{"timestamp", timestamp.ToString()},
{"signature", signature}
};
// Add optional parameters for enrollment
if (action == "enroll")
{
if (!string.IsNullOrEmpty(name))
parameters["name"] = name;
if (!string.IsNullOrEmpty(email))
parameters["email"] = email;
}
// Build query string
var queryString = string.Join("&",
parameters.Select(kvp => $"{HttpUtility.UrlEncode(kvp.Key)}={HttpUtility.UrlEncode(kvp.Value)}"));
return $"{KAINOS_BASE_URL}/{action}?{queryString}";
}
private string CreateHmacSha256(string message, string secret)
{
var keyBytes = Encoding.UTF8.GetBytes(secret);
var messageBytes = Encoding.UTF8.GetBytes(message);
using (var hmac = new HMACSHA256(keyBytes))
{
var hashBytes = hmac.ComputeHash(messageBytes);
return BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
}
}
[HttpGet("callback")]
public IActionResult AuthCallback([FromQuery] Dictionary parameters)
{
var status = parameters.GetValueOrDefault("status");
var userId = parameters.GetValueOrDefault("user_id");
var token = parameters.GetValueOrDefault("token");
if (status == "success")
{
// Handle successful authentication
var confidence = parameters.GetValueOrDefault("confidence");
return Ok(new
{
success = true,
message = $"Authentication successful for {userId}",
confidence = double.Parse(confidence ?? "0")
});
}
else
{
// Handle failed authentication
var error = parameters.GetValueOrDefault("error");
return BadRequest(new
{
success = false,
message = $"Authentication failed: {error}"
});
}
}
[HttpPost("enroll/{userId}")]
public IActionResult EnrollUser(string userId, [FromBody] EnrollmentRequest request)
{
try
{
var authUrl = CreateAuthUrl(userId, "enroll", request.Name, request.Email);
return Ok(new { redirectUrl = authUrl });
}
catch (Exception ex)
{
return StatusCode(500, new { error = ex.Message });
}
}
[HttpPost("authenticate/{userId}")]
public IActionResult AuthenticateUser(string userId)
{
try
{
var authUrl = CreateAuthUrl(userId, "authenticate");
return Ok(new { redirectUrl = authUrl });
}
catch (Exception ex)
{
return StatusCode(500, new { error = ex.Message });
}
}
}
public class EnrollmentRequest
{
public string Name { get; set; }
public string Email { get; set; }
}
Callback Parameters
When the authentication process completes, users are redirected to your callback URL with these parameters:
Success Response:
https://yourapp.com/callback? status=success& user_id=user123& confidence=0.92& liveness_score=0.85& gestures_completed=2& timestamp=1625097600
Failure Response:
https://yourapp.com/callback? status=failed& user_id=user123& error=Face+does+not+match& gestures_completed=5& timestamp=1625097600
Parameter Descriptions:
| Parameter | Description | Values |
|---|---|---|
status |
Authentication result | success, failed, cancelled, timeout |
user_id |
The user ID you provided | String |
confidence |
Face match confidence (success only) | 0.0 - 1.0 |
liveness_score |
Liveness detection score (success only) | 0.0 - 1.0 |
error |
Error description (failure only) | String |
gestures_completed |
Number of gesture challenges attempted | 1-5 |
timestamp |
Unix timestamp of completion | Integer |
- Timestamp Validation: Always generate fresh timestamps (within 5 minutes)
- Secret Protection: Keep your API secret secure and never expose it in client-side code
- Callback Validation: Validate callback parameters on your server before processing results
- HTTPS Required: Use HTTPS for all callback URLs in production
- Rate Limiting: Implement rate limiting on your callback endpoints
- HMAC Verification: The signature algorithm is: HMAC-SHA256(client_id + timestamp + callback_url + user_id, api_secret)
Test Integration
Use our test integration to see the full flow in action: