Astructr Full Audit
6-category comprehensive review — March 8, 2026
Executive Summary
6.2
/ 10
6/10
Security
7/10
API
8/10
Code Quality
4/10
Test Coverage
7/10
Performance
5/10
Deployment
Security — 6/10
Security Findings
3 Critical
2 High
4 Medium
▸
Security Findings
| Severity | Finding | Details |
|---|---|---|
| Critical | Exposed API key in .env.example |
Contains real-looking API key hash that could be mistaken for production credentials |
| Critical | DISABLE_AUTH environment variable |
When set to "true", completely bypasses all authentication. No safeguard against accidental production use |
| Critical | Timing attack on API key comparison | Uses == instead of hmac.compare_digest() for key hash comparison in auth.py |
| High | Rate limiting in-memory fallback | Trivially bypassed in multi-process/container deployments when Redis unavailable |
| High | No tenant isolation on job access | Any authenticated user can access any job by ID |
| Medium | No input validation on PDF file size/type | Unbounded file uploads accepted before processing |
| Medium | SQL injection risk | String formatting in some repository queries |
| Medium | CORS wildcard in non-production | Allows all origins when not in production mode |
| Medium | No request ID tracking | Missing security audit trail for forensics |
API Quality — 7/10
API Findings
1 Critical
1 High
5 Medium
▸
API Findings
| Severity | Finding | Details |
|---|---|---|
| Critical | 40% endpoints missing response_model |
No schema validation on API responses |
| High | Exception details leaked in errors | Stack traces exposed in non-production error responses |
| Medium | Inconsistent error response format | Different shapes across endpoints |
| Medium | No versioning strategy | Only /v1 prefix, no deprecation plan |
| Medium | Missing pagination on list endpoints | All results returned in single response |
| Medium | No request/response logging middleware | Missing observability layer |
| Medium | Health endpoint sync DB/Redis checks | Blocks event loop on health probes |
Code Quality — 8/10
Code Quality Findings
2 High
3 Medium
▸
Code Quality Findings
| Severity | Finding | Details |
|---|---|---|
| High | Hardcoded DB/Redis connection defaults | Scattered across multiple modules instead of centralized config |
| High | sys.path manipulation in workers |
Worker entry points modify Python path at runtime |
| Medium | Inconsistent error handling patterns | Mix of raise/return None across modules |
| Medium | Mixed sync/async in API layer | Some handlers sync, some async, inconsistent approach |
| Medium | Functions exceeding 50 lines | document_structurer.py has oversized methods |
Test Coverage — 4/10
Test Coverage Findings
2 Critical
3 High
3 Medium
▸
Test Coverage Findings
| Severity | Finding | Details |
|---|---|---|
| Critical | ZERO API endpoint tests | No integration tests for any FastAPI route. Every endpoint is completely untested. |
| Critical | ZERO database CRUD tests | Repository layer completely untested. SQL queries never verified. |
| High | No conftest.py with shared fixtures |
Tests duplicate setup, no centralized fixtures or factories |
| High | No auth middleware tests | Authentication bypass scenarios untested |
| High | No rate limiting tests | Rate limit middleware behavior unverified |
| Medium | Tests concentrated in routing module | 182 unit tests exist but ~90% cover routing only |
| Medium | No load/stress testing | No infrastructure for performance regression testing |
| Medium | No test database fixtures or factories | No reproducible test data generation |
Test Distribution
182 tests
Routing module: ~90%
Other modules: ~10%
Performance — 7/10
Performance Bottlenecks
12 Remaining
2 New
▸
Performance Bottlenecks
36 of 48 original bottlenecks fixed — 12 remaining + 2 new
- #1 Serial vLLM with blocking
time.sleep() - #5 Sync psycopg2 in async endpoints
- #6 Contextual chunking ignores batch_size
- #7 VectorStore OOM risk on large docs
- #8 Double HTML parsing per job
- #15 HTML response loads all pages to memory
- #17 N+1 API key validation (2 DB lookups)
- #18 Sequential batch_extract_charts
- #20 PaddleOCR response parsed 4 times
- #24 5 redundant directory globs
- #34 Sync psycopg2 on auth hot path
- #46 Sequential file processing in batch
- NEW AgglomerativeClustering O(N²)
- NEW active_downloads in-memory set
Deployment — 5/10
Deployment Findings
7 Critical
7 High
▸
Deployment Findings
| Severity | Finding | Details |
|---|---|---|
| Critical | No .dockerignore |
Builds include .git, .env, venv — bloated images, credential leak risk |
| Critical | No graceful shutdown in workers | In-flight jobs lost on deploy, data corruption risk |
| Critical | No centralized logging | stdout only — no structured logging, no log aggregation |
| Critical | Flower dashboard unauthenticated | Celery management UI exposed without auth |
| Critical | vLLM startup has no health check wait | Workers may start processing before model is loaded |
| Critical | No container resource limits | Containers can consume unlimited CPU/memory |
| Critical | No PostgreSQL backup strategy | No backup/restore procedures documented or automated |
| High | No Docker layer caching | Every build reinstalls all dependencies |
| High | No multi-stage builds | Dev dependencies included in production images |
| High | No container health checks | Orchestrator can't detect unhealthy containers |
| High | Secrets via env vars only | No secrets management (Vault, AWS SM, etc.) |
| High | No rollback procedure | No documented deployment rollback strategy |
| High | No monitoring/alerting | No Prometheus/Grafana/Datadog setup |
| High | Redis no persistence | Queue data lost on Redis restart |
Priority Action Plan
-
1
Add API endpoint integration testsBiggest coverage gap. Zero integration tests for any FastAPI route. Start withTest Coverage · Critical
/v1/process,/v1/jobs/{id}, and/health. -
2
Fix DISABLE_AUTH production safeguardAdd environment check: refuse to start ifSecurity · Critical
DISABLE_AUTH=trueandENV=production. Log a loud warning in staging. -
3
Add .dockerignore and optimize buildsCreateDeployment · Critical
.dockerignoreexcluding .git, .env, __pycache__, venv, models/, tests/. Add multi-stage builds. -
4
Fix timing attack in API key comparisonReplaceSecurity · Critical
==withhmac.compare_digest()inauth.pykey hash verification. One-line fix, high impact. -
5
Add tenant isolation to job accessFilter job queries bySecurity · High
tenant_idfrom the authenticated API key. Prevent cross-tenant data access. -
6
Add response_model to all endpointsDefine Pydantic response schemas for the 40% of endpoints currently missing them. Prevents accidental data leakage.API · Critical
-
7
Add graceful worker shutdownHandle SIGTERM in Celery workers to finish current task before exiting. Prevent data corruption during deploys.Deployment · Critical
-
8
Set up structured loggingReplace print/stdout with structured JSON logging. Add request IDs, correlation IDs, and log aggregation config.Deployment · Critical
-
9
Create conftest.py with shared fixturesBuild test infrastructure: mock DB, mock Redis, sample PDFs, API test client. Foundation for all future tests.Test Coverage · High
-
10
Add container health checks and resource limitsDocker HEALTHCHECK instructions, CPU/memory limits in compose, liveness probes for Kubernetes readiness.Deployment · Critical
Generated by Claude Code — March 8, 2026 — Astructr v1