Security¶
Medha includes built-in defenses for deployments where questions and file paths come from untrusted input. Three Settings fields cover the most common attack vectors.
Input Length Guard — max_question_length¶
Prevents DoS via oversized question strings. When the limit is exceeded:
search()returnsSearchStrategy.ERRORwithout raisingstore()raisesValueError
async with Medha("my_cache", embedder=embedder, settings=settings) as cache:
hit = await cache.search("A" * 10_000)
print(hit.strategy) # SearchStrategy.ERROR
File Size Limit — max_file_size_mb¶
warm_from_file() and load_templates_from_file() reject files larger than this limit before reading them — preventing memory exhaustion from malicious uploads.
Path Traversal Protection — allowed_file_dir¶
When set, warm_from_file() and load_templates_from_file() reject any path that resolves outside the specified directory. This blocks ../ traversal attacks when file paths come from user input.
# Raises ValueError — path resolves outside /app/data
await cache.warm_from_file("/app/data/../etc/passwd")
Secret Handling — qdrant_api_key¶
qdrant_api_key is stored as Pydantic SecretStr — it is never logged or printed, even in debug mode.
settings = Settings(
backend_type="qdrant",
qdrant_mode="cloud",
qdrant_url="https://your-cluster.cloud.qdrant.io",
qdrant_api_key="your-secret-key", # stored as SecretStr, never exposed
)
Prefer environment variables over hardcoded values:
PostgreSQL Identifier Validation¶
When using pgvector or vectorchord, Medha validates collection names and column identifiers against a strict allowlist ([a-zA-Z0-9_], max 63 chars) before interpolating them into SQL. This prevents SQL injection via crafted collection names.
# Raises ValueError — invalid identifier
settings = Settings(backend_type="pgvector", pg_dsn="postgresql://...")
cache = Medha("my_cache; DROP TABLE users;--", embedder=embedder, settings=settings)
await cache.start() # ValueError: invalid collection name
Recommended Production Configuration¶
from medha import Settings
settings = Settings(
# Input guard
max_question_length=4096,
# File operation guards
max_file_size_mb=50,
allowed_file_dir="/app/data",
# Credentials via env vars (MEDHA_QDRANT_API_KEY)
backend_type="qdrant",
qdrant_mode="cloud",
qdrant_url="https://your-cluster.cloud.qdrant.io",
)