Two stacks, one set of rules.
Both products are self-hosted Docker Compose stacks: an nginx front door, a FastAPI service, PostgreSQL for every record and Redis for everything that may be lost. Only the proxy is published. Every AI call goes through one server-side gateway.
Decisions both products make the same way.
One origin
The compiled React app and the API are served from the same origin behind nginx, so session cookies stay same-site and no cross-origin access is needed.
PostgreSQL holds the truth
Every business record lives in PostgreSQL, and Alembic owns the schema: the application never creates tables behind its back. Redis holds sessions, rate-limit counters, caches and queues only.
Protected by construction
Every router except sign-in is mounted behind a session check, so a new route cannot be added unauthenticated. Tests walk the whole route table to prove it.
Blocking work off the event loop
Route handlers are synchronous and run in a thread pool; long jobs in cognita dev run in a separate Celery worker with progress streamed back.
Secrets as files
Keys are mounted as Docker secrets, never baked into images. cognita dev refuses to start in production with a missing secret or an unsafe setting.
Evidence by design
Exports carry hashes, uploads are typed by their content and stored under generated names, and downloads go through an authenticated route only.
Four internal networks, one way in, one way out.
nginx is the only container with a published port. The API, worker and scheduler share an internal data network with PostgreSQL and Redis. Only the worker can reach the internet, through a proxy that allows the model providers' API hosts and nothing else.
A request, step by step
- nginx terminates TLS, adds the security headers and a per-response CSP nonce, and forwards
/api, unbuffered for progress streams. - Middleware records metrics, adds a request ID, checks the CSRF header and origin, and applies rate limits.
- The protected router checks the session cookie against Redis; a Redis failure is a 503, never a pass.
- The endpoint checks its named permission, then whether the project is in the caller's scope.
- The service writes to PostgreSQL with the audit event in the same transaction. If the audit write fails, the change rolls back.
What runs in the background
- AI generation, reviews and rewrites, with progress over server-sent events
- Word, PDF and PowerPoint exports, rendered in the worker and stored with their hash
- Upload scanning and retries every 30 minutes when ClamAV is enabled
- Evidence pack builds with a verifiable manifest
- Audit chain verification every night at 02:00 UTC
- Provider status checks every 5 minutes, shown in the admin console
A compact stack that degrades instead of failing.
In production, nginx serves the compiled app and proxies /api to FastAPI on the same origin. The API, PostgreSQL and Redis stay on the internal network. If Redis goes down, sessions survive and rate limiting falls back to in-process counting.
Every model call takes the same path, and can be stopped at one point.
In cognita dev, provider SDKs may be imported only inside one module, and CI fails the build if anything else tries. The API process never calls a model; the worker does.
- Checked. The job endpoint verifies the model key against the allowlist, the caller's role, the project's data classification, the emergency stop and the budgets. A refusal is audited and no provider is called.
- Queued. The job goes to the Celery worker; the browser follows its progress over server-sent events and can cancel it.
- Called. The gateway calls Claude or Gemini through the egress proxy, or vLLM on the internal network, with reference files passed as delimited data and no tools.
- Validated. Output is checked against the task's schema and retried once before failing with a clear message.
- Recorded. Model, prompt version, input hashes, tokens, cost and latency are stored with the job and in the audit log.
- Proposed. The result lands as a new draft version labelled AI-generated, and stays labelled until a person edits it.
cognita grc applies the same idea in one service: every AI request checks the database-held switch first (cached for 60 seconds, failing closed), then calls Gemini or the on-premises vLLM model and validates the JSON it gets back.
Outputs people already use, made safely.
Word, PDF, PowerPoint, Excel
cognita dev renders Word with python-docx and converts it to PDF with LibreOffice, builds decks with python-pptx, and stamps every page with the version hash. cognita grc builds PDFs with ReportLab and jsPDF, Excel with openpyxl and Word with python-docx.
Typed by content, not by name
File types are detected from their leading bytes, archives are read entry by entry with size, ratio and count limits, and files are stored under generated names outside any web-served path.
No formula injection
Every exported cell passes one escaping function, so text starting with =, +, - or @ can never run as a formula when someone opens the file.
One host, Docker Compose, your network.
Each product ships as a Compose file. Bring a Linux host with Docker, point DNS at it, add a certificate, and start the stack.
| cognita dev | cognita grc | |
|---|---|---|
| Services | proxy, api, worker, scheduler, egress, PostgreSQL 16, Redis 7 | frontend (nginx), backend, PostgreSQL 15, Redis 7 |
| Optional profiles | ClamAV upload scanning, vLLM on a GPU host, backup service | vLLM on a GPU host |
| Published ports | 443 and 80 on the proxy only | The nginx port only |
| First start | make up generates secrets and a certificate; make admin creates the first administrator | docker compose -f docker-compose.prod.yml up -d --build, then create the first administrator |
| Production guard rails | ENV=production refuses missing secrets, a non-HTTPS origin or test switches | Secure cookies and HSTS switched on together once served over HTTPS |
| Backups | Encrypted database and file backups, hourly WAL archiving, restore drill in CI | Nightly pg_dump snapshots with a verified manifest; export and import between environments |
| Migrations | Alembic, with grants for the application role in every migration | Alembic, applied once at start in production |
The same stack, pinned to exact versions.
| Layer | cognita dev | cognita grc |
|---|---|---|
| Language | Python 3.12, TypeScript 5.9 | Python 3.11, TypeScript 5.9 |
| API | FastAPI 0.141, Pydantic 2.13, gunicorn + uvicorn | FastAPI 0.141, Pydantic 2.9, uvicorn |
| Data | SQLAlchemy 2.0, Alembic 1.13, PostgreSQL 16, Redis 7 | SQLAlchemy 2.0, Alembic 1.13, PostgreSQL 15, Redis 7 |
| Background work | Celery 5.4 worker and beat | FastAPI background tasks, host scheduler for backups |
| Security libraries | argon2-cffi, PyJWT, slowapi, structlog | bcrypt, PyJWT, cryptography, slowapi |
| AI | anthropic, google-genai, OpenAI-compatible client for vLLM | google-generativeai, OpenAI-compatible client for vLLM |
| Documents | python-docx, python-pptx, openpyxl, LibreOffice, Graphviz | ReportLab, python-docx, openpyxl, pypdf, jsPDF |
| Frontend | React 19, Vite 7, MUI 7, React Router 7, TanStack Query, TipTap, React Flow | React 19, Vite 7, MUI 7 and MUI X DataGrid, React Router 7, Mermaid |
| Tests | pytest against PostgreSQL, Vitest, Playwright, axe | pytest with SQLite and an in-process Redis |
Walk your security architects through it.
We can run a technical session on the network layout, the AI gateway and the evidence model with your architecture and security teams.