High-performance forensic analysis leveraging Computer Vision and Agentic Workflows.
Deepfake Agentic AI is a sophisticated, service-oriented system designed to detect spatial and temporal inconsistencies in digital media. By utilizing a multi-signal pipeline β preprocessing quality analysis, CNN-based face detection, and LLM-powered log analysis β it provides an industry-standard approach to verifying media authenticity.
The system is built as a modular microservices mesh, ensuring that compute-intensive tasks like deep learning inference do not bottleneck the API responsiveness.
Flow: File Input β API Service β ML Service β Agent Service β Verdict or Human Review
- API Service (FastAPI + PostgreSQL): Accepts and validates media, manages the upload pipeline, stores metadata, and returns the final verdict to the client.
- ML Service (OpenCV + RetinaFace + Xception): Preprocesses media and runs deepfake detection. Each module produces a Signal β a score and a reliability value.
- Agent Service (LangGraph + SambaNova LLM): Reads structured logs, identifies anomalies, aggregates all signals weighted by reliability, and routes the final verdict.
- Signal Contract: Every module outputs
{ score, reliability, module, metadata }. The aggregator weights signals at runtime β adaptive, not fixed constants. - Object Storage (MinIO): Stores processed media files with automatic 30-day expiry.
- Structured Logging: JSON-formatted logs across all modules written to stdout and
logs/app.log.
- Docker & Docker Compose installed
- Git installed and configured
# 1οΈβ£ Clone the repository
git clone https://github.com/Santhosh-p653/deepfake-agentic-ai.git
cd deepfake-agentic-ai
# 2οΈβ£ Copy and configure environment variables
cp .env.example .env
# Edit .env with your actual values
# 3οΈβ£ Start the full environment
docker compose up -d --build
# 4οΈβ£ Start only the API service (brings DB and MinIO up with it)
docker compose up --build api
# 5οΈβ£ Wipe all volumes and restart clean (dev reset)
docker compose down -v && docker compose up --build api| Service | URL | Description |
|---|---|---|
| API | http://localhost:8000 | FastAPI β main entry point |
| API Docs | http://localhost:8000/docs | Auto-generated Swagger UI |
| ML | http://localhost:8001 | ML service β preprocessing + detection |
| MinIO UI | http://localhost:9001 | Object storage browser |
| Dozzle | http://localhost:8080 | Live Docker log viewer |
| Beszel | http://localhost:8090 | Container metrics dashboard |
| Agents | http://localhost:8123 | Agent service β log analyser, aggregator, decider |
MinIO default credentials:
minioadmin / minioadminβ change in production.
| Method | Endpoint | Description |
|---|---|---|
| GET | /ping |
Liveness check β returns pong |
| GET | /health |
DB connection status check |
| GET | /run-agents |
Ping agent service |
| Method | Endpoint | Description |
|---|---|---|
| POST | /upload |
Upload a media file for deepfake analysis |
| GET | /result/{id} |
Poll for detection verdict by record ID |
| POST | /verdict |
Internal β agents post verdict back to API |
Accepted formats: .jpeg, .png, .mp4
Request: multipart/form-data with field file
curl -X POST http://localhost:8000/upload \
-F "file=@/path/to/your/image.jpg"Success response 200:
{
"status": "accepted",
"id": 1,
"filename": "image.jpg",
"size_mb": 0.452,
"ml_result": {
"deepfake_probability": 0.07,
"model": "stub",
"file_path": "/app/tmp/abc123.jpg"
},
"minio_object": "def456.jpg"
}Rejection responses:
| Status | Reason |
|---|---|
| 400 | Invalid format or encoding mismatch |
| 429 | Temp storage at capacity (2 files max) |
| 500 | DB error or failed to write temp file |
Poll this after upload to retrieve the final verdict once the pipeline completes.
curl http://localhost:8000/result/1Response:
{
"id": 1,
"filename": "image.jpg",
"status": "completed",
"verdict": "REAL",
"verdict_score": 0.21,
"uploaded_at": "2026-04-25T10:00:00Z",
"processed_at": "2026-04-25T10:00:05Z"
}Verdict values: REAL Β· FAKE Β· FLAG_FOR_REVIEW
POST /upload
β Validate (format + encoding)
β Write to /app/tmp
β Push to MinIO
β [async] POST agents/run
β agents calls ml/process
β ml: preprocess β detect β return Signals
β agents: log analyser β Signal
β agents: aggregate all Signals (weighted by reliability)
β agents: decider β verdict
β agents POST api/verdict
β GET /result/{id} returns verdict to client
Upload β /app/tmp (max 2 files) β ML processing β MinIO bucket β auto-delete at 30 days
| Stage | DB Status | Description |
|---|---|---|
| Received | pending |
Record created, file not yet on disk |
| On disk | temp_stored |
File written to /app/tmp |
| ML running | processing |
ML invoked |
| ML done | processed |
Result returned, file pushed to MinIO |
| Cleaned up | deleted |
Temp file removed from /app/tmp |
| Verdict in | completed |
Verdict stored, pipeline done |
| Error | failed |
Any stage failure |
Table: media_uploads
| Column | Type | Description |
|---|---|---|
| id | Integer | Primary key |
| user_id | Integer | Optional user reference |
| filename | String | Original uploaded filename |
| file_type | String | Extension (jpeg, png, mp4) |
| size_mb | Float | File size in MB |
| status | Enum | Current pipeline status (see above) |
| temp_path | String | Path in /app/tmp while processing |
| drive_path | String | MinIO object name after upload |
| verdict | String | Final verdict: REAL / FAKE / FLAG_FOR_REVIEW |
| verdict_score | Float | Final aggregated score (0.0 β 1.0) |
| uploaded_at | DateTime | Upload timestamp (UTC) |
| processed_at | DateTime | ML completion timestamp (UTC) |
- Bucket:
deepfakemedia - Lifecycle: Files auto-deleted 30 days after ML processing
- Re-access: Presigned URLs generated on demand (24-hour expiry by default)
- UI: http://localhost:9001
Every module that produces a judgment outputs this schema:
{
"score": 0.0,
"reliability": 0.0,
"module": "ml.preprocessing",
"metadata": {}
}scoreβ judgment value, 0.0 to 1.0reliabilityβ trust in that score, 0.0 to 1.0moduleβ which module produced thismetadataβ module-specific context
The aggregator weights signals at runtime using reliability values β not fixed constants.
Decider paths:
| Path | Condition | Action |
|---|---|---|
| 1 | High confidence score | Output verdict directly |
| 2 | Low confidence score | Flag for human review |
| 3a | Middle zone (~45β55%) | Reanalyse once, adjust all module weights uniformly |
| 3b | 70/30 module conflict | Reanalyse once, adjust only conflicting modules |
Governance rules:
- One reanalysis attempt maximum β hard blocked after one
- Every weight adjustment logged: before, after, reason, affected modules
- All thresholds TBD via experimentation and version-controlled
All modules emit structured JSON logs to stdout and logs/app.log.
Log format:
{
"timestamp": "2026-04-25T10:45:00.123Z",
"level": "INFO",
"module": "api.main",
"message": "Upload pipeline complete",
"id": 1,
"filename": "image.jpg",
"size_mb": 0.452
}View live logs:
- Terminal:
docker compose logs -f api - Dozzle UI: http://localhost:8080
Create a .env file in the root directory. Never commit real credentials.
# PostgreSQL
DATABASE_URL=postgresql://<user>:<password>@db:5432/<dbname>
# MinIO
MINIO_ENDPOINT=minio:9000
MINIO_ACCESS_KEY=<your-access-key>
MINIO_SECRET_KEY=<your-secret-key>
MINIO_BUCKET=deepfakemedia
# SambaNova LLM (agent log analyser)
SAMBANOVA_API_KEY=<your-key>All secrets are injected via GitHub Secrets in CI β never hardcoded in workflows.
deepfake-agentic-ai/
βββ api/
β βββ main.py # FastAPI app, endpoints, upload pipeline
β βββ db.py # SQLAlchemy engine, session, helpers
β βββ models.py # MediaUpload ORM model, ProcessingStatus enum
β βββ input_validator.py # Format and encoding validation
β βββ temp_manager.py # Temp folder write/delete/cleanup
β βββ minio_client.py # MinIO upload, lifecycle, presigned URLs
β βββ ml_stub.py # ML placeholder (active until Detection unblocked)
β βββ logger.py # Central JSON logger
β βββ validate_logs.py # CI log validation script
βββ agents/
β βββ main.py # FastAPI app, /run /analyse /ping endpoints
β βββ log_analyser.py # SambaNova LLM log anomaly detection
β βββ aggregator.py # Runtime reliability-weighted signal aggregation
β βββ decider.py # Threshold routing, reanalysis hard block
β βββ ml_client.py # HTTP client β calls ml /process
βββ ml/
β βββ main.py # FastAPI app, /process endpoint
β βββ preprocessing.py # Frame extraction, quality checks, normalisation
β βββ detection.py # Detection stub (RetinaFace+Xception β see issue)
βββ shared/
β βββ signal.py # Pydantic Signal model β shared across all services
βββ logs/ # JSON log output (auto-created, gitignored)
βββ .github/
β βββ workflows/
β βββ ci-api.yml # Lint, format, build & push API image
β βββ ci-agents.yml # Lint, format, build & push agents image
β βββ ci-ml.yml # Lint, format, build & push ML image
β βββ ci-tests.yml # Pytest β API and ML unit tests
β βββ ci-network-audit.yml # Network audit + log validation
β βββ codespaces-prebuild.yml # Codespaces image prebuild
βββ docker-compose.yml
βββ Dockerfile.api
βββ Dockerfile.agents
βββ Dockerfile.ml
βββ .env.example
βββ .env # Never commit β gitignored
| Step | Description | Status |
|---|---|---|
| 1 | Input validation β format + encoding check | β Done |
| 2 | PostgreSQL metadata schema | β Done |
| 3 | Docker temp folder management | β Done |
| 4 | MinIO integration β push after ML, 30-day expiry | β Done |
| 5 | Structured JSON logging across all modules | β Done |
| 6 | CI workflow β network audit + logging validation | β Done |
| Step | Description | Status |
|---|---|---|
| 1 | Signal contract β shared Pydantic model | β Done |
| 2 | ML preprocessing β quality checks + normalisation | β Done |
| 3 | ML detection β RetinaFace + Xception | |
| 4 | Agent log analyser β SambaNova LLM | β Done |
| 5 | Aggregator + Decider β full pipeline wired | β Done |
| 2C | GET /result/{id} β client verdict polling | β Done |
| Task | Description | Status |
|---|---|---|
| β | Real RetinaFace + Xception detection | π Blocked by bandwidth |
| β | Threshold experimentation + version control | π Needs real data |
| β | Decider Path 3a/3b full reanalysis logic | π Needs real data |
| β | Authentication + rate limiting | π Planned |
| β | Frontend UI | π Planned |
| Workflow | Trigger | What it does |
|---|---|---|
ci-api.yml |
push/PR to main | Black, isort, flake8, build & push API image |
ci-agents.yml |
push/PR to main | Black, isort, flake8, build & push agents image |
ci-ml.yml |
push/PR to main | Black, isort, flake8, build & push ML image |
ci-tests.yml |
push/PR to main | Pytest β API and ML unit tests |
ci-network-audit.yml |
push/PR to main | Network audit, upload test, JSON log validation |
codespaces-prebuild |
push to codespaces/main | Prebuild API, agents, ML images for Codespaces |