Skip to content

IdentityProviders Plugin

Description

The Identity Providers plugin collection provides identity management and storage capabilities for CVEDIA-RT's face recognition and person identification systems. These plugins enable persistent biometric identity storage, fast retrieval, and cross-session identity persistence across different storage backends.

The plugin collection implements both the IdentityProvider and IdentityStore interfaces, offering:

  • Biometric Identity Storage: Secure storage and retrieval of face embeddings and identity metadata
  • Multi-Backend Support: Choice between in-memory and Redis-based storage systems
  • Real-time Performance: Optimized for high-speed identity matching in live video streams
  • Scalable Architecture: Support for large-scale identity databases and distributed deployments
  • Event Tracking: Identity-based event logging and historical data management

Available Implementations

Implementation Description Storage Backend Use Case
MemoryDb In-memory identity storage System RAM High-speed temporary operations, edge computing
RedisDb Redis-based distributed storage Redis database Persistent storage, multi-instance deployments

Requirements

Software Dependencies

  • CVEDIA-RT Core: Base runtime environment
  • OpenCV: Image processing and computer vision operations
  • Threading Libraries: Multi-threaded access support

Additional Requirements by Implementation

MemoryDb

  • Sufficient system RAM for identity database
  • No external dependencies

RedisDb

  • Redis Server: Version 6.0+ with RediSearch module
  • Redis C++ Client: hiredis, redis-plus-plus libraries
  • Network Connectivity: For distributed Redis access

Hardware Recommendations

  • Memory: Minimum 4GB RAM for moderate identity databases (1000-10000 identities)
  • Storage: SSD recommended for Redis persistence
  • Network: Gigabit Ethernet for distributed Redis deployments

Configuration

Basic MemoryDb Configuration

{
  "identity": {
    "provider": {
      "main": {
        "implementation": "memorydb",
        "config": {
          "default_ttl_ms": 60000,
          "vector_match_threshold": 0.5,
          "vector_match_algo": "euclidean",
          "string_match_threshold": 1.0
        }
      }
    }
  }
}

Basic RedisDb Configuration

{
  "identity": {
    "provider": {
      "main": {
        "implementation": "redisdb",
        "config": {
          "redis_ip": "localhost",
          "redis_port": 6379,
          "redis_user": "",
          "redis_pass": "",
          "default_ttl_ms": 86400000,
          "vector_match_threshold": 0.1,
          "string_match_threshold": 1.0
        }
      }
    }
  }
}

Advanced Multi-Provider Configuration

{
  "identity": {
    "provider": {
      "cache": {
        "implementation": "memorydb",
        "config": {
          "default_ttl_ms": 30000,
          "vector_match_threshold": 0.3
        }
      },
      "persistent": {
        "implementation": "redisdb",
        "config": {
          "redis_ip": "redis.example.com",
          "redis_port": 6379,
          "redis_user": "cvedia",
          "redis_pass": "secure_password",
          "default_ttl_ms": -1,
          "vector_match_threshold": 0.1
        }
      }
    }
  }
}

Configuration Parameters

Common Parameters

Parameter Type Default Description
implementation string - Backend implementation ("memorydb" or "redisdb")
default_ttl_ms integer 60000 Default time-to-live for identities in milliseconds (-1 for permanent)
vector_match_threshold float 0.5 Similarity threshold for vector-based identity matching (0.0-1.0)
string_match_threshold float 1.0 Similarity threshold for string-based identity matching

MemoryDb Specific Parameters

Parameter Type Default Description
vector_match_algo string "euclidean" Distance algorithm ("euclidean", "cosine")

RedisDb Specific Parameters

Parameter Type Default Description
redis_ip string "localhost" Redis server IP address
redis_port integer 6379 Redis server port
redis_user string "" Redis authentication username (optional)
redis_pass string "" Redis authentication password (optional)

Supported Storage Backends

MemoryDb Backend

Features: - Ultra-fast in-memory storage using system RAM - Thread-safe concurrent access with mutex protection - Support for both euclidean and cosine distance algorithms - Automatic memory cleanup with configurable TTL - No external dependencies or network requirements

Data Structures: - Vector features stored as FeatureVectorLookup with timestamps - String features stored as FeatureStringLookup with metadata - Identity fields stored as key-value maps - Events stored as time-ordered lists per identity

RedisDb Backend

Features: - Persistent storage with Redis database backend - Distributed access across multiple CVEDIA-RT instances - Support for Redis clustering and sharding - Real-time updates through Redis pub/sub mechanism - Automatic data persistence and recovery

Redis Data Organization: - Vector database: {configKey}_vector:* - String database: {configKey}_string:* - Fields database: {configKey}_fields:* - Events database: {configKey}_events:*

API Reference

C++ IdentityProvider Interface

class IdentityProvider {
public:
    // Identity Management
    virtual expected<void> deleteIdentity(Uuid const& id) = 0;
    virtual expected<Uuid> insertVector(std::vector<float> const& feature) = 0;
    virtual expected<Uuid> vectorLookup(std::vector<float> const& feature) = 0;
    virtual expected<Uuid> stringLookup(std::string const& feature) = 0;
    virtual expected<void> link(Uuid const& destId, Uuid const& srcId) = 0;

    // Configuration
    virtual expected<void> setConfigValue(std::string const& key, CValue const& val) = 0;
    virtual expected<CValue> getConfigValue(std::string const& key) = 0;
};

C++ IdentityStore Interface

class IdentityStore {
public:
    // Field Management
    virtual expected<void> setField(Uuid const& id, std::string const& key, std::string const& data) = 0;
    virtual expected<std::string> getField(Uuid const& id, std::string const& key) = 0;
    virtual expected<void> deleteField(Uuid const& id, std::string const& key) = 0;
    virtual expected<void> deleteFields(Uuid const& id) = 0;

    // Event Management
    virtual expected<void> addEvent(Uuid const& id, std::chrono::milliseconds eventTime, std::string const& eventData) = 0;
    virtual expected<std::vector<std::pair<std::chrono::milliseconds, std::string>>> getEvents(Uuid const& id, std::chrono::milliseconds startTime, std::chrono::milliseconds endTime) = 0;
    virtual expected<std::vector<std::pair<std::chrono::milliseconds, std::string>>> getEvents(Uuid const& id) = 0;
    virtual expected<void> deleteEvents(Uuid const& id) = 0;
};

Key Methods

Identity Operations

  • insertVector(): Add new identity with biometric feature vector
  • vectorLookup(): Find matching identity by feature vector similarity
  • stringLookup(): Find identity by string-based feature matching
  • deleteIdentity(): Remove identity and all associated data
  • link(): Link multiple identities together

Data Management

  • setField(): Store metadata associated with an identity
  • getField(): Retrieve identity metadata
  • addEvent(): Log events associated with an identity
  • getEvents(): Retrieve identity event history

Examples

Basic Identity Enrollment

#include "api/factory.h"

// Get current instance
auto instance = api::thread::getCurrentInstance();

// Create identity provider
auto provider = api::factory::IdentityProvider::create(instance, "IdentityDB");
if (!provider) {
    // Handle error
    return;
}

// Configure provider
provider.value()->setConfigValue("implementation", CValue("memorydb"));
provider.value()->setConfigValue("default_ttl_ms", CValue(60000));

// Enroll new identity with face embedding
std::vector<float> faceEmbedding = {0.1f, 0.2f, 0.3f, /* ... */};
auto enrollResult = provider.value()->insertVector(faceEmbedding);
if (enrollResult) {
    Uuid identityId = enrollResult.value();

    // Store additional metadata
    auto store = api::factory::IdentityStore::create(instance, "IdentityMetadata");
    store.value()->setField(identityId, "name", "John Doe");
    store.value()->setField(identityId, "department", "Engineering");
    store.value()->setField(identityId, "access_level", "admin");
}

Identity Search and Recognition

// Search for matching identity
std::vector<float> queryEmbedding = {0.11f, 0.19f, 0.31f, /* ... */};
auto searchResult = provider.value()->vectorLookup(queryEmbedding);

if (searchResult) {
    Uuid matchedId = searchResult.value();

    // Retrieve identity information
    auto instance = api::thread::getCurrentInstance();
    auto store = api::factory::IdentityStore::create(instance, "IdentityMetadata");
    auto name = store.value()->getField(matchedId, "name");
    auto department = store.value()->getField(matchedId, "department");

    // Log access event
    auto now = std::chrono::duration_cast<std::chrono::milliseconds>(
        std::chrono::system_clock::now().time_since_epoch());
    store.value()->addEvent(matchedId, now, "access_granted");

    // Log using CVEDIA-RT logging instead of printf
    api::logging::LogInfo("Access granted for " + name.value() + " from " + department.value());
}

Redis Distributed Setup

// Get current instance and configure Redis provider for distributed deployment
auto instance = api::thread::getCurrentInstance();
auto redisProvider = api::factory::IdentityProvider::create(instance, "RedisIdentityProvider");
if (!redisProvider) {
    return;
}

// Set Redis-specific configuration
redisProvider.value()->setConfigValue("implementation", CValue("redisdb"));
redisProvider.value()->setConfigValue("redis_ip", CValue("10.0.0.100"));
redisProvider.value()->setConfigValue("redis_port", CValue(6379));
redisProvider.value()->setConfigValue("default_ttl_ms", CValue(-1)); // Permanent storage

// Enroll identity that will be available across all instances
std::vector<float> embedding = getFaceEmbedding();
auto id = redisProvider.value()->insertVector(embedding);

if (id) {
    api::logging::LogInfo("Identity enrolled with UUID: " + id.value().toString());
} else {
    api::logging::LogError("Failed to enroll identity in Redis");
}

Batch Identity Management

// Batch enrollment example
std::vector<std::pair<std::string, std::vector<float>>> identities = {
    {"employee_001", {0.1f, 0.2f, 0.3f}},
    {"employee_002", {0.4f, 0.5f, 0.6f}},
    {"employee_003", {0.7f, 0.8f, 0.9f}}
};

auto instance = api::thread::getCurrentInstance();
auto provider = api::factory::IdentityProvider::create(instance, "BatchIdentityProvider");
auto store = api::factory::IdentityStore::create(instance, "BatchIdentityStore");

// Configure the provider
provider.value()->setConfigValue("implementation", CValue("memorydb"));

int enrolledCount = 0;
for (const auto& [empId, embedding] : identities) {
    auto result = provider.value()->insertVector(embedding);
    if (result) {
        store.value()->setField(result.value(), "employee_id", empId);
        store.value()->setField(result.value(), "enrollment_time", 
                               std::to_string(std::time(nullptr)));
        enrolledCount++;
    } else {
        api::logging::LogError("Failed to enroll employee: " + empId);
    }
}

api::logging::LogInfo("Batch enrollment completed: " + std::to_string(enrolledCount) + "/" + std::to_string(identities.size()) + " identities enrolled");

Performance Considerations

Memory Usage

  • MemoryDb: RAM usage scales linearly with identity count and embedding dimensions
  • Typical Usage: ~1KB per identity for 512-dimensional embeddings plus metadata
  • Large Databases: Consider Redis for >100,000 identities to avoid memory pressure

Search Performance

  • MemoryDb: O(n) linear search through all stored identities
  • RedisDb: Leverages Redis indexing for improved search performance
  • Optimization: Use higher match thresholds to reduce false positives

Network Considerations

  • RedisDb: Network latency affects all operations
  • Local Redis: Sub-millisecond latency for local Redis instances
  • Remote Redis: Consider connection pooling and keep-alive settings

Scaling Recommendations

  • Small Deployments (< 1,000 identities): MemoryDb for maximum speed
  • Medium Deployments (1,000 - 50,000 identities): Local Redis instance
  • Large Deployments (> 50,000 identities): Redis cluster with sharding
  • Multi-Site: Distributed Redis with replication across locations

Troubleshooting

Common Issues

MemoryDb Issues

Out of Memory Errors - Cause: Identity database exceeds available system RAM - Solution: Reduce TTL values or switch to RedisDb backend - Prevention: Monitor memory usage and set appropriate limits

Slow Search Performance - Cause: Large number of stored identities causing linear search delays - Solution: Implement periodic cleanup of expired identities - Alternative: Switch to RedisDb for indexed searches

RedisDb Issues

Connection Failed - Cause: Redis server unavailable or incorrect connection parameters - Solution: Verify Redis server status and network connectivity - Debug: Check Redis logs and network firewall settings

Authentication Errors - Cause: Incorrect Redis username/password or missing AUTH configuration - Solution: Verify Redis authentication settings in configuration - Check: Ensure Redis server has proper user permissions configured

RediSearch Module Missing - Cause: Redis server doesn't have RediSearch module loaded - Solution: Install and enable RediSearch module in Redis - Verify: Check module loading with MODULE LIST command

Performance Issues

High Memory Usage (RedisDb) - Monitor Redis memory usage with INFO memory - Configure Redis memory policies (allkeys-lru, volatile-ttl) - Consider Redis clustering for horizontal scaling

Slow Identity Lookups - Verify appropriate match thresholds are set - Check Redis server performance and network latency - Consider upgrading Redis server hardware or using SSD storage

Debugging Tips

  1. Enable Debug Logging: Set log level to debug for detailed operation traces
  2. Monitor Metrics: Track identity counts, search times, and memory usage
  3. Test Connectivity: Use Redis CLI to verify database connectivity and data
  4. Validate Configuration: Ensure all required parameters are properly set

See Also