Biometric Authentication Implementation Guide
This comprehensive guide covers the implementation of biometric authentication in the PVPipe ms-auth service, including device registration, mobile biometric login, action confirmation workflows, and security features.
Table of Contents
- Architecture Overview
- Implementation Components
- Security Features
- Database Schema
- API Endpoints
- Token Differentiation
- Push Notifications
- Usage Examples
- Security Best Practices
- Performance Considerations
Architecture Overview
Core Components
The biometric authentication system consists of several integrated services:
- BiometricService - Core business logic and cryptographic operations
- BiometricHandler - HTTP endpoint handlers with comprehensive validation
- FieldEncryption - AES-GCM field-level encryption for sensitive data
- AuditService - Security audit logging and compliance tracking
- ValidationService - Input validation and security checks
- NotificationService - Firebase FCM integration for push notifications
- TokenManagementService - Specialized JWT token handling
Authentication Flow
βββββββββββββββ ββββββββββββββββ βββββββββββββββββββ
βMobile App β βms-auth API β βSecure Hardware β
βββββββββββββββ ββββββββββββββββ βββββββββββββββββββ
β β β
1. β Request Challenge β β
ββββββββββββββββββββΊβ β
β β β
2. βββββββββββββββββββββ Challenge + Session β
β β β
3. β Biometric Prompt β β
ββββββββββββββββββββββββββββββββββββββββΊ β
β β β
4. ββββββββββββββββββββββββββββββββββββββββ β
β Signed Challenge β
β β β
5. β Submit Signature β β
ββββββββββββββββββββΊβ β
β β β
6. βββββββββββββββββββββ JWT Tokens β
β β βSecurity Architecture
The system implements multiple security layers:
- Hardware Security: Keys stored in Secure Enclave (iOS) or Hardware Security Module (Android)
- Cryptographic Security: ES256, RS256, PS256 signature algorithms
- Field-Level Encryption: AES-256-GCM for sensitive data storage
- Token Security: Device binding and time-limited validity
- Audit Trail: Comprehensive logging for compliance
Implementation Components
BiometricService
The core service handles all biometric operations:
type BiometricService struct {
db *sql.DB
redis *redis.Client
encryptionSvc *FieldEncryption
auditSvc *AuditService
validationSvc *ValidationService
notificationSvc *NotificationService
}
// Key methods
func (s *BiometricService) CreateRegistrationChallenge(ctx context.Context, req *DeviceRegistrationRequest) (*ChallengeResponse, error)
func (s *BiometricService) VerifyDeviceRegistration(ctx context.Context, req *VerificationRequest) (*RegistrationResponse, error)
func (s *BiometricService) CreateAuthChallenge(ctx context.Context, deviceFingerprint string) (*ChallengeResponse, error)
func (s *BiometricService) VerifyBiometricLogin(ctx context.Context, req *LoginRequest) (*TokenResponse, error)
func (s *BiometricService) InitiateConfirmation(ctx context.Context, req *ConfirmationRequest) (*ConfirmationResponse, error)
func (s *BiometricService) VerifyConfirmation(ctx context.Context, confirmationID string, req *VerificationRequest) errorFieldEncryption Service
Provides AES-256-GCM encryption for sensitive database fields:
type FieldEncryption struct {
key []byte
}
func (f *FieldEncryption) Encrypt(plaintext []byte, additionalData string) (*EncryptedField, error) {
cipher, _ := aes.NewCipher(f.key)
gcm, _ := cipher.NewGCM()
nonce := make([]byte, gcm.NonceSize())
rand.Read(nonce)
ciphertext := gcm.Seal(nil, nonce, plaintext, []byte(additionalData))
return &EncryptedField{
Ciphertext: ciphertext,
Nonce: nonce,
AAD: additionalData,
}, nil
}
func (f *FieldEncryption) Decrypt(field *EncryptedField) ([]byte, error) {
cipher, _ := aes.NewCipher(f.key)
gcm, _ := cipher.NewGCM()
return gcm.Open(nil, field.Nonce, field.Ciphertext, []byte(field.AAD))
}AuditService
Comprehensive security event logging:
type AuditService struct {
db *sql.DB
}
type AuditEvent struct {
ID string `json:"id"`
Timestamp time.Time `json:"timestamp"`
EventType string `json:"event_type"`
Severity string `json:"severity"`
UserID *int64 `json:"user_id"`
DeviceID *string `json:"device_id"`
IPAddress string `json:"ip_address"`
UserAgent string `json:"user_agent"`
Success bool `json:"success"`
ErrorMsg *string `json:"error_message"`
Details map[string]interface{} `json:"details"`
}
func (a *AuditService) LogEvent(ctx context.Context, event *AuditEvent) errorValidationService
Input validation with security-focused patterns:
type ValidationService struct {}
func (v *ValidationService) ValidateDeviceName(name string) error {
if len(name) == 0 || len(name) > 255 {
return errors.New("device name must be 1-255 characters")
}
// Allow alphanumeric, spaces, hyphens, apostrophes only
matched, _ := regexp.MatchString(`^[a-zA-Z0-9\s\-']+
Biometric Authentication Implementation Guide - Knowledge Center
{{additionalStyles}}
, name)
if !matched {
return errors.New("device name contains invalid characters")
}
return nil
}
func (v *ValidationService) ValidatePublicKey(key string, algorithm string) error {
// Validate PEM format
block, _ := pem.Decode([]byte(key))
if block == nil {
return errors.New("invalid PEM format")
}
// Size validation
if len(key) > 10240 { // 10KB max
return errors.New("public key too large")
}
// Algorithm-specific validation
switch algorithm {
case "ES256":
return v.validateECDSAKey(block.Bytes)
case "RS256", "PS256":
return v.validateRSAKey(block.Bytes)
default:
return errors.New("unsupported key algorithm")
}
}Security Features
Cryptographic Standards
Challenge Generation
- Entropy: 64 bytes of cryptographically secure random data
- Encoding: Base64-URL encoding for safe transport
- Expiration: 2-5 minutes depending on operation
- Single-Use: Each challenge can only be used once
Signature Algorithms
- ES256: ECDSA with P-256 curve and SHA-256 (recommended for mobile)
- RS256: RSA PKCS#1 v1.5 with SHA-256
- PS256: RSA PSS with SHA-256 (enhanced RSA)
Field Encryption
- Algorithm: AES-256-GCM
- Key Derivation: PBKDF2 from JWT secret
- Nonce: 96-bit random per encryption
- Tag: 128-bit authentication tag
Input Validation
Comprehensive validation for all inputs:
- Device Names: 1-255 chars, alphanumeric + limited special chars
- Device Fingerprints: Multiple format support (hex, base64, UUID)
- Public Keys: PEM format validation, 10KB max
- Signed Challenges: Base64 format, reasonable size limits
- Action Types: Alphanumeric with underscores/hyphens
- Action Payloads: JSON format, 4KB size limit
Audit Logging
All security events are logged with:
- User ID and device ID correlation
- IP address and User-Agent tracking
- Timestamp and success/failure status
- Error details for failed operations
- Structured details in JSON format
Database Schema
Core Tables
registered_devices
Stores encrypted device information:
CREATE TABLE registered_devices (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
device_name VARCHAR(255) NOT NULL,
device_type VARCHAR(50) NOT NULL CHECK (device_type IN ('mobile', 'desktop', 'tablet')),
device_fingerprint VARCHAR(255) NOT NULL,
public_key TEXT NOT NULL, -- Encrypted using field encryption
key_algorithm VARCHAR(10) NOT NULL CHECK (key_algorithm IN ('ES256', 'RS256', 'PS256')),
fcm_token VARCHAR(255),
is_active BOOLEAN NOT NULL DEFAULT true,
last_used_at TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
CONSTRAINT unique_user_device_fingerprint UNIQUE (user_id, device_fingerprint)
);
CREATE INDEX idx_registered_devices_user_active ON registered_devices(user_id, is_active);
CREATE INDEX idx_registered_devices_fingerprint ON registered_devices(device_fingerprint);
CREATE INDEX idx_registered_devices_fcm_token ON registered_devices(fcm_token) WHERE fcm_token IS NOT NULL;
mobile_auth_sessions
Manages biometric authentication sessions:
CREATE TABLE mobile_auth_sessions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
device_id UUID NOT NULL REFERENCES registered_devices(id) ON DELETE CASCADE,
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
challenge TEXT NOT NULL,
is_verified BOOLEAN NOT NULL DEFAULT false,
ip_address VARCHAR(45),
user_agent TEXT,
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
verified_at TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_mobile_auth_sessions_device_verified ON mobile_auth_sessions(device_id, is_verified, created_at);
CREATE INDEX idx_mobile_auth_sessions_expires ON mobile_auth_sessions(expires_at);
confirmation_sessions
Handles action confirmation workflows:
CREATE TABLE confirmation_sessions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
confirmation_id VARCHAR(255) NOT NULL UNIQUE,
action_type VARCHAR(100) NOT NULL,
action_payload JSONB, -- Encrypted using field encryption
challenge TEXT NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT 'pending'
CHECK (status IN ('pending', 'approved', 'rejected', 'expired')),
device_id UUID REFERENCES registered_devices(id) ON DELETE SET NULL,
ip_address VARCHAR(45),
user_agent TEXT,
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
approved_at TIMESTAMP WITH TIME ZONE,
rejected_at TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_confirmation_sessions_user_status ON confirmation_sessions(user_id, status, created_at);
CREATE INDEX idx_confirmation_sessions_confirmation_id ON confirmation_sessions(confirmation_id);
CREATE INDEX idx_confirmation_sessions_expires ON confirmation_sessions(expires_at);
audit_logs
Comprehensive audit trail:
CREATE TABLE audit_logs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
timestamp TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
event_type VARCHAR(50) NOT NULL,
severity VARCHAR(20) NOT NULL DEFAULT 'info'
CHECK (severity IN ('debug', 'info', 'warning', 'error', 'critical')),
user_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
device_id UUID REFERENCES registered_devices(id) ON DELETE SET NULL,
ip_address VARCHAR(45),
user_agent TEXT,
success BOOLEAN NOT NULL,
error_message TEXT,
details JSONB -- Encrypted using field encryption
);
CREATE INDEX idx_audit_logs_timestamp ON audit_logs(timestamp DESC);
CREATE INDEX idx_audit_logs_user_event ON audit_logs(user_id, event_type, timestamp);
CREATE INDEX idx_audit_logs_device_event ON audit_logs(device_id, event_type, timestamp);
CREATE INDEX idx_audit_logs_event_success ON audit_logs(event_type, success, timestamp);
notifications
Push notification tracking:
CREATE TABLE notifications (
id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
device_id UUID REFERENCES registered_devices(id) ON DELETE SET NULL,
confirmation_id VARCHAR(255) REFERENCES confirmation_sessions(confirmation_id) ON DELETE SET NULL,
notification_type VARCHAR(50) NOT NULL,
title VARCHAR(255) NOT NULL,
body TEXT NOT NULL,
data JSONB,
fcm_message_id VARCHAR(255),
delivery_status VARCHAR(50) NOT NULL DEFAULT 'pending'
CHECK (delivery_status IN ('pending', 'sent', 'delivered', 'failed')),
error_message TEXT,
sent_at TIMESTAMP WITH TIME ZONE,
delivered_at TIMESTAMP WITH TIME ZONE,
expires_at TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_notifications_user_type_status ON notifications(user_id, notification_type, delivery_status, created_at);
CREATE INDEX idx_notifications_confirmation ON notifications(confirmation_id);
CREATE INDEX idx_notifications_delivery_status ON notifications(delivery_status, created_at);
Token Management Tables
-- Biometric refresh token tracking
CREATE TABLE biometric_refresh_tokens (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
device_id UUID NOT NULL REFERENCES registered_devices(id) ON DELETE CASCADE,
token_family VARCHAR(255) NOT NULL,
rotation_count INTEGER NOT NULL DEFAULT 0,
auth_method VARCHAR(50) NOT NULL,
trust_level VARCHAR(50) NOT NULL CHECK (trust_level IN ('low', 'medium', 'high')),
is_revoked BOOLEAN NOT NULL DEFAULT false,
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
last_used_at TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
CONSTRAINT unique_token_family UNIQUE (token_family)
);
-- Action confirmation token sessions
CREATE TABLE action_confirmation_sessions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
confirmation_id VARCHAR(255) NOT NULL UNIQUE,
action_type VARCHAR(100) NOT NULL,
token_used BOOLEAN NOT NULL DEFAULT false,
nonce VARCHAR(255) NOT NULL UNIQUE,
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
used_at TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);
API Endpoints
Device Registration
POST /api/v1/auth/devices/register/challenge
Creates a registration challenge with public key validation.
Features:
- Validates public key format and algorithm
- Generates cryptographically secure challenge
- Stores session in Redis with 5-minute expiration
- Encrypts public key for secure storage
POST /api/v1/auth/devices/register/verify
Completes device registration with signature verification.
Features:
- Verifies cryptographic signature against challenge
- Validates signature algorithm matches key algorithm
- Creates encrypted device record
- Logs comprehensive audit trail
Mobile Biometric Authentication
POST /api/v1/auth/mobile/challenge
Requests authentication challenge for registered device.
Features:
- Device fingerprint validation
- Challenge generation with 2-minute expiration
- Session tracking for security
POST /api/v1/auth/mobile/biometric
Completes biometric authentication and issues specialized tokens.
Features:
- Signature verification against stored public key
- Generates biometric-specific JWT tokens
- Device binding and trust level calculation
- Token family management for security
POST /api/v1/auth/mobile/refresh
Refreshes biometric tokens with rotation.
Features:
- Secure token family rotation
- Incremental rotation counter
- Automatic revocation of old tokens
- Device binding validation
Action Confirmation
POST /api/v1/auth/confirmation/initiate
Initiates biometric confirmation for sensitive actions.
Features:
- Action payload validation and encryption
- Push notification to registered devices
- Challenge generation for biometric verification
- Comprehensive audit logging
GET /api/v1/auth/confirmation/{id}/status
Checks confirmation session status for polling.
POST /api/v1/auth/confirmation/{id}/verify
Verifies action with biometric signature.
Features:
- Signature verification with device validation
- Single-use token consumption
- Status update to approved
- Detailed audit logging
POST /api/v1/auth/confirmation/{id}/reject
Manually rejects confirmation session.
Device Management
GET /api/v1/auth/devices
Lists user's registered devices with metadata.
DELETE /api/v1/auth/devices/{deviceId}
Removes registered device and revokes associated tokens.
PUT /api/v1/auth/devices/fcm-token
Updates Firebase Cloud Messaging token for push notifications.
Token Differentiation
The system implements three distinct JWT token types:
1. Biometric Access Tokens
- Lifetime: 15 minutes
- Purpose: Mobile app authentication with biometric verification
- Claims: Include device_id, auth_method, trust_level, session_id
- Security: Device binding prevents cross-device usage
2. Biometric Refresh Tokens
- Lifetime: 30 days
- Purpose: Long-term session management with secure rotation
- Claims: Include token_family, rotation_count for security
- Security: Family-based rotation prevents token theft
3. Action Confirmation Tokens
- Lifetime: 5 minutes, single-use
- Purpose: Confirm sensitive actions via biometric verification
- Claims: Include confirmation_id, action_type, nonce
- Security: Single-use enforcement with replay protection
Trust Level Determination
- High: Strong key algorithm (ES256/PS256) + Mobile device + Recent usage
- Medium: Good key algorithm (RS256) + Any device type + Moderate usage
- Low: Basic algorithm + Desktop device + Infrequent usage
Token Security Features
Device Binding
All biometric tokens are bound to specific devices and cannot be used from other devices.
Family-based Rotation
Refresh tokens use hierarchical families with rotation counters to prevent token theft and enable secure renewal.
Single-use Enforcement
Action confirmation tokens can only be used once and include cryptographic nonces to prevent replay attacks.
Push Notifications
Firebase FCM Integration
The system integrates with Firebase Cloud Messaging for real-time push notifications:
type NotificationService struct {
fcmClient *messaging.Client
db *sql.DB
}
func (n *NotificationService) SendConfirmationNotification(ctx context.Context, userID int64, confirmationID string, actionType string, actionPayload map[string]interface{}) error {
// Find user's devices with FCM tokens
devices, err := n.getUserDevicesWithFCM(ctx, userID)
if err != nil {
return err
}
// Create notification content
notification := n.createNotificationContent(actionType, actionPayload)
// Send to all devices
for _, device := range devices {
message := &messaging.Message{
Token: device.FCMToken,
Notification: notification,
Data: map[string]string{
"type": "confirmation_request",
"confirmationId": confirmationID,
"actionType": actionType,
},
}
response, err := n.fcmClient.Send(ctx, message)
if err != nil {
n.logFailedNotification(ctx, device.ID, err)
} else {
n.logSuccessfulNotification(ctx, device.ID, response.Name)
}
}
return nil
}
Notification Templates
The system supports various notification types:
- Payment Approval: "Approve payment of {amount} {currency}"
- Document Approval: "Approve document: {documentName}"
- Purchase Order: "Approve purchase order from {supplier} ({amount} VND)"
- User Access: "Approve access for user: {username}"
Platform-specific Configuration
iOS (APNS)
- Category:
BIOMETRIC_CONFIRMATION
- Action:
CONFIRM_ACTION
- Sound:
default
Android
- Channel ID:
biometric_confirmations
- Icon:
ic_notification
- Color:
#2196F3
Usage Examples
Mobile Device Registration
// 1. Generate key pair on mobile device (iOS/Android)
keyPair := generateBiometricKeyPair()
// 2. Request registration challenge
challengeReq := &DeviceRegistrationRequest{
DeviceName: "John's iPhone 15",
DeviceType: "mobile",
DeviceFingerprint: createDeviceFingerprint(),
PublicKey: keyPair.PublicKey,
KeyAlgorithm: "ES256",
}
challenge, err := biometricService.CreateRegistrationChallenge(ctx, challengeReq)
// 3. Sign challenge with biometric authentication
signature := signChallengeWithBiometric(challenge.Challenge)
// 4. Complete registration
verifyReq := &VerificationRequest{
SessionID: challenge.SessionID,
SignedChallenge: signature,
}
device, err := biometricService.VerifyDeviceRegistration(ctx, verifyReq)
Biometric Login Flow
// 1. Request login challenge
challenge, err := biometricService.CreateAuthChallenge(ctx, deviceFingerprint)
// 2. Sign challenge with biometric
signature := signChallengeWithBiometric(challenge.Challenge)
// 3. Complete login
loginReq := &LoginRequest{
SessionID: challenge.SessionID,
SignedChallenge: signature,
RememberMe: true,
}
tokens, err := biometricService.VerifyBiometricLogin(ctx, loginReq)
Action Confirmation Flow
// 1. Web user initiates sensitive action
confirmationReq := &ConfirmationRequest{
UserID: userID,
ActionType: "payment_approval",
ActionPayload: map[string]interface{}{
"amount": 50000,
"currency": "VND",
"recipient": "Nguyen Van A",
},
}
confirmation, err := biometricService.InitiateConfirmation(ctx, confirmationReq)
// 2. Push notification sent to mobile devices automatically
// 3. Mobile user verifies with biometric
verifyReq := &VerificationRequest{
DeviceID: deviceID,
SignedChallenge: signature,
}
err := biometricService.VerifyConfirmation(ctx, confirmation.ID, verifyReq)
Token Refresh with Rotation
// Refresh biometric tokens
refreshReq := &RefreshRequest{
RefreshToken: existingRefreshToken,
}
newTokens, err := tokenService.RefreshBiometricTokens(ctx, refreshReq)
// Old refresh token family is automatically revoked
// New tokens have incremented rotation count
Security Best Practices
Mobile Implementation
- Secure Key Storage: Use Secure Enclave (iOS) or Hardware Security Module (Android)
- Biometric Validation: Require biometric authentication before signing
- Certificate Pinning: Implement certificate pinning for API calls
- Anti-Tampering: Implement jailbreak/root detection
Server Implementation
- Input Validation: Validate all inputs with strict patterns
- Error Handling: Prevent information disclosure in error messages
- Audit Logging: Log all security events comprehensively
- Rate Limiting: Implement progressive rate limiting
Cryptographic Security
- Key Management: Regular rotation of JWT secrets
- Algorithm Selection: Prefer ES256 for new implementations
- Challenge Generation: Use cryptographically secure random numbers
- Field Encryption: Encrypt all sensitive database fields
Operational Security
- Token Revocation: Implement emergency revocation capabilities
- Session Management: Monitor and clean up expired sessions
- Audit Analysis: Regular analysis of security logs
- Incident Response: Automated response to security events
Performance Considerations
Database Optimization
- Indexes: Proper indexing on frequently queried fields
- Connection Pooling: Efficient database connection management
- Query Optimization: Optimized queries with proper joins
Cache Strategy
- Redis Usage: Session storage and temporary data
- Token Caching: Cache validation results for performance
- Challenge Storage: Efficient challenge-response handling
Processing Performance
- Encrypted Fields: ~5ms overhead for encryption/decryption
- Challenge Generation: ~1ms with secure randomness
- Signature Verification: 10-50ms depending on algorithm
- Database Operations: Optimized with proper indexing
Scalability Considerations
- Horizontal Scaling: Stateless service design
- Database Partitioning: Consider partitioning for high-volume users
- Redis Clustering: Scale cache layer independently
- Microservice Architecture: Independent scaling of components
Vietnamese Enterprise Compliance
Legal Requirements
- Audit Trail: Comprehensive logging meets regulatory standards
- Digital Signatures: Support for Vietnamese legal document workflows
- Data Retention: Configurable retention policies
- Privacy Controls: Proper handling of personal biometric data
Business Integration
- Manufacturing Workflows: Support for factory approval processes
- Financial Controls: Multi-step approval for high-value transactions
- Vietnamese Currency: Proper VND formatting and handling
- Multi-language Support: Vietnamese and English interfaces
This implementation provides enterprise-grade biometric authentication with comprehensive security features, Vietnamese compliance, and high-performance scalability for the PVPipe ecosystem.