v0.1 · OSS-aligned

Cognita GRC documentation

Everything an operator, auditor, or contributing engineer needs to run, extend, or evaluate Cognita. Start with the Quickstart; jump to Evidence ledger for the cryptographic guarantees; read the Security policy separately if you're a researcher.

Quickstart

The fastest path to a running Cognita is the Docker compose stack. It boots Postgres, Mailhog, the Inngest dev server, and the Next.js app on a single command.

# The Cognita repository is private during the design-partner phase.
# Request access at [email protected]; you'll receive an invite that
# lets you clone the repo.
git clone [email protected]:<your-org>/cognitagrc.git
cd cognitagrc
docker compose up
# → http://localhost:3007 (app) · 8025 (Mailhog) · 8288 (Inngest)

On first start, the app applies npx prisma db push and runs the seed (Northwind Mutual demo org + 5 evidence rows). After that the data layer is real Postgres-backed; in-memory fallbacks only fire when DATABASE_URL is unset.

Production deploys: see Self-hosting for Vercel + Fly + Railway recipes.

Architecture

Cognita is a Next.js 15 App Router monolith over a Postgres + Inngest + S3 Object Lock substrate. Every authed surface reads through lib/data-source.ts which adapts between Prisma (when DATABASE_URL is set) and in-memory fixtures (when it isn't). Mutations go throughlib/persisted-ledger.ts which signs and chains every entry before persistence.

Edge
Cloudflare → Vercel/Fly. Middleware enforces Auditor Lock, CSRF, auth, security headers.
Web
Next.js 15 App Router, RSC by default, Tailwind v4 with tokens ported from styles.css.
Data
Postgres 16 with row-level security on every tenant-scoped table; per-region pools by org dataResidency.
Workflows
Inngest for durable workflows + cron. Per-org fan-out via cron-splitter.
Ledger
Append-only hash-chained evidence + KMS-asymmetric signatures + S3 Object Lock anchor commits.

Connectors

Cognita ingests model + telemetry data through typed connectors. Each connector implements a small interface (test, listModels, pullTelemetry); credentials are envelope-encrypted at rest and webhook signatures are HMAC-verified.

ConnectorModesAuth
HuggingFacePullBearer token
MLflowPull + WebhookBearer (or token query)
Weights & BiasesPull + WebhookAPI key + HMAC webhook
ArizeWebhookHMAC body signature
GitHub ActionsWebhookX-Hub-Signature-256

Install via POST /api/connectors/install; rotate credentials by re-installing with the same (connectorId, workspaceId) tuple — the row is upserted in place.

AI Impact Assessments

Every model registered in the registry triggers an AIIA when its intended-use changes materially or its tier crosses a boundary (PRD §5.3). The risk engine tokenizes the intended-use string and matches it against EU AI Act Annex III + supporting articles; each clause becomes an answerable question in the stepper.

Sign-off captures actor, role, decision, IP, and timestamp into both the regular audit log AND the evidence chain. PDF export is hand-rolled (lib/pdf-text.ts) so the artifact can be vetted at the byte level.

# Open or refresh the AIIA for a model
curl -X GET https://app.cognitagrc.io/api/aiia/<modelId>

# Save answers (debounced PUT in the UI)
curl -X PUT https://app.cognitagrc.io/api/aiia/<aiiaId>/answers \
  -H 'x-csrf-token: <token>' -H 'Content-Type: application/json' \
  -d '{ "answers": { "Annex III §1(b)": { "state": "addressed", "note": "..." } } }'

# Sign as model owner
curl -X POST https://app.cognitagrc.io/api/aiia/<aiiaId>/sign \
  -H 'x-csrf-token: <token>' \
  -d '{ "role": "model-owner", "decision": "approved" }'

Evidence ledger

Every state transition that affects compliance posture is appended to a hash-chained, KMS-signed ledger. Hourly Inngest cron computes a Merkle root over the past hour's entries and commits it to the configured anchor backend (S3 Object Lock COMPLIANCE in production, in-memory in dev).

PropertyHow it's enforced
Append-onlyPostgres BEFORE UPDATE/DELETE trigger raises EXCEPTION; role-level grant denies UPDATE.
Tamper-detectionPer-row hash chain + KMS asymmetric signature (HMAC-SHA256 in dev). verifyChain re-runs both.
Cross-tenant safeRow-level security: app.current_org_id GUC scopes every query.
PII-safelib/pii-redactor.ts strips emails / phones / tokens / SSNs before hashing.
Auditor-portablePOST /api/audit/export emits a self-verifying ZIP with chain.json + verify-ledger.mjs CLI.

Auditors run the bundled CLI offline: node verify-ledger.mjs <dir> exits 0 only when every entry hashes correctly, every signature verifies, and the recomputed Merkle root matches the anchor.

Auditor sessions

External auditors get scoped, time-boxed credentials that don't see operator-only data. Their actions write to a parallel chain (auditor_audit_log) so the regular activity feed stays untainted.

# Owner mints a one-time redemption token
curl -X POST https://app.cognitagrc.io/api/auditor-sessions \
  -H 'x-csrf-token: <token>' \
  -d '{ "auditorName": "TÜV SÜD", "scope": { "framework": "iso42001" } }'
# → { redemptionToken: "<one-time>", session: { ... } }

# Auditor exchanges the token for a session cookie (CSRF-exempt; rate-limited)
curl -X POST https://app.cognitagrc.io/api/auditor-sessions/redeem \
  -d '{ "token": "<one-time>" }'

API reference

Selected endpoints — see source for the full list. Every mutating call requires a CSRF token; vendor webhooks are signature-authenticated instead.

MethodPathPurpose
GET/api/healthLiveness + readiness (Docker, Fly, Vercel)
POST/api/auth/sign-inMint dev-bypass session (Clerk-only in prod)
POST/api/billing/checkoutStripe Checkout Session (rate-limited)
POST/api/billing/webhookStripe webhook; CSRF-exempt, sig-authenticated
POST/api/connectors/installUpsert connector + envelope-encrypt token
POST/api/connectors/syncPull telemetry now (manual trigger)
POST/api/connectors/{vendor}/webhookInbound vendor events (HMAC-verified)
GET/api/aiia/[id]Fetch (or lazy-open) an AIIA
PUT/api/aiia/[id]/answersSave answers (debounced)
POST/api/aiia/[id]/signRecord sign-off + write to chain
POST/api/aiia/[id]/pdfExport AIIA as PDF (rate-limited)
POST/api/audit/exportBuild evidence bundle ZIP
POST/api/audit/commentAuditor comment (allowlisted under lock)
POST/api/auditor-lockActivate auditor lock
DELETE/api/auditor-lockRelease lock (admin step-up MFA in prod)
GET/api/telemetry/streamSSE feed for live breaches
POST/api/policiesCreate new policy version
POST/api/policies/[id]/publishPromote a draft to LIVE
POST/api/policies/evaluateRun a monitor expression against context

Self-hosting

Cognita ships ready-to-deploy configs for Vercel, Fly.io, Railway, and any Docker host.

Vercel
git push to main; vercel.json sets headers + /api/health cron. Use Neon / Supabase Postgres + Inngest Cloud.
Fly.io
fly deploy; fly.toml runs prisma db push + seed in release_command, http_service.checks pings /api/health.
Railway
Provision Postgres add-on; pre-deploy command is npx prisma db push --skip-generate --accept-data-loss && npx prisma db seed.
Bare Docker
Multi-stage Dockerfile produces ~80MB runner image. docker compose for local Postgres/Inngest/Mailhog.

Required env at minimum: DATABASE_URL, CONNECTOR_KEY_MASTER (32 bytes base64), and either Clerk env keys or DEV_AUTH_BYPASS=1.