| Version | Supported |
|---|---|
| 1.0.x | ✅ Active support |
| < 1.0 | ❌ No longer supported |
Please do not open a public GitHub issue for security vulnerabilities.
To report a vulnerability, email the maintainers directly (contact details in the GitHub profile) or open a GitHub private security advisory.
Include:
- A description of the vulnerability and its potential impact
- Steps to reproduce (proof-of-concept if possible)
- The version you tested against
You will receive an acknowledgement within 72 hours and a status update within 7 days.
The API is currently a public API — there is no user authentication or authorization layer. All endpoints are accessible without credentials. This is a documented known limitation. For multi-tenant or internet-facing deployments, place a reverse proxy with authentication (e.g., nginx + OAuth2 proxy, Cloudflare Access) in front of the API.
- API keys are loaded exclusively from environment variables (
.envfile or OS environment) - Keys are never logged — only their presence (
bool) is recorded at startup - At startup, all configured providers run a
health_check()that validates credentials using a lightweight, non-quota-consuming API call (e.g., list models) - Error messages classify the failure type (e.g.,
invalid_credential_type,missing_credential) without exposing key values
A sliding-window per-IP rate limiter is implemented in backend/security_middleware.py:
- Default: 60 requests per minute per IP
- Configurable via
RATE_LIMIT_PER_MINUTEenvironment variable - Returns
429 Too Many Requestswhen exceeded - Exempt paths:
/health,/metrics,/api/v1/health,/api/v1/metrics
- All API request bodies are validated by Pydantic models before reaching business logic
- GitHub repository URLs are validated by
parse_repo_url()to prevent path traversal - File paths in graph and symbol operations are sanitized
- SQL queries use parameterized statements throughout
CORS is restricted to the configured FRONTEND_URL. allow_credentials=True is intentionally paired with a specific origin (not a wildcard) as required by the CORS specification and browser security policy.
In production, set FRONTEND_URL to your actual frontend domain.
The server binds to 0.0.0.0:8001 by default. In production:
- Place behind a TLS-terminating reverse proxy (nginx, Caddy, Cloudflare)
- Set
ALLOWED_HOSTSto your production hostname(s) - Set
APP_ENV=productionto enable fail-fast startup validation
Applied in this order to every request:
RequestIdMiddleware— injects a uniqueX-Request-IDfor audit tracingRateLimitMiddleware— per-IP sliding windowMetricsMiddleware— records request counts and durations (no PII)GZipMiddleware— compresses responses > 1000 bytesTrustedHostMiddleware— validatesHostheader againstALLOWED_HOSTSCORSMiddleware— validatesOriginagainstFRONTEND_URL
Analyzed repositories are cloned to CLONED_REPOS_PATH (defaults to ~/.repo_intelligence/cloned_repos). This path should be:
- Outside the project tree to prevent uvicorn's WatchFiles from triggering reload loops
- On a volume with sufficient space and appropriate permissions
- Not accessible over the network
data/analysis_store.json— written atomically viatmpfile +os.replace()to prevent corruptiondata/chroma_db/— local ChromaDB persistence; no network exposuredata/repo_understanding.db— SQLite database; no network exposure
- No user authentication: See above. Add a proxy layer for production.
- No request signing: Internal service-to-service calls are not authenticated.
- CORS in development: In development mode,
localhost:4321is added as an additional allowed origin alongsideFRONTEND_URL. This is intentional for local development. - GitHub token scope:
GITHUB_TOKENis used for cloning and API calls. Use a fine-grained PAT with the minimum required scopes (contents:read,metadata:read).