Facephi IAD Service
Injection Attack Detection REST API — Protect your biometric systems against spoofing attacks.
What is IAD Service?
The IAD Service is a REST API microservice that detects injection attacks in biometric captures. It verifies that biometric data comes from real sources, not from replays, or synthetic inputs.
Breaking change notice (2.0.0) Version 2.0.0 breaks public REST API compatibility with all previous 1.x.x releases. Integrations upgrading from 1.x.x must update endpoint paths, multipart request field names, and successful response parsing.
1.x.x contract 2.0.0 contract POST /api/v1/iad/check-capturePOST /api/v1/iad/liveness/evaluatePOST /api/v1/iad/extract-imagePOST /api/v1/iad/extractmultipart field filerequired multipart field capture;fileis rejected whencaptureis missingLegacy private success payloads ( capture_liveness,capture_type,rejection,mime_type)Facephi public payloads ( diagnostic,reason,probability,score,faceProbability,sdkDuration,queueDuration,mimeType)
Use it to:
- Extract valid images from authenticated captures
- Monitor system health and performance
- Integrate seamlessly with your authentication workflows
Quick Start
Requirements
| Component | Requirement |
|---|---|
| OS | Linux x86_64 (Ubuntu 24.04 recommended) |
| License | Valid Facephi license file |
Deploy with Docker
docker run -d \
-p 6982:6982 \
-v /path/to/license:/app/license \
-v /path/to/config:/app/config \
--name iad-service \
facephicorp.jfrog.io/docker-core-pro-fphi/facephi-iad-service:2.0.0
Verify it works
# Check health
curl http://localhost:6982/api/v1/iad/health
# Check version
curl http://localhost:6982/api/v1/iad/version
Typical responses:
{
"message": "Healthy"
}
{
"message": "2.0.0 Copyright © 2026 FacePhi Biometria. All rights reserved."
}
API Endpoints
Compatibility note The routes documented in this page are valid for version 2.0.0 and later only.
Core Operations
| Endpoint | Method | Purpose |
|---|---|---|
/api/v1/iad/liveness/evaluate |
POST | Evaluate encrypted capture liveness with a Facephi public contract |
/api/v1/iad/extract |
POST | Extract image from validated capture |
Management
| Endpoint | Method | Purpose |
|---|---|---|
/api/v1/iad/version |
GET | Service version and license status |
/api/v1/iad/health |
GET | Health check for monitoring |
/api/v1/iad/config |
GET/POST | Retrieve or update configuration |
Experimental Replay Attack Mitigation
The service can enforce a freshness window on incoming capture payloads. This experimental protection is disabled by default.
- Enable it with
FACEPHI_IAD_REPLAY_ATTACK_CHECKER_ENABLED=true - Adjust the freshness window with
FACEPHI_IAD_REPLAY_ATTACK_TOLERANCE_TIME=<seconds> - Default freshness window:
300seconds - Applies to capture-processing endpoints such as
POST /api/v1/iad/liveness/evaluateandPOST /api/v1/iad/extract - When the freshness window is exceeded, the service returns HTTP
400withmessageequal toReplay attack detected
Example deployment:
docker run -d \
-p 6982:6982 \
-e FACEPHI_IAD_REPLAY_ATTACK_CHECKER_ENABLED=true \
-e FACEPHI_IAD_REPLAY_ATTACK_TOLERANCE_TIME=60 \
-v /path/to/license:/app/license \
-v /path/to/config:/app/config \
--name iad-service \
facephicorp.jfrog.io/docker-core-pro-fphi/facephi-iad-service:2.0.0
This feature is configured only at startup through environment variables. It is not part of config.json and is not exposed through GET|POST /api/v1/iad/config.
Public Error Contract
In public HTTP 400 responses the service returns documented public messages in the standard response body.
Liveness Result
Successful POST /api/v1/iad/liveness/evaluate responses expose only the public fields below:
| Field | Meaning |
|---|---|
diagnostic |
High-level result: Live or NoLive |
reason |
Public reason value returned by the service |
probability |
Public capture probability |
score |
Public confidence score |
faceProbability |
Optional public face-liveness probability when available |
sdkDuration |
Capture analysis duration in milliseconds |
queueDuration |
Queue duration reported by RestManager in milliseconds |
Possible values for reason are:
NoneUnknownUntrustedEnvironmentSuspiciousActivityUntrustedDeviceSdkIntegrityViolationUntrustedCorruptedPayloadUntrustedContentUntrustedContentLowConfidence
reason |
Meaning |
|---|---|
None |
The capture was accepted as Live and no rejection reason applies. |
Unknown |
The service could not map the response to a documented public rejection reason. |
UntrustedEnvironment |
The capture was rejected because the runtime environment is not considered trusted. |
SuspiciousActivity |
The capture was rejected because the device showed activity patterns associated with an attack. |
UntrustedDevice |
The capture was rejected because the device could not be trusted as the device it claims to be. |
SdkIntegrityViolation |
The capture was rejected because the capture SDK or its libraries appear to have been altered. |
UntrustedCorruptedPayload |
The capture was rejected because the payload appears corrupted or tampered with. |
UntrustedContent |
The capture was rejected because an injection attack was detected. |
UntrustedContentLowConfidence |
The capture was rejected because the service detected signs of an injection attack with lower confidence; it should still be treated as a rejection. |
When multiple rejection causes are present, the service returns the first documented public rejection value in the service response order.
Normalized Validation Errors
For endpoint POST /api/v1/iad/liveness/evaluate, capture validation failures are returned as HTTP 400 with documented message values such as:
| Scenario | Public message |
|---|---|
| Face too close | NoneBecauseFaceTooClose |
| Face not found | NoneBecauseFaceNotFound |
| Face cropped | NoneBecauseFaceCropped |
| Face occluded | NoneBecauseFaceOccluded |
| Too many faces | NoneBecauseTooManyFaces |
| Face angle too large | NoneBecauseAngleTooLarge |
| Face too small | NoneBecauseFaceTooSmall |
| Face close to border | NoneBecauseFaceTooCloseToBorder |
| Eyes closed | NoneBecauseEyesClosed |
| Image or payload cannot be processed | NoneBecauseImageDataError |
| License problem reported by the service runtime | NoneBecauseLicenseError |
| Replay freshness window exceeded | Replay attack detected |
| Unclassified liveness failure | ErrorProcessing |
For endpoint POST /api/v1/iad/extract, parse and decrypt payload failures are returned as NoneBecauseImageDataError; expired captures rejected by replay protection return Replay attack detected; unclassified extraction failures are returned as ErrorFacialImage.
Usage Example
Upgrade note The examples below intentionally use the 2.0.0 wire contract: the
capturemultipart field and the new public response schema.
Liveness Evaluate
curl -X POST \
-F "capture=@biometric_capture.bin" \
http://localhost:6982/api/v1/iad/liveness/evaluate
Response:
{
"diagnostic": "Live",
"reason": "None",
"probability": 1,
"score": 1,
"sdkDuration": 12,
"queueDuration": 3
}
Extract Image
curl -X POST \
-F "capture=@biometric_capture.bin" \
http://localhost:6982/api/v1/iad/extract
Response:
{
"image": "base64_encoded_image...",
"mimeType": "image/jpeg"
}
Get Configuration
curl http://localhost:6982/api/v1/iad/config
Update Configuration
POST /api/v1/iad/config expects a JSON object with the config_json_string field, containing the full configuration serialized as a JSON string.
curl -X POST \
-H "Content-Type: application/json" \
-d '{"config_json_string":"{\"port\":6982,\"number_of_threads\":1,\"engine_url\":\"http://localhost:8080\"}"}' \
http://localhost:6982/api/v1/iad/config
Response:
{
"message": "Configuration updated successfully"
}
Configuration
Create /app/config/config.json:
{
"port": 6982,
"number_of_threads": 1,
"connection_timeout": 60,
"keep_alive_request_number": 0,
"client_max_body_size": 100,
"logger_level": "info",
"logger_path": "/app/logs",
"logger_rotation": "daily",
"logger_max_files": 7,
"engine_connection_timeout": 10000,
"engine_request_timeout": 60000,
"engine_max_retries": 3,
"engine_retry_delay": 1000,
"engine_verify_ssl": false,
"engine_verbose": false,
"engine_pool_size": 4,
"engine_url": "http://localhost:8080"
}
Key Parameters
| Parameter | Default | Description |
|---|---|---|
port |
6982 | Service listening port |
number_of_threads |
1 | Worker threads for request handling |
connection_timeout |
60 | Rest::Manager connection timeout |
keep_alive_request_number |
0 | Maximum keep-alive requests |
client_max_body_size |
100 | Maximum request body size in MB |
logger_level |
"info" | Logging level (trace/debug/info/warn/error) |
engine_connection_timeout |
10000 | Connection timeout (ms) |
engine_request_timeout |
60000 | Request timeout (ms) |
engine_max_retries |
3 | Engine retry attempts |
engine_retry_delay |
1000 | Delay between engine retries in ms |
engine_verify_ssl |
false | Verify capture-analysis SSL certificates |
engine_verbose |
false | Enable verbose capture-analysis proxy logs |
engine_pool_size |
4 | Connection pool size |
engine_url |
"http://localhost:8080" | Base URL of the capture-analysis runtime |
Architecture Overview
flowchart TD
Client["Client<br/>Application"]
Client -->|HTTP/REST| IADService
subgraph IADService["Facephi IAD Service"]
Components["• License<br/>• Endpoints<br/>• Capture validation<br/>• Replay attack mitigation<br/>• Connection Pool<br/>• Config Management"]
end
style Client fill:#4a9eff,stroke:#333,stroke-width:2px,color:#000
style IADService fill:#111111,stroke:#333,stroke-width:2px,color:#000
style Components fill:#60a5fa,stroke:#333,stroke-width:2px,color:#000
Documentation
- Installation Guide — Docker deployment and configuration
- API Reference — Complete OpenAPI specification
- Changelog — Version history
- Release Notes — Latest release details
Support
For licensing inquiries or technical support, contact your Facephi representative.