Integration Demo - Facial Authentication System
Kainos

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.

1
Redirect User

Send user to our enrollment/authentication page with signed parameters

2
Biometric Process

We handle face capture, liveness detection, and verification

3
Secure Processing

Banking-grade encryption and audit logging throughout

4
Return to App

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
Security Requirements:
  • 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: